From 57c77fe4d318a156d98606ee74f0064b22c31631 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:26:51 +0200 Subject: [PATCH 0001/1223] banlist: update set dirty to be more fine grained - move the SetBannedSetDirty(false) call from DumpData() into DumpBanlist() - ensure we only set false, if the write succeeded --- src/net.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 87c4f0af0..b13177fe2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1455,10 +1455,7 @@ void DumpData() DumpAddresses(); if (CNode::BannedSetIsDirty()) - { DumpBanlist(); - CNode::SetBannedSetDirty(false); - } } void static ProcessOneShot() @@ -2484,14 +2481,14 @@ bool CBanDB::Read(banmap_t& banSet) void DumpBanlist() { int64_t nStart = GetTimeMillis(); - - CNode::SweepBanned(); //clean unused entries (if bantime has expired) + CNode::SweepBanned(); // clean unused entries (if bantime has expired) CBanDB bandb; banmap_t banmap; CNode::GetBanned(banmap); - bandb.Write(banmap); + if (bandb.Write(banmap)) + CNode::SetBannedSetDirty(false); LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); + banmap.size(), GetTimeMillis() - nStart); } From ce479aaadaab296f0d06808fe230c4b13523cc28 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:44:49 +0200 Subject: [PATCH 0002/1223] banlist: better handling of banlist in StartNode() - only start working on/with banlist data, if reading in the banlist from disk didn't fail - as CNode::setBannedIsDirty is false (default) when reading fails, we don't need to explicitly set it to false to prevent writing banlist.dat in that case either --- src/net.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b13177fe2..6d39ccecd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1909,15 +1909,16 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) //try to read stored banlist CBanDB bandb; banmap_t banmap; - if (!bandb.Read(banmap)) + if (bandb.Read(banmap)) { + CNode::SetBanned(banmap); // thread save setter + CNode::SetBannedSetDirty(false); // no need to write down, just read data + CNode::SweepBanned(); // sweep out unused entries + + LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); + } else LogPrintf("Invalid or missing banlist.dat; recreating\n"); - CNode::SetBanned(banmap); //thread save setter - CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data - CNode::SweepBanned(); //sweap out unused entries - - LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); fAddressesInitialized = true; if (semOutbound == NULL) { From 2977c243efc9f122328de1bcfe12364498e0e2b6 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:46:17 +0200 Subject: [PATCH 0003/1223] banlist: add more banlist infos to log / add GUI signal - to match the peers.dat handling also supply a debug.log entry for how many entries were loaded from banlist.dat and how long it took - add a GUI init message for loading the banlist (same as with peers.dat) - move the same message for peers.dat upwards in the code, to be able to reuse the timing variable nStart and also just log, if our read from peers.dat didn't fail --- src/net.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 6d39ccecd..88a8edebc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -35,7 +35,7 @@ #include #include -// Dump addresses to peers.dat every 15 minutes (900s) +// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) @@ -555,11 +555,13 @@ void CNode::SweepBanned() banmap_t::iterator it = setBanned.begin(); while(it != setBanned.end()) { + CSubNet subNet = (*it).first; CBanEntry banEntry = (*it).second; if(now > banEntry.nBanUntil) { setBanned.erase(it++); setBannedIsDirty = true; + LogPrint("net", "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString()); } else ++it; @@ -1898,15 +1900,19 @@ void static Discover(boost::thread_group& threadGroup) void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { uiInterface.InitMessage(_("Loading addresses...")); - // Load addresses for peers.dat + // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { CAddrDB adb; - if (!adb.Read(addrman)) + if (adb.Read(addrman)) + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); + else LogPrintf("Invalid or missing peers.dat; recreating\n"); } - //try to read stored banlist + uiInterface.InitMessage(_("Loading banlist...")); + // Load addresses from banlist.dat + nStart = GetTimeMillis(); CBanDB bandb; banmap_t banmap; if (bandb.Read(banmap)) { @@ -1923,7 +1929,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); + int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } From e8600c924d58f3ef0450fc269998452e5b17aecb Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 10:46:08 +0200 Subject: [PATCH 0004/1223] banlist (bugfix): allow CNode::SweepBanned() to run on interval - allows CNode::SweepBanned() to run, even if !CNode::BannedSetIsDirty(), because if nBanUntil is over we want the ban to be disabled for these nodes --- src/net.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 88a8edebc..15ddaac63 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1455,9 +1455,7 @@ void DumpAddresses() void DumpData() { DumpAddresses(); - - if (CNode::BannedSetIsDirty()) - DumpBanlist(); + DumpBanlist(); } void static ProcessOneShot() @@ -2474,22 +2472,26 @@ bool CBanDB::Read(banmap_t& banSet) // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) return error("%s: Invalid network magic number", __func__); - + // de-serialize address data into one CAddrMan object ssBanlist >> banSet; } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - + return true; } void DumpBanlist() { - int64_t nStart = GetTimeMillis(); CNode::SweepBanned(); // clean unused entries (if bantime has expired) + if (!CNode::BannedSetIsDirty()) + return; + + int64_t nStart = GetTimeMillis(); + CBanDB bandb; banmap_t banmap; CNode::GetBanned(banmap); From 9e940fa4c650dd31c39dbc8ed4038e131c19d59c Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 10 Nov 2015 23:23:33 +0800 Subject: [PATCH 0005/1223] [depends] Boost 1.59.0 --- depends/packages/boost.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index d27a70134..215c694b6 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1_58_0 -$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.58.0 +$(package)_version=1_59_0 +$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.59.0 $(package)_file_name=$(package)_$($(package)_version).tar.bz2 -$(package)_sha256_hash=fdfc204fc33ec79c99b9a74944c3e54bd78be4f7f15e260c0e2700a36dc7d3e5 +$(package)_sha256_hash=727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca define $(package)_set_vars $(package)_config_opts_release=variant=release From 17ad964c2ff8f9be62a6826012b565843d3d72ba Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 10 Nov 2015 23:23:56 +0800 Subject: [PATCH 0006/1223] [depends] miniupnpc 1.9.20151026 --- depends/packages/miniupnpc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 77bae10c7..8cda7708c 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=1.9.20151008 +$(package)_version=1.9.20151026 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633 +$(package)_sha256_hash=f3cf9a5a31588a917d4d9237e5bc50f84d00c5aa48e27ed50d9b88dfa6a25d47 define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" From 26f8ea5342994bc3dcc22163b86f086328b50769 Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 10 Nov 2015 23:24:08 +0800 Subject: [PATCH 0007/1223] [depends] native ccache 3.2.4 --- depends/packages/native_ccache.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index 317674f79..cc76f9a79 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.2.3 +$(package)_version=3.2.4 $(package)_download_path=http://samba.org/ftp/ccache $(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b07165d4949d107d17f2f84b90b52953617bf1abbf249d5cc20636f43337c98c +$(package)_sha256_hash=ffeb967edb549e67da0bd5f44f729a2022de9fdde65dfd80d2a7204d7f75332e define $(package)_set_vars $(package)_config_opts= From 10d3c77644d894338a02b05f64ba822f3a516401 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 11 Nov 2015 14:28:13 +0800 Subject: [PATCH 0008/1223] [depends] Fix miniupnpc compilation on osx --- depends/packages/miniupnpc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 8cda7708c..3d5a6df97 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=f3cf9a5a31588a917d4d9237e5bc50f84d00c5aa48e27ed50d9b88dfa define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" -$(package)_build_opts_darwin=OS=Darwin +$(package)_build_opts_darwin=OS=Darwin LIBTOOL="$($(package)_libtool)" $(package)_build_opts_mingw32=-f Makefile.mingw $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" endef From 23a3c47f95c9c7c1778c488be6ea9ebbef2311ea Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 11 Nov 2015 17:53:34 +0800 Subject: [PATCH 0009/1223] [depends] zeromq 4.0.7 --- depends/packages/zeromq.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 24e8e5f1c..7b866e9c0 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.0.4 +$(package)_version=4.0.7 $(package)_download_path=http://download.zeromq.org $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399 +$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03 define $(package)_set_vars $(package)_config_opts=--without-documentation --disable-shared From 8504867b146014c99c6acb180020a1369069c761 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 12 Nov 2015 16:57:03 -0500 Subject: [PATCH 0010/1223] Save the last unnecessary database read It's possible coins with the same hash exist when you create a duplicate coinbase, so previously we were reading from the database to make sure we had the old coins cached so if we were to spend the new ones, the old ones would also be spent. This pull instead just marks the new coins as not fresh if they are from a coinbase, so if they are spent they will be written all the way down to the database anyway overwriting any duplicates. --- src/coins.cpp | 10 ++++++++-- src/coins.h | 2 +- src/main.cpp | 12 ++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index f0ea5c045..660181b0c 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -117,11 +117,17 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { return CCoinsModifier(*this, ret.first, cachedCoinUsage); } -CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) { +// ModifyNewCoins has to know whether the new outputs its creating are for a +// coinbase or not. If they are for a coinbase, it can not mark them as fresh. +// This is to ensure that the historical duplicate coinbases before BIP30 was +// in effect will still be properly overwritten when spent. +CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbase) { assert(!hasModifier); std::pair ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); ret.first->second.coins.Clear(); - ret.first->second.flags = CCoinsCacheEntry::FRESH; + if (!coinbase) { + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } ret.first->second.flags |= CCoinsCacheEntry::DIRTY; return CCoinsModifier(*this, ret.first, 0); } diff --git a/src/coins.h b/src/coins.h index 3b45cb0a3..77b4d5648 100644 --- a/src/coins.h +++ b/src/coins.h @@ -428,7 +428,7 @@ public: * would not properly overwrite the first coinbase of the pair. Simultaneous modifications * are not allowed. */ - CCoinsModifier ModifyNewCoins(const uint256 &txid); + CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase); /** * Push the modifications applied to this cache to its base. diff --git a/src/main.cpp b/src/main.cpp index 8fb121c00..3c9c77ef6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1310,17 +1310,9 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach undo.nVersion = coins->nVersion; } } - // add outputs - inputs.ModifyNewCoins(tx.GetHash())->FromTx(tx, nHeight); - } - else { - // add outputs for coinbase tx - // In this case call the full ModifyCoins which will do a database - // lookup to be sure the coins do not already exist otherwise we do not - // know whether to mark them fresh or not. We want the duplicate coinbases - // before BIP30 to still be properly overwritten. - inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } + // add outputs + inputs.ModifyNewCoins(tx.GetHash(), tx.IsCoinBase())->FromTx(tx, nHeight); } void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) From 086ee67d839b33bf475177f680fcc848a0625266 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 27 Nov 2015 13:20:29 +0100 Subject: [PATCH 0011/1223] Switch to a more efficient rolling Bloom filter For each 'bit' in the filter we really maintain 2 bits, which store either: 0: not set 1-3: set in generation N After (nElements / 2) insertions, we switch to a new generation, and wipe entries which already had the new generation number, effectively switching from the last 1.5 * nElements set to the last 1.0 * nElements set. This is 25% more space efficient than the previous implementation, and can (at peak) store 1.5 times the requested amount of history (though only 1.0 times the requested history is guaranteed). The existing unit tests should be sufficient. --- src/bloom.cpp | 77 +++++++++++++++++++++++++++++++++++---------------- src/bloom.h | 26 +++++++++++++---- src/main.cpp | 2 +- 3 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index de8720659..4bda2bbce 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -216,30 +216,54 @@ void CBloomFilter::UpdateEmptyFull() isEmpty = empty; } -CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) : - b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0) +CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) { - // Implemented using two bloom filters of 2 * nElements each. - // We fill them up, and clear them, staggered, every nElements - // inserted, so at least one always contains the last nElements - // inserted. - nInsertions = 0; - nBloomSize = nElements * 2; - + double logFpRate = log(fpRate); + /* The optimal number of hash functions is log(fpRate) / log(0.5), but + * restrict it to the range 1-50. */ + nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50)); + /* In this rolling bloom filter, we'll store between 2 and 3 generations of nElements / 2 entries. */ + nEntriesPerGeneration = (nElements + 1) / 2; + uint32_t nMaxElements = nEntriesPerGeneration * 3; + /* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits), nHashFuncs) + * => pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits) + * => 1.0 - pow(fpRate, 1.0 / nHashFuncs) = exp(-nHashFuncs * nMaxElements / nFilterBits) + * => log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) = -nHashFuncs * nMaxElements / nFilterBits + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs)) + */ + uint32_t nFilterBits = (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs))); + data.clear(); + /* We store up to 16 'bits' per data element. */ + data.resize((nFilterBits + 15) / 16); reset(); } +/* Similar to CBloomFilter::Hash */ +inline unsigned int CRollingBloomFilter::Hash(unsigned int nHashNum, const std::vector& vDataToHash) const { + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (data.size() * 16); +} + void CRollingBloomFilter::insert(const std::vector& vKey) { - if (nInsertions == 0) { - b1.clear(); - } else if (nInsertions == nBloomSize / 2) { - b2.clear(); + if (nEntriesThisGeneration == nEntriesPerGeneration) { + nEntriesThisGeneration = 0; + nGeneration++; + if (nGeneration == 4) { + nGeneration = 1; + } + /* Wipe old entries that used this generation number. */ + for (uint32_t p = 0; p < data.size() * 16; p++) { + if (get(p) == nGeneration) { + put(p, 0); + } + } } - b1.insert(vKey); - b2.insert(vKey); - if (++nInsertions == nBloomSize) { - nInsertions = 0; + nEntriesThisGeneration++; + + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + put(h, nGeneration); } } @@ -251,10 +275,13 @@ void CRollingBloomFilter::insert(const uint256& hash) bool CRollingBloomFilter::contains(const std::vector& vKey) const { - if (nInsertions < nBloomSize / 2) { - return b2.contains(vKey); + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + if (get(h) == 0) { + return false; + } } - return b1.contains(vKey); + return true; } bool CRollingBloomFilter::contains(const uint256& hash) const @@ -265,8 +292,10 @@ bool CRollingBloomFilter::contains(const uint256& hash) const void CRollingBloomFilter::reset() { - unsigned int nNewTweak = GetRand(std::numeric_limits::max()); - b1.reset(nNewTweak); - b2.reset(nNewTweak); - nInsertions = 0; + nTweak = GetRand(std::numeric_limits::max()); + nEntriesThisGeneration = 0; + nGeneration = 1; + for (std::vector::iterator it = data.begin(); it != data.end(); it++) { + *it = 0; + } } diff --git a/src/bloom.h b/src/bloom.h index a4dba8cb4..98cfbdb83 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -110,8 +110,11 @@ public: * reset() is provided, which also changes nTweak to decrease the impact of * false-positives. * - * contains(item) will always return true if item was one of the last N things + * contains(item) will always return true if item was one of the last N to 1.5*N * insert()'ed ... but may also return true for items that were not inserted. + * + * It needs around 1.8 bytes per element per factor 0.1 of false positive rate. + * (More accurately: 3/(log(256)*log(2)) * log(1/fpRate) * nElements bytes) */ class CRollingBloomFilter { @@ -129,10 +132,23 @@ public: void reset(); private: - unsigned int nBloomSize; - unsigned int nInsertions; - CBloomFilter b1, b2; + int nEntriesPerGeneration; + int nEntriesThisGeneration; + int nGeneration; + std::vector data; + unsigned int nTweak; + int nHashFuncs; + + unsigned int Hash(unsigned int nHashNum, const std::vector& vDataToHash) const; + + inline int get(uint32_t position) const { + return (data[(position >> 4) % data.size()] >> (2 * (position & 0xF))) & 0x3; + } + + inline void put(uint32_t position, uint32_t val) { + uint32_t& cell = data[(position >> 4) % data.size()]; + cell = (cell & ~(((uint32_t)3) << (2 * (position & 0xF)))) | (val << (2 * (position & 0xF))); + } }; - #endif // BITCOIN_BLOOM_H diff --git a/src/main.cpp b/src/main.cpp index ceb5cb66f..422b1e784 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -180,7 +180,7 @@ namespace { * million to make it highly unlikely for users to have issues with this * filter. * - * Memory used: 1.7MB + * Memory used: 1.3 MB */ boost::scoped_ptr recentRejects; uint256 hashRecentRejectsChainTip; From ec73ef37eccfeda76de55c4ff93ea54d4e69e1ec Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Thu, 26 Nov 2015 05:25:30 +0000 Subject: [PATCH 0012/1223] Replace setInventoryKnown with a rolling bloom filter. Mruset setInventoryKnown was reduced to a remarkably small 1000 entries as a side effect of sendbuffer size reductions in 2012. This removes setInventoryKnown filtering from merkleBlock responses because false positives there are especially unattractive and also because I'm not sure if there aren't race conditions around the relay pool that would cause some transactions there to be suppressed. (Also, ProcessGetData was accessing setInventoryKnown without taking the required lock.) --- src/main.cpp | 9 ++++----- src/net.cpp | 3 ++- src/net.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 901a34bde..5e39c31bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4138,8 +4138,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) - if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) - pfrom->PushMessage("tx", block.vtx[pair.first]); + pfrom->PushMessage("tx", block.vtx[pair.first]); } // else // no response @@ -5511,7 +5510,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { - if (pto->setInventoryKnown.count(inv)) + if (pto->setInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -5532,9 +5531,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } - // returns true if wasn't already contained in the set - if (pto->setInventoryKnown.insert(inv).second) + if (!pto->setInventoryKnown.contains(inv.hash)) { + pto->setInventoryKnown.insert(inv.hash); vInv.push_back(inv); if (vInv.size() >= 1000) { diff --git a/src/net.cpp b/src/net.cpp index abc7cbb8f..fc8fa30ee 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2342,7 +2342,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(SendBufferSize() / 1000) + setInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2369,6 +2369,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; + setInventoryKnown.reset(); fGetAddr = false; fRelayTxes = false; pfilter = new CBloomFilter(); diff --git a/src/net.h b/src/net.h index fb299fb0b..b0be3e652 100644 --- a/src/net.h +++ b/src/net.h @@ -386,7 +386,7 @@ public: std::set setKnown; // inventory based relay - mruset setInventoryKnown; + CRollingBloomFilter setInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; std::multimap mapAskFor; @@ -494,7 +494,7 @@ public: { { LOCK(cs_inventory); - setInventoryKnown.insert(inv); + setInventoryKnown.insert(inv.hash); } } @@ -502,7 +502,7 @@ public: { { LOCK(cs_inventory); - if (!setInventoryKnown.count(inv)) + if (!setInventoryKnown.contains(inv.hash)) vInventoryToSend.push_back(inv); } } From e20672479ef7f2048c2e27494397641d47a4d88d Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 28 Nov 2015 13:19:59 +0000 Subject: [PATCH 0013/1223] Remove mruset as it is no longer used. --- src/Makefile.am | 1 - src/Makefile.test.include | 1 - src/mruset.h | 65 ------------------------------- src/net.h | 1 - src/test/mruset_tests.cpp | 81 --------------------------------------- 5 files changed, 149 deletions(-) delete mode 100644 src/mruset.h delete mode 100644 src/test/mruset_tests.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 40f2e19af..b1dea69c9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,7 +117,6 @@ BITCOIN_CORE_H = \ memusage.h \ merkleblock.h \ miner.h \ - mruset.h \ net.h \ netbase.h \ noui.h \ diff --git a/src/Makefile.test.include b/src/Makefile.test.include index c377183ad..0f9cdd7fd 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -59,7 +59,6 @@ BITCOIN_TESTS =\ test/mempool_tests.cpp \ test/merkle_tests.cpp \ test/miner_tests.cpp \ - test/mruset_tests.cpp \ test/multisig_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ diff --git a/src/mruset.h b/src/mruset.h deleted file mode 100644 index 398aa173b..000000000 --- a/src/mruset.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_MRUSET_H -#define BITCOIN_MRUSET_H - -#include -#include -#include - -/** STL-like set container that only keeps the most recent N elements. */ -template -class mruset -{ -public: - typedef T key_type; - typedef T value_type; - typedef typename std::set::iterator iterator; - typedef typename std::set::const_iterator const_iterator; - typedef typename std::set::size_type size_type; - -protected: - std::set set; - std::vector order; - size_type first_used; - size_type first_unused; - const size_type nMaxSize; - -public: - mruset(size_type nMaxSizeIn = 1) : nMaxSize(nMaxSizeIn) { clear(); } - iterator begin() const { return set.begin(); } - iterator end() const { return set.end(); } - size_type size() const { return set.size(); } - bool empty() const { return set.empty(); } - iterator find(const key_type& k) const { return set.find(k); } - size_type count(const key_type& k) const { return set.count(k); } - void clear() - { - set.clear(); - order.assign(nMaxSize, set.end()); - first_used = 0; - first_unused = 0; - } - bool inline friend operator==(const mruset& a, const mruset& b) { return a.set == b.set; } - bool inline friend operator==(const mruset& a, const std::set& b) { return a.set == b; } - bool inline friend operator<(const mruset& a, const mruset& b) { return a.set < b.set; } - std::pair insert(const key_type& x) - { - std::pair ret = set.insert(x); - if (ret.second) { - if (set.size() == nMaxSize + 1) { - set.erase(order[first_used]); - order[first_used] = set.end(); - if (++first_used == nMaxSize) first_used = 0; - } - order[first_unused] = ret.first; - if (++first_unused == nMaxSize) first_unused = 0; - } - return ret; - } - size_type max_size() const { return nMaxSize; } -}; - -#endif // BITCOIN_MRUSET_H diff --git a/src/net.h b/src/net.h index b0be3e652..0332c0733 100644 --- a/src/net.h +++ b/src/net.h @@ -9,7 +9,6 @@ #include "bloom.h" #include "compat.h" #include "limitedmap.h" -#include "mruset.h" #include "netbase.h" #include "protocol.h" #include "random.h" diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp deleted file mode 100644 index 2b68f8899..000000000 --- a/src/test/mruset_tests.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "mruset.h" - -#include "random.h" -#include "util.h" -#include "test/test_bitcoin.h" - -#include - -#include - -#define NUM_TESTS 16 -#define MAX_SIZE 100 - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(mruset_test) -{ - // The mruset being tested. - mruset mru(5000); - - // Run the test 10 times. - for (int test = 0; test < 10; test++) { - // Reset mru. - mru.clear(); - - // A deque + set to simulate the mruset. - std::deque rep; - std::set all; - - // Insert 10000 random integers below 15000. - for (int j=0; j<10000; j++) { - int add = GetRandInt(15000); - mru.insert(add); - - // Add the number to rep/all as well. - if (all.count(add) == 0) { - all.insert(add); - rep.push_back(add); - if (all.size() == 5001) { - all.erase(rep.front()); - rep.pop_front(); - } - } - - // Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements. - if (j % 1000 == 0 || j % 5001 == 0) { - mruset mru2 = mru; // Also try making a copy - - // Check that all elements that should be in there, are in there. - BOOST_FOREACH(int x, rep) { - BOOST_CHECK(mru.count(x)); - BOOST_CHECK(mru2.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru) { - BOOST_CHECK(all.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru2) { - BOOST_CHECK(all.count(x)); - } - - for (int t = 0; t < 10; t++) { - int r = GetRandInt(15000); - BOOST_CHECK(all.count(r) == mru.count(r)); - BOOST_CHECK(all.count(r) == mru2.count(r)); - } - } - } - } -} - -BOOST_AUTO_TEST_SUITE_END() From 6b849350ab074a7ccb80ecbef387f59e1271ded6 Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Sun, 29 Nov 2015 01:52:51 -0800 Subject: [PATCH 0014/1223] Rename setInventoryKnown filterInventoryKnown --- src/main.cpp | 6 +++--- src/net.cpp | 4 ++-- src/net.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5e39c31bd..98457d31e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5510,7 +5510,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { - if (pto->setInventoryKnown.contains(inv.hash)) + if (pto->filterInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -5531,9 +5531,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } - if (!pto->setInventoryKnown.contains(inv.hash)) + if (!pto->filterInventoryKnown.contains(inv.hash)) { - pto->setInventoryKnown.insert(inv.hash); + pto->filterInventoryKnown.insert(inv.hash); vInv.push_back(inv); if (vInv.size() >= 1000) { diff --git a/src/net.cpp b/src/net.cpp index fc8fa30ee..59c0faac2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2342,7 +2342,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(50000, 0.000001) + filterInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2369,7 +2369,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; - setInventoryKnown.reset(); + filterInventoryKnown.reset(); fGetAddr = false; fRelayTxes = false; pfilter = new CBloomFilter(); diff --git a/src/net.h b/src/net.h index 0332c0733..7f3143510 100644 --- a/src/net.h +++ b/src/net.h @@ -385,7 +385,7 @@ public: std::set setKnown; // inventory based relay - CRollingBloomFilter setInventoryKnown; + CRollingBloomFilter filterInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; std::multimap mapAskFor; @@ -493,7 +493,7 @@ public: { { LOCK(cs_inventory); - setInventoryKnown.insert(inv.hash); + filterInventoryKnown.insert(inv.hash); } } @@ -501,7 +501,7 @@ public: { { LOCK(cs_inventory); - if (!setInventoryKnown.contains(inv.hash)) + if (!filterInventoryKnown.contains(inv.hash)) vInventoryToSend.push_back(inv); } } From b6a0da45db8d534e7a77d1cebe382cd5d83ba9b8 Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Sun, 29 Nov 2015 01:56:00 -0800 Subject: [PATCH 0015/1223] Only use filterInventoryKnown with MSG_TX inventory messages. Previously this logic could erroneously filter a MSG_BLOCK inventory message. --- src/net.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/net.h b/src/net.h index 7f3143510..25dea3fc3 100644 --- a/src/net.h +++ b/src/net.h @@ -501,8 +501,9 @@ public: { { LOCK(cs_inventory); - if (!filterInventoryKnown.contains(inv.hash)) - vInventoryToSend.push_back(inv); + if (inv.type == MSG_TX && filterInventoryKnown.contains(inv.hash)) + return; + vInventoryToSend.push_back(inv); } } From d41e44c9accb3df84e0abbc602cc76b72754d382 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 29 Nov 2015 22:10:31 +0000 Subject: [PATCH 0016/1223] Actually only use filterInventoryKnown with MSG_TX inventory messages. Previously this logic could erroneously filter a MSG_BLOCK inventory message. --- src/main.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 98457d31e..238e2276c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5510,7 +5510,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { - if (pto->filterInventoryKnown.contains(inv.hash)) + if (inv.type == MSG_TX && pto->filterInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -5531,15 +5531,13 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } - if (!pto->filterInventoryKnown.contains(inv.hash)) + pto->filterInventoryKnown.insert(inv.hash); + + vInv.push_back(inv); + if (vInv.size() >= 1000) { - pto->filterInventoryKnown.insert(inv.hash); - vInv.push_back(inv); - if (vInv.size() >= 1000) - { - pto->PushMessage("inv", vInv); - vInv.clear(); - } + pto->PushMessage("inv", vInv); + vInv.clear(); } } pto->vInventoryToSend = vInvWait; From aa4b0c26b0a94ca6164c441aae723e118554d214 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 30 Nov 2015 13:29:20 +0100 Subject: [PATCH 0017/1223] When not filtering blocks, getdata sends more in one test --- qa/rpc-tests/sendheaders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index d7f429209..63e071805 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -389,7 +389,7 @@ class SendHeadersTest(BitcoinTestFramework): # Use getblocks/getdata test_node.send_getblocks(locator = [fork_point]) - assert_equal(test_node.check_last_announcement(inv=new_block_hashes[0:-1]), True) + assert_equal(test_node.check_last_announcement(inv=new_block_hashes), True) test_node.get_data(new_block_hashes) test_node.wait_for_block(new_block_hashes[-1]) From b4404090259be4e34ef5dba33e47a41e7d9acc03 Mon Sep 17 00:00:00 2001 From: Matt Bogosian Date: Tue, 1 Dec 2015 22:49:51 -0800 Subject: [PATCH 0018/1223] Add missing automake package to deb-based UNIX install instructions. --- doc/build-unix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 159a14060..31bbab7f0 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -61,7 +61,7 @@ Dependency Build Instructions: Ubuntu & Debian ---------------------------------------------- Build requirements: - sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libevent-dev bsdmainutils + sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the individual boost development packages, so the following can be used to only From 110ff1142c5284edba8aab77fcac0bea0e551969 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 30 Nov 2015 15:42:27 +0100 Subject: [PATCH 0019/1223] [Tests] Add mempool_limit.py test --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/mempool_limit.py | 119 ++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100755 qa/rpc-tests/mempool_limit.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index df71e44b6..993646c50 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -83,6 +83,7 @@ testScripts = [ 'rest.py', 'mempool_spendcoinbase.py', 'mempool_reorg.py', + 'mempool_limit.py', 'httpbasics.py', 'multi_rpc.py', 'zapwallettxes.py', diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py new file mode 100755 index 000000000..aeaaa29f3 --- /dev/null +++ b/qa/rpc-tests/mempool_limit.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Test mempool limiting together/eviction with the wallet + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +class MempoolLimitTest(BitcoinTestFramework): + + def satoshi_round(self, amount): + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + + def __init__(self): + # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create + # So we have big transactions (and therefore can't fit very many into each block) + # create one script_pubkey + script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes + for i in xrange (512): + script_pubkey = script_pubkey + "01" + # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change + self.txouts = "81" + for k in xrange(128): + # add txout value + self.txouts = self.txouts + "0000000000000000" + # add length of script_pubkey + self.txouts = self.txouts + "fd0402" + # add script_pubkey + self.txouts = self.txouts + script_pubkey + + def create_confirmed_utxos(self, count): + self.nodes[0].generate(int(0.5*90)+102) + utxos = self.nodes[0].listunspent() + iterations = count - len(utxos) + addr1 = self.nodes[0].getnewaddress() + addr2 = self.nodes[0].getnewaddress() + if iterations <= 0: + return utxos + for i in xrange(iterations): + t = utxos.pop() + fee = self.relayfee + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr1] = self.satoshi_round(send_value/2) + outputs[addr2] = self.satoshi_round(send_value/2) + raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) + signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"] + txid = self.nodes[0].sendrawtransaction(signed_tx) + + while (self.nodes[0].getmempoolinfo()['size'] > 0): + self.nodes[0].generate(1) + + utxos = self.nodes[0].listunspent() + assert(len(utxos) >= count) + return utxos + + def create_lots_of_big_transactions(self, utxos, fee): + addr = self.nodes[0].getnewaddress() + txids = [] + for i in xrange(len(utxos)): + t = utxos.pop() + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr] = self.satoshi_round(send_value) + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + newtx = rawtx[0:92] + newtx = newtx + self.txouts + newtx = newtx + rawtx[94:] + signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE") + txid = self.nodes[0].sendrawtransaction(signresult["hex"], True) + txids.append(txid) + return txids + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, [])) + connect_nodes(self.nodes[0], 1) + self.is_network_split = False + self.sync_all() + self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def run_test(self): + txids = [] + utxos = self.create_confirmed_utxos(90) + + #create a mempool tx that will be evicted + us0 = utxos.pop() + inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] + outputs = {self.nodes[1].getnewaddress() : 0.0001} + tx = self.nodes[0].createrawtransaction(inputs, outputs) + txF = self.nodes[0].fundrawtransaction(tx) + txFS = self.nodes[0].signrawtransaction(txF['hex']) + txid = self.nodes[0].sendrawtransaction(txFS['hex']) + self.nodes[0].lockunspent(True, [us0]) + + relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + base_fee = relayfee*100 + for i in xrange (4): + txids.append([]) + txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee) + + # by now, the tx should be evicted, check confirmation state + assert(txid not in self.nodes[0].getrawmempool()) + txdata = self.nodes[0].gettransaction(txid); + assert(txdata['confirmations'] == 0) #confirmation should still be 0 + +if __name__ == '__main__': + MempoolLimitTest().main() From a3c3ddbd7ba68b9a9871b8574e05cc146a69f811 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 30 Nov 2015 16:15:15 +0100 Subject: [PATCH 0020/1223] [Qt] add InMempool() info to transaction details --- src/qt/transactiondesc.cpp | 4 +++- src/wallet/wallet.cpp | 17 +++++++++++------ src/wallet/wallet.h | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 801c6c62d..920ff0635 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -35,9 +35,11 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { int nDepth = wtx.GetDepthInMainChain(); if (nDepth < 0) - return tr("conflicted"); + return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth); else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) return tr("%1/offline").arg(nDepth); + else if (nDepth == 0) + return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))); else if (nDepth < 6) return tr("%1/unconfirmed").arg(nDepth); else diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 30b9869be..f49950da6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1359,6 +1359,15 @@ CAmount CWalletTx::GetChange() const return nChangeCached; } +bool CWalletTx::InMempool() const +{ + LOCK(mempool.cs); + if (mempool.exists(GetHash())) { + return true; + } + return false; +} + bool CWalletTx::IsTrusted() const { // Quick answer in most cases @@ -1373,12 +1382,8 @@ bool CWalletTx::IsTrusted() const return false; // Don't trust unconfirmed transactions from us unless they are in the mempool. - { - LOCK(mempool.cs); - if (!mempool.exists(GetHash())) { - return false; - } - } + if (!InMempool()) + return false; // Trusted if all inputs are from us and are in the mempool: BOOST_FOREACH(const CTxIn& txin, vin) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 859788893..7354ff19c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -384,6 +384,7 @@ public: // True if only scriptSigs are different bool IsEquivalentTo(const CWalletTx& tx) const; + bool InMempool() const; bool IsTrusted() const; bool WriteToDisk(CWalletDB *pwalletdb); From 6e765873605ee5e31652ce107848a157151791b4 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 2 Dec 2015 13:42:47 +0100 Subject: [PATCH 0021/1223] rpc: remove cs_main lock from `createrawtransaction` This is a pure utility function that doesn't use main's data structures, so it does not require that lock. --- src/rpcrawtransaction.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 1f2d77aef..4947ad1f7 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -353,7 +353,6 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); - LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true); if (params[0].isNull() || params[1].isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null"); From eb306664e786ae43d539fde66f0fbe2a3e89d910 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 19 Nov 2015 11:18:28 -0500 Subject: [PATCH 0022/1223] Fix mempool limiting for PrioritiseTransaction Redo the feerate index to be based on mining score, rather than fee. Update mempool_packages.py to test prioritisetransaction's effect on package scores. --- qa/rpc-tests/mempool_packages.py | 24 +++++++++++++++ src/rpcblockchain.cpp | 4 +-- src/txmempool.cpp | 53 ++++++++++++++++++-------------- src/txmempool.h | 43 +++++++++++++------------- 4 files changed, 78 insertions(+), 46 deletions(-) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 34b316a6a..063308d39 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -64,17 +64,41 @@ class MempoolPackagesTest(BitcoinTestFramework): for x in reversed(chain): assert_equal(mempool[x]['descendantcount'], descendant_count) descendant_fees += mempool[x]['fee'] + assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees) descendant_size += mempool[x]['size'] assert_equal(mempool[x]['descendantsize'], descendant_size) descendant_count += 1 + # Check that descendant modified fees includes fee deltas from + # prioritisetransaction + self.nodes[0].prioritisetransaction(chain[-1], 0, 1000) + mempool = self.nodes[0].getrawmempool(True) + + descendant_fees = 0 + for x in reversed(chain): + descendant_fees += mempool[x]['fee'] + assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+1000) + # Adding one more transaction on to the chain should fail. try: self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) except JSONRPCException as e: print "too-long-ancestor-chain successfully rejected" + # Check that prioritising a tx before it's added to the mempool works + self.nodes[0].generate(1) + self.nodes[0].prioritisetransaction(chain[-1], 0, 2000) + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + mempool = self.nodes[0].getrawmempool(True) + + descendant_fees = 0 + for x in reversed(chain): + descendant_fees += mempool[x]['fee'] + if (x == chain[-1]): + assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002)) + assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+2000) + # TODO: check that node1's mempool is as expected # TODO: test ancestor size limits diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ee04636ce..73e6f8029 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -197,7 +197,7 @@ UniValue mempoolToJSON(bool fVerbose = false) info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetFeesWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); const CTransaction& tx = e.GetTx(); set setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -255,7 +255,7 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) " \"currentpriority\" : n, (numeric) transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" - " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" " ... ]\n" diff --git a/src/txmempool.cpp b/src/txmempool.cpp index fea5da802..c72a1e8c1 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -33,7 +33,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = nFee; CAmount nValueIn = tx.GetValueOut()+nFee; assert(inChainInputValue <= nValueIn); @@ -57,6 +57,7 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) { + nModFeesWithDescendants += newFeeDelta - feeDelta; feeDelta = newFeeDelta; } @@ -114,7 +115,7 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit BOOST_FOREACH(txiter cit, setAllDescendants) { if (!setExclude.count(cit->GetTx().GetHash())) { modifySize += cit->GetTxSize(); - modifyFee += cit->GetFee(); + modifyFee += cit->GetModifiedFee(); modifyCount++; cachedDescendants[updateIt].insert(cit); } @@ -244,7 +245,7 @@ void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors } const int64_t updateCount = (add ? 1 : -1); const int64_t updateSize = updateCount * it->GetTxSize(); - const CAmount updateFee = updateCount * it->GetFee(); + const CAmount updateFee = updateCount * it->GetModifiedFee(); BOOST_FOREACH(txiter ancestorIt, setAncestors) { mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount)); } @@ -304,7 +305,7 @@ void CTxMemPoolEntry::SetDirty() { nCountWithDescendants = 0; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = GetModifiedFee(); } void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) @@ -312,8 +313,7 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t if (!IsDirty()) { nSizeWithDescendants += modifySize; assert(int64_t(nSizeWithDescendants) > 0); - nFeesWithDescendants += modifyFee; - assert(nFeesWithDescendants >= 0); + nModFeesWithDescendants += modifyFee; nCountWithDescendants += modifyCount; assert(int64_t(nCountWithDescendants) > 0); } @@ -372,6 +372,17 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, indexed_transaction_set::iterator newit = mapTx.insert(entry).first; mapLinks.insert(make_pair(newit, TxLinks())); + // Update transaction for any feeDelta created by PrioritiseTransaction + // TODO: refactor so that the fee delta is calculated before inserting + // into mapTx. + std::map >::const_iterator pos = mapDeltas.find(hash); + if (pos != mapDeltas.end()) { + const std::pair &deltas = pos->second; + if (deltas.second) { + mapTx.modify(newit, update_fee_delta(deltas.second)); + } + } + // Update cachedInnerUsage to include contained transaction's usage. // (When we update the entry for in-mempool parents, memory usage will be // further updated.) @@ -399,15 +410,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, } UpdateAncestorsOf(true, newit, setAncestors); - // Update transaction's score for any feeDelta created by PrioritiseTransaction - std::map >::const_iterator pos = mapDeltas.find(hash); - if (pos != mapDeltas.end()) { - const std::pair &deltas = pos->second; - if (deltas.second) { - mapTx.modify(newit, update_fee_delta(deltas.second)); - } - } - nTransactionsUpdated++; totalTxSize += entry.GetTxSize(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); @@ -644,27 +646,24 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const CTxMemPool::setEntries setChildrenCheck; std::map::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; - CAmount childFees = 0; + CAmount childModFee = 0; for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { txiter childit = mapTx.find(iter->second.ptx->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); - childFees += childit->GetFee(); + childModFee += childit->GetModifiedFee(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); - // Also check to make sure size/fees is greater than sum with immediate children. + // Also check to make sure size is greater than sum with immediate children. // just a sanity check, not definitive that this calc is correct... - // also check that the size is less than the size of the entire mempool. if (!it->IsDirty()) { assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); - assert(it->GetFeesWithDescendants() >= childFees + it->GetFee()); } else { assert(it->GetSizeWithDescendants() == it->GetTxSize()); - assert(it->GetFeesWithDescendants() == it->GetFee()); + assert(it->GetModFeesWithDescendants() == it->GetModifiedFee()); } - assert(it->GetFeesWithDescendants() >= 0); if (fDependsWait) waitingOnDependants.push_back(&(*it)); @@ -788,6 +787,14 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, txiter it = mapTx.find(hash); if (it != mapTx.end()) { mapTx.modify(it, update_fee_delta(deltas.second)); + // Now update all ancestors' modified fees with descendants + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0)); + } } } LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); @@ -956,7 +963,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe // "minimum reasonable fee rate" (ie some value under which we consider txn // to have 0 fee). This way, we don't allow txn to enter mempool with feerate // equal to txn which were removed with no block in between. - CFeeRate removed(it->GetFeesWithDescendants(), it->GetSizeWithDescendants()); + CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants()); removed += minReasonableRelayFee; trackPackageRemoved(removed); maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed); diff --git a/src/txmempool.h b/src/txmempool.h index 920317186..4b726cc90 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -44,12 +44,12 @@ class CTxMemPool; * ("descendant" transactions). * * When a new entry is added to the mempool, we update the descendant state - * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for + * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for * all ancestors of the newly added transaction. * * If updating the descendant state is skipped, we can mark the entry as - * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/ - * nTxFee. (This can potentially happen during a reorg, where we limit the + * "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/ + * nFee+feeDelta. (This can potentially happen during a reorg, where we limit the * amount of work we're willing to do to avoid consuming too much CPU.) * */ @@ -74,11 +74,11 @@ private: // Information about descendants of this transaction that are in the // mempool; if we remove this transaction we must remove all of these // descendants as well. if nCountWithDescendants is 0, treat this entry as - // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be + // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be // correct. uint64_t nCountWithDescendants; //! number of descendant transactions uint64_t nSizeWithDescendants; //! ... and size - CAmount nFeesWithDescendants; //! ... and total fees (all including us) + CAmount nModFeesWithDescendants; //! ... and total fees (all including us) public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, @@ -104,7 +104,8 @@ public: // Adjusts the descendant state, if this entry is not dirty. void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); - // Updates the fee delta used for mining priority score + // Updates the fee delta used for mining priority score, and the + // modified fees with descendants. void UpdateFeeDelta(int64_t feeDelta); /** We can set the entry to be dirty if doing the full calculation of in- @@ -116,7 +117,7 @@ public: uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } - CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; } + CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } bool GetSpendsCoinbase() const { return spendsCoinbase; } }; @@ -163,27 +164,27 @@ struct mempoolentry_txid } }; -/** \class CompareTxMemPoolEntryByFee +/** \class CompareTxMemPoolEntryByDescendantScore * - * Sort an entry by max(feerate of entry's tx, feerate with all descendants). + * Sort an entry by max(score/size of entry's tx, score/size with all descendants). */ -class CompareTxMemPoolEntryByFee +class CompareTxMemPoolEntryByDescendantScore { public: bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) { - bool fUseADescendants = UseDescendantFeeRate(a); - bool fUseBDescendants = UseDescendantFeeRate(b); + bool fUseADescendants = UseDescendantScore(a); + bool fUseBDescendants = UseDescendantScore(b); - double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee(); + double aModFee = fUseADescendants ? a.GetModFeesWithDescendants() : a.GetModifiedFee(); double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); - double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee(); + double bModFee = fUseBDescendants ? b.GetModFeesWithDescendants() : b.GetModifiedFee(); double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize(); // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). - double f1 = aFees * bSize; - double f2 = aSize * bFees; + double f1 = aModFee * bSize; + double f2 = aSize * bModFee; if (f1 == f2) { return a.GetTime() >= b.GetTime(); @@ -191,11 +192,11 @@ public: return f1 < f2; } - // Calculate which feerate to use for an entry (avoiding division). - bool UseDescendantFeeRate(const CTxMemPoolEntry &a) + // Calculate which score to use for an entry (avoiding division). + bool UseDescendantScore(const CTxMemPoolEntry &a) { - double f1 = (double)a.GetFee() * a.GetSizeWithDescendants(); - double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize(); + double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants(); + double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize(); return f2 > f1; } }; @@ -350,7 +351,7 @@ public: // sorted by fee rate boost::multi_index::ordered_non_unique< boost::multi_index::identity, - CompareTxMemPoolEntryByFee + CompareTxMemPoolEntryByDescendantScore >, // sorted by entry time boost::multi_index::ordered_non_unique< From 9ef2a25603c9ec4e44c4f45c6a5d4e4386ec86d3 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 30 Nov 2015 16:42:36 -0500 Subject: [PATCH 0023/1223] Update replace-by-fee logic to use fee deltas --- qa/rpc-tests/replace-by-fee.py | 80 +++++++++++++++++++++++++++++++++- src/main.cpp | 18 +++++--- 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 6e9e0b304..734db33b5 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -63,8 +63,14 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): # If requested, ensure txouts are confirmed. if confirmed: - while len(node.getrawmempool()): + mempool_size = len(node.getrawmempool()) + while mempool_size > 0: node.generate(1) + new_size = len(node.getrawmempool()) + # Error out if we have something stuck in the mempool, as this + # would likely be a bug. + assert(new_size < mempool_size) + mempool_size = new_size return COutPoint(int(txid, 16), 0) @@ -72,7 +78,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug", "-relaypriority=0", "-whitelist=127.0.0.1", "-limitancestorcount=50", "-limitancestorsize=101", @@ -108,6 +114,9 @@ class ReplaceByFeeTest(BitcoinTestFramework): print "Running test opt-in..." self.test_opt_in() + print "Running test prioritised transactions..." + self.test_prioritised_transactions() + print "Passed\n" def test_simple_doublespend(self): @@ -513,5 +522,72 @@ class ReplaceByFeeTest(BitcoinTestFramework): # but make sure it is accepted anyway self.nodes[0].sendrawtransaction(tx3c_hex, True) + def test_prioritised_transactions(self): + # Ensure that fee deltas used via prioritisetransaction are + # correctly used by replacement logic + + # 1. Check that feeperkb uses modified fees + tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx1a = CTransaction() + tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + # Higher fee, but the actual fee per KB is much lower. + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))] + tx1b_hex = txToHex(tx1b) + + # Verify tx1b cannot replace tx1a. + try: + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Use prioritisetransaction to set tx1a's fee to 0. + self.nodes[0].prioritisetransaction(tx1a_txid, 0, int(-0.1*COIN)) + + # Now tx1b should be able to replace tx1a + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + + assert(tx1b_txid in self.nodes[0].getrawmempool()) + + # 2. Check that absolute fee checks use modified fee. + tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx2a = CTransaction() + tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)] + tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx2a_hex = txToHex(tx2a) + tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True) + + # Lower fee, but we'll prioritise it + tx2b = CTransaction() + tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] + tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))] + tx2b.rehash() + tx2b_hex = txToHex(tx2b) + + # Verify tx2b cannot replace tx2a. + try: + tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Now prioritise tx2b to have a higher modified fee + self.nodes[0].prioritisetransaction(tx2b.hash, 0, int(0.1*COIN)) + + # tx2b should now be accepted + tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True) + + assert(tx2b_txid in self.nodes[0].getrawmempool()) + if __name__ == '__main__': ReplaceByFeeTest().main() diff --git a/src/main.cpp b/src/main.cpp index cb3f8f39f..23df8ca68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1061,13 +1061,17 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C uint64_t nConflictingCount = 0; CTxMemPool::setEntries allConflicting; + CAmount nModifiedFees = nFees; + double nPriorityDummy = 0; + pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); + // If we don't hold the lock allConflicting might be incomplete; the // subsequent RemoveStaged() and addUnchecked() calls don't guarantee // mempool consistency for us. LOCK(pool.cs); if (setConflicts.size()) { - CFeeRate newFeeRate(nFees, nSize); + CFeeRate newFeeRate(nModifiedFees, nSize); set setConflictsParents; const int maxDescendantsToVisit = 100; CTxMemPool::setEntries setIterConflicting; @@ -1110,7 +1114,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // ignored when deciding whether or not to replace, we do // require the replacement to pay more overall fees too, // mitigating most cases. - CFeeRate oldFeeRate(mi->GetFee(), mi->GetTxSize()); + CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); if (newFeeRate <= oldFeeRate) { return state.DoS(0, @@ -1138,7 +1142,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C pool.CalculateDescendants(it, allConflicting); } BOOST_FOREACH(CTxMemPool::txiter it, allConflicting) { - nConflictingFees += it->GetFee(); + nConflictingFees += it->GetModifiedFee(); nConflictingSize += it->GetTxSize(); } } else { @@ -1171,16 +1175,16 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // The replacement must pay greater fees than the transactions it // replaces - if we did the bandwidth used by those conflicting // transactions would not be paid for. - if (nFees < nConflictingFees) + if (nModifiedFees < nConflictingFees) { return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", - hash.ToString(), FormatMoney(nFees), FormatMoney(nConflictingFees)), + hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), REJECT_INSUFFICIENTFEE, "insufficient fee"); } // Finally in addition to paying more fees than the conflicts the // new transaction must pay for its own bandwidth. - CAmount nDeltaFees = nFees - nConflictingFees; + CAmount nDeltaFees = nModifiedFees - nConflictingFees; if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) { return state.DoS(0, @@ -1218,7 +1222,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C LogPrint("mempool", "replacing tx %s with %s for %s BTC additional fees, %d delta bytes\n", it->GetTx().GetHash().ToString(), hash.ToString(), - FormatMoney(nFees - nConflictingFees), + FormatMoney(nModifiedFees - nConflictingFees), (int)nSize - (int)nConflictingSize); } pool.RemoveStaged(allConflicting); From 27fae3484cdb21b0d24face833b966fce5926be5 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 2 Dec 2015 09:37:18 -0500 Subject: [PATCH 0024/1223] Use fee deltas for determining mempool acceptance --- qa/rpc-tests/prioritise_transaction.py | 40 ++++++++++++++++++++++++++ src/main.cpp | 18 +++++++----- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index f376ceee5..d9492f27a 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -143,5 +143,45 @@ class PrioritiseTransactionTest(BitcoinTestFramework): if (x != high_fee_tx): assert(x not in mempool) + # Create a free, low priority transaction. Should be rejected. + utxo_list = self.nodes[0].listunspent() + assert(len(utxo_list) > 0) + utxo = utxo_list[0] + + inputs = [] + outputs = {} + inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]}) + outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee + raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) + tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"] + txid = self.nodes[0].sendrawtransaction(tx_hex) + + # A tx that spends an in-mempool tx has 0 priority, so we can use it to + # test the effect of using prioritise transaction for mempool acceptance + inputs = [] + inputs.append({"txid": txid, "vout": 0}) + outputs = {} + outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee + raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs) + tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"] + tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"] + + try: + self.nodes[0].sendrawtransaction(tx2_hex) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + assert(tx2_id not in self.nodes[0].getrawmempool()) + else: + assert(False) + + # This is a less than 1000-byte transaction, so just set the fee + # to be the minimum for a 1000 byte transaction and check that it is + # accepted. + self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN)) + + print "Assert that prioritised free transaction is accepted to mempool" + assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id) + assert(tx2_id in self.nodes[0].getrawmempool()) + if __name__ == '__main__': PrioritiseTransactionTest().main() diff --git a/src/main.cpp b/src/main.cpp index 23df8ca68..12642f319 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -968,6 +968,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; + // nModifiedFees includes any fee deltas from PrioritiseTransaction + CAmount nModifiedFees = nFees; + double nPriorityDummy = 0; + pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); + CAmount inChainInputValue; double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue); @@ -987,14 +992,17 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // Don't accept it if it can't get into a block CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true); + + // txMinFee takes into account priority/fee deltas, so compare using + // nFees rather than nModifiedFees if (fLimitFree && nFees < txMinFee) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, strprintf("%d < %d", nFees, txMinFee)); CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); - if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) { + if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); - } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { + } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { // Require that free transactions have sufficient priority to be mined in the next block. return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } @@ -1002,7 +1010,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) + if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -1061,10 +1069,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C uint64_t nConflictingCount = 0; CTxMemPool::setEntries allConflicting; - CAmount nModifiedFees = nFees; - double nPriorityDummy = 0; - pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); - // If we don't hold the lock allConflicting might be incomplete; the // subsequent RemoveStaged() and addUnchecked() calls don't guarantee // mempool consistency for us. From 901b01d674031f9aca717deeb372bafa160a24af Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 2 Dec 2015 11:04:15 -0500 Subject: [PATCH 0025/1223] Remove GetMinRelayFee One test in AcceptToMemoryPool was to compare a transaction's fee agains the value returned by GetMinRelayFee. This value was zero for all small transactions. For larger transactions (between DEFAULT_BLOCK_PRIORITY_SIZE and MAX_STANDARD_TX_SIZE), this function was preventing low fee transactions from ever being accepted. With this function removed, we will now allow transactions in that range with fees (including modifications via PrioritiseTransaction) below the minRelayTxFee, provided that they have sufficient priority. --- src/main.cpp | 35 ----------------------------------- src/main.h | 2 -- 2 files changed, 37 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 12642f319..9363015a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -800,32 +800,6 @@ void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) { pcoinsTip->Uncache(removed); } -CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes, bool fAllowFree) -{ - uint256 hash = tx.GetHash(); - double dPriorityDelta = 0; - CAmount nFeeDelta = 0; - pool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); - if (dPriorityDelta > 0 || nFeeDelta > 0) - return 0; - - CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); - - if (fAllowFree) - { - // There is a free transaction area in blocks created by most miners, - // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000 - // to be considered to fall into this category. We don't want to encourage sending - // multiple transactions instead of one big transaction to avoid fees. - if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)) - nMinFee = 0; - } - - if (!MoneyRange(nMinFee)) - nMinFee = MAX_MONEY; - return nMinFee; -} - /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state) { @@ -990,15 +964,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps); unsigned int nSize = entry.GetTxSize(); - // Don't accept it if it can't get into a block - CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true); - - // txMinFee takes into account priority/fee deltas, so compare using - // nFees rather than nModifiedFees - if (fLimitFree && nFees < txMinFee) - return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, - strprintf("%d < %d", nFees, txMinFee)); - CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); diff --git a/src/main.h b/src/main.h index 19623f4d9..d813f01ba 100644 --- a/src/main.h +++ b/src/main.h @@ -293,8 +293,6 @@ struct CDiskTxPos : public CDiskBlockPos }; -CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); - /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent From c12ff995f7d70aafb12f34887fb64aa7482bbc85 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 3 Dec 2015 11:59:37 +0100 Subject: [PATCH 0026/1223] Now that 0.12 has been branched, master is 0.12.99 ... in preparation for 0.13 --- configure.ac | 2 +- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- doc/Doxyfile | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- doc/release-notes.md | 268 +------------------- src/clientversion.h | 2 +- 9 files changed, 11 insertions(+), 273 deletions(-) diff --git a/configure.ac b/configure.ac index 63a745393..9161e2b2c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 11) +define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 0c3c439dd..52b898b67 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.12" +name: "bitcoin-linux-0.13" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 9ac774c8a..cdb266d75 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-osx-0.12" +name: "bitcoin-osx-0.13" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 6bb482d45..51240b2ce 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.12" +name: "bitcoin-win-0.13" enable_cache: true suites: - "trusty" diff --git a/doc/Doxyfile b/doc/Doxyfile index 925a33ee8..428fba98e 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.11.99 +PROJECT_NUMBER = 0.12.99 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index f6df28a89..c0f9ee522 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.11.99 +Bitcoin Core 0.12.99 ===================== Setup diff --git a/doc/README_windows.txt b/doc/README_windows.txt index e4fd9bdf9..2d1c4503c 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.11.99 +Bitcoin Core 0.12.99 ===================== Intro diff --git a/doc/release-notes.md b/doc/release-notes.md index 96c830d17..8bb842ddb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -4,236 +4,11 @@ release-notes at release time) Notable changes =============== -SSL support for RPC dropped ----------------------------- +Example item +---------------- -SSL support for RPC, previously enabled by the option `rpcssl` has been dropped -from both the client and the server. This was done in preparation for removing -the dependency on OpenSSL for the daemon completely. -Trying to use `rpcssl` will result in an error: - - Error: SSL mode for RPC (-rpcssl) is no longer supported. - -If you are one of the few people that relies on this feature, a flexible -migration path is to use `stunnel`. This is an utility that can tunnel -arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with: - - sudo apt-get install stunnel4 - -Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do: - - stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P '' - -It can also be set up system-wide in inetd style. - -Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution -would allow the use of different authentication, loadbalancing, on-the-fly compression and -caching. A sample config for apache2 could look like: - - Listen 443 - - NameVirtualHost *:443 - - - SSLEngine On - SSLCertificateFile /etc/apache2/ssl/server.crt - SSLCertificateKeyFile /etc/apache2/ssl/server.key - - - ProxyPass http://127.0.0.1:8332/ - ProxyPassReverse http://127.0.0.1:8332/ - # optional enable digest auth - # AuthType Digest - # ... - - # optional bypass bitcoind rpc basic auth - # RequestHeader set Authorization "Basic " - # get the from the shell with: base64 <<< bitcoinrpc: - - - # Or, balance the load: - # ProxyPass / balancer://balancer_cluster_name - - - -Random-cookie RPC authentication ---------------------------------- - -When no `-rpcpassword` is specified, the daemon now uses a special 'cookie' -file for authentication. This file is generated with random content when the -daemon starts, and deleted when it exits. Its contents are used as -authentication token. Read access to this file controls who can access through -RPC. By default it is stored in the data directory but its location can be -overridden with the option `-rpccookiefile`. - -This is similar to Tor's CookieAuthentication: see -https://www.torproject.org/docs/tor-manual.html.en - -This allows running bitcoind without having to do any manual configuration. - -Low-level RPC API changes --------------------------- - -- Monetary amounts can be provided as strings. This means that for example the - argument to sendtoaddress can be "0.0001" instead of 0.0001. This can be an - advantage if a JSON library insists on using a lossy floating point type for - numbers, which would be dangerous for monetary amounts. - -Option parsing behavior ------------------------ - -Command line options are now parsed strictly in the order in which they are -specified. It used to be the case that `-X -noX` ends up, unintuitively, with X -set, as `-X` had precedence over `-noX`. This is no longer the case. Like for -other software, the last specified value for an option will hold. - -`NODE_BLOOM` service bit ------------------------- - -Support for the `NODE_BLOOM` service bit, as described in [BIP -111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been -added to the P2P protocol code. - -BIP 111 defines a service bit to allow peers to advertise that they support -bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol -version to allow peers to identify old nodes which allow bloom filtering of the -connection despite lacking the new service bit. - -In this version, it is only enforced for peers that send protocol versions -`>=70011`. For the next major version it is planned that this restriction will be -removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` -service bit for nodes that report versions newer than 70011. - -Any sequence of pushdatas in OP_RETURN outputs now allowed ----------------------------------------------------------- - -Previously OP_RETURN outputs with a payload were only relayed and mined if they -had a single pushdata. This restriction has been lifted to allow any -combination of data pushes and numeric constant opcodes (OP_1 to OP_16). The -limit on OP_RETURN output size is now applied to the entire serialized -scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three -bytes overhead) - -Merkle branches removed from wallet ------------------------------------ - -Previously, every wallet transaction stored a Merkle branch to prove its -presence in blocks. This wasn't being used for more than an expensive -sanity check. Since 0.12, these are no longer stored. When loading a -0.12 wallet into an older version, it will automatically rescan to avoid -failed checks. - -BIP65 - CHECKLOCKTIMEVERIFY ---------------------------- - -Previously it was impossible to create a transaction output that was guaranteed -to be unspendable until a specific date in the future. CHECKLOCKTIMEVERIFY is a -new opcode that allows a script to check if a specific block height or time has -been reached, failing the script otherwise. This enables a wide variety of new -functionality such as time-locked escrows, secure payment channels, etc. - -BIP65 implements CHECKLOCKTIMEVERIFY by introducing block version 4, which adds -additional restrictions to the NOP2 opcode. The same miner-voting mechanism as -in BIP34 and BIP66 is used: when 751 out of a sequence of 1001 blocks have -version number 4 or higher, the new consensus rule becomes active for those -blocks. When 951 out of a sequence of 1001 blocks have version number 4 or -higher, it becomes mandatory for all blocks and blocks with versions less than -4 are rejected. - -Bitcoin Core's block templates are now for version 4 blocks only, and any -mining software relying on its `getblocktemplate` must be updated in parallel -to use either libblkmaker version 0.4.3 or any version from 0.5.2 onward. If -you are solo mining, this will affect you the moment you upgrade Bitcoin Core, -which must be done prior to BIP65 achieving its 951/1001 status. If you are -mining with the stratum mining protocol: this does not affect you. If you are -mining with the getblocktemplate protocol to a pool: this will affect you at -the pool operator's discretion, which must be no later than BIP65 achieving its -951/1001 status. - -Automatically use Tor hidden services -------------------------------------- - -Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket -API, to create and destroy 'ephemeral' hidden services programmatically. -Bitcoin Core has been updated to make use of this. - -This means that if Tor is running (and proper authorization is available), -Bitcoin Core automatically creates a hidden service to listen on, without -manual configuration. Bitcoin Core will also use Tor automatically to connect -to other .onion nodes if the control socket can be successfully opened. This -will positively affect the number of available .onion nodes and their usage. - -This new feature is enabled by default if Bitcoin Core is listening, and -a connection to Tor can be made. It can be configured with the `-listenonion`, -`-torcontrol` and `-torpassword` settings. To show verbose debugging -information, pass `-debug=tor`. - -Reduce upload traffic ---------------------- - -A major part of the outbound traffic is caused by serving historic blocks to -other nodes in initial block download state. - -It is now possible to reduce the total upload traffic via the `-maxuploadtarget` -parameter. This is *not* a hard limit but a threshold to minimize the outbound -traffic. When the limit is about to be reached, the uploaded data is cut by not -serving historic blocks (blocks older than one week). -Moreover, any SPV peer is disconnected when they request a filtered block. - -This option can be specified in MiB per day and is turned off by default -(`-maxuploadtarget=0`). -The recommended minimum is 144 * MAX_BLOCK_SIZE (currently 144MB) per day. - -Whitelisted peers will never be disconnected, although their traffic counts for -calculating the target. - -A more detailed documentation about keeping traffic low can be found in -[/doc/reducetraffic.md](/doc/reducetraffic.md). - -Signature validation using libsecp256k1 ---------------------------------------- - -ECDSA signatures inside Bitcoin transactions now use validation using -[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. - -Depending on the platform, this means a significant speedup for raw signature -validation speed. The advantage is largest on x86_64, where validation is over -five times faster. In practice, this translates to a raw reindexing and new -block validation times that are less than half of what it was before. - -Libsecp256k1 has undergone very extensive testing and validation. - -A side effect of this change is that libconsensus no longer depends on OpenSSL. - -Direct headers announcement (BIP 130) -------------------------------------- - -Between compatible peers, BIP 130 direct headers announcement is used. This -means that blocks are advertized by announcing their headers directly, instead -of just announcing the hash. In a reorganization, all new headers are sent, -instead of just the new tip. This can often prevent an extra roundtrip before -the actual block is downloaded. - -Negative confirmations and conflict detection ---------------------------------------------- - -The wallet will now report a negative number for confirmations that indicates -how deep in the block chain the conflict is found. For example, if a transaction -A has 5 confirmations and spends the same input as a wallet transaction B, B -will be reported as having -5 confirmations. If another wallet transaction C -spends an output from B, it will also be reported as having -5 confirmations. -To detect conflicts with historical transactions in the chain a one-time -`-rescan` may be needed. - -Unlike earlier versions, unconfirmed but non-conflicting transactions will never -get a negative confirmation count. They are not treated as spendable unless -they're coming from ourself (change) and accepted into our local mempool, -however. The new "trusted" field in the `listtransactions` RPC output -indicates whether outputs of an unconfirmed transaction are considered -spendable. - -0.12.0 Change log +0.13.0 Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -243,33 +18,6 @@ git merge commit are mentioned. ### RPC and REST -Asm representations of scriptSig signatures now contain SIGHASH type decodes ----------------------------------------------------------------------------- - -The `asm` property of each scriptSig now contains the decoded signature hash -type for each signature that provides a valid defined hash type. - -The following items contain assembly representations of scriptSig signatures -and are affected by this change: - -- RPC `getrawtransaction` -- RPC `decoderawtransaction` -- REST `/rest/tx/` (JSON format) -- REST `/rest/block/` (JSON format when including extended tx details) -- `bitcoin-tx -json` - -For example, the `scriptSig.asm` property of a transaction input that -previously showed an assembly representation of: - - 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 - -now shows as: - - 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] - -Note that the output of the RPC `decodescript` did not change because it is -configured specifically to process scriptPubKey and not scriptSig scripts. - ### Configuration and command-line options ### Block and transaction handling @@ -288,13 +36,3 @@ configured specifically to process scriptPubKey and not scriptSig scripts. ### Miscellaneous -- Removed bitrpc.py from contrib - -Addition of ZMQ-based Notifications -================================== - -Bitcoind can now (optionally) asynchronously notify clients through a -ZMQ-based PUB socket of the arrival of new transactions and blocks. -This feature requires installation of the ZMQ C API library 4.x and -configuring its use through the command line or configuration file. -Please see docs/zmq.md for details of operation. diff --git a/src/clientversion.h b/src/clientversion.h index 5a06b310a..cd947a976 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -15,7 +15,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 11 +#define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 From 7632cf689a9b959dd7a059b8b4a04761a4bc6e6a Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 3 Dec 2015 11:02:24 +0100 Subject: [PATCH 0027/1223] [Tests] Refactor some shared functions --- qa/rpc-tests/mempool_limit.py | 58 ++------------------------ qa/rpc-tests/prioritise_transaction.py | 51 +--------------------- qa/rpc-tests/test_framework/util.py | 46 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 104 deletions(-) diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index aeaaa29f3..48a2ea294 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -10,9 +10,6 @@ from test_framework.util import * class MempoolLimitTest(BitcoinTestFramework): - def satoshi_round(self, amount): - return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) - def __init__(self): # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create # So we have big transactions (and therefore can't fit very many into each block) @@ -29,59 +26,10 @@ class MempoolLimitTest(BitcoinTestFramework): self.txouts = self.txouts + "fd0402" # add script_pubkey self.txouts = self.txouts + script_pubkey - - def create_confirmed_utxos(self, count): - self.nodes[0].generate(int(0.5*90)+102) - utxos = self.nodes[0].listunspent() - iterations = count - len(utxos) - addr1 = self.nodes[0].getnewaddress() - addr2 = self.nodes[0].getnewaddress() - if iterations <= 0: - return utxos - for i in xrange(iterations): - t = utxos.pop() - fee = self.relayfee - inputs = [] - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - outputs = {} - send_value = t['amount'] - fee - outputs[addr1] = self.satoshi_round(send_value/2) - outputs[addr2] = self.satoshi_round(send_value/2) - raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) - signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"] - txid = self.nodes[0].sendrawtransaction(signed_tx) - - while (self.nodes[0].getmempoolinfo()['size'] > 0): - self.nodes[0].generate(1) - - utxos = self.nodes[0].listunspent() - assert(len(utxos) >= count) - return utxos - - def create_lots_of_big_transactions(self, utxos, fee): - addr = self.nodes[0].getnewaddress() - txids = [] - for i in xrange(len(utxos)): - t = utxos.pop() - inputs = [] - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - outputs = {} - send_value = t['amount'] - fee - outputs[addr] = self.satoshi_round(send_value) - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - newtx = rawtx[0:92] - newtx = newtx + self.txouts - newtx = newtx + rawtx[94:] - signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE") - txid = self.nodes[0].sendrawtransaction(signresult["hex"], True) - txids.append(txid) - return txids def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) - self.nodes.append(start_node(1, self.options.tmpdir, [])) - connect_nodes(self.nodes[0], 1) self.is_network_split = False self.sync_all() self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] @@ -92,12 +40,12 @@ class MempoolLimitTest(BitcoinTestFramework): def run_test(self): txids = [] - utxos = self.create_confirmed_utxos(90) + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) #create a mempool tx that will be evicted us0 = utxos.pop() inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] - outputs = {self.nodes[1].getnewaddress() : 0.0001} + outputs = {self.nodes[0].getnewaddress() : 0.0001} tx = self.nodes[0].createrawtransaction(inputs, outputs) txF = self.nodes[0].fundrawtransaction(tx) txFS = self.nodes[0].signrawtransaction(txF['hex']) @@ -108,7 +56,7 @@ class MempoolLimitTest(BitcoinTestFramework): base_fee = relayfee*100 for i in xrange (4): txids.append([]) - txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) # by now, the tx should be evicted, check confirmation state assert(txid not in self.nodes[0].getrawmempool()) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index f376ceee5..b4ef1a9b3 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -42,62 +42,15 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"])) self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] - def create_confirmed_utxos(self, count): - self.nodes[0].generate(int(0.5*count)+101) - utxos = self.nodes[0].listunspent() - iterations = count - len(utxos) - addr1 = self.nodes[0].getnewaddress() - addr2 = self.nodes[0].getnewaddress() - if iterations <= 0: - return utxos - for i in xrange(iterations): - t = utxos.pop() - fee = self.relayfee - inputs = [] - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - outputs = {} - send_value = t['amount'] - fee - outputs[addr1] = satoshi_round(send_value/2) - outputs[addr2] = satoshi_round(send_value/2) - raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) - signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"] - txid = self.nodes[0].sendrawtransaction(signed_tx) - - while (self.nodes[0].getmempoolinfo()['size'] > 0): - self.nodes[0].generate(1) - - utxos = self.nodes[0].listunspent() - assert(len(utxos) >= count) - return utxos - - def create_lots_of_big_transactions(self, utxos, fee): - addr = self.nodes[0].getnewaddress() - txids = [] - for i in xrange(len(utxos)): - t = utxos.pop() - inputs = [] - inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) - outputs = {} - send_value = t['amount'] - fee - outputs[addr] = satoshi_round(send_value) - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - newtx = rawtx[0:92] - newtx = newtx + self.txouts - newtx = newtx + rawtx[94:] - signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE") - txid = self.nodes[0].sendrawtransaction(signresult["hex"], True) - txids.append(txid) - return txids - def run_test(self): - utxos = self.create_confirmed_utxos(90) + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) base_fee = self.relayfee*100 # our transactions are smaller than 100kb txids = [] # Create 3 batches of transactions at 3 different fee rate levels for i in xrange(3): txids.append([]) - txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) # add a fee delta to something in the cheapest bucket and make sure it gets mined # also check that a different entry in the cheapest bucket is NOT mined (lower diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index b7e90a8a8..80ee8ea16 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -408,3 +408,49 @@ def assert_raises(exc, fun, *args, **kwds): def satoshi_round(amount): return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + +def create_confirmed_utxos(fee, node, count): + node.generate(int(0.5*count)+101) + utxos = node.listunspent() + iterations = count - len(utxos) + addr1 = node.getnewaddress() + addr2 = node.getnewaddress() + if iterations <= 0: + return utxos + for i in xrange(iterations): + t = utxos.pop() + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr1] = satoshi_round(send_value/2) + outputs[addr2] = satoshi_round(send_value/2) + raw_tx = node.createrawtransaction(inputs, outputs) + signed_tx = node.signrawtransaction(raw_tx)["hex"] + txid = node.sendrawtransaction(signed_tx) + + while (node.getmempoolinfo()['size'] > 0): + node.generate(1) + + utxos = node.listunspent() + assert(len(utxos) >= count) + return utxos + +def create_lots_of_big_transactions(node, txouts, utxos, fee): + addr = node.getnewaddress() + txids = [] + for i in xrange(len(utxos)): + t = utxos.pop() + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr] = satoshi_round(send_value) + rawtx = node.createrawtransaction(inputs, outputs) + newtx = rawtx[0:92] + newtx = newtx + txouts + newtx = newtx + rawtx[94:] + signresult = node.signrawtransaction(newtx, None, None, "NONE") + txid = node.sendrawtransaction(signresult["hex"], True) + txids.append(txid) + return txids \ No newline at end of file From 6aadc7557823b7673b8f661b3d41cf867e2936a3 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Thu, 3 Dec 2015 20:13:10 +0000 Subject: [PATCH 0028/1223] Disconnect on mempool requests from peers when over the upload limit. Mempool requests use a fair amount of bandwidth when the mempool is large, disconnecting peers using them follows the same logic as disconnecting peers fetching historical blocks. --- src/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index bfa71a729..22e71c0c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4981,6 +4981,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == "mempool") { + if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) + { + LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId()); + pfrom->fDisconnect = true; + return true; + } LOCK2(cs_main, pfrom->cs_filter); std::vector vtxid; From 7d0bf0bb4652fad052d5bf3ca3bf883754b46ead Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 27 Jul 2015 15:33:03 +0200 Subject: [PATCH 0029/1223] include the chaintip *blockIndex in the SyncTransaction signal - allows reducing of calls to main.cpp for getting the chaintip during transaction syncing - potentially allows reducing of cs_main locks --- src/main.cpp | 8 ++++---- src/validationinterface.cpp | 8 ++++---- src/validationinterface.h | 7 ++++--- src/wallet/wallet.cpp | 2 +- src/wallet/wallet.h | 2 +- src/zmq/zmqnotificationinterface.cpp | 2 +- src/zmq/zmqnotificationinterface.h | 2 +- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bfa71a729..be14dec1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1234,7 +1234,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C } } - SyncWithWallets(tx, NULL); + SyncWithWallets(tx, NULL, NULL); return true; } @@ -2391,7 +2391,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons // Let wallets know transactions went from 1-confirmed to // 0-confirmed or conflicted: BOOST_FOREACH(const CTransaction &tx, block.vtx) { - SyncWithWallets(tx, NULL); + SyncWithWallets(tx, pindexDelete->pprev, NULL); } return true; } @@ -2450,11 +2450,11 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, // Tell wallet about transactions that went from mempool // to conflicted: BOOST_FOREACH(const CTransaction &tx, txConflicted) { - SyncWithWallets(tx, NULL); + SyncWithWallets(tx, pindexNew, NULL); } // ... and about transactions that got confirmed: BOOST_FOREACH(const CTransaction &tx, pblock->vtx) { - SyncWithWallets(tx, pblock); + SyncWithWallets(tx, pindexNew, pblock); } int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 81f3b775f..8da0c7285 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -14,7 +14,7 @@ CMainSignals& GetMainSignals() void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); - g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2, _3)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); @@ -32,7 +32,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2, _3)); g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); } @@ -48,6 +48,6 @@ void UnregisterAllValidationInterfaces() { g_signals.UpdatedBlockTip.disconnect_all_slots(); } -void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { - g_signals.SyncTransaction(tx, pblock); +void SyncWithWallets(const CTransaction &tx, const CBlockIndex *pindex, const CBlock *pblock) { + g_signals.SyncTransaction(tx, pindex, pblock); } diff --git a/src/validationinterface.h b/src/validationinterface.h index ffb56d266..b2d570df3 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -10,6 +10,7 @@ #include class CBlock; +class CBlockIndex; struct CBlockLocator; class CBlockIndex; class CReserveScript; @@ -27,12 +28,12 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllValidationInterfaces(); /** Push an updated transaction to all registered wallets */ -void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); +void SyncWithWallets(const CTransaction& tx, const CBlockIndex *pindex, const CBlock* pblock = NULL); class CValidationInterface { protected: virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} - virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} + virtual void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, const CBlock *pblock) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual void UpdatedTransaction(const uint256 &hash) {} virtual void Inventory(const uint256 &hash) {} @@ -49,7 +50,7 @@ struct CMainSignals { /** Notifies listeners of updated block chain tip */ boost::signals2::signal UpdatedBlockTip; /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ - boost::signals2::signal SyncTransaction; + boost::signals2::signal SyncTransaction; /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ boost::signals2::signal UpdatedTransaction; /** Notifies listeners of a new active block chain. */ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d23d54e67..701eac6e3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -815,7 +815,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) } } -void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) +void CWallet::SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, const CBlock* pblock) { LOCK2(cs_main, cs_wallet); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 859788893..ade825787 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -635,7 +635,7 @@ public: void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); - void SyncTransaction(const CTransaction& tx, const CBlock* pblock); + void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index be2aec7d1..c8adcf846 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -142,7 +142,7 @@ void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) } } -void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) +void CZMQNotificationInterface::SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, const CBlock* pblock) { for (std::list::iterator i = notifiers.begin(); i!=notifiers.end(); ) { diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index 3ccfaf341..7b52e7775 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -24,7 +24,7 @@ protected: void Shutdown(); // CValidationInterface - void SyncTransaction(const CTransaction &tx, const CBlock *pblock); + void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, const CBlock* pblock); void UpdatedBlockTip(const CBlockIndex *pindex); private: From 2f601d215da1683ae99ab9973219044c32fa2093 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 4 Dec 2015 13:10:58 +0100 Subject: [PATCH 0030/1223] test: remove necessity to call create_callback_map Remove necessity to call create_callback_map (as well as the function itself) from the Python P2P test framework. Invoke the appropriate methods directly. - Easy to forget to call it and wonder why it doesn't work - Simplifies the code - This makes it easier to handle new messages in subclasses --- qa/rpc-tests/README.md | 5 +---- qa/rpc-tests/maxblocksinflight.py | 1 - qa/rpc-tests/maxuploadtarget.py | 1 - qa/rpc-tests/p2p-acceptblock.py | 1 - qa/rpc-tests/sendheaders.py | 1 - qa/rpc-tests/test_framework/comptool.py | 1 - qa/rpc-tests/test_framework/mininode.py | 24 +----------------------- 7 files changed, 2 insertions(+), 32 deletions(-) diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index 898931936..651b01f18 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -47,10 +47,7 @@ implements the test logic. * ```NodeConn``` is the class used to connect to a bitcoind. If you implement a callback class that derives from ```NodeConnCB``` and pass that to the ```NodeConn``` object, your code will receive the appropriate callbacks when -events of interest arrive. NOTE: be sure to call -```self.create_callback_map()``` in your derived classes' ```__init__``` -function, so that the correct mappings are set up between p2p messages and your -callback functions. +events of interest arrive. * You can pass the same handler to multiple ```NodeConn```'s if you like, or pass different ones to each -- whatever makes the most sense for your test. diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index a601147ce..1a9ae480a 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -34,7 +34,6 @@ class TestManager(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) self.log = logging.getLogger("BlockRelayTest") - self.create_callback_map() def add_new_connection(self, connection): self.connection = connection diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index e714465db..249663779 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -25,7 +25,6 @@ if uploadtarget has been reached. class TestNode(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) - self.create_callback_map() self.connection = None self.ping_counter = 1 self.last_pong = msg_pong() diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 700deab20..23872d849 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -62,7 +62,6 @@ The test: class TestNode(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) - self.create_callback_map() self.connection = None self.ping_counter = 1 self.last_pong = msg_pong() diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 63e071805..e6e26dbce 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -70,7 +70,6 @@ f. Announce 1 more header that builds on that fork. class BaseNode(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) - self.create_callback_map() self.connection = None self.last_inv = None self.last_headers = None diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index e0b3ce040..9444424dc 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -45,7 +45,6 @@ class TestNode(NodeConnCB): def __init__(self, block_store, tx_store): NodeConnCB.__init__(self) - self.create_callback_map() self.conn = None self.bestblockhash = None self.block_store = block_store diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 64985d58e..9d0fb713a 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1015,32 +1015,10 @@ class NodeConnCB(object): return time.sleep(0.05) - # Derived classes should call this function once to set the message map - # which associates the derived classes' functions to incoming messages - def create_callback_map(self): - self.cbmap = { - "version": self.on_version, - "verack": self.on_verack, - "addr": self.on_addr, - "alert": self.on_alert, - "inv": self.on_inv, - "getdata": self.on_getdata, - "getblocks": self.on_getblocks, - "tx": self.on_tx, - "block": self.on_block, - "getaddr": self.on_getaddr, - "ping": self.on_ping, - "pong": self.on_pong, - "headers": self.on_headers, - "getheaders": self.on_getheaders, - "reject": self.on_reject, - "mempool": self.on_mempool - } - def deliver(self, conn, message): with mininode_lock: try: - self.cbmap[message.command](conn, message) + getattr(self, 'on_' + message.command)(conn, message) except: print "ERROR delivering %s (%s)" % (repr(message), sys.exc_info()[0]) From 4c40ec0451a8f279f3e2e40af068c9451afd699e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 4 Dec 2015 13:24:12 +0100 Subject: [PATCH 0031/1223] tests: Disable Tor interaction This is unnecessary during the current tests (any test for Tor interaction can explicitly enable it) and interferes with the proxy test. --- qa/rpc-tests/test_framework/util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index b7e90a8a8..72df3ae68 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -107,6 +107,7 @@ def initialize_datadir(dirname, n): f.write("rpcpassword=rt\n"); f.write("port="+str(p2p_port(n))+"\n"); f.write("rpcport="+str(rpc_port(n))+"\n"); + f.write("listenonion=0\n"); return datadir def initialize_chain(test_dir): From 96918a2f0990a8207d7631b8de73af8ae5d24aeb Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 5 Dec 2015 17:45:44 +0800 Subject: [PATCH 0032/1223] Don't do mempool lookups for "mempool" command without a filter --- src/main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 22e71c0c4..a0e996ae7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4994,12 +4994,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vector vInv; BOOST_FOREACH(uint256& hash, vtxid) { CInv inv(MSG_TX, hash); - CTransaction tx; - bool fInMemPool = mempool.lookup(hash, tx); - if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... - if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) || - (!pfrom->pfilter)) - vInv.push_back(inv); + if (pfrom->pfilter) { + CTransaction tx; + bool fInMemPool = mempool.lookup(hash, tx); + if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... + if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue; + } + vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { pfrom->PushMessage("inv", vInv); vInv.clear(); From 5c03483e26ab414d22ef192691b2336c1bb3cb02 Mon Sep 17 00:00:00 2001 From: AlSzacrel Date: Sat, 13 Sep 2014 02:09:18 +0200 Subject: [PATCH 0033/1223] Coinselection prunes extraneous inputs from ApproximateBestSubset A further pass over the available inputs has been added to ApproximateBestSubset after a candidate set has been found. It will prune any extraneous inputs in the selected subset, in order to decrease the number of input and the resulting change. --- src/wallet/wallet.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d23d54e67..06b77bb9b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1620,6 +1620,19 @@ static void ApproximateBestSubset(vector= nTargetValue) { fReachedTarget = true; + + for (unsigned int i = 0; i < vValue.size(); i++) + { + //The target has been reached, but the candidate set may contain extraneous inputs. + //This iterates over all inputs and deducts any that are included, but smaller + //than the amount nTargetValue is still exceeded by. + if (vfIncluded[i] && (nTotal - vValue[i].first) >= nTargetValue ) + { + vfIncluded[i] = false; + nTotal -= vValue[i].first; + } + } + if (nTotal < nBest) { nBest = nTotal; From ca188c629e90fd90b533f43d769348d6a42d24b9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 25 Aug 2015 16:30:31 +0200 Subject: [PATCH 0034/1223] log bytes recv/sent per command --- src/net.cpp | 28 +++++++++++++++++++++++++++- src/net.h | 28 +++++++++++++++++----------- src/rpcnet.cpp | 22 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index a8aa97fee..649c6134d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -67,6 +67,15 @@ namespace { }; } +//immutable thread safe array of allowed commands for logging inbound traffic +const static std::string logAllowIncomingMsgCmds[] = { + "version", "addr", "inv", "getdata", "merkleblock", + "getblocks", "getheaders", "tx", "headers", "block", + "getaddr", "mempool", "ping", "pong", "alert", "notfound", + "filterload", "filteradd", "filterclear", "reject"}; + +const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; + // // Global state variables // @@ -627,7 +636,9 @@ void CNode::copyStats(CNodeStats &stats) X(fInbound); X(nStartingHeight); X(nSendBytes); + X(mapSendBytesPerMsgCmd); X(nRecvBytes); + X(mapRecvBytesPerMsgCmd); X(fWhitelisted); // It is common for nodes with good ping times to suddenly become lagged, @@ -682,6 +693,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) nBytes -= handled; if (msg.complete()) { + + //store received bytes per message command + //to prevent a memory DOS, only allow valid commands + mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand); + if (i == mapRecvBytesPerMsgCmd.end()) + i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); + assert(i != mapRecvBytesPerMsgCmd.end()); + i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE; + msg.nTime = GetTimeMicros(); messageHandlerCondition.notify_one(); } @@ -2378,6 +2398,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); + for (unsigned int i = 0; i < sizeof(logAllowIncomingMsgCmds)/sizeof(logAllowIncomingMsgCmds[0]); i++) + mapRecvBytesPerMsgCmd[logAllowIncomingMsgCmds[i]] = 0; + mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { LOCK(cs_nLastNodeId); @@ -2457,7 +2480,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) LogPrint("net", "(aborted)\n"); } -void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) +void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend) { // The -*messagestest options are intentionally not documented in the help message, // since they are only used during development to debug the networking code and are @@ -2480,6 +2503,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); + //log total amount of bytes per command + mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE; + // Set the checksum uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); unsigned int nChecksum = 0; diff --git a/src/net.h b/src/net.h index 6886d070b..3ed438605 100644 --- a/src/net.h +++ b/src/net.h @@ -182,6 +182,7 @@ struct LocalServiceInfo { extern CCriticalSection cs_mapLocalHost; extern std::map mapLocalHost; +typedef std::map mapMsgCmdSize; //command, total bytes class CNodeStats { @@ -199,7 +200,9 @@ public: bool fInbound; int nStartingHeight; uint64_t nSendBytes; + mapMsgCmdSize mapSendBytesPerMsgCmd; uint64_t nRecvBytes; + mapMsgCmdSize mapRecvBytesPerMsgCmd; bool fWhitelisted; double dPingTime; double dPingWait; @@ -373,6 +376,9 @@ protected: static std::vector vWhitelistedRange; static CCriticalSection cs_vWhitelistedRange; + mapMsgCmdSize mapSendBytesPerMsgCmd; + mapMsgCmdSize mapRecvBytesPerMsgCmd; + // Basic fuzz-testing void Fuzz(int nChance); // modifies ssSend @@ -525,7 +531,7 @@ public: void AbortMessage() UNLOCK_FUNCTION(cs_vSend); // TODO: Document the precondition of this function. Is cs_vSend locked? - void EndMessage() UNLOCK_FUNCTION(cs_vSend); + void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend); void PushVersion(); @@ -535,7 +541,7 @@ public: try { BeginMessage(pszCommand); - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -551,7 +557,7 @@ public: { BeginMessage(pszCommand); ssSend << a1; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -567,7 +573,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -583,7 +589,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -599,7 +605,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -615,7 +621,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -631,7 +637,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -647,7 +653,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -663,7 +669,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -679,7 +685,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - EndMessage(); + EndMessage(pszCommand); } catch (...) { diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 257884889..0ce108b06 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -111,6 +111,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " n, (numeric) The heights of blocks we're currently asking from this peer\n" " ...\n" " ]\n" + " \"bytessent_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes sent aggregated by message type\n" + " ...\n" + " }\n" + " \"bytesrecv_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes received aggregated by message type\n" + " ...\n" + " }\n" " }\n" " ,...\n" "]\n" @@ -165,6 +173,20 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) } obj.push_back(Pair("whitelisted", stats.fWhitelisted)); + UniValue sendPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapSendBytesPerMsgCmd) { + if (i.second > 0) + sendPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd)); + + UniValue recvPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapRecvBytesPerMsgCmd) { + if (i.second > 0) + recvPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd)); + ret.push_back(obj); } From 9fc6ed6003da42f035309240c715ce0fd063ec03 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Dec 2015 14:47:58 +0100 Subject: [PATCH 0035/1223] net: Fix sent reject messages for blocks and transactions Ever since we #5913 have been sending invalid reject messages for transactions and blocks. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a0e996ae7..84f737258 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4824,7 +4824,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->id, FormatStateMessage(state)); if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage("reject", strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); @@ -4954,7 +4954,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage("reject", strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { LOCK(cs_main); From e3bc5e0e927af14bd34cc30cfdf11cacbb346262 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Dec 2015 15:15:12 +0100 Subject: [PATCH 0036/1223] net: Account for `sendheaders` `verack` messages Looks like these were forgotten in #6589. --- src/net.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 649c6134d..159d44cba 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -72,7 +72,8 @@ const static std::string logAllowIncomingMsgCmds[] = { "version", "addr", "inv", "getdata", "merkleblock", "getblocks", "getheaders", "tx", "headers", "block", "getaddr", "mempool", "ping", "pong", "alert", "notfound", - "filterload", "filteradd", "filterclear", "reject"}; + "filterload", "filteradd", "filterclear", "reject", + "sendheaders", "verack"}; const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; From af9510e0374443b093d633a91c4f1f8bf5071292 Mon Sep 17 00:00:00 2001 From: Murch Date: Sun, 6 Dec 2015 22:20:41 +0100 Subject: [PATCH 0037/1223] Moved set reduction to the end of ApproximateBestSubset to reduce performance impact --- src/wallet/wallet.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 06b77bb9b..f9e8a97ae 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1605,7 +1605,7 @@ static void ApproximateBestSubset(vector= nTargetValue) { fReachedTarget = true; - - for (unsigned int i = 0; i < vValue.size(); i++) - { - //The target has been reached, but the candidate set may contain extraneous inputs. - //This iterates over all inputs and deducts any that are included, but smaller - //than the amount nTargetValue is still exceeded by. - if (vfIncluded[i] && (nTotal - vValue[i].first) >= nTargetValue ) - { - vfIncluded[i] = false; - nTotal -= vValue[i].first; - } - } - if (nTotal < nBest) { nBest = nTotal; vfBest = vfIncluded; } - nTotal -= vValue[i].first; - vfIncluded[i] = false; } } } } } + + //Reduces the approximate best subset by removing any inputs that are smaller than the surplus of nTotal beyond nTargetValue. + for (unsigned int i = 0; i < vValue.size(); i++) + { + if (vfBest[i] && (nBest - vValue[i].first) >= nTargetValue ) + { + vfBest[i] = false; + nBest -= vValue[i].first; + } + } } bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector vCoins, From fc0f52d78085b6ef97d6821fc7592326c2d9b495 Mon Sep 17 00:00:00 2001 From: Murch Date: Mon, 7 Dec 2015 00:15:36 +0100 Subject: [PATCH 0038/1223] Added a test for the pruning of extraneous inputs after ApproximateBestSet --- src/wallet/test/wallet_tests.cpp | 18 ++++++++++++++++++ src/wallet/wallet.cpp | 14 ++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 8b9292bd1..5e8ccd90a 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -328,4 +328,22 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } +BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet) +{ + CoinSet setCoinsRet; + CAmount nValueRet; + + LOCK(wallet.cs_wallet); + + empty_wallet(); + for (int i = 0; i < 12; i++) + { + add_coin(10*CENT); + } + add_coin(100*CENT); + add_coin(100*CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(221*CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 230*CENT); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f9e8a97ae..a262769c4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1605,7 +1605,7 @@ static void ApproximateBestSubset(vector= nTargetValue ) - { - vfBest[i] = false; - nBest -= vValue[i].first; - } + if (vfBest[i] && (nBest - vValue[i].first) >= nTargetValue ) + { + vfBest[i] = false; + nBest -= vValue[i].first; + } } } From a3d5eec54613044fc149445cc8e544a350ed312e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 20 Nov 2015 16:46:03 +0100 Subject: [PATCH 0039/1223] Build: Consensus: Move consensus files from common to its own module/package --- src/Makefile.am | 64 ++++++++++++++++++++----------------- src/Makefile.bench.include | 1 + src/Makefile.qt.include | 2 +- src/Makefile.qttest.include | 2 +- src/Makefile.test.include | 2 +- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index bb627a544..af34ed7a9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ BITCOIN_INCLUDES += -I$(srcdir)/univalue/include LIBBITCOIN_SERVER=libbitcoin_server.a LIBBITCOIN_WALLET=libbitcoin_wallet.a LIBBITCOIN_COMMON=libbitcoin_common.a +LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a LIBBITCOIN_CLI=libbitcoin_cli.a LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a @@ -47,6 +48,7 @@ EXTRA_LIBRARIES = \ crypto/libbitcoin_crypto.a \ libbitcoin_util.a \ libbitcoin_common.a \ + libbitcoin_consensus.a \ libbitcoin_server.a \ libbitcoin_cli.a if ENABLE_WALLET @@ -59,9 +61,9 @@ endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libbitcoinconsensus.la -LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la +LIBBITCOINCONSENSUS=libbitcoinconsensus.la else -LIBBITCOIN_CONSENSUS= +LIBBITCOINCONSENSUS= endif bin_PROGRAMS = @@ -81,7 +83,6 @@ endif BITCOIN_CORE_H = \ addrman.h \ alert.h \ - amount.h \ arith_uint256.h \ base58.h \ bloom.h \ @@ -105,7 +106,6 @@ BITCOIN_CORE_H = \ consensus/validation.h \ core_io.h \ core_memusage.h \ - hash.h \ httprpc.h \ httpserver.h \ init.h \ @@ -124,24 +124,17 @@ BITCOIN_CORE_H = \ policy/fees.h \ policy/policy.h \ pow.h \ - prevector.h \ primitives/block.h \ - primitives/transaction.h \ protocol.h \ - pubkey.h \ random.h \ reverselock.h \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ scheduler.h \ - script/interpreter.h \ - script/script.h \ - script/script_error.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ - serialize.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ @@ -150,19 +143,15 @@ BITCOIN_CORE_H = \ sync.h \ threadsafety.h \ timedata.h \ - tinyformat.h \ torcontrol.h \ txdb.h \ txmempool.h \ ui_interface.h \ - uint256.h \ undo.h \ util.h \ utilmoneystr.h \ - utilstrencodings.h \ utiltime.h \ validationinterface.h \ - version.h \ wallet/crypter.h \ wallet/db.h \ wallet/wallet.h \ @@ -260,6 +249,33 @@ crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha512.cpp \ crypto/sha512.h +# consensus: shared between all executables that validate any consensus rules. +libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_consensus_a_SOURCES = \ + amount.h \ + hash.cpp \ + hash.h \ + prevector.h \ + primitives/transaction.cpp \ + primitives/transaction.h \ + pubkey.cpp \ + pubkey.h \ + script/bitcoinconsensus.cpp \ + script/interpreter.cpp \ + script/interpreter.h \ + script/script.cpp \ + script/script.h \ + script/script_error.cpp \ + script/script_error.h \ + serialize.h \ + tinyformat.h \ + uint256.cpp \ + uint256.h \ + utilstrencodings.cpp \ + utilstrencodings.h \ + version.h + # common: shared between bitcoind, and bitcoin-qt and non-server tools libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -273,18 +289,12 @@ libbitcoin_common_a_SOURCES = \ consensus/merkle.cpp \ core_read.cpp \ core_write.cpp \ - hash.cpp \ key.cpp \ keystore.cpp \ netbase.cpp \ primitives/block.cpp \ - primitives/transaction.cpp \ protocol.cpp \ - pubkey.cpp \ scheduler.cpp \ - script/interpreter.cpp \ - script/script.cpp \ - script/script_error.cpp \ script/sign.cpp \ script/standard.cpp \ $(BITCOIN_CORE_H) @@ -305,7 +315,6 @@ libbitcoin_util_a_SOURCES = \ rpcprotocol.cpp \ support/cleanse.cpp \ sync.cpp \ - uint256.cpp \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ @@ -341,6 +350,7 @@ bitcoind_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ @@ -388,6 +398,7 @@ bitcoin_tx_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBSECP256K1) @@ -403,14 +414,7 @@ libbitcoinconsensus_la_SOURCES = \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ - hash.cpp \ - primitives/transaction.cpp \ - pubkey.cpp \ - script/bitcoinconsensus.cpp \ - script/interpreter.cpp \ - script/script.cpp \ - uint256.cpp \ - utilstrencodings.cpp + $(libbitcoin_consensus_a_SOURCES) if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index d660a3a74..d3cecb6b4 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -16,6 +16,7 @@ bench_bench_bitcoin_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index a390d96a9..18a45e6ac 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -375,7 +375,7 @@ endif if ENABLE_ZMQ qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ +qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index ede3fac4c..813a343ff 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -33,7 +33,7 @@ endif if ENABLE_ZMQ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ +qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 4d0894b71..88ee5bad7 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -96,7 +96,7 @@ endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) -test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ +test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) if ENABLE_WALLET From 4feadec98e0b610d1272c398505e41962218bc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Tue, 24 Nov 2015 06:26:15 +0100 Subject: [PATCH 0040/1223] Build: Libconsensus: Move libconsensus-ready files to the consensus package --- src/Makefile.am | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index af34ed7a9..502bbd831 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,7 +83,6 @@ endif BITCOIN_CORE_H = \ addrman.h \ alert.h \ - arith_uint256.h \ base58.h \ bloom.h \ chain.h \ @@ -101,9 +100,6 @@ BITCOIN_CORE_H = \ compat/sanity.h \ compressor.h \ consensus/consensus.h \ - consensus/merkle.h \ - consensus/params.h \ - consensus/validation.h \ core_io.h \ core_memusage.h \ httprpc.h \ @@ -124,7 +120,6 @@ BITCOIN_CORE_H = \ policy/fees.h \ policy/policy.h \ pow.h \ - primitives/block.h \ protocol.h \ random.h \ reverselock.h \ @@ -254,9 +249,17 @@ libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_consensus_a_SOURCES = \ amount.h \ + arith_uint256.cpp \ + arith_uint256.h \ + consensus/merkle.cpp \ + consensus/merkle.h \ + consensus/params.h \ + consensus/validation.h \ hash.cpp \ hash.h \ prevector.h \ + primitives/block.cpp \ + primitives/block.h \ primitives/transaction.cpp \ primitives/transaction.h \ pubkey.cpp \ @@ -281,18 +284,15 @@ libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ amount.cpp \ - arith_uint256.cpp \ base58.cpp \ chainparams.cpp \ coins.cpp \ compressor.cpp \ - consensus/merkle.cpp \ core_read.cpp \ core_write.cpp \ key.cpp \ keystore.cpp \ netbase.cpp \ - primitives/block.cpp \ protocol.cpp \ scheduler.cpp \ script/sign.cpp \ From cf82d05dd45b0e8c97a70deb2d539c02b03d1917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Mon, 23 Nov 2015 17:34:42 +0100 Subject: [PATCH 0041/1223] Build: Consensus: Make libbitcoinconsensus_la_SOURCES fully dynamic and dependend on both crypto and consensus packages Some extra bytes in libconsensus to get all the crypto (except for signing, which is in the common module) below the libconsensus future independent repo (that has libsecp256k1 as a subtree). hmac_sha256.o seems to be the only thing libbitcoinconsensus doesn't depend on from crypto, some more bytes for the final libconsensus: I'm not personally worried. --- src/Makefile.am | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 502bbd831..726cc0c30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -408,13 +408,7 @@ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # bitcoinconsensus library # if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h -libbitcoinconsensus_la_SOURCES = \ - crypto/hmac_sha512.cpp \ - crypto/ripemd160.cpp \ - crypto/sha1.cpp \ - crypto/sha256.cpp \ - crypto/sha512.cpp \ - $(libbitcoin_consensus_a_SOURCES) +libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES) $(libbitcoin_consensus_a_SOURCES) if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp From 20411903d7b356ebb174df2daad1dcd5d6117f79 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 8 Dec 2015 17:10:41 +0100 Subject: [PATCH 0042/1223] test: Add basic test for `reject` code Extend P2P test framework to make it possible to expect reject codes for transactions and blocks. --- qa/pull-tester/rpc-tests.py | 3 +- qa/rpc-tests/invalidblockrequest.py | 6 +- qa/rpc-tests/invalidtxrequest.py | 76 +++++++++++++++++++++++++ qa/rpc-tests/test_framework/comptool.py | 40 +++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100755 qa/rpc-tests/invalidtxrequest.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index df71e44b6..0cb721b03 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -100,6 +100,8 @@ testScripts = [ 'sendheaders.py', 'keypool.py', 'prioritise_transaction.py', + 'invalidblockrequest.py', + 'invalidtxrequest.py', ] testScriptsExt = [ 'bip65-cltv.py', @@ -116,7 +118,6 @@ testScriptsExt = [ # 'rpcbind_test.py', #temporary, bug in libevent, see #6655 'smartfees.py', 'maxblocksinflight.py', - 'invalidblockrequest.py', 'p2p-acceptblock.py', 'mempool_packages.py', 'maxuploadtarget.py', diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 6a7980cd4..a74ecb128 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -6,7 +6,7 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.comptool import TestManager, TestInstance +from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.mininode import * from test_framework.blocktools import * import logging @@ -97,7 +97,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): assert(block2_orig.vtx != block2.vtx) self.tip = block2.sha256 - yield TestInstance([[block2, False], [block2_orig, True]]) + yield TestInstance([[block2, RejectResult(16,'bad-txns-duplicate')], [block2_orig, True]]) height += 1 ''' @@ -112,7 +112,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): block3.rehash() block3.solve() - yield TestInstance([[block3, False]]) + yield TestInstance([[block3, RejectResult(16,'bad-cb-amount')]]) if __name__ == '__main__': diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py new file mode 100755 index 000000000..d17b3d098 --- /dev/null +++ b/qa/rpc-tests/invalidtxrequest.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python2 +# +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.comptool import TestManager, TestInstance, RejectResult +from test_framework.mininode import * +from test_framework.blocktools import * +import logging +import copy +import time + + +''' +In this test we connect to one node over p2p, and test tx requests. +''' + +# Use the ComparisonTestFramework with 1 node: only use --testbinary. +class InvalidTxRequestTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def __init__(self): + self.num_nodes = 1 + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + self.tip = None + self.block_time = None + NetworkThread().start() # Start up network handling in another thread + test.run() + + def get_tests(self): + if self.tip is None: + self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.block_time = int(time.time())+1 + + ''' + Create a new block with an anyone-can-spend coinbase + ''' + height = 1 + block = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + block.solve() + # Save the coinbase for later + self.block1 = block + self.tip = block.sha256 + height += 1 + yield TestInstance([[block, True]]) + + ''' + Now we need that block to mature so we can spend the coinbase. + ''' + test = TestInstance(sync_every_block=False) + for i in xrange(100): + block = create_block(self.tip, create_coinbase(height), self.block_time) + block.solve() + self.tip = block.sha256 + self.block_time += 1 + test.blocks_and_transactions.append([block, True]) + height += 1 + yield test + + # chr(100) is OP_NOTIF + # Transaction will be rejected with code 16 (REJECT_INVALID) + tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000) + yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) + + # TODO: test further transactions... + +if __name__ == '__main__': + InvalidTxRequestTest().main() diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 9444424dc..badbc0a1f 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -41,6 +41,20 @@ def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): return False +class RejectResult(object): + ''' + Outcome that expects rejection of a transaction or block. + ''' + def __init__(self, code, reason=''): + self.code = code + self.reason = reason + def match(self, other): + if self.code != other.code: + return False + return other.reason.startswith(self.reason) + def __repr__(self): + return '%i:%s' % (self.code,self.reason or '*') + class TestNode(NodeConnCB): def __init__(self, block_store, tx_store): @@ -51,6 +65,8 @@ class TestNode(NodeConnCB): self.block_request_map = {} self.tx_store = tx_store self.tx_request_map = {} + self.block_reject_map = {} + self.tx_reject_map = {} # When the pingmap is non-empty we're waiting for # a response @@ -94,6 +110,12 @@ class TestNode(NodeConnCB): except KeyError: raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) + def on_reject(self, conn, message): + if message.message == 'tx': + self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) + if message.message == 'block': + self.block_reject_map[message.data] = RejectResult(message.code, message.reason) + def send_inv(self, obj): mtype = 2 if isinstance(obj, CBlock) else 1 self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)])) @@ -243,6 +265,15 @@ class TestManager(object): if outcome is None: if c.cb.bestblockhash != self.connections[0].cb.bestblockhash: return False + elif isinstance(outcome, RejectResult): # Check that block was rejected w/ code + if c.cb.bestblockhash == blockhash: + return False + if blockhash not in c.cb.block_reject_map: + print 'Block not in reject map: %064x' % (blockhash) + return False + if not outcome.match(c.cb.block_reject_map[blockhash]): + print 'Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash) + return False elif ((c.cb.bestblockhash == blockhash) != outcome): # print c.cb.bestblockhash, blockhash, outcome return False @@ -262,6 +293,15 @@ class TestManager(object): if c.cb.lastInv != self.connections[0].cb.lastInv: # print c.rpc.getrawmempool() return False + elif isinstance(outcome, RejectResult): # Check that tx was rejected w/ code + if txhash in c.cb.lastInv: + return False + if txhash not in c.cb.tx_reject_map: + print 'Tx not in reject map: %064x' % (txhash) + return False + if not outcome.match(c.cb.tx_reject_map[txhash]): + print 'Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash) + return False elif ((txhash in c.cb.lastInv) != outcome): # print c.rpc.getrawmempool(), c.cb.lastInv return False From fafd09375eb5133abf921132643384a1ac6fa444 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 9 Dec 2015 09:27:08 +0100 Subject: [PATCH 0043/1223] [wallet] Adjust pruning test --- src/wallet/test/wallet_tests.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 5e8ccd90a..ee4f228a0 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -336,14 +336,16 @@ BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet) LOCK(wallet.cs_wallet); empty_wallet(); - for (int i = 0; i < 12; i++) - { - add_coin(10*CENT); - } - add_coin(100*CENT); - add_coin(100*CENT); - BOOST_CHECK(wallet.SelectCoinsMinConf(221*CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 230*CENT); + for (int i = 0; i < 100; i++) + add_coin(10 * CENT); + for (int i = 0; i < 100; i++) + add_coin(1000 * CENT); + + BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + // We need all 100 larger coins and exactly one small coin. + // Superfluous small coins must be pruned: + BOOST_CHECK_EQUAL(nValueRet, 100010 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); } BOOST_AUTO_TEST_SUITE_END() From e0769e1928f892fb16f851991d8e09a90587a1f4 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 9 Dec 2015 16:49:58 +0800 Subject: [PATCH 0044/1223] [depends] Latest config.guess & config.sub --- depends/config.guess | 5 ++++- depends/config.sub | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/depends/config.guess b/depends/config.guess index b3f905370..fba6e87a0 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2015-10-21' +timestamp='2015-11-19' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -1393,6 +1393,9 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 < Date: Mon, 7 Dec 2015 15:31:32 +0100 Subject: [PATCH 0045/1223] net: Add and document network messages in protocol.h - Avoids string typos (by making the compiler check) - Makes it easier to grep for handling/generation of a certain message type - Refer directly to documentation by following the symbol in IDE - Move list of valid message types to protocol.cpp: protocol.cpp is a more appropriate place for this, and having the array there makes it easier to keep things consistent. --- src/alert.cpp | 2 +- src/main.cpp | 114 ++++++++++++++++----------------- src/net.cpp | 14 +---- src/protocol.cpp | 67 ++++++++++++++++++-- src/protocol.h | 159 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+), 73 deletions(-) diff --git a/src/alert.cpp b/src/alert.cpp index 91e54a917..b70506940 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -138,7 +138,7 @@ bool CAlert::RelayTo(CNode* pnode) const AppliesToMe() || GetAdjustedTime() < nRelayUntil) { - pnode->PushMessage("alert", *this); + pnode->PushMessage(NetMsgType::ALERT, *this); return true; } } diff --git a/src/main.cpp b/src/main.cpp index 84f737258..d2e736d42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4171,14 +4171,14 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) - pfrom->PushMessage("block", block); + pfrom->PushMessage(NetMsgType::BLOCK, block); else // MSG_FILTERED_BLOCK) { LOCK(pfrom->cs_filter); if (pfrom->pfilter) { CMerkleBlock merkleBlock(block, *pfrom->pfilter); - pfrom->PushMessage("merkleblock", merkleBlock); + pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip // Note that there is currently no way for a node to request any single transactions we didn't send here - @@ -4187,7 +4187,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) - pfrom->PushMessage("tx", block.vtx[pair.first]); + pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -4201,7 +4201,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // wait for other stuff first. vector vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); pfrom->hashContinue.SetNull(); } } @@ -4224,7 +4224,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); ss << tx; - pfrom->PushMessage("tx", ss); + pfrom->PushMessage(NetMsgType::TX, ss); pushed = true; } } @@ -4251,7 +4251,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // do that because they want to know about (and store and rebroadcast and // risk analyze) the dependencies of transactions relevant to them, without // having to download the entire memory pool. - pfrom->PushMessage("notfound", vNotFound); + pfrom->PushMessage(NetMsgType::NOTFOUND, vNotFound); } } @@ -4268,9 +4268,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!(nLocalServices & NODE_BLOOM) && - (strCommand == "filterload" || - strCommand == "filteradd" || - strCommand == "filterclear")) + (strCommand == NetMsgType::FILTERLOAD || + strCommand == NetMsgType::FILTERADD || + strCommand == NetMsgType::FILTERCLEAR)) { if (pfrom->nVersion >= NO_BLOOM_VERSION) { Misbehaving(pfrom->GetId(), 100); @@ -4282,12 +4282,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - if (strCommand == "version") + if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) { - pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message")); Misbehaving(pfrom->GetId(), 1); return false; } @@ -4301,7 +4301,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { // disconnect from peers older than this proto version LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); - pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION)); pfrom->fDisconnect = true; return false; @@ -4346,7 +4346,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, UpdatePreferredDownload(pfrom, State(pfrom->GetId())); // Change version - pfrom->PushMessage("verack"); + pfrom->PushMessage(NetMsgType::VERACK); pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); if (!pfrom->fInbound) @@ -4369,7 +4369,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Get recent addresses if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) { - pfrom->PushMessage("getaddr"); + pfrom->PushMessage(NetMsgType::GETADDR); pfrom->fGetAddr = true; } addrman.Good(pfrom->addr); @@ -4413,7 +4413,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "verack") + else if (strCommand == NetMsgType::VERACK) { pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); @@ -4428,12 +4428,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // We send this to non-NODE NETWORK peers as well, because even // non-NODE NETWORK peers can announce blocks (such as pruning // nodes) - pfrom->PushMessage("sendheaders"); + pfrom->PushMessage(NetMsgType::SENDHEADERS); } } - else if (strCommand == "addr") + else if (strCommand == NetMsgType::ADDR) { vector vAddr; vRecv >> vAddr; @@ -4499,14 +4499,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fDisconnect = true; } - else if (strCommand == "sendheaders") + else if (strCommand == NetMsgType::SENDHEADERS) { LOCK(cs_main); State(pfrom->GetId())->fPreferHeaders = true; } - else if (strCommand == "inv") + else if (strCommand == NetMsgType::INV) { vector vInv; vRecv >> vInv; @@ -4547,7 +4547,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // time the block arrives, the header chain leading up to it is already validated. Not // doing this will result in the received block being rejected as an orphan in case it is // not a direct successor. - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); if (CanDirectFetch(chainparams.GetConsensus()) && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { @@ -4577,11 +4577,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!vToFetch.empty()) - pfrom->PushMessage("getdata", vToFetch); + pfrom->PushMessage(NetMsgType::GETDATA, vToFetch); } - else if (strCommand == "getdata") + else if (strCommand == NetMsgType::GETDATA) { vector vInv; vRecv >> vInv; @@ -4602,7 +4602,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getblocks") + else if (strCommand == NetMsgType::GETBLOCKS) { CBlockLocator locator; uint256 hashStop; @@ -4646,7 +4646,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getheaders") + else if (strCommand == NetMsgType::GETHEADERS) { CBlockLocator locator; uint256 hashStop; @@ -4691,11 +4691,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // headers message). In both cases it's safe to update // pindexBestHeaderSent to be our tip. nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip(); - pfrom->PushMessage("headers", vHeaders); + pfrom->PushMessage(NetMsgType::HEADERS, vHeaders); } - else if (strCommand == "tx") + else if (strCommand == NetMsgType::TX) { // Stop processing the transaction early if // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off @@ -4824,7 +4824,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->id, FormatStateMessage(state)); if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P - pfrom->PushMessage("reject", strCommand, (unsigned char)state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); @@ -4833,7 +4833,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing + else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing { std::vector headers; @@ -4881,7 +4881,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()); } bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); @@ -4926,7 +4926,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { - pfrom->PushMessage("getdata", vGetData); + pfrom->PushMessage(NetMsgType::GETDATA, vGetData); } } } @@ -4934,7 +4934,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CheckBlockIndex(chainparams.GetConsensus()); } - else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing + else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing { CBlock block; vRecv >> block; @@ -4954,7 +4954,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes - pfrom->PushMessage("reject", strCommand, (unsigned char)state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { LOCK(cs_main); @@ -4970,7 +4970,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // to users' AddrMan and later request them by sending getaddr messages. // Making nodes which are behind NAT and can only make outgoing connections ignore // the getaddr message mitigates the attack. - else if ((strCommand == "getaddr") && (pfrom->fInbound)) + else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) { pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); @@ -4979,7 +4979,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "mempool") + else if (strCommand == NetMsgType::MEMPOOL) { if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) { @@ -5002,16 +5002,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); vInv.clear(); } } if (vInv.size() > 0) - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); } - else if (strCommand == "ping") + else if (strCommand == NetMsgType::PING) { if (pfrom->nVersion > BIP0031_VERSION) { @@ -5028,12 +5028,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // it, if the remote node sends a ping once per second and this node takes 5 // seconds to respond to each, the 5th ping the remote sends would appear to // return very quickly. - pfrom->PushMessage("pong", nonce); + pfrom->PushMessage(NetMsgType::PONG, nonce); } } - else if (strCommand == "pong") + else if (strCommand == NetMsgType::PONG) { int64_t pingUsecEnd = nTimeReceived; uint64_t nonce = 0; @@ -5090,7 +5090,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (fAlerts && strCommand == "alert") + else if (fAlerts && strCommand == NetMsgType::ALERT) { CAlert alert; vRecv >> alert; @@ -5121,7 +5121,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filterload") + else if (strCommand == NetMsgType::FILTERLOAD) { CBloomFilter filter; vRecv >> filter; @@ -5140,7 +5140,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filteradd") + else if (strCommand == NetMsgType::FILTERADD) { vector vData; vRecv >> vData; @@ -5160,7 +5160,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filterclear") + else if (strCommand == NetMsgType::FILTERCLEAR) { LOCK(pfrom->cs_filter); delete pfrom->pfilter; @@ -5169,7 +5169,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "reject") + else if (strCommand == NetMsgType::REJECT) { if (fDebug) { try { @@ -5179,7 +5179,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ostringstream ss; ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - if (strMsg == "block" || strMsg == "tx") + if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) { uint256 hash; vRecv >> hash; @@ -5287,7 +5287,7 @@ bool ProcessMessages(CNode* pfrom) } catch (const std::ios_base::failure& e) { - pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, string("error parsing message")); if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv @@ -5355,11 +5355,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->nPingUsecStart = GetTimeMicros(); if (pto->nVersion > BIP0031_VERSION) { pto->nPingNonceSent = nonce; - pto->PushMessage("ping", nonce); + pto->PushMessage(NetMsgType::PING, nonce); } else { // Peer is too old to support ping command with nonce, pong will never arrive. pto->nPingNonceSent = 0; - pto->PushMessage("ping"); + pto->PushMessage(NetMsgType::PING); } } @@ -5401,14 +5401,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // receiver rejects addr messages larger than 1000 if (vAddr.size() >= 1000) { - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); vAddr.clear(); } } } pto->vAddrToSend.clear(); if (!vAddr.empty()) - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); } CNodeState &state = *State(pto->GetId()); @@ -5428,7 +5428,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } BOOST_FOREACH(const CBlockReject& reject, state.rejects) - pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); + pto->PushMessage(NetMsgType::REJECT, (string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock); state.rejects.clear(); // Start block sync @@ -5451,7 +5451,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pindexStart->pprev) pindexStart = pindexStart->pprev; LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256()); + pto->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexStart), uint256()); } } @@ -5551,7 +5551,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) LogPrint("net", "%s: sending header %s to peer=%d\n", __func__, vHeaders.front().GetHash().ToString(), pto->id); } - pto->PushMessage("headers", vHeaders); + pto->PushMessage(NetMsgType::HEADERS, vHeaders); state.pindexBestHeaderSent = pBestIndex; } pto->vBlockHashesToAnnounce.clear(); @@ -5594,14 +5594,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vInv.push_back(inv); if (vInv.size() >= 1000) { - pto->PushMessage("inv", vInv); + pto->PushMessage(NetMsgType::INV, vInv); vInv.clear(); } } pto->vInventoryToSend = vInvWait; } if (!vInv.empty()) - pto->PushMessage("inv", vInv); + pto->PushMessage(NetMsgType::INV, vInv); // Detect whether we're stalling int64_t nNow = GetTimeMicros(); @@ -5670,7 +5670,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.push_back(inv); if (vGetData.size() >= 1000) { - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); vGetData.clear(); } } else { @@ -5680,7 +5680,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); } return true; diff --git a/src/net.cpp b/src/net.cpp index 159d44cba..c5e7ece79 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -67,14 +67,6 @@ namespace { }; } -//immutable thread safe array of allowed commands for logging inbound traffic -const static std::string logAllowIncomingMsgCmds[] = { - "version", "addr", "inv", "getdata", "merkleblock", - "getblocks", "getheaders", "tx", "headers", "block", - "getaddr", "mempool", "ping", "pong", "alert", "notfound", - "filterload", "filteradd", "filterclear", "reject", - "sendheaders", "verack"}; - const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; // @@ -469,7 +461,7 @@ void CNode::PushVersion() LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); } @@ -2399,8 +2391,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); - for (unsigned int i = 0; i < sizeof(logAllowIncomingMsgCmds)/sizeof(logAllowIncomingMsgCmds[0]); i++) - mapRecvBytesPerMsgCmd[logAllowIncomingMsgCmds[i]] = 0; + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) + mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { diff --git a/src/protocol.cpp b/src/protocol.cpp index dd855aa33..5d3ae87de 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -12,14 +12,68 @@ # include #endif +namespace NetMsgType { +const char *VERSION="version"; +const char *VERACK="verack"; +const char *ADDR="addr"; +const char *INV="inv"; +const char *GETDATA="getdata"; +const char *MERKLEBLOCK="merkleblock"; +const char *GETBLOCKS="getblocks"; +const char *GETHEADERS="getheaders"; +const char *TX="tx"; +const char *HEADERS="headers"; +const char *BLOCK="block"; +const char *GETADDR="getaddr"; +const char *MEMPOOL="mempool"; +const char *PING="ping"; +const char *PONG="pong"; +const char *ALERT="alert"; +const char *NOTFOUND="notfound"; +const char *FILTERLOAD="filterload"; +const char *FILTERADD="filteradd"; +const char *FILTERCLEAR="filterclear"; +const char *REJECT="reject"; +const char *SENDHEADERS="sendheaders"; +}; + static const char* ppszTypeName[] = { - "ERROR", - "tx", - "block", - "filtered block" + "ERROR", // Should never occur + NetMsgType::TX, + NetMsgType::BLOCK, + "filtered block" // Should never occur }; +/** All known message types. Keep this in the same order as the list of + * messages above and in protocol.h. + */ +const static std::string allNetMessageTypes[] = { + NetMsgType::VERSION, + NetMsgType::VERACK, + NetMsgType::ADDR, + NetMsgType::INV, + NetMsgType::GETDATA, + NetMsgType::MERKLEBLOCK, + NetMsgType::GETBLOCKS, + NetMsgType::GETHEADERS, + NetMsgType::TX, + NetMsgType::HEADERS, + NetMsgType::BLOCK, + NetMsgType::GETADDR, + NetMsgType::MEMPOOL, + NetMsgType::PING, + NetMsgType::PONG, + NetMsgType::ALERT, + NetMsgType::NOTFOUND, + NetMsgType::FILTERLOAD, + NetMsgType::FILTERADD, + NetMsgType::FILTERCLEAR, + NetMsgType::REJECT, + NetMsgType::SENDHEADERS +}; +const static std::vector allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); + CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn) { memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); @@ -140,3 +194,8 @@ std::string CInv::ToString() const { return strprintf("%s %s", GetCommand(), hash.ToString()); } + +const std::vector &getAllNetMessageTypes() +{ + return allNetMessageTypesVec; +} diff --git a/src/protocol.h b/src/protocol.h index 50aeaf44b..b84c78bac 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -65,6 +65,165 @@ public: unsigned int nChecksum; }; +/** + * Bitcoin protocol message types. When adding new message types, don't forget + * to update allNetMessageTypes in protocol.cpp. + */ +namespace NetMsgType { + +/** + * The version message provides information about the transmitting node to the + * receiving node at the beginning of a connection. + * @see https://bitcoin.org/en/developer-reference#version + */ +extern const char *VERSION; +/** + * The verack message acknowledges a previously-received version message, + * informing the connecting node that it can begin to send other messages. + * @see https://bitcoin.org/en/developer-reference#verack + */ +extern const char *VERACK; +/** + * The addr (IP address) message relays connection information for peers on the + * network. + * @see https://bitcoin.org/en/developer-reference#addr + */ +extern const char *ADDR; +/** + * The inv message (inventory message) transmits one or more inventories of + * objects known to the transmitting peer. + * @see https://bitcoin.org/en/developer-reference#inv + */ +extern const char *INV; +/** + * The getdata message requests one or more data objects from another node. + * @see https://bitcoin.org/en/developer-reference#getdata + */ +extern const char *GETDATA; +/** + * The merkleblock message is a reply to a getdata message which requested a + * block using the inventory type MSG_MERKLEBLOCK. + * @since protocol version 70001 as described by BIP37. + * @see https://bitcoin.org/en/developer-reference#merkleblock + */ +extern const char *MERKLEBLOCK; +/** + * The getblocks message requests an inv message that provides block header + * hashes starting from a particular point in the block chain. + * @see https://bitcoin.org/en/developer-reference#getblocks + */ +extern const char *GETBLOCKS; +/** + * The getheaders message requests a headers message that provides block + * headers starting from a particular point in the block chain. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#getheaders + */ +extern const char *GETHEADERS; +/** + * The tx message transmits a single transaction. + * @see https://bitcoin.org/en/developer-reference#tx + */ +extern const char *TX; +/** + * The headers message sends one or more block headers to a node which + * previously requested certain headers with a getheaders message. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#headers + */ +extern const char *HEADERS; +/** + * The block message transmits a single serialized block. + * @see https://bitcoin.org/en/developer-reference#block + */ +extern const char *BLOCK; +/** + * The getaddr message requests an addr message from the receiving node, + * preferably one with lots of IP addresses of other receiving nodes. + * @see https://bitcoin.org/en/developer-reference#getaddr + */ +extern const char *GETADDR; +/** + * The mempool message requests the TXIDs of transactions that the receiving + * node has verified as valid but which have not yet appeared in a block. + * @since protocol version 60002. + * @see https://bitcoin.org/en/developer-reference#mempool + */ +extern const char *MEMPOOL; +/** + * The ping message is sent periodically to help confirm that the receiving + * peer is still connected. + * @see https://bitcoin.org/en/developer-reference#ping + */ +extern const char *PING; +/** + * The pong message replies to a ping message, proving to the pinging node that + * the ponging node is still alive. + * @since protocol version 60001 as described by BIP31. + * @see https://bitcoin.org/en/developer-reference#pong + */ +extern const char *PONG; +/** + * The alert message warns nodes of problems that may affect them or the rest + * of the network. + * @since protocol version 311. + * @see https://bitcoin.org/en/developer-reference#alert + */ +extern const char *ALERT; +/** + * The notfound message is a reply to a getdata message which requested an + * object the receiving node does not have available for relay. + * @ince protocol version 70001. + * @see https://bitcoin.org/en/developer-reference#notfound + */ +extern const char *NOTFOUND; +/** + * The filterload message tells the receiving peer to filter all relayed + * transactions and requested merkle blocks through the provided filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterload + */ +extern const char *FILTERLOAD; +/** + * The filteradd message tells the receiving peer to add a single element to a + * previously-set bloom filter, such as a new public key. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filteradd + */ +extern const char *FILTERADD; +/** + * The filterclear message tells the receiving peer to remove a previously-set + * bloom filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterclear + */ +extern const char *FILTERCLEAR; +/** + * The reject message informs the receiving node that one of its previous + * messages has been rejected. + * @since protocol version 70002 as described by BIP61. + * @see https://bitcoin.org/en/developer-reference#reject + */ +extern const char *REJECT; +/** + * Indicates that a node prefers to receive new block announcements via a + * "headers" message rather than an "inv". + * @since protocol version 70012 as described by BIP130. + * @see https://bitcoin.org/en/developer-reference#sendheaders + */ +extern const char *SENDHEADERS; + +}; + +/* Get a vector of all valid message types (see above) */ +const std::vector &getAllNetMessageTypes(); + /** nServices flags */ enum { // NODE_NETWORK means that the node is capable of serving the block chain. It is currently From 00423e1a71204696ec37e6d757f9afe091bc7ee1 Mon Sep 17 00:00:00 2001 From: Suriyaa Kudo Date: Thu, 10 Dec 2015 18:45:23 +0100 Subject: [PATCH 0046/1223] Set link from http:// to https:// For opensource.org/licenses/MIT! --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55ab65a68..5bf56947d 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ License ------- Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more -information or see http://opensource.org/licenses/MIT. +information or see https://opensource.org/licenses/MIT. Development Process ------------------- From e1030dddab11553d2854c1f466e5757d9815bfb8 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 7 Dec 2015 16:14:12 -0800 Subject: [PATCH 0047/1223] Note that reviewers should mention the commit hash of the commits they reviewed. --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d42dea84..53d6527d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,6 +95,8 @@ Anyone may participate in peer review which is expressed by comments in the pull - Concept ACK means "I agree in the general principle of this pull request"; - Nit refers to trivial, often non-blocking issues. +Reviewers should include the commit hash which they reviewed in their comments. + Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and also may weight based on meritocracy: Those that have demonstrated a deeper commitment and understanding towards the project (over time) or have clear domain expertise may naturally have more weight, as one would expect in all walks of life. Where a patch set affects consensus critical code, the bar will be set much higher in terms of discussion and peer review requirements, keeping in mind that mistakes could be very costly to the wider community. This includes refactoring of consensus critical code. From 5400ef6bcb9d243b2b21697775aa6491115420f3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Apr 2015 11:20:00 -0700 Subject: [PATCH 0048/1223] Replace trickle nodes with per-node/message Poisson delays We used to have a trickle node, a node which was chosen in each iteration of the send loop that was privileged and allowed to send out queued up non-time critical messages. Since the removal of the fixed sleeps in the network code, this resulted in fast and attackable treatment of such broadcasts. This pull request changes the 3 remaining trickle use cases by random delays: * Local address broadcast (while also removing the the wiping of the seen filter) * Address relay * Inv relay (for transactions; blocks are always relayed immediately) The code is based on older commits by Patrick Strateman. --- src/main.cpp | 34 ++++++++++++++-------------------- src/main.h | 11 +++++++++-- src/net.cpp | 16 ++++++++++------ src/net.h | 8 +++++++- src/test/DoS_tests.cpp | 14 +++++++------- 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d2e736d42..41fc0b809 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5326,7 +5326,7 @@ bool ProcessMessages(CNode* pfrom) } -bool SendMessages(CNode* pto, bool fSendTrickle) +bool SendMessages(CNode* pto) { const Consensus::Params& consensusParams = Params().GetConsensus(); { @@ -5368,28 +5368,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear addrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->addrKnown.reset(); - - // Rebroadcast our address - AdvertizeLocal(pnode); - } - if (!vNodes.empty()) - nLastRebroadcast = GetTime(); + int64_t nNow = GetTimeMicros(); + if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { + AdvertizeLocal(pto); + pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); } // // Message: addr // - if (fSendTrickle) - { + if (pto->nNextAddrSend < nNow) { + pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL); vector vAddr; vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) @@ -5563,8 +5552,13 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vector vInv; vector vInvWait; { + bool fSendTrickle = pto->fWhitelisted; + if (pto->nNextInvSend < nNow) { + fSendTrickle = true; + pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL); + } LOCK(pto->cs_inventory); - vInv.reserve(pto->vInventoryToSend.size()); + vInv.reserve(std::min(1000, pto->vInventoryToSend.size())); vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { @@ -5604,7 +5598,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->PushMessage(NetMsgType::INV, vInv); // Detect whether we're stalling - int64_t nNow = GetTimeMicros(); + nNow = GetTimeMicros(); if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { // Stalling only triggers when the block download window cannot move. During normal steady state, // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection diff --git a/src/main.h b/src/main.h index 19623f4d9..25a006387 100644 --- a/src/main.h +++ b/src/main.h @@ -87,6 +87,14 @@ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; +/** Average delay between local address broadcasts in seconds. */ +static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60; +/** Average delay between peer address broadcasts in seconds. */ +static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30; +/** Average delay between trickled inventory broadcasts in seconds. + * Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */ +static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; + static const unsigned int DEFAULT_LIMITFREERELAY = 15; static const bool DEFAULT_RELAYPRIORITY = true; @@ -197,9 +205,8 @@ bool ProcessMessages(CNode* pfrom); * Send queued protocol messages to be sent to a give node. * * @param[in] pto The node which we are sending messages to. - * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true. */ -bool SendMessages(CNode* pto, bool fSendTrickle); +bool SendMessages(CNode* pto); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); /** Try to detect Partition (network isolation) attacks against us */ diff --git a/src/net.cpp b/src/net.cpp index c5e7ece79..e0d96a2dc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -36,6 +36,8 @@ #include #include +#include + // Dump addresses to peers.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 @@ -1733,11 +1735,6 @@ void ThreadMessageHandler() } } - // Poll the connected nodes for messages - CNode* pnodeTrickle = NULL; - if (!vNodesCopy.empty()) - pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; - bool fSleep = true; BOOST_FOREACH(CNode* pnode, vNodesCopy) @@ -1768,7 +1765,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted); + g_signals.SendMessages(pnode); } boost::this_thread::interruption_point(); } @@ -2384,6 +2381,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nStartingHeight = -1; filterInventoryKnown.reset(); fGetAddr = false; + nNextLocalAddrSend = 0; + nNextAddrSend = 0; + nNextInvSend = 0; fRelayTxes = false; pfilter = new CBloomFilter(); nPingNonceSent = 0; @@ -2634,3 +2634,7 @@ void DumpBanlist() LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); } + +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { + return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); +} diff --git a/src/net.h b/src/net.h index 3ed438605..bc64571ae 100644 --- a/src/net.h +++ b/src/net.h @@ -113,7 +113,7 @@ struct CNodeSignals { boost::signals2::signal GetHeight; boost::signals2::signal ProcessMessages; - boost::signals2::signal SendMessages; + boost::signals2::signal SendMessages; boost::signals2::signal InitializeNode; boost::signals2::signal FinalizeNode; }; @@ -391,6 +391,8 @@ public: CRollingBloomFilter addrKnown; bool fGetAddr; std::set setKnown; + int64_t nNextAddrSend; + int64_t nNextLocalAddrSend; // inventory based relay CRollingBloomFilter filterInventoryKnown; @@ -398,6 +400,7 @@ public: CCriticalSection cs_inventory; std::set setAskFor; std::multimap mapAskFor; + int64_t nNextInvSend; // Used for headers announcements - unfiltered blocks to relay // Also protected by cs_inventory std::vector vBlockHashesToAnnounce; @@ -791,4 +794,7 @@ public: void DumpBanlist(); +/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); + #endif // BITCOIN_NET_H diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index da296a046..51d296502 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned @@ -57,11 +57,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(CNode::IsBanned(addr2)); } @@ -73,13 +73,13 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 10); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 1); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); mapArgs.erase("-banscore"); } @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) dummyNode.nVersion = 1; Misbehaving(dummyNode.GetId(), 100); - SendMessages(&dummyNode, false); + SendMessages(&dummyNode); BOOST_CHECK(CNode::IsBanned(addr)); SetMockTime(nStartTime+60*60); From b6915b82398d2e1d1f888b3816adfaf06d9a450e Mon Sep 17 00:00:00 2001 From: accraze Date: Fri, 11 Dec 2015 18:07:11 -0800 Subject: [PATCH 0049/1223] checks for null data transaction before debug.log CWalletTx::GetAmounts could not find output address for null data transactions, thus issuing an error in debug.log. This change checks to see if the transaction is OP_RETURN before issuing error. resolves #6142 --- src/wallet/wallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f3911f314..a45a9367a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1034,7 +1034,8 @@ void CWalletTx::GetAmounts(list& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address)) + + if (!ExtractDestination(txout.scriptPubKey, address) && txout.scriptPubKey[0] != OP_RETURN) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); From c611acc38a95d336a824b632823aa1b652e570df Mon Sep 17 00:00:00 2001 From: accraze Date: Sat, 12 Dec 2015 10:33:37 -0800 Subject: [PATCH 0050/1223] wallet: check if tx scriptPubKey is unspendable --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a45a9367a..82f3b42b5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1035,7 +1035,7 @@ void CWalletTx::GetAmounts(list& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address) && txout.scriptPubKey[0] != OP_RETURN) + if (!ExtractDestination(txout.scriptPubKey, address) && txout.scriptPubKey.IsUnspendable()) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); From d812daf967ba4173bfa1c37eeb4ab7a0ccc4df25 Mon Sep 17 00:00:00 2001 From: accraze Date: Sat, 12 Dec 2015 10:45:53 -0800 Subject: [PATCH 0051/1223] fix logic for error log --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 82f3b42b5..2cbb89e5a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1035,7 +1035,7 @@ void CWalletTx::GetAmounts(list& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address) && txout.scriptPubKey.IsUnspendable()) + if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable()) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); From fa6ad855e9159b2247da4fa0054f32fa181499ab Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 14:51:43 +0100 Subject: [PATCH 0052/1223] [devtools] Rewrite fix-copyright-headers.py --- contrib/devtools/README.md | 8 +-- contrib/devtools/fix-copyright-headers.py | 67 ++++++++++------------- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index a58b8733a..240ab6d9e 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -11,16 +11,16 @@ fix-copyright-headers.py ======================== Every year newly updated files need to have its copyright headers updated to reflect the current year. -If you run this script from src/ it will automatically update the year on the copyright header for all -.cpp and .h files if these have a git commit from the current year. +If you run this script from the root folder it will automatically update the year on the copyright header for all +source files if these have a git commit from the current year. -For example a file changed in 2014 (with 2014 being the current year): +For example a file changed in 2015 (with 2015 being the current year): ```// Copyright (c) 2009-2013 The Bitcoin Core developers``` would be changed to: -```// Copyright (c) 2009-2014 The Bitcoin Core developers``` +```// Copyright (c) 2009-2015 The Bitcoin Core developers``` git-subtree-check.sh ==================== diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index 5e8495254..1262e29ac 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -1,53 +1,46 @@ #!/usr/bin/env python ''' -Run this script inside of src/ and it will look for all the files -that were changed this year that still have the last year in the -copyright headers, and it will fix the headers on that file using -a perl regex one liner. +Run this script to update all the copyright headers of files +that were changed this year. -For example: if it finds something like this and we're in 2014 +For example: -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2012 The Bitcoin Core developers it will change it to -// Copyright (c) 2009-2014 The Bitcoin Core developers - -It will do this for all the files in the folder and its children. - -Author: @gubatron +// Copyright (c) 2009-2015 The Bitcoin Core developers ''' import os import time +import re year = time.gmtime()[0] -last_year = year - 1 -command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s" -listFilesCommand = "find . | grep %s" +CMD_GIT_DATE = "git log %s | grep Date | head -n 1" +CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s" +REGEX_CURRENT= re.compile("%s The Bitcoin" % year) +CMD_LIST_FILES= "find %s | grep %s" -extensions = [".cpp",".h"] +FOLDERS = ["./qa", "./src"] +EXTENSIONS = [".cpp",".h", ".py"] -def getLastGitModifiedDate(filePath): - gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1" - p = os.popen(gitGetLastCommitDateCommand) - result = "" - for l in p: - result = l - break - result = result.replace("\n","") - return result +def get_git_date(file_path): + r = os.popen(CMD_GIT_DATE % file_path) + for l in r: + # Result is one line, so just return + return l.replace("\n","") + return "" n=1 -for extension in extensions: - foundFiles = os.popen(listFilesCommand % extension) - for filePath in foundFiles: - filePath = filePath[1:-1] - if filePath.endswith(extension): - filePath = os.getcwd() + filePath - modifiedTime = getLastGitModifiedDate(filePath) - if len(modifiedTime) > 0 and str(year) in modifiedTime: - print n,"Last Git Modified: ", modifiedTime, " - ", filePath - os.popen(command % (last_year,year,filePath)) - n = n + 1 - - +for folder in FOLDERS: + for extension in EXTENSIONS: + for file_path in os.popen(CMD_LIST_FILES % (folder, extension)): + file_path = os.getcwd() + file_path[1:-1] + if file_path.endswith(extension): + git_date = get_git_date(file_path) + if len(git_date) > 0 and str(year) in git_date: + # Only update if current year is not found + if REGEX_CURRENT.search(open(file_path, "r").read()) is None: + print n,"Last git edit", git_date, "-", file_path + os.popen(CMD_REGEX % (year,file_path)) + n = n + 1 From fa24439ff3d8ab5b9efaf66ef4dae6713b88cb35 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 17:58:29 +0100 Subject: [PATCH 0053/1223] Bump copyright headers to 2015 --- qa/pull-tester/rpc-tests.py | 2 +- qa/rpc-tests/bipdersig.py | 2 +- qa/rpc-tests/blockchain.py | 2 +- qa/rpc-tests/disablewallet.py | 2 +- qa/rpc-tests/forknotify.py | 2 +- qa/rpc-tests/fundrawtransaction.py | 2 +- qa/rpc-tests/getblocktemplate_longpoll.py | 2 +- qa/rpc-tests/getblocktemplate_proposals.py | 2 +- qa/rpc-tests/getchaintips.py | 2 +- qa/rpc-tests/httpbasics.py | 2 +- qa/rpc-tests/invalidateblock.py | 2 +- qa/rpc-tests/keypool.py | 2 +- qa/rpc-tests/listtransactions.py | 2 +- qa/rpc-tests/mempool_reorg.py | 2 +- qa/rpc-tests/mempool_resurrect_test.py | 2 +- qa/rpc-tests/mempool_spendcoinbase.py | 2 +- qa/rpc-tests/merkle_blocks.py | 2 +- qa/rpc-tests/nodehandling.py | 2 +- qa/rpc-tests/pruning.py | 2 +- qa/rpc-tests/rawtransactions.py | 2 +- qa/rpc-tests/receivedby.py | 2 +- qa/rpc-tests/reindex.py | 2 +- qa/rpc-tests/rest.py | 2 +- qa/rpc-tests/rpcbind_test.py | 2 +- qa/rpc-tests/test_framework/netutil.py | 2 +- qa/rpc-tests/test_framework/test_framework.py | 2 +- qa/rpc-tests/test_framework/util.py | 2 +- qa/rpc-tests/txn_clone.py | 2 +- qa/rpc-tests/txn_doublespend.py | 2 +- qa/rpc-tests/wallet.py | 2 +- qa/rpc-tests/walletbackup.py | 2 +- qa/rpc-tests/zapwallettxes.py | 2 +- src/alert.cpp | 2 +- src/alert.h | 2 +- src/amount.cpp | 2 +- src/amount.h | 2 +- src/arith_uint256.h | 2 +- src/base58.cpp | 2 +- src/base58.h | 2 +- src/bitcoin-cli.cpp | 2 +- src/bitcoin-tx.cpp | 2 +- src/bitcoind.cpp | 2 +- src/bloom.cpp | 2 +- src/bloom.h | 2 +- src/chain.h | 2 +- src/chainparams.cpp | 2 +- src/chainparams.h | 2 +- src/chainparamsbase.cpp | 2 +- src/chainparamsbase.h | 2 +- src/checkpoints.cpp | 2 +- src/checkpoints.h | 2 +- src/checkqueue.h | 2 +- src/clientversion.h | 2 +- src/coincontrol.h | 2 +- src/coins.cpp | 2 +- src/coins.h | 2 +- src/compat.h | 2 +- src/compat/endian.h | 2 +- src/consensus/consensus.h | 2 +- src/consensus/params.h | 2 +- src/consensus/validation.h | 2 +- src/core_io.h | 2 +- src/core_read.cpp | 2 +- src/core_write.cpp | 2 +- src/dbwrapper.cpp | 2 +- src/dbwrapper.h | 2 +- src/hash.cpp | 2 +- src/hash.h | 2 +- src/init.cpp | 2 +- src/init.h | 2 +- src/key.cpp | 2 +- src/key.h | 2 +- src/keystore.cpp | 2 +- src/keystore.h | 2 +- src/limitedmap.h | 2 +- src/main.cpp | 2 +- src/main.h | 2 +- src/merkleblock.cpp | 2 +- src/merkleblock.h | 2 +- src/miner.cpp | 2 +- src/miner.h | 2 +- src/net.cpp | 2 +- src/net.h | 2 +- src/netbase.cpp | 2 +- src/netbase.h | 2 +- src/policy/policy.cpp | 2 +- src/policy/policy.h | 2 +- src/pow.cpp | 2 +- src/pow.h | 2 +- src/primitives/block.cpp | 2 +- src/primitives/block.h | 2 +- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 2 +- src/protocol.cpp | 2 +- src/protocol.h | 2 +- src/pubkey.cpp | 2 +- src/pubkey.h | 2 +- src/qt/addressbookpage.cpp | 2 +- src/qt/addressbookpage.h | 2 +- src/qt/addresstablemodel.cpp | 2 +- src/qt/addresstablemodel.h | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/askpassphrasedialog.h | 2 +- src/qt/bantablemodel.h | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/bitcoinamountfield.cpp | 2 +- src/qt/bitcoinamountfield.h | 2 +- src/qt/bitcoingui.cpp | 2 +- src/qt/bitcoingui.h | 2 +- src/qt/bitcoinunits.cpp | 2 +- src/qt/bitcoinunits.h | 2 +- src/qt/clientmodel.cpp | 2 +- src/qt/clientmodel.h | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/coincontroldialog.h | 2 +- src/qt/coincontroltreewidget.cpp | 2 +- src/qt/editaddressdialog.h | 2 +- src/qt/guiconstants.h | 2 +- src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 2 +- src/qt/intro.cpp | 2 +- src/qt/intro.h | 2 +- src/qt/macdockiconhandler.h | 2 +- src/qt/networkstyle.cpp | 2 +- src/qt/notificator.h | 2 +- src/qt/openuridialog.h | 2 +- src/qt/optionsdialog.cpp | 2 +- src/qt/optionsdialog.h | 2 +- src/qt/optionsmodel.cpp | 2 +- src/qt/optionsmodel.h | 2 +- src/qt/overviewpage.cpp | 2 +- src/qt/overviewpage.h | 2 +- src/qt/paymentrequestplus.cpp | 2 +- src/qt/paymentrequestplus.h | 2 +- src/qt/paymentserver.cpp | 2 +- src/qt/paymentserver.h | 2 +- src/qt/peertablemodel.cpp | 2 +- src/qt/peertablemodel.h | 2 +- src/qt/qvalidatedlineedit.cpp | 2 +- src/qt/qvalidatedlineedit.h | 2 +- src/qt/qvaluecombobox.cpp | 2 +- src/qt/qvaluecombobox.h | 2 +- src/qt/receivecoinsdialog.cpp | 2 +- src/qt/receivecoinsdialog.h | 2 +- src/qt/receiverequestdialog.h | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/recentrequeststablemodel.h | 2 +- src/qt/rpcconsole.cpp | 2 +- src/qt/rpcconsole.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/sendcoinsdialog.h | 2 +- src/qt/sendcoinsentry.cpp | 2 +- src/qt/sendcoinsentry.h | 2 +- src/qt/signverifymessagedialog.cpp | 2 +- src/qt/signverifymessagedialog.h | 2 +- src/qt/splashscreen.cpp | 2 +- src/qt/splashscreen.h | 2 +- src/qt/test/paymentrequestdata.h | 2 +- src/qt/test/paymentservertests.cpp | 2 +- src/qt/test/paymentservertests.h | 2 +- src/qt/test/test_main.cpp | 2 +- src/qt/test/uritests.h | 2 +- src/qt/trafficgraphwidget.cpp | 2 +- src/qt/trafficgraphwidget.h | 2 +- src/qt/transactiondesc.cpp | 2 +- src/qt/transactionrecord.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactiontablemodel.h | 2 +- src/qt/transactionview.cpp | 2 +- src/qt/transactionview.h | 2 +- src/qt/utilitydialog.cpp | 2 +- src/qt/utilitydialog.h | 2 +- src/qt/walletframe.cpp | 2 +- src/qt/walletframe.h | 2 +- src/qt/walletmodel.cpp | 2 +- src/qt/walletmodel.h | 2 +- src/qt/walletmodeltransaction.cpp | 2 +- src/qt/walletview.cpp | 2 +- src/qt/walletview.h | 2 +- src/random.cpp | 2 +- src/rest.cpp | 2 +- src/rpcblockchain.cpp | 2 +- src/rpcclient.cpp | 2 +- src/rpcclient.h | 2 +- src/rpcmining.cpp | 2 +- src/rpcmisc.cpp | 2 +- src/rpcnet.cpp | 2 +- src/rpcprotocol.cpp | 2 +- src/rpcprotocol.h | 2 +- src/rpcserver.cpp | 2 +- src/rpcserver.h | 2 +- src/script/bitcoinconsensus.cpp | 2 +- src/script/bitcoinconsensus.h | 2 +- src/script/interpreter.cpp | 2 +- src/script/interpreter.h | 2 +- src/script/script.cpp | 2 +- src/script/script.h | 2 +- src/script/sigcache.cpp | 2 +- src/script/sigcache.h | 2 +- src/script/sign.cpp | 2 +- src/script/sign.h | 2 +- src/script/standard.cpp | 2 +- src/script/standard.h | 2 +- src/serialize.h | 2 +- src/streams.h | 2 +- src/support/allocators/secure.h | 2 +- src/support/allocators/zeroafterfree.h | 2 +- src/support/pagelocker.cpp | 2 +- src/support/pagelocker.h | 2 +- src/sync.cpp | 2 +- src/sync.h | 2 +- src/test/Checkpoints_tests.cpp | 2 +- src/test/DoS_tests.cpp | 2 +- src/test/accounting_tests.cpp | 2 +- src/test/addrman_tests.cpp | 2 +- src/test/alert_tests.cpp | 2 +- src/test/allocator_tests.cpp | 2 +- src/test/arith_uint256_tests.cpp | 2 +- src/test/base32_tests.cpp | 2 +- src/test/base58_tests.cpp | 2 +- src/test/base64_tests.cpp | 2 +- src/test/bip32_tests.cpp | 2 +- src/test/bloom_tests.cpp | 2 +- src/test/checkblock_tests.cpp | 2 +- src/test/coins_tests.cpp | 2 +- src/test/compress_tests.cpp | 2 +- src/test/crypto_tests.cpp | 2 +- src/test/dbwrapper_tests.cpp | 2 +- src/test/getarg_tests.cpp | 2 +- src/test/hash_tests.cpp | 2 +- src/test/key_tests.cpp | 2 +- src/test/main_tests.cpp | 2 +- src/test/mempool_tests.cpp | 2 +- src/test/miner_tests.cpp | 2 +- src/test/netbase_tests.cpp | 2 +- src/test/pmt_tests.cpp | 2 +- src/test/rpc_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 2 +- src/test/sanity_tests.cpp | 2 +- src/test/scheduler_tests.cpp | 2 +- src/test/script_P2SH_tests.cpp | 2 +- src/test/script_tests.cpp | 2 +- src/test/scriptnum10.h | 2 +- src/test/scriptnum_tests.cpp | 2 +- src/test/serialize_tests.cpp | 2 +- src/test/sighash_tests.cpp | 2 +- src/test/sigopcount_tests.cpp | 2 +- src/test/skiplist_tests.cpp | 2 +- src/test/streams_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 2 +- src/test/timedata_tests.cpp | 2 +- src/test/transaction_tests.cpp | 2 +- src/test/txvalidationcache_tests.cpp | 2 +- src/test/uint256_tests.cpp | 2 +- src/test/util_tests.cpp | 2 +- src/timedata.cpp | 2 +- src/txdb.cpp | 2 +- src/txdb.h | 2 +- src/txmempool.cpp | 2 +- src/txmempool.h | 2 +- src/ui_interface.h | 2 +- src/uint256.cpp | 2 +- src/uint256.h | 2 +- src/util.cpp | 2 +- src/util.h | 2 +- src/utilmoneystr.cpp | 2 +- src/utilmoneystr.h | 2 +- src/utilstrencodings.cpp | 2 +- src/utilstrencodings.h | 2 +- src/utiltime.cpp | 2 +- src/utiltime.h | 2 +- src/validationinterface.h | 2 +- src/wallet/crypter.cpp | 2 +- src/wallet/crypter.h | 2 +- src/wallet/db.cpp | 2 +- src/wallet/db.h | 2 +- src/wallet/rpcdump.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/test/wallet_tests.cpp | 2 +- src/wallet/wallet.cpp | 2 +- src/wallet/wallet.h | 2 +- src/wallet/wallet_ismine.cpp | 2 +- src/wallet/wallet_ismine.h | 2 +- src/wallet/walletdb.cpp | 2 +- src/wallet/walletdb.h | 2 +- 285 files changed, 285 insertions(+), 285 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index df71e44b6..a5b08347a 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index 243f816f6..5afc9ddde 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index b7bfe3628..673f1cc54 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 4cb01575e..2112097af 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 0acef8e30..2deede0c3 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 93d13faa0..d6493dbb8 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 1ddff8a29..3e85957ae 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index aca0cd749..f83b5f140 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index 6a2bcb296..e8d2d8f3f 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 7888114c5..5b9fa0097 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index 2b9c8154e..0e78a3c80 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 92d91e029..c300bbc57 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index b30a6bc9d..8a1e3dc4b 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index fdbaf689a..d96a3f826 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 19c74bb75..750953ee5 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index fc17c5069..35ce76e24 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 72a80ce6c..08e5db45f 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index e383a3a12..3239dd033 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 21f8d6938..01b014062 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 173faf736..d77b41979 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 16d6bd4cf..18af0e810 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index f2e3f248e..d90177a02 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index e084ad55a..682c53169 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 7a9da6678..5f409ad61 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index b30a88a4f..50daa8793 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index ae2d91ab6..60f1dcfdf 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index b7e90a8a8..04e70a75f 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index b1f603a19..bad090bcb 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index d4665b3d4..05a3a3478 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 6f6bc3189..6045b8268 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index da100d7fc..1221a0911 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 0ec8ec536..1ee0f79ac 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/alert.cpp b/src/alert.cpp index 91e54a917..3a3e563cf 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/alert.h b/src/alert.h index 4f9fff918..8cb86e338 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.cpp b/src/amount.cpp index b46918198..a3abd8cd8 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.h b/src/amount.h index a2e4a59d1..a48b17d51 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 103c78bb8..ba3d62015 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.cpp b/src/base58.cpp index c80918505..5e26cf8d4 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.h b/src/base58.h index 90014b949..a3980118a 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 2fa91e4e7..fb2052108 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 9f8b2b98a..2c502ead3 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 4cee2d3cf..3b6608c95 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bloom.cpp b/src/bloom.cpp index de8720659..6e97dc572 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bloom.h b/src/bloom.h index a4dba8cb4..f48ebe55e 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chain.h b/src/chain.h index 01be2d6e5..b9b1b9306 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a46866a2b..87e408606 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparams.h b/src/chainparams.h index 8aa0c71d6..fdf5c17a0 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index bc64cdc5d..cb71a8b55 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 9c3e9a0eb..59493afb9 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index a9822eed8..aefddce46 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.h b/src/checkpoints.h index 5fce6fa81..cd25ea537 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkqueue.h b/src/checkqueue.h index 20ba25bb4..32e25d5c8 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/clientversion.h b/src/clientversion.h index 5a06b310a..de64612ab 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coincontrol.h b/src/coincontrol.h index 3945644ce..9626ad2c5 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coins.cpp b/src/coins.cpp index 122bf4e48..4d1dbdea4 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/coins.h b/src/coins.h index 60c1ba8a7..eab94ec1b 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat.h b/src/compat.h index 20c2a2514..1225ea18e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/endian.h b/src/compat/endian.h index 9fec2a07f..6bfae42c7 100644 --- a/src/compat/endian.h +++ b/src/compat/endian.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 6d6ce7e09..5a099cf53 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/params.h b/src/consensus/params.h index 5ebc48a8d..335750fe8 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/validation.h b/src/consensus/validation.h index d6051edc3..d7e57f5b5 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_io.h b/src/core_io.h index ba5b4e648..e8c0c49e8 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_read.cpp b/src/core_read.cpp index 4be24f8e0..444a4c7eb 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_write.cpp b/src/core_write.cpp index 533fedfe7..b660e86c3 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index b6307cf0b..1907e2fa7 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 1d31ab8ae..5e7313f7e 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.cpp b/src/hash.cpp index 9711293e3..7f3cf1a1f 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.h b/src/hash.h index daa92a009..97955c8d5 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/init.cpp b/src/init.cpp index 645c8f94b..c768ca75b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/init.h b/src/init.h index d4872e779..af1b94b72 100644 --- a/src/init.h +++ b/src/init.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.cpp b/src/key.cpp index a24fa8a4b..28ba5144e 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.h b/src/key.h index 021eac2a8..6c820d49c 100644 --- a/src/key.h +++ b/src/key.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.cpp b/src/keystore.cpp index cf49ba83a..cc8a57336 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.h b/src/keystore.h index b917bf20b..d9290722e 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/limitedmap.h b/src/limitedmap.h index 5456dfc7c..4d9bb4fa2 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index cb3f8f39f..dc891fecf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.h b/src/main.h index 19623f4d9..bcd6ef1ab 100644 --- a/src/main.h +++ b/src/main.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f8e877df2..8447f924e 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.h b/src/merkleblock.h index 904c22abc..996cd1262 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.cpp b/src/miner.cpp index 2728c7e6a..c454c0279 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.h b/src/miner.h index 16c8e2a97..512494198 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/net.cpp b/src/net.cpp index e5659efc0..48a181dee 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/net.h b/src/net.h index a5a5c770d..078ffb9d2 100644 --- a/src/net.h +++ b/src/net.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/netbase.cpp b/src/netbase.cpp index 05214cb02..4e1f26760 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/netbase.h b/src/netbase.h index 9c2df0338..1db66ac27 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 46c7f1894..273a482fa 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/policy/policy.h b/src/policy/policy.h index 31655f2f3..726864f19 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pow.cpp b/src/pow.cpp index 5ace3fbc9..7392defe6 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pow.h b/src/pow.h index e864a474c..439944092 100644 --- a/src/pow.h +++ b/src/pow.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 7280c18f7..59e949d71 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/block.h b/src/primitives/block.h index 5c017d436..0e93399c0 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 46d3cbbe2..aea96d8a1 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index c5d8a64a6..8bd6d00e2 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/protocol.cpp b/src/protocol.cpp index dd855aa33..3e21c5322 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/protocol.h b/src/protocol.h index 50aeaf44b..dce298b44 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 6ebb152c7..db06a8928 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pubkey.h b/src/pubkey.h index a1d437e70..e1a17b658 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 8bd158644..135f15ffa 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 92e6cab9a..c22566d47 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index a488d298c..71ed3618e 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 2b7475c4e..d04b95eba 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 441814ff0..680751bb6 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index d4d832825..727b5a1ad 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index c21dd04e3..fe9600ac0 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6e6330d2a..dcf752cc3 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d19b9fd4a..73eb35a54 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 3703b1f8d..2f03a3d17 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b2bd167ae..701c96d06 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index b121a443e..871ca1ba3 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 425b45d91..de5799130 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 1871c33a7..252942e47 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 127118742..b4ac69639 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 2d204fdb6..62c9f71ac 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 0f4224304..63e904329 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 8ff1eac70..1a467eb2f 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 5dcbf0c3f..f86bc0851 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index d59fce2d4..ddb67ece7 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 216f23f13..5ceffcd70 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 6dce9370d..85d53cfa6 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index ec678c4af..9267e0a6c 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index ab63e98d4..e0b84ba13 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/intro.h b/src/qt/intro.h index 1d49922e9..9e2e96dc9 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 8bd867c10..1c28593d4 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 4541c7588..5f31f4937 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.h b/src/qt/notificator.h index f2a15e9c3..f92b791d4 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 28b8f56ca..e94593d5b 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 647c860bd..ae1c05240 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 489e35da4..e944fb9ee 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3e5c6c72b..d091bb9e6 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index d5bddb1a9..841711dd2 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index a56c80ac6..d577345e4 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 4139eb35d..911443c76 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 1000c143f..20e1f79ff 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 8a7c4c062..a73fe5f29 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 31a6d65a8..c80aebb00 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index fa120a435..2d27ed078 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 94837679d..5f7b3d97e 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 5f149ea87..a2aaaa5d2 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index 5658a0bdc..baa2eb67f 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 8cb6a425f..66734cc9d 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index 800436661..146f3dd57 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 5b20e6a5a..f26630231 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 7fb68cc32..b1f82023b 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index eaaf129a9..543854a2f 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 69f84ebbd..4cab4caff 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 5692a7aae..ef9422506 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 64faa72d4..f3cf03f4e 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 30e551de1..4c869b9ac 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 4aebad480..8a48179c5 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ec4e598bf..dace70982 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 391905ffc..ec171734f 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 4f4b5b70d..d063f2c89 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 107ab7015..a8be670c2 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 96f50a265..8e2e8a509 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index d651d5049..d2e04cd4f 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index c15b64c32..9195b3b72 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 29d16d4ea..821f39db1 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index c548ffe42..74a2db8ea 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index fa5696325..84ccfea73 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 71d61fcbe..9ffcbb02a 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f91de2008..db193420b 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index 434169dcd..499484279 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 9b67445bc..601d554c0 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 6336a8d14..00660574a 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 801c6c62d..eb4b12202 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index d8623daf5..5b16b108e 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index e8ada9f76..1647b2a6f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 601f893d4..fe59a15f6 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 11e6d750a..28928d821 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index dde700c4d..cf2b8fbcd 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 81b597e2e..5e7345144 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 47282ae2d..843bd7f67 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index ba8c28464..e4ca5e183 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 9a56e97f9..9a5bc273c 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 690ea0811..cf38c64eb 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index a5e877d81..7a47eda86 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 6a9b2d5bd..8c970ee8a 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 77efdb5cd..6ce98ef16 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 2a6a6a2df..dbb289f42 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/random.cpp b/src/random.cpp index 0ba0de908..6155c0d8c 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rest.cpp b/src/rest.cpp index 2ad7bc106..ad884dac1 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ee04636ce..797157ce7 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index cab581901..047158023 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcclient.h b/src/rpcclient.h index 8937a56f0..ae015860b 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c8649ec27..958c817d6 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 0c656d5cf..9871c3fcc 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 257884889..779e7fbc6 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index d83cd87f9..b7605545d 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 9cf1ab6d9..55d0aac68 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 83d2c2d50..bc419d14d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcserver.h b/src/rpcserver.h index fc88f82be..f85ab42f0 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 79504f6ad..47ad1d080 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index a48ff1e18..5b8c33c6b 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 57e0edc4b..a92822326 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 213e8c765..7b34547ff 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.cpp b/src/script/script.cpp index 9c77ed9fc..fa1307d61 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.h b/src/script/script.h index 3650957fc..2b95a4af8 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index eee96e7c2..bdc0bfdc1 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 226997256..be1df09c2 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 90f557fc6..2f4111f78 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.h b/src/script/sign.h index 13f45007d..47a9cde7f 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 4863b9639..30935768a 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.h b/src/script/standard.h index 2b9fbe78d..6bac6e409 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/serialize.h b/src/serialize.h index 5fe7fc1f3..5c2db9d33 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/streams.h b/src/streams.h index 8610e4d18..0fc6135a6 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index 5e7bb66ea..1ec40fe83 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 41e23392e..28a940ad1 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.cpp b/src/support/pagelocker.cpp index 440e0a519..7cea2d88c 100644 --- a/src/support/pagelocker.cpp +++ b/src/support/pagelocker.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 88b95cce7..6b3979e55 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.cpp b/src/sync.cpp index 1837e8d53..8df8ae43f 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2012 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.h b/src/sync.h index 68a944308..34dd8c228 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 0a23c430e..1b7d368e1 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index da296a046..39fb532c5 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 4a294c671..dad191c68 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index cfcdd9abb..a1e6a204f 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "addrman.h" diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 468eda1c9..0895ef332 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 2108efece..613f6c12d 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 17d6bed6d..53ab7e95e 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 8ec886142..6422b3a88 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 9845df697..e5a2e28b2 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 54c081b0e..ccad94d94 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 69084213a..ce29e692d 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 6b30d6aa8..98f9de767 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index f7e247061..c945a95ad 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 9489a19f6..3fe536f91 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 376ae9368..35e4458bb 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index aeb2a5caa..0b46d718d 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 8b6b0697a..e39931587 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index eb61a2884..9f59de3ef 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index e5d2e5a43..35079d161 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 13ca94946..4978c9513 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 2b92d239e..dbfbdd934 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index e9f7378f7..1347d2365 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 19ddb5b79..71b52409b 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index b1ef0ed24..4168f75e9 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 0d7fb2bc3..113b9437e 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index ce2297500..9abae69b1 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 2e652f76e..398372af3 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index f5f7f381d..51f9e9f39 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index fc07aa72c..9acd0e243 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index e36aca8df..7bd4b8441 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 0059e4a99..46959d5fe 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h index 00419746b..94dd58526 100644 --- a/src/test/scriptnum10.h +++ b/src/test/scriptnum10.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 2405ab3ff..6b6689c7d 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index cc8f2b788..c0fd99aca 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 6fca64d5d..04c6fa962 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index ea2b9b795..a207fd921 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index a904e3862..f14b902fe 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 0ed8f363d..34f501e86 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 2147dbb06..f81050b15 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 887cfb476..1224ff845 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index fb0df1aff..3dca7ea0f 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 9b8e1c088..66be9d3d5 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 426d296a9..da0a3d73e 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "arith_uint256.h" diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 997dc3193..28cecfffa 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/timedata.cpp b/src/timedata.cpp index 861c37598..de8cc62b2 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.cpp b/src/txdb.cpp index cd76c0155..f99e11f26 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.h b/src/txdb.h index 586ab55d0..22e0c5704 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txmempool.cpp b/src/txmempool.cpp index fea5da802..03a8e8eab 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txmempool.h b/src/txmempool.h index 920317186..28ec362ba 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/ui_interface.h b/src/ui_interface.h index 00d930312..967d24327 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2012 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.cpp b/src/uint256.cpp index 25148808c..c58c88bf4 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.h b/src/uint256.h index 6e37cd5d4..4495000f2 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/util.cpp b/src/util.cpp index 191318171..019c912f5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/util.h b/src/util.h index fb154f666..4d3c029e9 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 0f3203432..bebe56130 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 99c3ba830..5839b0734 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index c5a2b5cdb..130bc997b 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index ce93e8349..d40613cfc 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 7d9f6210e..91b40d999 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.h b/src/utiltime.h index 241b5211e..b2807267d 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/validationinterface.h b/src/validationinterface.h index ffb56d266..4da145473 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c86ad9758..95aa4c259 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 70aeb7672..eb06a7866 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 4b9dbebdd..d18250b76 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/db.h b/src/wallet/db.h index 7f58d03f0..01b8c71a0 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index c431fc401..b025c3745 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index db60e498d..374f2fd40 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 8b9292bd1..e8001df50 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d23d54e67..f6ff150e4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 859788893..33c339bba 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index d27b1531e..ebda5cc53 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 9f45f76c6..93cdf6ab8 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index e2e827d81..88dc3102d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 77f795881..8da33dead 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From daf6466330d9d3e4d9034fd316cded192d2a7d67 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 13 Dec 2015 16:20:08 -0800 Subject: [PATCH 0054/1223] Add "NODE_BLOOM" to guiutil so that peers don't get UNKNOWN[4] --- src/qt/guiutil.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 6dce9370d..43cfba63d 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -898,6 +898,9 @@ QString formatServicesStr(quint64 mask) case NODE_GETUTXO: strList.append("GETUTXO"); break; + case NODE_BLOOM: + strList.append("BLOOM"); + break; default: strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); } From d5f46832de900cee0801ca40bba743c9564cccb8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 9 Dec 2015 10:53:12 +0000 Subject: [PATCH 0055/1223] Unify package name to as few places as possible without major changes --- build-aux/m4/bitcoin_find_bdb48.m4 | 4 ++-- build-aux/m4/bitcoin_qt.m4 | 2 +- libbitcoinconsensus.pc.in | 2 +- share/qt/Info.plist.in | 2 +- share/qt/extract_strings_qt.py | 1 + share/setup.nsi.in | 4 ++-- src/Makefile.am | 3 ++- src/Makefile.qt.include | 2 +- src/bitcoin-cli-res.rc | 2 +- src/bitcoin-cli.cpp | 8 ++++++-- src/bitcoin-tx.cpp | 6 +++++- src/bitcoind.cpp | 8 ++++++-- src/clientversion.h | 2 +- src/init.cpp | 12 ++++++------ src/net.cpp | 2 +- src/qt/askpassphrasedialog.cpp | 8 ++++++-- src/qt/bitcoin.cpp | 8 ++++---- src/qt/bitcoingui.cpp | 16 ++++++++++------ src/qt/forms/debugwindow.ui | 2 +- src/qt/forms/helpmessagedialog.ui | 3 --- src/qt/forms/intro.ui | 10 +++++----- src/qt/forms/optionsdialog.ui | 6 +++--- src/qt/intro.cpp | 10 ++++++++-- src/qt/optionsdialog.cpp | 5 +++++ src/qt/res/bitcoin-qt-res.rc | 4 ++-- src/qt/rpcconsole.cpp | 8 +++++++- src/qt/splashscreen.cpp | 8 ++++++-- src/qt/utilitydialog.cpp | 10 +++++++--- src/timedata.cpp | 6 +++++- 29 files changed, 106 insertions(+), 58 deletions(-) diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index 0bf558d25..2aa493a6a 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -38,7 +38,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ done if test "x$bdbpath" = "xX"; then AC_MSG_RESULT([no]) - AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + AC_MSG_ERROR([libdb_cxx headers missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) elif test "x$bdb48path" = "xX"; then BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ @@ -60,7 +60,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ ]) done if test "x$BDB_LIBS" = "x"; then - AC_MSG_ERROR([libdb_cxx missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) fi AC_SUBST(BDB_LIBS) ]) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 2480267dc..5fe12fda9 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -220,7 +220,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl enable qt support - AC_MSG_CHECKING(whether to build Bitcoin Core GUI) + AC_MSG_CHECKING(whether to build ]AC_PACKAGE_NAME[ GUI) BITCOIN_QT_CHECK([ bitcoin_enable_qt=yes bitcoin_enable_qt_test=yes diff --git a/libbitcoinconsensus.pc.in b/libbitcoinconsensus.pc.in index 3ca1696a3..eb920c47e 100644 --- a/libbitcoinconsensus.pc.in +++ b/libbitcoinconsensus.pc.in @@ -3,7 +3,7 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -Name: Bitcoin Core consensus library +Name: @PACKAGE_NAME@ consensus library Description: Library for the Bitcoin consensus protocol. Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lbitcoinconsensus diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index a389332a5..d1a9ed704 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -17,7 +17,7 @@ APPL CFBundleGetInfoString - @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers + @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The @PACKAGE_NAME@ developers CFBundleShortVersionString @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index d4bd58513..045eb27f4 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -70,6 +70,7 @@ f.write(""" #endif """) f.write('static const char UNUSED *bitcoin_strings[] = {\n') +f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('PACKAGE_NAME'),)) messages.sort(key=operator.itemgetter(0)) for (msgid, msgstr) in messages: if msgid != EMPTY: diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 6c0e895bb..26d382274 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -6,7 +6,7 @@ SetCompressor /SOLID lzma # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" !define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ -!define COMPANY "Bitcoin Core project" +!define COMPANY "@PACKAGE_NAME@ project" !define URL http://www.bitcoin.org/ # MUI Symbol Definitions @@ -59,7 +59,7 @@ XPStyle on BrandingText " " ShowInstDetails show VIProductVersion ${VERSION}.@CLIENT_VERSION_BUILD@ -VIAddVersionKey ProductName "Bitcoin Core" +VIAddVersionKey ProductName "@PACKAGE_NAME@" VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" VIAddVersionKey CompanyWebsite "${URL}" diff --git a/src/Makefile.am b/src/Makefile.am index f1e98dabd..959eef8a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -448,7 +448,8 @@ clean-local: .rc.o: @test -f $(WINDRES) - $(AM_V_GEN) $(WINDRES) -DWINDRES_PREPROC -i $< -o $@ + ## FIXME: How to get the appropriate modulename_CPPFLAGS in here? + $(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@ .mm.o: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index e62003a51..c93667038 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -382,7 +382,7 @@ SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" - $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) ../share/qt/extract_strings_qt.py $^ + $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" ../share/qt/extract_strings_qt.py $^ translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index 1e4aa609b..58f8f1e8a 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -17,7 +17,7 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", "bitcoin-cli (JSON-RPC client for Bitcoin Core)" + VALUE "FileDescription", "bitcoin-cli (JSON-RPC client for " PACKAGE_NAME ")" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-cli" VALUE "LegalCopyright", COPYRIGHT_STR diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 956457365..f8e3880ea 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "chainparamsbase.h" #include "clientversion.h" #include "rpcclient.h" @@ -68,10 +72,10 @@ static bool AppInitRPC(int argc, char* argv[]) // ParseParameters(argc, argv); if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { - std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n"; + std::string strUsage = strprintf(_("%s RPC client version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n"; if (!mapArgs.count("-version")) { strUsage += "\n" + _("Usage:") + "\n" + - " bitcoin-cli [options] [params] " + _("Send command to Bitcoin Core") + "\n" + + " bitcoin-cli [options] [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" + " bitcoin-cli [options] help " + _("List commands") + "\n" + " bitcoin-cli [options] help " + _("Get help for a command") + "\n"; diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 9f8b2b98a..aaa2ef128 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "base58.h" #include "clientversion.h" #include "coins.h" @@ -47,7 +51,7 @@ static bool AppInitRawTx(int argc, char* argv[]) if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help")) { // First part of help message is specific to this utility - std::string strUsage = _("Bitcoin Core bitcoin-tx utility version") + " " + FormatFullVersion() + "\n\n" + + std::string strUsage = strprintf(_("%s bitcoin-tx utility version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n\n" + _("Usage:") + "\n" + " bitcoin-tx [options] [commands] " + _("Update hex-encoded bitcoin transaction") + "\n" + " bitcoin-tx [options] -create [commands] " + _("Create hex-encoded bitcoin transaction") + "\n" + diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index addf0e6a2..440356aa8 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "chainparams.h" #include "clientversion.h" #include "rpcserver.h" @@ -74,7 +78,7 @@ bool AppInit(int argc, char* argv[]) // Process help and version before taking care about datadir if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { - std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n"; + std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n"; if (mapArgs.count("-version")) { @@ -83,7 +87,7 @@ bool AppInit(int argc, char* argv[]) else { strUsage += "\n" + _("Usage:") + "\n" + - " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n"; + " bitcoind [options] " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n"; strUsage += "\n" + HelpMessage(HMM_BITCOIND); } diff --git a/src/clientversion.h b/src/clientversion.h index 5a06b310a..ba15ebf3b 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -38,7 +38,7 @@ #define DO_STRINGIZE(X) #X //! Copyright string used in Windows .rc files -#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers" +#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The " PACKAGE_NAME " Developers" /** * bitcoind-res.rc includes this file, but it cannot cope with real c++ code. diff --git a/src/init.cpp b/src/init.cpp index 162b18186..8d44f833a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -513,7 +513,7 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { // todo: remove urls from translations on next change - return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" + + return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The %s Developers"), COPYRIGHT_YEAR, _(PACKAGE_NAME))) + "\n" + "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + @@ -997,7 +997,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Sanity check if (!InitSanityCheck()) - return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down.")); + return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), _(PACKAGE_NAME))); std::string strDataDir = GetDataDir().string(); #ifdef ENABLE_WALLET @@ -1013,9 +1013,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) try { static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); if (!lock.try_lock()) - return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running."), strDataDir)); + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME))); } catch(const boost::interprocess::interprocess_exception& e) { - return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.") + " %s.", strDataDir, e.what())); + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what())); } #ifndef WIN32 @@ -1423,10 +1423,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) " or address book entries might be missing or incorrect.")); } else if (nLoadWalletRet == DB_TOO_NEW) - strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin Core") << "\n"; + strErrors << strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) << "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) { - strErrors << _("Wallet needed to be rewritten: restart Bitcoin Core to complete") << "\n"; + strErrors << strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) << "\n"; LogPrintf("%s", strErrors.str()); return InitError(strErrors.str()); } diff --git a/src/net.cpp b/src/net.cpp index cff4c5450..2b804b0b4 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1849,7 +1849,7 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString()); + strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), _(PACKAGE_NAME)); else strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr)); LogPrintf("%s\n", strError); diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 441814ff0..e8e5825d1 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "askpassphrasedialog.h" #include "ui_askpassphrasedialog.h" @@ -119,9 +123,9 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "" + - tr("Bitcoin Core will close now to finish the encryption process. " + tr("%1 will close now to finish the encryption process. " "Remember that encrypting your wallet cannot fully protect " - "your bitcoins from being stolen by malware infecting your computer.") + + "your bitcoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) + "

" + tr("IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated, encrypted wallet file. " diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 06a6c239e..e108c84e3 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -578,14 +578,14 @@ int main(int argc, char *argv[]) /// - Do not call GetDataDir(true) before this step finishes if (!boost::filesystem::is_directory(GetDataDir(false))) { - QMessageBox::critical(0, QObject::tr("Bitcoin Core"), + QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); return 1; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { - QMessageBox::critical(0, QObject::tr("Bitcoin Core"), + QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); return false; } @@ -600,7 +600,7 @@ int main(int argc, char *argv[]) try { SelectParams(ChainNameFromCommandLine()); } catch(std::exception &e) { - QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: %1").arg(e.what())); + QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); return 1; } #ifdef ENABLE_WALLET @@ -658,7 +658,7 @@ int main(int argc, char *argv[]) app.createWindow(networkStyle.data()); app.requestInitialize(); #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000 - WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Bitcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId()); + WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), (HWND)app.getMainWinId()); #endif app.exec(); app.requestShutdown(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 6f9f6e90d..811f27f97 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "bitcoingui.h" #include "bitcoinunits.h" @@ -105,7 +109,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n { GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this); - QString windowTitle = tr("Bitcoin Core") + " - "; + QString windowTitle = tr(PACKAGE_NAME) + " - "; #ifdef ENABLE_WALLET /* if compiled with wallet support, -disablewallet can still disable the wallet */ enableWallet = !GetBoolArg("-disablewallet", false); @@ -303,14 +307,14 @@ void BitcoinGUI::createActions() quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); - aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); + aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About %1").arg(tr(PACKAGE_NAME)), this); + aboutAction->setStatusTip(tr("Show information about %1").arg(tr(PACKAGE_NAME))); aboutAction->setMenuRole(QAction::AboutRole); aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this); - optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); + optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(tr(PACKAGE_NAME))); optionsAction->setMenuRole(QAction::PreferencesRole); toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); @@ -340,7 +344,7 @@ void BitcoinGUI::createActions() showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setMenuRole(QAction::NoRole); - showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); + showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(tr(PACKAGE_NAME))); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); @@ -518,7 +522,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) { #ifndef Q_OS_MAC trayIcon = new QSystemTrayIcon(this); - QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText(); + QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText(); trayIcon->setToolTip(toolTip); trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); trayIcon->show(); diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 247147036..7a3d29417 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -415,7 +415,7 @@ - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. &Open diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui index dc7df9d6c..b7f941f70 100644 --- a/src/qt/forms/helpmessagedialog.ui +++ b/src/qt/forms/helpmessagedialog.ui @@ -10,9 +10,6 @@ 400 - - Bitcoin Core - Command-line options - 0 diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui index 09e7bdb02..e4ff3da1a 100644 --- a/src/qt/forms/intro.ui +++ b/src/qt/forms/intro.ui @@ -15,12 +15,12 @@ - + QLabel { font-style:italic; } - Welcome to Bitcoin Core. + Welcome to %1. true @@ -44,9 +44,9 @@ - + - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + As this is the first time the program is launched, you can choose where %1 will store its data. true @@ -56,7 +56,7 @@ - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. true diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 22c67b804..c712e6ea0 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -30,10 +30,10 @@ - Automatically start Bitcoin Core after logging in to the system. + Automatically start %1 after logging in to the system. - &Start Bitcoin Core on system login + &Start %1 on system login @@ -562,7 +562,7 @@ - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + The user interface language can be set here. This setting will take effect after restarting %1. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 4ab87e0f3..8d1dc349d 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "intro.h" #include "ui_intro.h" @@ -112,7 +116,9 @@ Intro::Intro(QWidget *parent) : signalled(false) { ui->setupUi(this); - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(BLOCK_CHAIN_SIZE/GB_BYTES)); + ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME))); + ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME))); + ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(BLOCK_CHAIN_SIZE/GB_BYTES)); startThread(); } @@ -181,7 +187,7 @@ void Intro::pickDataDirectory() TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir)); break; } catch (const fs::filesystem_error&) { - QMessageBox::critical(0, tr("Bitcoin Core"), + QMessageBox::critical(0, tr(PACKAGE_NAME), tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir)); /* fall through, back to choosing screen */ } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index d0191fa6d..79a740612 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -80,6 +80,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* Display elements init */ QDir translations(":translations"); + + ui->bitcoinAtStartup->setToolTip(ui->bitcoinAtStartup->toolTip().arg(tr(PACKAGE_NAME))); + ui->bitcoinAtStartup->setText(ui->bitcoinAtStartup->text().arg(tr(PACKAGE_NAME))); + + ui->lang->setToolTip(ui->lang->toolTip().arg(tr(PACKAGE_NAME))); ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); Q_FOREACH(const QString &langStr, translations.entryList()) { diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 9f66d0af7..19c3d5d97 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -19,13 +19,13 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", "Bitcoin Core (GUI node for Bitcoin)" + VALUE "FileDescription", PACKAGE_NAME " (GUI node for Bitcoin)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" VALUE "LegalCopyright", COPYRIGHT_STR VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoin-qt.exe" - VALUE "ProductName", "Bitcoin Core" + VALUE "ProductName", PACKAGE_NAME VALUE "ProductVersion", VER_PRODUCTVERSION_STR END END diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 619c8631a..b60aa00f1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "rpcconsole.h" #include "ui_debugwindow.h" @@ -250,6 +254,8 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); + ui->openDebugLogfileButton->setToolTip(ui->openDebugLogfileButton->toolTip().arg(tr(PACKAGE_NAME))); + if (platformStyle->getImagesOnButtons()) { ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); } @@ -478,7 +484,7 @@ void RPCConsole::clear() ).arg(fixedFontInfo.family(), ptSize) ); - message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "
" + + message(CMD_REPLY, (tr("Welcome to the %1 RPC console.").arg(tr(PACKAGE_NAME)) + "
" + tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.") + "
" + tr("Type help for an overview of available commands.")), true); } diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index c15b64c32..339b68442 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "splashscreen.h" #include "networkstyle.h" @@ -38,9 +42,9 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) #endif // define text to place - QString titleText = tr("Bitcoin Core"); + QString titleText = tr(PACKAGE_NAME); QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion())); - QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers")); + QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The %1 developers").arg(tr(PACKAGE_NAME))); QString titleAddText = networkStyle->getTitleAddText(); QString font = QApplication::font().toString(); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 5e26f3e01..3e96f26b3 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "utilitydialog.h" #include "ui_helpmessagedialog.h" @@ -30,7 +34,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : { ui->setupUi(this); - QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); + QString version = tr(PACKAGE_NAME) + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); /* On x86 add a bit specifier to the version so that users can distinguish between * 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious. */ @@ -42,7 +46,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : if (about) { - setWindowTitle(tr("About Bitcoin Core")); + setWindowTitle(tr("About %1").arg(tr(PACKAGE_NAME))); /// HTML-format the license message from the core QString licenseInfo = QString::fromStdString(LicenseInfo()); @@ -144,7 +148,7 @@ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): { QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(new QLabel( - tr("Bitcoin Core is shutting down...") + "

" + + tr("%1 is shutting down...").arg(tr(PACKAGE_NAME)) + "

" + tr("Do not shut down the computer until this window disappears."))); setLayout(layout); } diff --git a/src/timedata.cpp b/src/timedata.cpp index 861c37598..2eaa9e4c8 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "timedata.h" #include "netbase.h" @@ -99,7 +103,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) if (!fMatch) { fDone = true; - string strMessage = _("Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); + string strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly."), _(PACKAGE_NAME)); strMiscWarning = strMessage; uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); } From 979698c1715ce86a98934e48acadbc936c95c9a3 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 14 Dec 2015 12:54:55 +0100 Subject: [PATCH 0056/1223] [RPC-Tests] add option to run rpc test over QT clients --- qa/rpc-tests/test_framework/test_framework.py | 2 +- qa/rpc-tests/test_framework/util.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index ae2d91ab6..86d2f06df 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -120,7 +120,7 @@ class BitcoinTestFramework(object): if self.options.coveragedir: enable_coverage(self.options.coveragedir) - os.environ['PATH'] = self.options.srcdir+":"+os.environ['PATH'] + os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH'] check_json_precision() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 72df3ae68..4948680ba 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -131,7 +131,7 @@ def initialize_chain(test_dir): # Create cache directories, run bitcoinds: for i in range(4): datadir=initialize_datadir("cache", i) - args = [ os.getenv("BITCOIND", "bitcoind"), "-keypool=1", "-datadir="+datadir, "-discover=0" ] + args = [ os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir="+datadir, "-discover=0" ] if i > 0: args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) @@ -219,7 +219,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= if binary is None: binary = os.getenv("BITCOIND", "bitcoind") # RPC tests still depend on free transactions - args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000" ] + args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000" ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) devnull = open(os.devnull, "w") From 64360f13044125fbb3cdcbe2e5e8f2bfb82a8b27 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 14 Dec 2015 13:23:45 +0100 Subject: [PATCH 0057/1223] Make max tip age an option instead of chainparam After discussion in #7164 I think this is better. Max tip age was introduced in #5987 to make it possible to run testnet-in-a-box. But associating this behavior with the testnet chain is wrong conceptually, as it is not needed in normal usage. Should aim to make testnet test the software as-is. Replace it with a (debug) option `-maxtipage`, which can be specified only in the specific case. --- src/chainparams.cpp | 3 --- src/chainparams.h | 2 -- src/init.cpp | 3 +++ src/main.cpp | 5 ++++- src/main.h | 2 ++ 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a46866a2b..c2db53fe1 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -92,7 +92,6 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - nMaxTipAge = 24 * 60 * 60; nPruneAfterHeight = 100000; genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); @@ -169,7 +168,6 @@ public: pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nMaxTipAge = 0x7fffffff; nPruneAfterHeight = 1000; genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); @@ -233,7 +231,6 @@ public: pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nMaxTipAge = 24 * 60 * 60; nDefaultPort = 18444; nPruneAfterHeight = 1000; diff --git a/src/chainparams.h b/src/chainparams.h index 8aa0c71d6..1c8c89820 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -64,7 +64,6 @@ public: bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } /** Policy: Filter transactions that do not match well-defined patterns */ bool RequireStandard() const { return fRequireStandard; } - int64_t MaxTipAge() const { return nMaxTipAge; } uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } @@ -84,7 +83,6 @@ protected: //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; - long nMaxTipAge; uint64_t nPruneAfterHeight; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; diff --git a/src/init.cpp b/src/init.cpp index 645c8f94b..60ae5272a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -456,6 +456,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); + strUsage += HelpMessageOpt("-maxtipage=", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); } strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE))); @@ -994,6 +995,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-peerbloomfilters", true)) nLocalServices |= NODE_BLOOM; + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize elliptic curve code diff --git a/src/main.cpp b/src/main.cpp index d2e736d42..72cfb4ca3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,9 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; +/* If the tip is older than this (in seconds), the node is considered to be in initial block download. + */ +int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -1402,7 +1405,7 @@ bool IsInitialBlockDownload() if (lockIBDState) return false; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge()); + pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge); if (!state) lockIBDState = true; return state; diff --git a/src/main.h b/src/main.h index 19623f4d9..d06ad6caf 100644 --- a/src/main.h +++ b/src/main.h @@ -89,6 +89,7 @@ static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; static const unsigned int DEFAULT_LIMITFREERELAY = 15; static const bool DEFAULT_RELAYPRIORITY = true; +static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60; /** Default for -permitbaremultisig */ static const bool DEFAULT_PERMIT_BAREMULTISIG = true; @@ -127,6 +128,7 @@ extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; extern bool fAlerts; +extern int64_t nMaxTipAge; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; From 83cdcbdca41583a5a754a89f45b04b56cd0df627 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 14 Dec 2015 14:18:12 +0100 Subject: [PATCH 0058/1223] test: don't override BITCOIND and BITCOINCLI if they're set In rpc-tests.py, don't override BITCOIND and BITCOINCLI if they're already set. Makes it possible to run the tests with either another tree or the GUI. --- qa/pull-tester/rpc-tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 0cb721b03..57b423344 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -62,8 +62,10 @@ for arg in sys.argv[1:]: #Set env vars buildDir = BUILDDIR -os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT -os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT +if "BITCOIND" not in os.environ: + os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT +if "BITCOINCLI" not in os.environ: + os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT #Disable Windows tests by default if EXEEXT == ".exe" and "-win" not in opts: From 16d4fce0b203bdaa679ad5b3f1e6b6f46880d5d2 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 9 Dec 2015 09:01:34 -0800 Subject: [PATCH 0059/1223] Add assert_is_hex_string and assert_is_hash_string to RPC test utils. --- qa/rpc-tests/test_framework/util.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 72df3ae68..a0f5b1afd 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -407,5 +407,22 @@ def assert_raises(exc, fun, *args, **kwds): else: raise AssertionError("No exception raised") +def assert_is_hex_string(string): + try: + int(string, 16) + except Exception as e: + raise AssertionError( + "Couldn't interpret %r as hexadecimal; raised: %s" % (string, e)) + +def assert_is_hash_string(string, length=64): + if not isinstance(string, basestring): + raise AssertionError("Expected a string, got type %r" % type(string)) + elif length and len(string) != length: + raise AssertionError( + "String of length %d expected; got %d" % (length, len(string))) + elif not re.match('[abcdef0-9]+$', string): + raise AssertionError( + "String %r contains invalid characters for a hash." % string) + def satoshi_round(amount): return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) From 4745636126d9a4f28f701f701be392779815a7bf Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 9 Dec 2015 09:02:19 -0800 Subject: [PATCH 0060/1223] Add RPC documentation for getblockheader[chainwork]. --- src/rpcblockchain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ee04636ce..28c2db450 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -323,7 +323,8 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" - " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" + " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" + " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" "}\n" "\nResult (for verbose=false):\n" "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" From 135d6ec8cedc83ad800da45080c16d49e9182e80 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 9 Dec 2015 09:02:59 -0800 Subject: [PATCH 0061/1223] Add RPC tests for getblockheader. --- qa/rpc-tests/blockchain.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index b7bfe3628..81deab890 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -4,19 +4,25 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -# Test RPC calls related to blockchain state. +# Test RPC calls related to blockchain state. Tests correspond to code in +# rpcblockchain.cpp. # import decimal from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException from test_framework.util import ( initialize_chain, assert_equal, + assert_raises, + assert_is_hex_string, + assert_is_hash_string, start_nodes, connect_nodes_bi, ) + class BlockchainTest(BitcoinTestFramework): """ Test blockchain-related RPC calls: @@ -36,6 +42,10 @@ class BlockchainTest(BitcoinTestFramework): self.sync_all() def run_test(self): + self._test_gettxoutsetinfo() + self._test_getblockheader() + + def _test_gettxoutsetinfo(self): node = self.nodes[0] res = node.gettxoutsetinfo() @@ -47,6 +57,30 @@ class BlockchainTest(BitcoinTestFramework): assert_equal(len(res[u'bestblock']), 64) assert_equal(len(res[u'hash_serialized']), 64) + def _test_getblockheader(self): + node = self.nodes[0] + + assert_raises( + JSONRPCException, lambda: node.getblockheader('nonsense')) + + besthash = node.getbestblockhash() + secondbesthash = node.getblockhash(199) + header = node.getblockheader(besthash) + + assert_equal(header['hash'], besthash) + assert_equal(header['height'], 200) + assert_equal(header['confirmations'], 1) + assert_equal(header['previousblockhash'], secondbesthash) + assert_is_hex_string(header['chainwork']) + assert_is_hash_string(header['hash']) + assert_is_hash_string(header['previousblockhash']) + assert_is_hash_string(header['merkleroot']) + assert_is_hash_string(header['bits'], length=None) + assert isinstance(header['time'], int) + assert isinstance(header['mediantime'], int) + assert isinstance(header['nonce'], int) + assert isinstance(header['version'], int) + assert isinstance(header['difficulty'], decimal.Decimal) if __name__ == '__main__': BlockchainTest().main() From fa2f4bc4eb0f21f5be8c88954ae2d99c5b18b987 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 14 Dec 2015 21:23:05 +0100 Subject: [PATCH 0062/1223] qt5: Use the fixed font the system recommends --- src/qt/guiutil.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 43cfba63d..34675b53d 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -62,6 +62,10 @@ #include #endif +#if QT_VERSION >= 0x50200 +#include +#endif + #if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; #endif @@ -90,6 +94,9 @@ QString dateTimeStr(qint64 nTime) QFont fixedPitchFont() { +#if QT_VERSION >= 0x50200 + return QFontDatabase::systemFont(QFontDatabase::FixedFont); +#else QFont font("Monospace"); #if QT_VERSION >= 0x040800 font.setStyleHint(QFont::Monospace); @@ -97,6 +104,7 @@ QFont fixedPitchFont() font.setStyleHint(QFont::TypeWriter); #endif return font; +#endif } void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) From 37d271d7cce44885f835292ffe99b54399b014d6 Mon Sep 17 00:00:00 2001 From: mb300sd Date: Mon, 14 Dec 2015 14:21:34 -0500 Subject: [PATCH 0063/1223] Rename OP_NOP2 to OP_CHECKLOCKTIMEVERIFY. --- doc/release-notes.md | 14 ++++++++++++ qa/rpc-tests/bip65-cltv-p2p.py | 4 ++-- qa/rpc-tests/decodescript.py | 4 ++-- qa/rpc-tests/test_framework/script.py | 8 +++---- src/script/script.cpp | 2 +- src/script/script.h | 4 ++-- src/test/data/script_invalid.json | 6 ++--- src/test/data/script_valid.json | 6 ++--- src/test/data/tx_invalid.json | 32 +++++++++++++-------------- src/test/data/tx_valid.json | 20 ++++++++--------- src/test/script_tests.cpp | 8 +++---- 11 files changed, 61 insertions(+), 47 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 8bb842ddb..801b684e6 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -18,6 +18,20 @@ git merge commit are mentioned. ### RPC and REST +Asm script outputs now contain OP_CHECKLOCKTIMEVERIFY in place of OP_NOP2 +------------------------------------------------------------------------- + +OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP +65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) + +The following outputs are affected by this change: +- RPC `getrawtransaction` (in verbose mode) +- RPC `decoderawtransaction` +- RPC `decodescript` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `bitcoin-tx -json` + ### Configuration and command-line options ### Block and transaction handling diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 9ca5c69f1..5bb41df1a 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -9,7 +9,7 @@ from test_framework.util import * from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager -from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP +from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP from binascii import hexlify, unhexlify import cStringIO import time @@ -19,7 +19,7 @@ def cltv_invalidate(tx): Prepends -1 CLTV DROP in the scriptSig itself. ''' - tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] + + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) ''' diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 4bca62338..490808d49 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -102,13 +102,13 @@ class DecodeScriptTest(BitcoinTestFramework): # OP_IF # OP_CHECKSIGVERIFY # OP_ELSE - # OP_NOP2 OP_DROP + # OP_CHECKLOCKTIMEVERIFY OP_DROP # OP_ENDIF # OP_CHECKSIG # # lock until block 500,000 rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac') - assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) + assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) def decoderawtransaction_asm_sighashtype(self): """Tests decoding scripts via RPC command "decoderawtransaction". diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 0a78cf6fb..008887602 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -226,7 +226,7 @@ OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf) # expansion OP_NOP1 = CScriptOp(0xb0) -OP_NOP2 = CScriptOp(0xb1) +OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1) OP_NOP3 = CScriptOp(0xb2) OP_NOP4 = CScriptOp(0xb3) OP_NOP5 = CScriptOp(0xb4) @@ -353,7 +353,7 @@ VALID_OPCODES = { OP_CHECKMULTISIGVERIFY, OP_NOP1, - OP_NOP2, + OP_CHECKLOCKTIMEVERIFY, OP_NOP3, OP_NOP4, OP_NOP5, @@ -472,7 +472,7 @@ OPCODE_NAMES.update({ OP_CHECKMULTISIG : 'OP_CHECKMULTISIG', OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY', OP_NOP1 : 'OP_NOP1', - OP_NOP2 : 'OP_NOP2', + OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY', OP_NOP3 : 'OP_NOP3', OP_NOP4 : 'OP_NOP4', OP_NOP5 : 'OP_NOP5', @@ -591,7 +591,7 @@ OPCODES_BY_NAME = { 'OP_CHECKMULTISIG' : OP_CHECKMULTISIG, 'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY, 'OP_NOP1' : OP_NOP1, - 'OP_NOP2' : OP_NOP2, + 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY, 'OP_NOP3' : OP_NOP3, 'OP_NOP4' : OP_NOP4, 'OP_NOP5' : OP_NOP5, diff --git a/src/script/script.cpp b/src/script/script.cpp index 9c77ed9fc..a7ba57e65 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -131,7 +131,7 @@ const char* GetOpName(opcodetype opcode) // expanson case OP_NOP1 : return "OP_NOP1"; - case OP_NOP2 : return "OP_NOP2"; + case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_NOP3 : return "OP_NOP3"; case OP_NOP4 : return "OP_NOP4"; case OP_NOP5 : return "OP_NOP5"; diff --git a/src/script/script.h b/src/script/script.h index 3650957fc..7a37b66cc 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -162,8 +162,8 @@ enum opcodetype // expansion OP_NOP1 = 0xb0, - OP_NOP2 = 0xb1, - OP_CHECKLOCKTIMEVERIFY = OP_NOP2, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_NOP3 = 0xb2, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 7afa2abf4..7ce7e0879 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -160,12 +160,12 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index a4e15faea..e5f0d17b0 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], @@ -442,7 +442,7 @@ ["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"], ["NOP", "NOP1 1", "P2SH,STRICTENC"], -["NOP", "NOP2 1", "P2SH,STRICTENC"], +["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"], ["NOP", "NOP3 1", "P2SH,STRICTENC"], ["NOP", "NOP4 1", "P2SH,STRICTENC"], ["NOP", "NOP5 1", "P2SH,STRICTENC"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index cc059e814..902584194 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -127,66 +127,66 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument just beyond tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument missing"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blockheight nLockTime=0"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blocktime nLockTime=500,000,000"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Input locked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] , +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"] , ["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]], "010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument/tx height/time mismatch, both versions"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument 2^32 with nLockTime=2^32-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Same, but with nLockTime=2^31-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], ["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 0dfef73ae..76d29bcf2 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -190,35 +190,35 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument == 0 and == tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Any non-maxint nSequence is fine"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["The argument can be calculated rather than created directly by a PUSHDATA"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["5 byte non-minimally-encoded arguments are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Valid CHECKLOCKTIMEVERIFY in scriptSig"], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 0059e4a99..9eff6d0c6 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -985,10 +985,10 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) BOOST_AUTO_TEST_CASE(script_GetScriptAsm) { - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); From e18378e53fb71c39236db35ab2d560b43602b1be Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 15 Dec 2015 14:53:15 +0100 Subject: [PATCH 0064/1223] Removed offline testnet DNSSeed 'alexykot.me'. --- src/chainparams.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a46866a2b..abeaaf927 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -179,7 +179,6 @@ public: vFixedSeeds.clear(); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me")); vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); From 39a525c21fd1b34df63ab30868423b97b708ee49 Mon Sep 17 00:00:00 2001 From: ptschip Date: Sat, 5 Dec 2015 09:02:02 -0800 Subject: [PATCH 0065/1223] Do not download transactions during inital sync --- qa/rpc-tests/listtransactions.py | 5 +++++ qa/rpc-tests/receivedby.py | 5 +++++ qa/rpc-tests/test_framework/util.py | 30 +++++++++++++++++++++++++---- src/main.cpp | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index b30a6bc9d..c54a25390 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -32,6 +32,11 @@ def check_array_result(object_array, to_match, expected): class ListTransactionsTest(BitcoinTestFramework): + def setup_nodes(self): + #This test requires mocktime + enable_mocktime() + return start_nodes(4, self.options.tmpdir) + def run_test(self): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 16d6bd4cf..7e0b30592 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -53,6 +53,11 @@ def check_array_result(object_array, to_match, expected, should_not_find = False class ReceivedByTest(BitcoinTestFramework): + def setup_nodes(self): + #This test requires mocktime + enable_mocktime() + return start_nodes(4, self.options.tmpdir) + def run_test(self): ''' listreceivedbyaddress Test diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 4948680ba..128225a06 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -22,6 +22,26 @@ from .authproxy import AuthServiceProxy, JSONRPCException COVERAGE_DIR = None +#Set Mocktime default to OFF. +#MOCKTIME is only needed for scripts that use the +#cached version of the blockchain. If the cached +#version of the blockchain is used without MOCKTIME +#then the mempools will not sync due to IBD. +MOCKTIME = 0 + +def enable_mocktime(): + #For backwared compatibility of the python scripts + #with previous versions of the cache, set MOCKTIME + #to Jan 1, 2014 + (201 * 10 * 60) + global MOCKTIME + MOCKTIME = 1388534400 + (201 * 10 * 60) + +def disable_mocktime(): + global MOCKTIME + MOCKTIME = 0 + +def get_mocktime(): + return MOCKTIME def enable_coverage(dirname): """Maintain a log of which RPC calls are made during testing.""" @@ -155,9 +175,10 @@ def initialize_chain(test_dir): # Create a 200-block-long chain; each of the 4 nodes # gets 25 mature blocks and 25 immature. - # blocks are created with timestamps 10 minutes apart, starting - # at 1 Jan 2014 - block_time = 1388534400 + # blocks are created with timestamps 10 minutes apart + # starting from 2010 minutes in the past + enable_mocktime() + block_time = get_mocktime() - (201 * 10 * 60) for i in range(2): for peer in range(4): for j in range(25): @@ -170,6 +191,7 @@ def initialize_chain(test_dir): # Shut them down, and clean up cache directories: stop_nodes(rpcs) wait_bitcoinds() + disable_mocktime() for i in range(4): os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "db.log")) @@ -219,7 +241,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= if binary is None: binary = os.getenv("BITCOIND", "bitcoind") # RPC tests still depend on free transactions - args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000" ] + args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000", "-mocktime="+str(get_mocktime()) ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) devnull = open(os.devnull, "w") diff --git a/src/main.cpp b/src/main.cpp index 41fc0b809..875248446 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4563,7 +4563,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { if (fBlocksOnly) LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); - else if (!fAlreadyHave && !fImporting && !fReindex) + else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) pfrom->AskFor(inv); } From 5246180f168c9b761b6158b0725f5718239ba66c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 15 Dec 2015 15:40:50 -0500 Subject: [PATCH 0066/1223] Mark blocks with too many sigops as failed --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 41fc0b809..001da9c6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3005,7 +3005,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops", true); + REJECT_INVALID, "bad-blk-sigops"); if (fCheckPOW && fCheckMerkleRoot) block.fChecked = true; From fa5769e95a44427e1ed7d63795d4ff60985f0059 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 16 Dec 2015 13:06:51 +0100 Subject: [PATCH 0067/1223] [qt] Fix misleading translation --- src/qt/locale/bitcoin_en.ts | 2 +- src/qt/utilitydialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index e709f8515..00411741f 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1153,7 +1153,7 @@ - Reset all settings changes made over the GUI + Reset all settings changed in the GUI diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 81b597e2e..088578b7a 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -84,7 +84,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); strUsage += HelpMessageOpt("-rootcertificates=", tr("Set SSL root certificates for payment request (default: -system-)").toStdString()); strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN)); - strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changes made over the GUI").toStdString()); + strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changed in the GUI").toStdString()); if (showDebug) { strUsage += HelpMessageOpt("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM)); } From 9b41a5fba278e9ab56a9b86e7a5fe195dcad0b7a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 15 Dec 2015 15:53:10 -0500 Subject: [PATCH 0068/1223] Add more tests to p2p-fullblocktest --- qa/rpc-tests/p2p-fullblocktest.py | 157 ++++++++++++++++++++++-- qa/rpc-tests/test_framework/mininode.py | 1 + 2 files changed, 146 insertions(+), 12 deletions(-) diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index 9555940ce..a6525e679 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -7,7 +7,7 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.comptool import TestManager, TestInstance +from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.mininode import * from test_framework.blocktools import * import logging @@ -15,7 +15,7 @@ import copy import time import numbers from test_framework.key import CECKey -from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE +from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE class PreviousSpendableOutput(object): def __init__(self, tx = CTransaction(), n = -1): @@ -122,13 +122,29 @@ class FullBlockTest(ComparisonTestFramework): return TestInstance([[self.tip, True]]) # returns a test case that asserts that the current tip was rejected - def rejected(): - return TestInstance([[self.tip, False]]) + def rejected(reject = None): + if reject is None: + return TestInstance([[self.tip, False]]) + else: + return TestInstance([[self.tip, reject]]) # move the tip back to a previous block def tip(number): self.tip = self.blocks[number] + # add transactions to a block produced by next_block + def update_block(block_number, new_transactions): + block = self.blocks[block_number] + old_hash = block.sha256 + self.add_transactions_to_block(block, new_transactions) + block.solve() + # Update the internal state just like in next_block + self.tip = block + self.block_heights[block.sha256] = self.block_heights[old_hash] + del self.block_heights[old_hash] + self.blocks[block_number] = block + return block + # creates a new block and advances the tip to that block block = self.next_block @@ -141,14 +157,15 @@ class FullBlockTest(ComparisonTestFramework): # Now we need that block to mature so we can spend the coinbase. test = TestInstance(sync_every_block=False) - for i in range(100): + for i in range(99): block(1000 + i) test.blocks_and_transactions.append([self.tip, True]) save_spendable_output() yield test - # Start by bulding a couple of blocks on top (which output is spent is in parentheses): + # Start by building a couple of blocks on top (which output is spent is + # in parentheses): # genesis -> b1 (0) -> b2 (1) out0 = get_spendable_output() block(1, spend=out0) @@ -156,8 +173,7 @@ class FullBlockTest(ComparisonTestFramework): yield accepted() out1 = get_spendable_output() - block(2, spend=out1) - # Inv again, then deliver twice (shouldn't break anything). + b2 = block(2, spend=out1) yield accepted() @@ -168,8 +184,8 @@ class FullBlockTest(ComparisonTestFramework): # # Nothing should happen at this point. We saw b2 first so it takes priority. tip(1) - block(3, spend=out1) - # Deliver twice (should still not break anything) + b3 = block(3, spend=out1) + txout_b3 = PreviousSpendableOutput(b3.vtx[1], 1) yield rejected() @@ -214,7 +230,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) tip(6) block(9, spend=out4, additional_coinbase_value=1) - yield rejected() + yield rejected(RejectResult(16, 'bad-cb-amount')) # Create a fork that ends in a block with too much fee (the one that causes the reorg) @@ -226,7 +242,7 @@ class FullBlockTest(ComparisonTestFramework): yield rejected() block(11, spend=out4, additional_coinbase_value=1) - yield rejected() + yield rejected(RejectResult(16, 'bad-cb-amount')) # Try again, but with a valid fork first @@ -252,6 +268,10 @@ class FullBlockTest(ComparisonTestFramework): yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. + # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6) + # \-> b3 (1) -> b4 (2) # Test that a block with a lot of checksigs is okay lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1)) @@ -264,8 +284,121 @@ class FullBlockTest(ComparisonTestFramework): out6 = get_spendable_output() too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50)) block(16, spend=out6, script=too_many_checksigs) + yield rejected(RejectResult(16, 'bad-blk-sigops')) + + + # Attempt to spend a transaction created on a different fork + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1]) + # \-> b3 (1) -> b4 (2) + tip(15) + block(17, spend=txout_b3) + yield rejected(RejectResult(16, 'bad-txns-inputs-missingorspent')) + + # Attempt to spend a transaction created on a different fork (on a fork this time) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) + # \-> b18 (b3.vtx[1]) -> b19 (6) + # \-> b3 (1) -> b4 (2) + tip(13) + block(18, spend=txout_b3) yield rejected() + block(19, spend=out6) + yield rejected() + + # Attempt to spend a coinbase at depth too low + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7) + # \-> b3 (1) -> b4 (2) + tip(15) + out7 = get_spendable_output() + block(20, spend=out7) + yield rejected(RejectResult(16, 'bad-txns-premature-spend-of-coinbase')) + + # Attempt to spend a coinbase at depth too low (on a fork this time) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) + # \-> b21 (6) -> b22 (5) + # \-> b3 (1) -> b4 (2) + tip(13) + block(21, spend=out6) + yield rejected() + + block(22, spend=out5) + yield rejected() + + # Create a block on either side of MAX_BLOCK_SIZE and make sure its accepted/rejected + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) + # \-> b24 (6) -> b25 (7) + # \-> b3 (1) -> b4 (2) + tip(15) + b23 = block(23, spend=out6) + old_hash = b23.sha256 + tx = CTransaction() + script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69 + script_output = CScript([chr(0)*script_length]) + tx.vout.append(CTxOut(0, script_output)) + tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1))) + b23 = update_block(23, [tx]) + # Make sure the math above worked out to produce a max-sized block + assert_equal(len(b23.serialize()), MAX_BLOCK_SIZE) + yield accepted() + + # Make the next block one byte bigger and check that it fails + tip(15) + b24 = block(24, spend=out6) + script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69 + script_output = CScript([chr(0)*(script_length+1)]) + tx.vout = [CTxOut(0, script_output)] + b24 = update_block(24, [tx]) + assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1) + yield rejected(RejectResult(16, 'bad-blk-length')) + + b25 = block(25, spend=out7) + yield rejected() + + # Create blocks with a coinbase input script size out of range + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) + # \-> ... (6) -> ... (7) + # \-> b3 (1) -> b4 (2) + tip(15) + b26 = block(26, spend=out6) + b26.vtx[0].vin[0].scriptSig = chr(0) + b26.vtx[0].rehash() + # update_block causes the merkle root to get updated, even with no new + # transactions, and updates the required state. + b26 = update_block(26, []) + yield rejected(RejectResult(16, 'bad-cb-length')) + + # Extend the b26 chain to make sure bitcoind isn't accepting b26 + b27 = block(27, spend=out7) + yield rejected() + + # Now try a too-large-coinbase script + tip(15) + b28 = block(28, spend=out6) + b28.vtx[0].vin[0].scriptSig = chr(0)*101 + b28.vtx[0].rehash() + b28 = update_block(28, []) + yield rejected(RejectResult(16, 'bad-cb-length')) + + # Extend the b28 chain to make sure bitcoind isn't accepted b28 + b29 = block(29, spend=out7) + # TODO: Should get a reject message back with "bad-prevblk", except + # there's a bug that prevents this from being detected. Just note + # failure for now, and add the reject result later. + yield rejected() + + # b30 has a max-sized coinbase scriptSig. + tip(23) + b30 = block(30) + b30.vtx[0].vin[0].scriptSig = chr(0)*100 + b30.vtx[0].rehash() + b30 = update_block(30, []) + yield accepted() if __name__ == '__main__': diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 9d0fb713a..8e49b5656 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -36,6 +36,7 @@ MY_VERSION = 60001 # past bip-31 for ping/pong MY_SUBVERSION = "/python-mininode-tester:0.0.1/" MAX_INV_SZ = 50000 +MAX_BLOCK_SIZE = 1000000 # Keep our own socket map for asyncore, so that we can track disconnects # ourselves (to workaround an issue with closing an asyncore socket when From fa0765d433eb6d44a5cbec44f136b62814c663e5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 15 Dec 2015 17:15:13 +0100 Subject: [PATCH 0069/1223] [qa] Cleanup wallet.py test * Remove outdated comment * Remove unneeded 0s * Remove semicolons --- qa/rpc-tests/wallet.py | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 6f6bc3189..f6cffe612 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -3,21 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# -# Exercise the wallet. Ported from wallet.sh. -# Does the following: -# a) creates 3 nodes, with an empty chain (no blocks). -# b) node0 mines a block -# c) node1 mines 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none. -# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc). -# e) node0 mines a block, collects the fee on the second transaction -# f) node1 mines 100 blocks, to mature node0's just-mined block -# g) check that node0 has 100-21, node2 has 21 -# h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1 -# i) have node1 mine a block -# j) check balances - node0 should have 0, node2 should have 100 -# k) test ResendWalletTransactions - create transactions, startup fourth node, make sure it syncs -# from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -190,7 +175,7 @@ class WalletTest (BitcoinTestFramework): for uTx in unspentTxs: if uTx['txid'] == zeroValueTxid: found = True - assert_equal(uTx['amount'], Decimal('0.00000000')); + assert_equal(uTx['amount'], Decimal('0')) assert(found) #do some -walletbroadcast tests @@ -202,21 +187,21 @@ class WalletTest (BitcoinTestFramework): connect_nodes_bi(self.nodes,0,2) self.sync_all() - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) self.nodes[1].generate(1) #mine a block, tx should not be in there self.sync_all() - assert_equal(self.nodes[2].getbalance(), node_2_bal); #should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted #now broadcast from another node, mine a block, sync, and check the balance self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) self.nodes[1].generate(1) self.sync_all() txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('2')); #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('2')) #should not be #create another tx - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) @@ -231,21 +216,21 @@ class WalletTest (BitcoinTestFramework): sync_blocks(self.nodes) #tx should be added to balance because after restarting the nodes tx should be broadcastet - assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('4')); #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('4')) #should not be #send a tx with value in a string (PR#6380 +) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-2.00000000')) + assert_equal(txObj['amount'], Decimal('-2')) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amount'], Decimal('-0.0001')) #check if JSON parser can handle scientific notation in strings txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amount'], Decimal('-0.0001')) #this should fail errorString = "" @@ -254,7 +239,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Invalid amount" in errorString, True); + assert_equal("Invalid amount" in errorString, True) errorString = "" try: @@ -262,7 +247,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("not an integer" in errorString, True); + assert_equal("not an integer" in errorString, True) if __name__ == '__main__': From fa14d994843fe2d700c977653cd3133d0a77cb67 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 18 Dec 2015 12:35:50 +0100 Subject: [PATCH 0070/1223] [qa] check if wallet or blochchain maintenance changes the balance --- qa/rpc-tests/wallet.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index f6cffe612..11abb5797 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -197,8 +197,9 @@ class WalletTest (BitcoinTestFramework): self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) self.nodes[1].generate(1) self.sync_all() + node_2_bal += 2 txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('2')) #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal) #create another tx txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) @@ -214,9 +215,10 @@ class WalletTest (BitcoinTestFramework): self.nodes[0].generate(1) sync_blocks(self.nodes) + node_2_bal += 2 #tx should be added to balance because after restarting the nodes tx should be broadcastet - assert_equal(self.nodes[2].getbalance(), node_2_bal + Decimal('4')) #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal) #send a tx with value in a string (PR#6380 +) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") @@ -249,6 +251,29 @@ class WalletTest (BitcoinTestFramework): assert_equal("not an integer" in errorString, True) + #check if wallet or blochchain maintenance changes the balance + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + balance_nodes = [self.nodes[i].getbalance() for i in range(3)] + + maintenance = [ + '-rescan', + '-reindex', + '-zapwallettxes=1', + '-zapwallettxes=2', + '-salvagewallet', + ] + for m in maintenance: + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.sync_all() + assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) + if __name__ == '__main__': WalletTest ().main () From 1a6c67c8f507ad6918b6a27cab9eb734cc1d4bd4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 13 Dec 2015 05:54:21 +0000 Subject: [PATCH 0071/1223] Parameterise 2009 in translatable copyright strings --- src/init.cpp | 2 +- src/qt/splashscreen.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 8d44f833a..4bcf8ec78 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -513,7 +513,7 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { // todo: remove urls from translations on next change - return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The %s Developers"), COPYRIGHT_YEAR, _(PACKAGE_NAME))) + "\n" + + return FormatParagraph(strprintf(_("Copyright (C) %i-%i The %s Developers"), 2009, COPYRIGHT_YEAR, _(PACKAGE_NAME))) + "\n" + "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 339b68442..ad8d7b3f2 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -44,7 +44,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) // define text to place QString titleText = tr(PACKAGE_NAME); QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion())); - QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The %1 developers").arg(tr(PACKAGE_NAME))); + QString copyrightText = QChar(0xA9)+QString(" %1-%2 ").arg(2009).arg(COPYRIGHT_YEAR) + QString(tr("The %1 developers").arg(tr(PACKAGE_NAME))); QString titleAddText = networkStyle->getTitleAddText(); QString font = QApplication::font().toString(); From fa33d9740c9b0d1071094ab6c1736f27a7090c95 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 19 Dec 2015 14:26:56 +0100 Subject: [PATCH 0072/1223] [walletdb] Add missing LOCK() in Recover() for dummyWallet --- src/wallet/walletdb.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index e2e827d81..44b79ed1f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -960,8 +960,13 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION); CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION); string strType, strErr; - bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, + bool fReadOK; + { + // Required in LoadKeyMetadata(): + LOCK(dummyWallet.cs_wallet); + fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss, strType, strErr); + } if (!IsKeyType(strType)) continue; if (!fReadOK) From e279038e84035e0477886183495c2d9c132b6773 Mon Sep 17 00:00:00 2001 From: Tom Harding Date: Sun, 20 Dec 2015 15:41:20 -0800 Subject: [PATCH 0073/1223] Use createrawtx locktime parm in txn_clone Streamlines the test and serves as a test of the createrawtransaction locktime parameter. --- qa/rpc-tests/txn_clone.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index b1f603a19..62e76eb69 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -57,16 +57,10 @@ class TxnMallTest(BitcoinTestFramework): clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}] clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"], rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]} - clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs) + clone_locktime = rawtx1["locktime"] + clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime) - # 3 hex manipulations on the clone are required - - # manipulation 1. sequence is at version+#inputs+input+sigstub - posseq = 2*(4+1+36+1) - seqbe = '%08x' % rawtx1["vin"][0]["sequence"] - clone_raw = clone_raw[:posseq] + seqbe[6:8] + seqbe[4:6] + seqbe[2:4] + seqbe[0:2] + clone_raw[posseq + 8:] - - # manipulation 2. createrawtransaction randomizes the order of its outputs, so swap them if necessary. + # createrawtransaction randomizes the order of its outputs, so swap them if necessary. # output 0 is at version+#inputs+input+sigstub+sequence+#outputs # 40 BTC serialized is 00286bee00000000 pos0 = 2*(4+1+36+1+4+1) @@ -78,11 +72,6 @@ class TxnMallTest(BitcoinTestFramework): output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len] clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:] - # manipulation 3. locktime is after outputs - poslt = pos0 + 2 * output_len - ltbe = '%08x' % rawtx1["locktime"] - clone_raw = clone_raw[:poslt] + ltbe[6:8] + ltbe[4:6] + ltbe[2:4] + ltbe[0:2] + clone_raw[poslt + 8:] - # Use a different signature hash type to sign. This creates an equivalent but malleated clone. # Don't send the clone anywhere yet tx1_clone = self.nodes[0].signrawtransaction(clone_raw, None, None, "ALL|ANYONECANPAY") From 63bcdc5227578015870c1eedc8c59861e9734971 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 10 Dec 2015 21:49:27 +0000 Subject: [PATCH 0074/1223] More complicated package name substitution for Mac deployment --- .travis.yml | 3 +- Makefile.am | 39 ++++++++---- configure.ac | 3 + .../gitian-descriptors/gitian-osx-signer.yml | 3 +- contrib/gitian-descriptors/gitian-osx.yml | 17 ++++- .../macdeploy/Base.lproj/InfoPlist.strings | 1 - contrib/macdeploy/DS_Store | Bin 10244 -> 0 bytes contrib/macdeploy/background.png | Bin 48690 -> 0 bytes contrib/macdeploy/background.psd | Bin 982442 -> 0 bytes contrib/macdeploy/background.svg | 34 ++++++++++ contrib/macdeploy/background.tiff | Bin 202136 -> 0 bytes contrib/macdeploy/background@2x.png | Bin 138890 -> 0 bytes contrib/macdeploy/custom_dsstore.py | 60 ++++++++++++++++++ contrib/macdeploy/macdeployqtplus | 14 +++- doc/README_osx.txt | 5 +- 15 files changed, 156 insertions(+), 23 deletions(-) delete mode 100644 contrib/macdeploy/Base.lproj/InfoPlist.strings delete mode 100644 contrib/macdeploy/DS_Store delete mode 100644 contrib/macdeploy/background.png delete mode 100644 contrib/macdeploy/background.psd create mode 100644 contrib/macdeploy/background.svg delete mode 100644 contrib/macdeploy/background.tiff delete mode 100644 contrib/macdeploy/background@2x.png create mode 100755 contrib/macdeploy/custom_dsstore.py diff --git a/.travis.yml b/.travis.yml index d2fbfee6f..673a0d0a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev libz-dev libbz2-dev libffi-dev libtiff-tools python-dev python-pip" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" exclude: - compiler: gcc install: @@ -49,6 +49,7 @@ install: - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi + - if [[ "$HOST" =~ apple ]]; then pip install --user cairosvg mac_alias ds_store; export PATH="$HOME/.local/bin:$PATH"; ( wget 'https://bitbucket.org/al45tair/ds_store/get/c80c23706eae.tar.gz' && tar -xzvpf c80c23706eae.tar.gz && cd al45tair-ds_store-c80c23706eae/ && python setup.py install --user; ) fi before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources diff --git a/Makefile.am b/Makefile.am index b2b781172..f9fca357c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,12 +14,18 @@ BITCOIN_QT_BIN=$(top_builddir)/src/qt/bitcoin-qt$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/bitcoin-cli$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) +empty := +space := $(empty) $(empty) + OSX_APP=Bitcoin-Qt.app -OSX_DMG=Bitcoin-Core.dmg +OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) +OSX_DMG = $(OSX_VOLNAME).dmg +OSX_BACKGROUND_SVG=background.svg OSX_BACKGROUND_IMAGE=background.tiff +OSX_BACKGROUND_IMAGE_DPIS=36 72 +OSX_DSSTORE_GEN=$(top_srcdir)/contrib/macdeploy/custom_dsstore.py OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist -OSX_BASE_LPROJ_DIR=$(top_srcdir)/contrib/macdeploy/Base.lproj/InfoPlist.strings OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_srcdir)/share/qt/Info.plist #not installed OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW @@ -31,9 +37,9 @@ WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ $(top_srcdir)/doc/README_windows.txt -OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $(OSX_BASE_LPROJ_DIR) \ - $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \ - $(top_srcdir)/contrib/macdeploy/DS_Store \ +OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ + $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \ + $(OSX_DSSTORE_GEN) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh @@ -87,17 +93,20 @@ $(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(BITCOIN_QT_BIN) $(MKDIR_P) $(@D) STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $< $@ -$(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(OSX_BASE_LPROJ_DIR) +$(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(MKDIR_P) $(@D) - $(INSTALL_DATA) $< $@ + echo '{ CFBundleDisplayName = "$(PACKAGE_NAME)"; CFBundleName = "$(PACKAGE_NAME)"; }' > $@ OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \ $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \ $(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings +osx_volname: + echo $(OSX_VOLNAME) >$@ + if BUILD_DARWIN $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) - $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 + $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) deploydir: $(OSX_DMG) else @@ -111,13 +120,17 @@ $(APP_DIST_DIR)/Applications: $(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_DMG): $(APP_DIST_EXTRAS) - $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -dir-mode 0755 -apple -o $@ dist + $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist -$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) +dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) + sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(CAIROSVG) -fpng -d$* - | $(IMAGEMAGICK_CONVERT) - $@ +OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) +$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIFILES) $(MKDIR_P) $(@D) - $(INSTALL) $< $@ -$(APP_DIST_DIR)/.DS_Store: contrib/macdeploy/DS_Store - $(INSTALL) $< $@ + $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ + +$(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) + $< "$@" "$(OSX_VOLNAME)" $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 diff --git a/configure.ac b/configure.ac index 63a745393..732f550be 100644 --- a/configure.ac +++ b/configure.ac @@ -314,6 +314,9 @@ case $host in AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) + AC_PATH_PROGS([CAIROSVG], [cairosvg cairosvg-py3 cairosvg-py2],cairosvg) + AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) + AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index aa9494b7e..d349a13dd 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -33,6 +33,7 @@ script: | SIGNED=bitcoin-osx-signed.dmg tar -xf ${UNSIGNED} + OSX_VOLNAME="$(cat osx_volname)" ./detached-sig-apply.sh ${UNSIGNED} signature/osx - ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -apple -o uncompressed.dmg signed-app ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 9ac774c8a..13dbe890c 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -10,14 +10,22 @@ packages: - "git-core" - "pkg-config" - "autoconf" +- "libffi-dev" +- "libtiff-tools" - "libtool" - "automake" - "faketime" - "bsdmainutils" - "cmake" +- "imagemagick" - "libcap-dev" +- "libxslt-dev" - "libz-dev" - "libbz2-dev" +- "python-cairo" +- "python-dev" +- "python-pip" +- "fonts-tuffy" reference_datetime: "2015-06-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" @@ -25,6 +33,10 @@ remotes: files: - "MacOSX10.9.sdk.tar.gz" script: | + # FIXME: We should probably install these in some other (cachable) way, but the depends system doesn't appear to make native packages available to Core's build system itself? + pip install --user mac_alias ds_store cairosvg cssselect tinycss lxml + export PATH="$HOME/.local/bin:$PATH" + WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage" @@ -107,8 +119,11 @@ script: | make ${MAKEOPTS} make install-strip + make osx_volname make deploydir + OSX_VOLNAME="$(cat osx_volname)" mkdir -p unsigned-app-${i} + cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} @@ -120,7 +135,7 @@ script: | popd make deploy - ${WRAP_DIR}/dmg dmg Bitcoin-Core.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg + ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg cd installed find . -name "lib*.la" -delete diff --git a/contrib/macdeploy/Base.lproj/InfoPlist.strings b/contrib/macdeploy/Base.lproj/InfoPlist.strings deleted file mode 100644 index b259ea141..000000000 --- a/contrib/macdeploy/Base.lproj/InfoPlist.strings +++ /dev/null @@ -1 +0,0 @@ -{ CFBundleDisplayName = "Bitcoin Core"; CFBundleName = "Bitcoin Core"; } diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store deleted file mode 100644 index db9d16f1d700f18b64edafa0f8d981a680567b4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 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 KMNUMnLSTZWI*(%j diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd deleted file mode 100644 index fdc4f4ca4a07ea4c6082ee1357b6ec7e8db99d72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982442 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

!)k`<*rLT67|!`(51D}=SCls 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

{o5I;6^)cSnzyyLxf*K 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 vRP!ZvkUdN1-_9EPCvT%FCr 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

9Y7qJ~d|*B=vPfnkY;$r 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

4XtY}z@xsiDk@#VR$SUSIbDrK7O9=ZX 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 E18DGLm;e9( diff --git a/contrib/macdeploy/background.svg b/contrib/macdeploy/background.svg new file mode 100644 index 000000000..6ab6a23e6 --- /dev/null +++ b/contrib/macdeploy/background.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + PACKAGE_NAME + + + + + diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff deleted file mode 100644 index 4b44ac672e627be82bb9b74dac0016057b11c126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202136 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 z 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 diff --git a/contrib/macdeploy/background@2x.png b/contrib/macdeploy/background@2x.png deleted file mode 100644 index 4858183f75c382a9b8d75ae4fb8a74abd830615f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138890 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 2: @@ -757,7 +765,7 @@ if config.dmg is not None: if fancy is None: try: - runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname="Bitcoin-Core", ov=True) + runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=volname, ov=True) except subprocess.CalledProcessError as e: sys.exit(e.returncode) else: @@ -772,7 +780,7 @@ if config.dmg is not None: if verbose >= 3: print "Creating temp image for modification..." try: - runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname="Bitcoin-Core", ov=True) + runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=volname, ov=True) except subprocess.CalledProcessError as e: sys.exit(e.returncode) @@ -837,7 +845,7 @@ if config.dmg is not None: items_positions.append(itemscript.substitute(params)) params = { - "disk" : "Bitcoin-Core", + "disk" : volname, "window_bounds" : "300,300,800,620", "icon_size" : "96", "background_commands" : "", diff --git a/doc/README_osx.txt b/doc/README_osx.txt index f589bfc67..c13efaa14 100644 --- a/doc/README_osx.txt +++ b/doc/README_osx.txt @@ -63,9 +63,8 @@ functionality is broken. Only the compression feature is currently used. Ideally, the creation could be fixed and genisoimage would no longer be necessary. Background images and other features can be added to DMG files by inserting a -.DS_Store before creation. The easiest way to create this file is to build a -DMG without one, move it to a device running OS X, customize the layout, then -grab the .DS_Store file for later use. That is the approach taken here. +.DS_Store before creation. This is generated by the script +contrib/macdeploy/custom_dsstore.py. As of OS X Mavericks (10.9), using an Apple-blessed key to sign binaries is a requirement in order to satisfy the new Gatekeeper requirements. Because this From e611b6e3290ee08b5c77b6d68f906ce48cc5731d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 17 Dec 2015 20:40:05 +0000 Subject: [PATCH 0075/1223] macdeploy: Use rsvg-convert rather than cairosvg --- .travis.yml | 4 ++-- Makefile.am | 2 +- configure.ac | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 673a0d0a5..28dcfad0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev libz-dev libbz2-dev libffi-dev libtiff-tools python-dev python-pip" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python-pip" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" exclude: - compiler: gcc install: @@ -49,7 +49,7 @@ install: - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi - - if [[ "$HOST" =~ apple ]]; then pip install --user cairosvg mac_alias ds_store; export PATH="$HOME/.local/bin:$PATH"; ( wget 'https://bitbucket.org/al45tair/ds_store/get/c80c23706eae.tar.gz' && tar -xzvpf c80c23706eae.tar.gz && cd al45tair-ds_store-c80c23706eae/ && python setup.py install --user; ) fi + - if [[ "$HOST" =~ apple ]]; then pip install --user mac_alias ds_store; export PATH="$HOME/.local/bin:$PATH"; ( wget 'https://bitbucket.org/al45tair/ds_store/get/c80c23706eae.tar.gz' && tar -xzvpf c80c23706eae.tar.gz && cd al45tair-ds_store-c80c23706eae/ && python setup.py install --user; ) fi before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources diff --git a/Makefile.am b/Makefile.am index f9fca357c..452278497 100644 --- a/Makefile.am +++ b/Makefile.am @@ -123,7 +123,7 @@ $(OSX_DMG): $(APP_DIST_EXTRAS) $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(CAIROSVG) -fpng -d$* - | $(IMAGEMAGICK_CONVERT) - $@ + sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIFILES) $(MKDIR_P) $(@D) diff --git a/configure.ac b/configure.ac index 732f550be..b555b11ff 100644 --- a/configure.ac +++ b/configure.ac @@ -314,7 +314,7 @@ case $host in AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) - AC_PATH_PROGS([CAIROSVG], [cairosvg cairosvg-py3 cairosvg-py2],cairosvg) + AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 13dbe890c..f7b68739e 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -10,7 +10,7 @@ packages: - "git-core" - "pkg-config" - "autoconf" -- "libffi-dev" +- "librsvg2-bin" - "libtiff-tools" - "libtool" - "automake" @@ -19,10 +19,8 @@ packages: - "cmake" - "imagemagick" - "libcap-dev" -- "libxslt-dev" - "libz-dev" - "libbz2-dev" -- "python-cairo" - "python-dev" - "python-pip" - "fonts-tuffy" @@ -34,7 +32,7 @@ files: - "MacOSX10.9.sdk.tar.gz" script: | # FIXME: We should probably install these in some other (cachable) way, but the depends system doesn't appear to make native packages available to Core's build system itself? - pip install --user mac_alias ds_store cairosvg cssselect tinycss lxml + pip install --user mac_alias ds_store export PATH="$HOME/.local/bin:$PATH" WRAP_DIR=$HOME/wrapped From de619a37fd18a17225c8a10b828fc61958abe4cf Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 17 Dec 2015 16:43:56 -0500 Subject: [PATCH 0076/1223] depends: Pass PYTHONPATH along to configure --- Makefile.am | 1 + configure.ac | 2 ++ depends/config.site.in | 1 + 3 files changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 452278497..e293e4fc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = src .PHONY: deploy FORCE GZIP_ENV="-9n" +export PYTHONPATH if BUILD_BITCOIN_LIBS pkgconfigdir = $(libdir)/pkgconfig diff --git a/configure.ac b/configure.ac index b555b11ff..1aa6aac4b 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,8 @@ AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) +AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) + dnl pkg-config check. PKG_PROG_PKG_CONFIG diff --git a/depends/config.site.in b/depends/config.site.in index 873f66018..984ddb1e6 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -66,6 +66,7 @@ CXX="@CXX@" OBJC="${CC}" OBJCXX="${CXX}" CCACHE=$prefix/native/bin/ccache +PYTHONPATH=$prefix/native/lib/python/dist-packages:$PYTHONPATH if test -n "@AR@"; then AR=@AR@ From 82a2d98d9a824242197fbd9ceca4bc66b487a457 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 17 Dec 2015 16:43:56 -0500 Subject: [PATCH 0077/1223] depends: Add ds_store to depends --- depends/packages/native_biplist.mk | 15 +++++++++++++++ depends/packages/native_ds_store.mk | 17 +++++++++++++++++ depends/packages/packages.mk | 4 +++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 depends/packages/native_biplist.mk create mode 100644 depends/packages/native_ds_store.mk diff --git a/depends/packages/native_biplist.mk b/depends/packages/native_biplist.mk new file mode 100644 index 000000000..eb8672d55 --- /dev/null +++ b/depends/packages/native_biplist.mk @@ -0,0 +1,15 @@ +package=native_biplist +$(package)_version=0.9 +$(package)_download_path=https://pypi.python.org/packages/source/b/biplist +$(package)_file_name=biplist-$($(package)_version).tar.gz +$(package)_sha256_hash=b57cadfd26e4754efdf89e9e37de87885f9b5c847b2615688ca04adfaf6ca604 +$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages + +define $(package)_build_cmds + python setup.py build +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_install_libdir) && \ + python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) +endef diff --git a/depends/packages/native_ds_store.mk b/depends/packages/native_ds_store.mk new file mode 100644 index 000000000..8e902af1b --- /dev/null +++ b/depends/packages/native_ds_store.mk @@ -0,0 +1,17 @@ +package=native_ds_store +$(package)_version=c80c23706eae +$(package)_download_path=https://bitbucket.org/al45tair/ds_store/get +$(package)_download_file=$($(package)_version).tar.bz2 +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=ce1aa412211610c63d567bbe3e06213006a2d5ba5d76d89399c151b5472cb0da +$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_dependencies=native_biplist + +define $(package)_build_cmds + python setup.py build +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_install_libdir) && \ + python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 02cc18842..d2b09ef0a 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -15,6 +15,8 @@ wallet_packages=bdb upnp_packages=miniupnpc +darwin_native_packages = native_biplist native_ds_store + ifneq ($(build_os),darwin) -darwin_native_packages=native_cctools native_cdrkit native_libdmg-hfsplus +darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus endif From 902ccde85e7464363a94d8492b3e6c49ab755058 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 18 Dec 2015 12:27:26 +0000 Subject: [PATCH 0078/1223] depends: Add mac_alias to depends --- depends/packages/native_mac_alias.mk | 16 ++++++++++++++++ depends/packages/packages.mk | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 depends/packages/native_mac_alias.mk diff --git a/depends/packages/native_mac_alias.mk b/depends/packages/native_mac_alias.mk new file mode 100644 index 000000000..d117c1c9a --- /dev/null +++ b/depends/packages/native_mac_alias.mk @@ -0,0 +1,16 @@ +package=native_mac_alias +$(package)_version=1.1.0 +$(package)_download_path=https://bitbucket.org/al45tair/mac_alias/get +$(package)_download_file=v$($(package)_version).tar.bz2 +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=87ad827e66790028361e43fc754f68ed041a9bdb214cca03c853f079b04fb120 +$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages + +define $(package)_build_cmds + python setup.py build +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_install_libdir) && \ + python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index d2b09ef0a..59b009b66 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -15,7 +15,7 @@ wallet_packages=bdb upnp_packages=miniupnpc -darwin_native_packages = native_biplist native_ds_store +darwin_native_packages = native_biplist native_ds_store native_mac_alias ifneq ($(build_os),darwin) darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus From c39a6fffd789cb3591ae859c1464703c5fa7f668 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 18 Dec 2015 12:27:49 +0000 Subject: [PATCH 0079/1223] Travis & gitian-osx: Use depends for ds_store and mac_alias modules --- .travis.yml | 3 +-- contrib/gitian-descriptors/gitian-osx.yml | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28dcfad0b..cedd8bdf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python-pip" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" exclude: - compiler: gcc install: @@ -49,7 +49,6 @@ install: - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi - - if [[ "$HOST" =~ apple ]]; then pip install --user mac_alias ds_store; export PATH="$HOME/.local/bin:$PATH"; ( wget 'https://bitbucket.org/al45tair/ds_store/get/c80c23706eae.tar.gz' && tar -xzvpf c80c23706eae.tar.gz && cd al45tair-ds_store-c80c23706eae/ && python setup.py install --user; ) fi before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index f7b68739e..50b914ab6 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -22,7 +22,6 @@ packages: - "libz-dev" - "libbz2-dev" - "python-dev" -- "python-pip" - "fonts-tuffy" reference_datetime: "2015-06-01 00:00:00" remotes: @@ -31,10 +30,6 @@ remotes: files: - "MacOSX10.9.sdk.tar.gz" script: | - # FIXME: We should probably install these in some other (cachable) way, but the depends system doesn't appear to make native packages available to Core's build system itself? - pip install --user mac_alias ds_store - export PATH="$HOME/.local/bin:$PATH" - WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage" From 917b1d03cf3afa6939113e2fb0bf89dbfd9db2d7 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 22 Dec 2015 12:29:13 +0000 Subject: [PATCH 0080/1223] Set copyright holders displayed in notices separately from the package name This helps avoid accidental removal of upstream copyright names --- configure.ac | 7 +++++++ share/qt/Info.plist.in | 2 +- share/qt/extract_strings_qt.py | 1 + src/Makefile.qt.include | 2 +- src/clientversion.h | 2 +- src/init.cpp | 2 +- src/qt/splashscreen.cpp | 2 +- src/util.cpp | 7 +++++++ src/util.h | 2 ++ 9 files changed, 22 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 1aa6aac4b..5d4468e51 100644 --- a/configure.ac +++ b/configure.ac @@ -6,6 +6,8 @@ define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) define(_COPYRIGHT_YEAR, 2015) +define(_COPYRIGHT_HOLDERS,[The %s developers]) +define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[Bitcoin Core]) AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) @@ -912,12 +914,17 @@ AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision]) AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release]) +AC_DEFINE(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS", [Copyright holder(s) before %s replacement]) +define(_COPYRIGHT_HOLDERS_FINAL, patsubst(_COPYRIGHT_HOLDERS, [%s], [AC_PACKAGE_NAME])) +AC_DEFINE(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL", [Copyright holder(s)]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) +AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS") +AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL") AC_SUBST(RELDFLAGS) AC_SUBST(HARDENED_CXXFLAGS) diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index d1a9ed704..6a34d64cd 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -17,7 +17,7 @@ APPL CFBundleGetInfoString - @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The @PACKAGE_NAME@ developers + @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@ CFBundleShortVersionString @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 045eb27f4..470d1f2b4 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -71,6 +71,7 @@ f.write(""" """) f.write('static const char UNUSED *bitcoin_strings[] = {\n') f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('PACKAGE_NAME'),)) +f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('COPYRIGHT_HOLDERS'),)) messages.sort(key=operator.itemgetter(0)) for (msgid, msgstr) in messages: if msgid != EMPTY: diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index c93667038..2d5e715ee 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -382,7 +382,7 @@ SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" - $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" ../share/qt/extract_strings_qt.py $^ + $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" ../share/qt/extract_strings_qt.py $^ translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" diff --git a/src/clientversion.h b/src/clientversion.h index ba15ebf3b..6157423f0 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -38,7 +38,7 @@ #define DO_STRINGIZE(X) #X //! Copyright string used in Windows .rc files -#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The " PACKAGE_NAME " Developers" +#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " " COPYRIGHT_HOLDERS_FINAL /** * bitcoind-res.rc includes this file, but it cannot cope with real c++ code. diff --git a/src/init.cpp b/src/init.cpp index 4bcf8ec78..8a9cc6d96 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -513,7 +513,7 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { // todo: remove urls from translations on next change - return FormatParagraph(strprintf(_("Copyright (C) %i-%i The %s Developers"), 2009, COPYRIGHT_YEAR, _(PACKAGE_NAME))) + "\n" + + return FormatParagraph(strprintf(_("Copyright (C) %i-%i %s"), 2009, COPYRIGHT_YEAR, CopyrightHolders())) + "\n" + "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index ad8d7b3f2..facee62ea 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -44,7 +44,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) // define text to place QString titleText = tr(PACKAGE_NAME); QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion())); - QString copyrightText = QChar(0xA9)+QString(" %1-%2 ").arg(2009).arg(COPYRIGHT_YEAR) + QString(tr("The %1 developers").arg(tr(PACKAGE_NAME))); + QString copyrightText = QChar(0xA9)+QString(" %1-%2 ").arg(2009).arg(COPYRIGHT_YEAR) + QString::fromStdString(CopyrightHolders()); QString titleAddText = networkStyle->getTitleAddText(); QString font = QApplication::font().toString(); diff --git a/src/util.cpp b/src/util.cpp index e8514a2ef..66dd45dc8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -834,3 +834,10 @@ int GetNumCores() #endif } +std::string CopyrightHolders() +{ + std::string strCopyrightHolders = _(COPYRIGHT_HOLDERS); + if (strCopyrightHolders.find("%s") == strCopyrightHolders.npos) + return strCopyrightHolders; + return strprintf(strCopyrightHolders, _(PACKAGE_NAME)); +} diff --git a/src/util.h b/src/util.h index b2779fe78..88e1fe9fb 100644 --- a/src/util.h +++ b/src/util.h @@ -242,4 +242,6 @@ template void TraceThread(const char* name, Callable func) } } +std::string CopyrightHolders(); + #endif // BITCOIN_UTIL_H From e4ab5e5f432c11101ff6ef5a54180781222b75a5 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 22 Dec 2015 12:31:33 +0000 Subject: [PATCH 0081/1223] Bugfix: Correct copyright year in Mac DMG background image --- contrib/macdeploy/background.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/macdeploy/background.svg b/contrib/macdeploy/background.svg index 6ab6a23e6..9c330af45 100644 --- a/contrib/macdeploy/background.svg +++ b/contrib/macdeploy/background.svg @@ -3,7 +3,7 @@ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> From 4d5a3df9d4ea920bb2c63e17a044d14f3eb0fe90 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 22 Dec 2015 13:27:22 +0000 Subject: [PATCH 0082/1223] Bugfix: gitian-descriptors: Add missing python-setuptools requirement for OS X (biplist module) --- contrib/gitian-descriptors/gitian-osx.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 50b914ab6..0eb97d6a7 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -22,6 +22,7 @@ packages: - "libz-dev" - "libbz2-dev" - "python-dev" +- "python-setuptools" - "fonts-tuffy" reference_datetime: "2015-06-01 00:00:00" remotes: From fa0a9749eb09f6b537b98075241a7fcb46f758e3 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 24 Dec 2015 11:58:41 +0100 Subject: [PATCH 0083/1223] [qa] Move gen_return_txouts() to util.py --- qa/rpc-tests/maxuploadtarget.py | 17 +---------------- qa/rpc-tests/mempool_limit.py | 18 ++---------------- qa/rpc-tests/prioritise_transaction.py | 16 +--------------- qa/rpc-tests/pruning.py | 19 +------------------ qa/rpc-tests/test_framework/util.py | 20 +++++++++++++++++++- 5 files changed, 24 insertions(+), 66 deletions(-) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index e714465db..be87c3bb4 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -85,22 +85,7 @@ class TestNode(NodeConnCB): class MaxUploadTest(BitcoinTestFramework): def __init__(self): self.utxo = [] - - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions and full blocks to fill up our block files - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey + self.txouts = gen_return_txouts() def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index 48a2ea294..3ba17ac4f 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -11,22 +11,8 @@ from test_framework.util import * class MempoolLimitTest(BitcoinTestFramework): def __init__(self): - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions (and therefore can't fit very many into each block) - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey - + self.txouts = gen_return_txouts() + def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index b4ef1a9b3..ae6ad63e1 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -15,21 +15,7 @@ COIN = 100000000 class PrioritiseTransactionTest(BitcoinTestFramework): def __init__(self): - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions (and therefore can't fit very many into each block) - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey + self.txouts = gen_return_txouts() def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 21f8d6938..fbf40f24c 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -23,24 +23,7 @@ class PruneTest(BitcoinTestFramework): def __init__(self): self.utxo = [] self.address = ["",""] - - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions and full blocks to fill up our block files - - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey - + self.txouts = gen_return_txouts() def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 80ee8ea16..147def46d 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -436,6 +436,24 @@ def create_confirmed_utxos(fee, node, count): assert(len(utxos) >= count) return utxos +def gen_return_txouts(): + # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create + # So we have big transactions (and therefore can't fit very many into each block) + # create one script_pubkey + script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes + for i in xrange (512): + script_pubkey = script_pubkey + "01" + # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change + txouts = "81" + for k in xrange(128): + # add txout value + txouts = txouts + "0000000000000000" + # add length of script_pubkey + txouts = txouts + "fd0402" + # add script_pubkey + txouts = txouts + script_pubkey + return txouts + def create_lots_of_big_transactions(node, txouts, utxos, fee): addr = node.getnewaddress() txids = [] @@ -453,4 +471,4 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee): signresult = node.signrawtransaction(newtx, None, None, "NONE") txid = node.sendrawtransaction(signresult["hex"], True) txids.append(txid) - return txids \ No newline at end of file + return txids From 0d595894f028248a1a1b00491dad95320844c685 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 25 Dec 2015 13:12:37 +0000 Subject: [PATCH 0084/1223] Bugfix: update-translations: Allow numerus translations to omit %n specifier (usually when it only has one possible value) --- contrib/devtools/update-translations.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py index 0be632069..3e34b3397 100755 --- a/contrib/devtools/update-translations.py +++ b/contrib/devtools/update-translations.py @@ -70,7 +70,7 @@ def sanitize_string(s): '''Sanitize string for printing''' return s.replace('\n',' ') -def check_format_specifiers(source, translation, errors): +def check_format_specifiers(source, translation, errors, numerus): source_f = split_format_specifiers(find_format_specifiers(source)) # assert that no source messages contain both Qt and strprintf format specifiers # if this fails, go change the source as this is hacky and confusing! @@ -78,10 +78,13 @@ def check_format_specifiers(source, translation, errors): try: translation_f = split_format_specifiers(find_format_specifiers(translation)) except IndexError: - errors.append("Parse error in translation '%s'" % sanitize_string(translation)) + errors.append("Parse error in translation for '%s': '%s'" % (sanitize_string(source), sanitize_string(translation))) return False else: if source_f != translation_f: + if numerus and source_f == (set(), ['n']) and translation_f == (set(), []) and translation.find('%') == -1: + # Allow numerus translations to omit %n specifier (usually when it only has one possible value) + return True errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation))) return False return True @@ -148,7 +151,7 @@ def postprocess_translations(reduce_diff_hacks=False): if translation is None: continue errors = [] - valid = check_format_specifiers(source, translation, errors) + valid = check_format_specifiers(source, translation, errors, numerus) for error in errors: print('%s: %s' % (filename, error)) From 5fdf32de7ed85a1a0aec7cdedb83f750f4a0f7ff Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 26 Dec 2015 11:49:19 +0800 Subject: [PATCH 0085/1223] Replace some instances of formatWithUnit with formatHtmlWithUnit Strings in a HTML context should be using formatHtmlWithUnit. --- src/qt/bitcoinunits.cpp | 7 ------- src/qt/bitcoinunits.h | 1 + src/qt/coincontroldialog.cpp | 6 +++--- src/qt/receiverequestdialog.cpp | 2 +- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 425b45d91..9c86cb71d 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -111,13 +111,6 @@ QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, Separator } -// TODO: Review all remaining calls to BitcoinUnits::formatWithUnit to -// TODO: determine whether the output is used in a plain text context -// TODO: or an HTML context (and replace with -// TODO: BtcoinUnits::formatHtmlWithUnit in the latter case). Hopefully -// TODO: there aren't instances where the result could be used in -// TODO: either context. - // NOTE: Using formatWithUnit in an HTML context risks wrapping // quantities at the thousands separator. More subtly, it also results // in a standard space rather than a thin space, due to a bug in Qt's diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 1871c33a7..f9f67c9f1 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -88,6 +88,7 @@ public: static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Format as string (with unit) static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + //! Format as HTML string (with unit) static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Parse string to coin amount static bool parse(int unit, const QString &value, CAmount *val_out); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 0f4224304..064882847 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -637,14 +637,14 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // tool tips QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "

"; - toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "

"; + toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "

"; toolTip1 += tr("Can vary +/- 1 byte per input."); QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "

"; toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "

"; - toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); + toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); - QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); + QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); // how many satoshis the estimated fee can vary per byte we guess wrong double dFeeVary; diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 0c4a20cf9..75108e0a1 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -144,7 +144,7 @@ void ReceiveRequestDialog::update() html += "
" + GUIUtil::HtmlEscape(uri) + "
"; html += ""+tr("Address")+": " + GUIUtil::HtmlEscape(info.address) + "
"; if(info.amount) - html += ""+tr("Amount")+": " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "
"; + html += ""+tr("Amount")+": " + BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(), info.amount) + "
"; if(!info.label.isEmpty()) html += ""+tr("Label")+": " + GUIUtil::HtmlEscape(info.label) + "
"; if(!info.message.isEmpty()) From 5e109225aede0333a9c58915d8a92ea98a00c45b Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 26 Dec 2015 08:01:55 +0000 Subject: [PATCH 0086/1223] Combine common error strings for different options so translations can be shared and reused --- src/init.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 479a3f75d..0e4cae886 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -755,6 +755,16 @@ void InitParameterInteraction() } } +static std::string ResolveErrMsg(const char * const optname, const std::string& strBind) +{ + return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); +} + +static std::string AmountErrMsg(const char * const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); +} + void InitLogging() { fPrintToConsole = GetBoolArg("-printtoconsole", false); @@ -948,7 +958,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) ::minRelayTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -minrelaytxfee=: '%s'"), mapArgs["-minrelaytxfee"])); + return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"])); } fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard()); @@ -962,13 +972,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -mintxfee=: '%s'"), mapArgs["-mintxfee"])); + return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s'"), mapArgs["-paytxfee"])); + return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); if (nFeePerK > nHighTransactionFeeWarning) InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); @@ -982,7 +992,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s'"), mapArgs["-maptxfee"])); + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maptxfee"])); if (nMaxFee > nHighTransactionMaxFeeWarning) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; @@ -1188,13 +1198,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) - return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("bind", strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, 0, false)) - return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("whitebind", strBind)); if (addrBind.GetPort() == 0) return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); @@ -1214,7 +1224,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { CService addrLocal(strAddr, GetListenPort(), fNameLookup); if (!addrLocal.IsValid()) - return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr)); + return InitError(ResolveErrMsg("externalip", strAddr)); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } From fa71669452e57039e4270fd2b33a0e0e1635b813 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 26 Dec 2015 17:18:35 +0100 Subject: [PATCH 0087/1223] [devtools] Use git pretty-format for year parsing --- contrib/devtools/fix-copyright-headers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index 1262e29ac..b6414a551 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -16,7 +16,7 @@ import time import re year = time.gmtime()[0] -CMD_GIT_DATE = "git log %s | grep Date | head -n 1" +CMD_GIT_DATE = 'git log --format=@%%at -1 %s | date +"%%Y" -u -f -' CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s" REGEX_CURRENT= re.compile("%s The Bitcoin" % year) CMD_LIST_FILES= "find %s | grep %s" @@ -38,7 +38,7 @@ for folder in FOLDERS: file_path = os.getcwd() + file_path[1:-1] if file_path.endswith(extension): git_date = get_git_date(file_path) - if len(git_date) > 0 and str(year) in git_date: + if str(year) == git_date: # Only update if current year is not found if REGEX_CURRENT.search(open(file_path, "r").read()) is None: print n,"Last git edit", git_date, "-", file_path From 2409865e14dca0704e5618915d6ef902610d91be Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 28 Dec 2015 16:56:53 -0800 Subject: [PATCH 0088/1223] Reduce inefficiency of GetAccountAddress() Don't scan the wallet to see if the current key has been used if we're going to make a new key anyway. Stop scanning the wallet as soon as we see that the current key has been used. Don't call isValid() twice on the current key. --- src/wallet/rpcwallet.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index db60e498d..f5b1a7de9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -137,26 +137,25 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) CAccount account; walletdb.ReadAccount(strAccount, account); - bool bKeyUsed = false; - - // Check if the current key has been used - if (account.vchPubKey.IsValid()) - { - CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); - for (map::iterator it = pwalletMain->mapWallet.begin(); - it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); - ++it) - { - const CWalletTx& wtx = (*it).second; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - bKeyUsed = true; + if (!bForceNew) { + if (!account.vchPubKey.IsValid()) + bForceNew = true; + else { + // Check if the current key has been used + CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); + for (map::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); + ++it) + BOOST_FOREACH(const CTxOut& txout, (*it).second.vout) + if (txout.scriptPubKey == scriptPubKey) { + bForceNew = true; + break; + } } } // Generate a new key - if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) - { + if (bForceNew) { if (!pwalletMain->GetKeyFromPool(account.vchPubKey)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); From a5a0831458d8290c1e7591cf32a529669b613d86 Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Tue, 29 Dec 2015 22:42:27 -0500 Subject: [PATCH 0089/1223] Double semicolon cleanup. --- src/main.cpp | 4 ++-- src/net.cpp | 2 +- src/qt/bantablemodel.cpp | 4 ++-- src/qt/guiutil.cpp | 2 +- src/qt/peertablemodel.cpp | 2 +- src/test/rpc_tests.cpp | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a43eef07b..dbfb0c812 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,8 +84,8 @@ struct COrphanTx { CTransaction tx; NodeId fromPeer; }; -map mapOrphanTransactions GUARDED_BY(cs_main);; -map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map mapOrphanTransactions GUARDED_BY(cs_main); +map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** diff --git a/src/net.cpp b/src/net.cpp index e0d96a2dc..2ad20ac22 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1370,7 +1370,7 @@ void ThreadMapPort() LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); else - LogPrintf("UPnP Port Mapping successful.\n");; + LogPrintf("UPnP Port Mapping successful.\n"); MilliSleep(20*60*1000); // Refresh every 20 minutes } diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 33792af5b..d95106b5a 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -103,7 +103,7 @@ int BanTableModel::rowCount(const QModelIndex &parent) const int BanTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant BanTableModel::data(const QModelIndex &index, int role) const @@ -178,4 +178,4 @@ bool BanTableModel::shouldShow() if (priv->size() > 0) return true; return false; -} \ No newline at end of file +} diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 34675b53d..f7b610dbb 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -225,7 +225,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) if (!info.message.isEmpty()) { - QString msg(QUrl::toPercentEncoding(info.message));; + QString msg(QUrl::toPercentEncoding(info.message)); ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); paramCount++; } diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 94837679d..df8f4f07f 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -147,7 +147,7 @@ int PeerTableModel::rowCount(const QModelIndex &parent) const int PeerTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant PeerTableModel::data(const QModelIndex &index, int role) const diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index ce2297500..58b34cbfa 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) UniValue o1 = ar[0].get_obj(); UniValue adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) // must throw an exception because 127.0.0.1 is in already banned suubnet range BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); From 6cd198f3807c9b4e9753f997f2af4a704fc0e147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Kr=C3=BCger?= Date: Wed, 30 Dec 2015 21:53:40 +0100 Subject: [PATCH 0090/1223] Removed comment about IsStandard for P2SH scripts Since #4365 (62599373883a66a958136f48ab0e2b826e3d5bf8) P2SH scripts do not have to be IsStandard scripts. --- src/policy/policy.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 46c7f1894..75bd4ba0d 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -23,9 +23,6 @@ * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations * - * Check transaction inputs, and make sure any - * pay-to-script-hash transactions are evaluating IsStandard scripts - * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transaction, * which will get accepted into blocks. The redemption From 33877ed3b8c7ee7e814ebee894ccdcc8ce6ab122 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 2 Jan 2016 17:35:33 +0800 Subject: [PATCH 0091/1223] Add note to CoinControl Dialog workaround --- src/qt/coincontroldialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 0f4224304..916e66706 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -411,7 +411,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node // including all children are partially selected. But the parent node should be fully selected // as well as the children. Children should never be partially selected in the first place. - // Please remove this ugly fix, once the bug is solved upstream. + // Should be fixed in Qt5.4 and above. https://bugreports.qt.io/browse/QTBUG-43473 #if QT_VERSION >= 0x050000 else if (column == COLUMN_CHECKBOX && item->childCount() > 0) { From fa095622c25492ddc7096c5825f327e4427e7d75 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 25 Dec 2015 12:30:45 +0100 Subject: [PATCH 0092/1223] [gitian] Set reference date to something more recent --- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx-signer.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win-signer.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 0c3c439dd..80571fb05 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -15,7 +15,7 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index aa9494b7e..5b52c492f 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -7,7 +7,7 @@ architectures: packages: - "libc6:i386" - "faketime" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 9ac774c8a..8064804b9 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -18,7 +18,7 @@ packages: - "libcap-dev" - "libz-dev" - "libbz2-dev" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index a29d7ab47..27c4f01eb 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -7,7 +7,7 @@ architectures: packages: - "libssl-dev" - "autoconf" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 6bb482d45..1475cd7eb 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -18,7 +18,7 @@ packages: - "g++-mingw-w64" - "nsis" - "zip" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" From 6fd0a079d8f9fa552d84be7a6787b1165b99b302 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 3 Jan 2016 05:57:51 +0800 Subject: [PATCH 0093/1223] Remove hardcoded fee from CoinControl ToolTip --- src/qt/coincontroldialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 064882847..357edf4aa 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -130,7 +130,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_DATE, 110); ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); - ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but don't show it + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it @@ -644,7 +644,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "

"; toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); - QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); + QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than the current dust threshold."); // how many satoshis the estimated fee can vary per byte we guess wrong double dFeeVary; From fae7a369cb137000897d32afab7eb13aa79ec34e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Jan 2016 15:15:21 +0100 Subject: [PATCH 0094/1223] [debian] Bump manpages and only mention -? The manpages are outdated and are very rarely updated when changes to the code happen. --- contrib/debian/manpages/bitcoin-cli.1 | 28 +--- contrib/debian/manpages/bitcoin-qt.1 | 186 +------------------------ contrib/debian/manpages/bitcoin.conf.5 | 66 +-------- contrib/debian/manpages/bitcoind.1 | 173 +---------------------- 4 files changed, 14 insertions(+), 439 deletions(-) diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 index 154b45873..16c338dd3 100644 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -1,4 +1,4 @@ -.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10" +.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12" .SH NAME bitcoin-cli \- a remote procedure call client for Bitcoin Core. .SH SYNOPSIS @@ -11,31 +11,7 @@ This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client .SH OPTIONS .TP \fB\-?\fR -Show the help message. -.TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf). -.TP -\fB\-datadir=\fR

-Specify data directory. -.TP -\fB\-testnet\fR -Connect to a Bitcoin Core instance running in testnet mode. -.TP -\fB\-regtest\fR -Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind). -.TP -\fB\-rpcuser=\fR -Username for JSON\-RPC connections. -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections. -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332). -.TP -\fB\-rpcconnect=\fR -Send commands to node running on (default: 127.0.0.1). +Show possible options. .SH "SEE ALSO" \fBbitcoind\fP, \fBbitcoin.conf\fP diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index 05eadc94c..685a28208 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -1,4 +1,4 @@ -.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1" +.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12" .SH NAME bitcoin-qt \- peer-to-peer network based digital currency .SH DESCRIPTION @@ -8,184 +8,6 @@ bitcoin\-qt [command\-line options] .SH OPTIONS .TP \-? -This help message -.TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf) -.TP -\fB\-pid=\fR -Specify pid file (default: bitcoind.pid) -.TP -\fB\-gen\fR -Generate coins -.TP -\fB\-gen\fR=\fI0\fR -Don't generate coins -.TP -\fB\-datadir=\fR -Specify data directory -.TP -\fB\-dbcache=\fR -Set database cache size in megabytes (default: 25) -.TP -\fB\-timeout=\fR -Specify connection timeout in milliseconds (default: 5000) -.TP -\fB\-proxy=\fR -Connect through SOCKS5 proxy -.TP -\fB\-tor=\fR -Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR) -.TP -\fB\-dns\fR -Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR -.TP -\fB\-port=\fR -Listen for connections on (default: 8333 or testnet: 18333) -.TP -\fB\-maxconnections=\fR -Maintain at most connections to peers (default: 125) -.TP -\fB\-addnode=\fR -Add a node to connect to and attempt to keep the connection open -.TP -\fB\-connect=\fR -Connect only to the specified node(s) -.TP -\fB\-seednode=\fR -Connect to a node to retrieve peer addresses, and disconnect -.TP -\fB\-externalip=\fR -Specify your own public address -.TP -\fB\-onlynet=\fR -Only connect to nodes in network (IPv4, IPv6 or Tor) -.TP -\fB\-discover\fR -Discover own IP address (default: 1 when listening and no \fB\-externalip\fR) -.TP -\fB\-checkpoints\fR -Only accept block chain matching built\-in checkpoints (default: 1) -.TP -\fB\-listen\fR -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) -.TP -\fB\-bind=\fR -Bind to given address and always listen on it. Use [host]:port notation for IPv6 -.TP -\fB\-dnsseed\fR -Find peers using DNS lookup (default: 1 unless \fB\-connect\fR) -.TP -\fB\-banscore=\fR -Threshold for disconnecting misbehaving peers (default: 100) -.TP -\fB\-bantime=\fR -Number of seconds to keep misbehaving peers from reconnecting (default: 86400) -.TP -\fB\-maxreceivebuffer=\fR -Maximum per\-connection receive buffer, *1000 bytes (default: 5000) -.TP -\fB\-maxsendbuffer=\fR -Maximum per\-connection send buffer, *1000 bytes (default: 1000) -.TP -\fB\-upnp\fR -Use UPnP to map the listening port (default: 1 when listening) -.TP -\fB\-paytxfee=\fR -Fee per KB to add to transactions you send -.TP -\fB\-server\fR -Accept command line and JSON\-RPC commands -.TP -\fB\-testnet\fR -Use the test network -.TP -\fB\-debug\fR -Output extra debugging information. Implies all other \fB\-debug\fR* options -.TP -\fB\-debugnet\fR -Output extra network debugging information -.TP -\fB\-logtimestamps\fR -Prepend debug output with timestamp -.TP -\fB\-shrinkdebugfile\fR -Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) -.TP -\fB\-printtoconsole\fR -Send trace/debug info to console instead of debug.log file -.TP -\fB\-rpcuser=\fR -Username for JSON\-RPC connections -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332) -.TP -\fB\-rpcallowip=\fR -Allow JSON\-RPC connections from specified IP address -.TP -\fB\-rpcthreads=\fR -Set the number of threads to service RPC calls (default: 4) -.TP -\fB\-blocknotify=\fR -Execute command when the best block changes (%s in cmd is replaced by block hash) -.TP -\fB\-walletnotify=\fR -Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) -.TP -\fB\-alertnotify=\fR -Execute command when a relevant alert is received (%s in cmd is replaced by message) -.TP -\fB\-upgradewallet\fR -Upgrade wallet to latest format -.TP -\fB\-keypool=\fR -Set key pool size to (default: 100) -.TP -\fB\-rescan\fR -Rescan the block chain for missing wallet transactions -.TP -\fB\-salvagewallet\fR -Attempt to recover private keys from a corrupt wallet.dat -.TP -\fB\-checkblocks=\fR -How many blocks to check at startup (default: 288, 0 = all) -.TP -\fB\-checklevel=\fR -How thorough the block verification is (0\-4, default: 3) -.TP -\fB\-txindex\fR -Maintain a full transaction index (default: 0) -.TP -\fB\-loadblock=\fR -Imports blocks from external blk000??.dat file -.TP -\fB\-reindex\fR -Rebuild block chain index from current blk000??.dat files -.TP -\fB\-par=\fR -Set the number of script verification threads (1\-16, 0=auto, default: 0) -.SS "Block creation options:" -.TP -\fB\-blockminsize=\fR -Set minimum block size in bytes (default: 0) -.TP -\fB\-blockmaxsize=\fR -Set maximum block size in bytes (default: 250000) -.HP -\fB\-blockprioritysize=\fR Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000) -.PP -Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) -.SS "UI options:" -.TP -\fB\-lang=\fR -Set language, for example "de_DE" (default: system locale) -.TP -\fB\-min\fR -Start minimized -.TP -\fB\-splash\fR -Show splash screen on startup (default: 1) +List options. +.SH "SEE ALSO" +bitcoind(1) diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 index 0cf4d991e..839dc26c1 100644 --- a/contrib/debian/manpages/bitcoin.conf.5 +++ b/contrib/debian/manpages/bitcoin.conf.5 @@ -1,75 +1,15 @@ -.TH BITCOIN.CONF "5" "January 2011" "bitcoin.conf 3.19" +.TH BITCOIN.CONF "5" "February 2016" "bitcoin.conf 0.12" .SH NAME bitcoin.conf \- bitcoin configuration file .SH SYNOPSIS All command-line options (except for '\-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file. .TP -The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. +The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. Please refer to bitcoind(1) for a up to date list of valid options. .TP The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '\-datadir' and '\-conf' command-line arguments. .SH LOCATION bitcoin.conf should be located in $HOME/.bitcoin -.SH NETWORK-RELATED SETTINGS -.TP -.TP -\fBtestnet=\fR[\fI'1'\fR|\fI'0'\fR] -Enable or disable run on the test network instead of the real *bitcoin* network. -.TP -\fBproxy=\fR\fI'127.0.0.1:9050'\fR -Connect via a socks4 proxy. -.TP -\fBaddnode=\fR\fI'10.0.0.2:8333'\fR -Use as many *addnode=* settings as you like to connect to specific peers. -.TP -\fBconnect=\fR\fI'10.0.0.1:8333'\fR -Use as many *connect=* settings as you like to connect ONLY to specific peers. -.TP -\fRmaxconnections=\fR\fI'value'\fR -Maximum number of inbound+outbound connections. -.SH JSON-RPC OPTIONS -.TP -\fBserver=\fR[\fI'1'\fR|\fI'0'\fR] -Tells *bitcoin* to accept or not accept JSON-RPC commands. -.TP -\fBrpcuser=\fR\fI'username'\fR -You must set *rpcuser* to secure the JSON-RPC api. -.TP -\fBrpcpassword=\fR\fI'password'\fR -You must set *rpcpassword* to secure the JSON-RPC api. -.TP -\fBrpcallowip=\fR\fI'192.168.1.*'\fR -By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character). -.TP -\fBrpcport=\fR\fI'8332'\fR -Listen for RPC connections on this TCP port. -.TP -\fBrpcconnect=\fR\fI'127.0.0.1'\fR -You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option. -.TP -.SH MISCELLANEOUS OPTIONS -.TP -\fBgen=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable attempt to generate bitcoins. -.TP -\fB4way=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable use SSE instructions to try to generate bitcoins faster. -.TP -\fBkeypool=\fR\fI'100'\fR -Pre-generate this many public/private key pairs, so wallet backups will be valid for both prior transactions and several dozen future transactions. -.TP -\fBpaytxfee=\fR\fI'0.00'\fR -Pay an optional transaction fee every time you send bitcoins. Transactions with fees are more likely than free transactions to be included in generated blocks, so may be validated sooner. -.TP -\fBallowreceivebyip=\fR\fI'1'\fR -Allow direct connections for the 'pay via IP address' feature. -.TP -.SH USER INTERFACE OPTIONS -.TP -\fBmin=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable start bitcoind minimized. -.TP -\fBminimizetotray=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable minimize to the system tray. + .SH "SEE ALSO" bitcoind(1) .SH AUTHOR diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index 5b0f2921a..443cb6855 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -1,4 +1,4 @@ -.TH BITCOIND "1" "January 2011" "bitcoind 3.19" +.TH BITCOIND "1" "February 2016" "bitcoind 0.12" .SH NAME bitcoind \- peer-to-peer network based digital currency .SH SYNOPSIS @@ -12,179 +12,16 @@ Bitcoins can be sent easily through the Internet, without having to trust middle .SH OPTIONS .TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf) -.TP -\fB\-gen\fR -Generate coins -.TP -\fB\-gen\fR=\fI0\fR -Don't generate coins -.TP -\fB\-min\fR -Start minimized -.TP -\fB\-datadir=\fR -Specify data directory -.TP -\fB\-proxy=\fR -Connect through SOCKS5 proxy -.TP -\fB\-addnode=\fR -Add a node to connect to -.TP -\fB\-connect=\fR -Connect only to the specified node -.TP -\fB\-paytxfee=\fR -Fee per KB to add to transactions you send -.TP -\fB\-server\fR -Accept command line and JSON\-RPC commands -.TP -\fB\-daemon\fR -Run in the background as a daemon and accept commands -.TP -\fB\-testnet\fR -Use the test network -.TP -\fB\-rpcuser=\fR -Username for JSON\-RPC connections -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on -.TP -\fB\-rpcallowip=\fR -Allow JSON\-RPC connections from specified IP address -.TP -\fB\-rpcconnect=\fR -Send commands to node running on -.TP \-? -This help message +List of possible options. .SH COMMANDS .TP -\fBbackupwallet 'destination'\fR -Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename. -.TP -\fBgetaccount 'bitcoinaddress'\fR -DEPRECATED. Returns the account associated with the given address. -.TP -\fBsetaccount 'bitcoinaddress' ['account']\fR -DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account']. -.TP -\fBgetaccountaddress 'account'\fR -DEPRECATED. Returns a new bitcoin address for 'account'. -.TP -\fBgetaddressesbyaccount 'account'\fR -DEPRECATED. Returns the list of addresses associated with the given 'account'. -.TP -\fBgetbalance 'account'\fR -Returns the server's available balance, or the balance for 'account' (accounts are deprecated). -.TP -\fBgetblockcount\fR -Returns the number of blocks in the longest block chain. -.TP -\fBgetblocknumber\fR -Returns the block number of the latest block in the longest block chain. -.TP -\fBgetconnectioncount\fR -Returns the number of connections to other nodes. -.TP -\fBgetdifficulty\fR -Returns the proof-of-work difficulty as a multiple of the minimum difficulty. -.TP -\fBgetgenerate\fR -Returns boolean true if server is trying to generate bitcoins, false otherwise. -.TP -\fBsetgenerate 'generate' ['genproclimit']\fR -Generation is limited to ['genproclimit'] processors, \-1 is unlimited. -.TP -\fBgethashespersec\fR -Returns a recent hashes per second performance measurement while generating. -.TP -\fBgetinfo\fR -Returns an object containing server information. -.TP -\fBgetnewaddress 'account'\fR -Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'. -.TP -\fBgetreceivedbyaccount 'account' ['minconf=1']\fR -DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations. -.TP -\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR -Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations. -.TP -\fBgettransaction 'txid'\fR -Returns information about a specific transaction, given hexadecimal transaction ID. -.TP -\fBgetwork 'data'\fR -If 'data' is specified, tries to solve the block and returns true if it was successful. If 'data' is not specified, returns formatted hash 'data' to work on: +\fBhelp\fR +List commands. - "midstate" : precomputed hash state after hashing the first half of the data. - "data" : block data. - "hash1" : formatted hash buffer for second hash. - "target" : little endian hash target. .TP \fBhelp 'command'\fR -List commands, or get help for a command. -.TP -\fBlistaccounts ['minconf=1']\fR -DEPRECATED. List accounts and their current balances. - *note: requires bitcoin 0.3.20 or later. -.TP -\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR -['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: - - "account" : DEPRECATED. the account of the receiving address. - "amount" : total amount received by the address. - "confirmations" : number of confirmations of the most recent transaction included. -.TP -\fBlistreceivedbyaddress ['minconf=1'] ['includeempty=false']\fR -['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: - - "address" : receiving address. - "account" : DEPRECATED. the account of the receiving address. - "amount" : total amount received by the address. - "confirmations" : number of confirmations of the most recent transaction included. -.TP -\fBlisttransactions 'account' ['count=10']\fR -Returns a list of the last ['count'] transactions for 'account' \- for all accounts if 'account' is not specified or is "*". Each entry in the list may contain: - - "category" : will be generate, send, receive, or move. - "amount" : amount of transaction. - "fee" : Fee (if any) paid (only for send transactions). - "confirmations" : number of confirmations (only for generate/send/receive). - "txid" : transaction ID (only for generate/send/receive). - "otheraccount" : account funds were moved to or from (only for move). - "message" : message associated with transaction (only for send). - "to" : message-to associated with transaction (only for send). - - *note: requires bitcoin 0.3.20 or later. -.TP -\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR -DEPRECATED. Moves funds between accounts. -.TP -\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR -DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success. -.TP -\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR -Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success. -.TP -\fBstop\fR -Stops the bitcoin server. -.TP -\fBvalidateaddress 'bitcoinaddress'\fR -Checks that 'bitcoinaddress' looks like a proper bitcoin address. Returns an object containing: - - "isvalid" : true or false. - "ismine" : true if the address is in the server's wallet. - "address" : bitcoinaddress. - - *note: ismine and address are only returned if the address is valid. +Get help for a command. .SH "SEE ALSO" bitcoin.conf(5) From fa6ce44bf98fe1dd5be779fd77b844e7016d209e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Jan 2016 16:00:58 +0100 Subject: [PATCH 0095/1223] [debian] Update bitcoind manpage description Update the description to match that description in the main bitcoin README.md --- contrib/debian/manpages/bitcoind.1 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index 443cb6855..5c3e52f44 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -6,9 +6,7 @@ bitcoin [options] [params] .TP bitcoin [options] help \- Get help for a command .SH DESCRIPTION -This manual page documents the bitcoind program. Bitcoin is a peer-to-peer digital currency. Peer-to-peer (P2P) means that there is no central authority to issue new money or keep track of transactions. Instead, these tasks are managed collectively by the nodes of the network. Advantages: - -Bitcoins can be sent easily through the Internet, without having to trust middlemen. Transactions are designed to be irreversible. Be safe from instability caused by fractional reserve banking and central banks. The limited inflation of the Bitcoin system’s money supply is distributed evenly (by CPU power) throughout the network, not monopolized by banks. +This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. .SH OPTIONS .TP From 7ef8f3c072a8750c72a3a1cdc727b5c1d173bac8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 3 Jan 2016 16:50:31 +0100 Subject: [PATCH 0096/1223] Report non-mandatory script failures correctly --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a43eef07b..0766b1458 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1653,9 +1653,9 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(*coins, tx, i, + CScriptCheck check2(*coins, tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); - if (check()) + if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is From fd836153d5c99073b290edd74c3507a00231885d Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Sun, 3 Jan 2016 20:39:05 -0800 Subject: [PATCH 0097/1223] Improve CheckInputs() comment about sig verification --- src/main.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a43eef07b..60e96bbf1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1631,9 +1631,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Only if ALL inputs pass do we perform expensive ECDSA signature checks. // Helps prevent CPU exhaustion attacks. - // Skip ECDSA signature verification when connecting blocks - // before the last block chain checkpoint. This is safe because block merkle hashes are - // still computed and checked, and any change will be caught at the next checkpoint. + // Skip ECDSA signature verification when connecting blocks before the + // last block chain checkpoint. Assuming the checkpoints are valid this + // is safe because block merkle hashes are still computed and checked, + // and any change will be caught at the next checkpoint. Of course, if + // the checkpoint is for a chain that's invalid due to false scriptSigs + // this optimisation would allow an invalid chain to be accepted. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; From 621bd6919f47be4d23091d8ae7c980f9567d83a9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 4 Jan 2016 09:44:36 +0100 Subject: [PATCH 0098/1223] [Qt] fix coincontrol update issue when deleting a send coin entry --- src/qt/sendcoinsdialog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ec4e598bf..546cceda9 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -373,8 +373,6 @@ SendCoinsEntry *SendCoinsDialog::addEntry() connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels())); - updateTabsAndLabels(); - // Focus the field, so that entry can start immediately entry->clear(); entry->setFocus(); @@ -383,6 +381,8 @@ SendCoinsEntry *SendCoinsDialog::addEntry() QScrollBar* bar = ui->scrollArea->verticalScrollBar(); if(bar) bar->setSliderPosition(bar->maximum()); + + updateTabsAndLabels(); return entry; } @@ -808,7 +808,7 @@ void SendCoinsDialog::coinControlUpdateLabels() for(int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); - if(entry) + if(entry && !entry->isHidden()) { SendCoinsRecipient rcp = entry->getValue(); CoinControlDialog::payAmounts.append(rcp.amount); From 136abda59728708ab4dffeac6fb08e0abf7e3b27 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 4 Jan 2016 09:47:50 +0100 Subject: [PATCH 0099/1223] qt: periodic translations pull from transifex --- src/qt/locale/bitcoin_af_ZA.ts | 36 ++ src/qt/locale/bitcoin_ar.ts | 86 +++- src/qt/locale/bitcoin_be_BY.ts | 34 +- src/qt/locale/bitcoin_bg.ts | 48 ++- src/qt/locale/bitcoin_bg_BG.ts | 4 + src/qt/locale/bitcoin_ca.ts | 126 +++++- src/qt/locale/bitcoin_ca@valencia.ts | 10 +- src/qt/locale/bitcoin_ca_ES.ts | 126 +++++- src/qt/locale/bitcoin_cs.ts | 10 +- src/qt/locale/bitcoin_cs_CZ.ts | 36 ++ src/qt/locale/bitcoin_cy.ts | 20 + src/qt/locale/bitcoin_da.ts | 58 ++- src/qt/locale/bitcoin_de.ts | 132 ++++++ src/qt/locale/bitcoin_el.ts | 20 + src/qt/locale/bitcoin_el_GR.ts | 30 +- src/qt/locale/bitcoin_en_GB.ts | 52 +++ src/qt/locale/bitcoin_eo.ts | 102 ++++- src/qt/locale/bitcoin_es.ts | 50 ++- src/qt/locale/bitcoin_es_CL.ts | 52 +++ src/qt/locale/bitcoin_es_DO.ts | 22 +- src/qt/locale/bitcoin_es_ES.ts | 12 + src/qt/locale/bitcoin_es_MX.ts | 198 +++++++-- src/qt/locale/bitcoin_es_UY.ts | 226 ++++++++++- src/qt/locale/bitcoin_es_VE.ts | 60 ++- src/qt/locale/bitcoin_et.ts | 58 ++- src/qt/locale/bitcoin_eu_ES.ts | 36 ++ src/qt/locale/bitcoin_fa.ts | 62 ++- src/qt/locale/bitcoin_fa_IR.ts | 48 +++ src/qt/locale/bitcoin_fi.ts | 270 +++++++++++- src/qt/locale/bitcoin_fr.ts | 344 +++++++++++++++- src/qt/locale/bitcoin_fr_CA.ts | 28 ++ src/qt/locale/bitcoin_fr_FR.ts | 20 + src/qt/locale/bitcoin_gl.ts | 38 +- src/qt/locale/bitcoin_he.ts | 18 +- src/qt/locale/bitcoin_hi_IN.ts | 16 + src/qt/locale/bitcoin_hr.ts | 34 +- src/qt/locale/bitcoin_hu.ts | 62 ++- src/qt/locale/bitcoin_id_ID.ts | 30 +- src/qt/locale/bitcoin_it.ts | 336 ++++++++++++++- src/qt/locale/bitcoin_ja.ts | 52 +++ src/qt/locale/bitcoin_ka.ts | 22 +- src/qt/locale/bitcoin_kk_KZ.ts | 20 + src/qt/locale/bitcoin_ko_KR.ts | 42 +- src/qt/locale/bitcoin_ky.ts | 12 + src/qt/locale/bitcoin_la.ts | 46 ++- src/qt/locale/bitcoin_lt.ts | 140 ++++++- src/qt/locale/bitcoin_lv_LV.ts | 26 +- src/qt/locale/bitcoin_mk_MK.ts | 12 + src/qt/locale/bitcoin_mn.ts | 36 ++ src/qt/locale/bitcoin_ms_MY.ts | 4 + src/qt/locale/bitcoin_nb.ts | 56 +++ src/qt/locale/bitcoin_nl.ts | 587 +++++++++++++++++++++------ src/qt/locale/bitcoin_pam.ts | 58 ++- src/qt/locale/bitcoin_pl.ts | 140 +++++++ src/qt/locale/bitcoin_pt_BR.ts | 144 ++++++- src/qt/locale/bitcoin_pt_PT.ts | 14 +- src/qt/locale/bitcoin_ro_RO.ts | 30 +- src/qt/locale/bitcoin_ru.ts | 74 +++- src/qt/locale/bitcoin_ru_RU.ts | 16 + src/qt/locale/bitcoin_sk.ts | 10 +- src/qt/locale/bitcoin_sl_SI.ts | 24 +- src/qt/locale/bitcoin_sq.ts | 40 ++ src/qt/locale/bitcoin_sr.ts | 40 ++ src/qt/locale/bitcoin_sv.ts | 68 ++++ src/qt/locale/bitcoin_th_TH.ts | 12 + src/qt/locale/bitcoin_tr.ts | 334 ++++++++++++++- src/qt/locale/bitcoin_tr_TR.ts | 16 + src/qt/locale/bitcoin_uk.ts | 132 ++++++ src/qt/locale/bitcoin_ur_PK.ts | 24 ++ src/qt/locale/bitcoin_uz@Cyrl.ts | 22 +- src/qt/locale/bitcoin_vi.ts | 20 + src/qt/locale/bitcoin_vi_VN.ts | 44 ++ src/qt/locale/bitcoin_zh.ts | 4 + src/qt/locale/bitcoin_zh_CN.ts | 204 +++++++++- src/qt/locale/bitcoin_zh_TW.ts | 64 ++- 75 files changed, 5302 insertions(+), 237 deletions(-) diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index d55d2f58a..d77aa77f8 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -214,6 +214,14 @@ EditAddressDialog + + &Label + &Etiket + + + &Address + &Adres + New receiving address Nuwe ontvangende adres @@ -261,6 +269,10 @@ Options Opsies + + W&allet + &Beursie + OverviewPage @@ -294,6 +306,14 @@ ReceiveCoinsDialog + + &Amount: + &Bedrag: + + + &Message: + &Boodskap: + Copy amount Kopieer bedrag @@ -347,10 +367,18 @@ Send Coins Stuur Munstukke + + Insufficient funds! + Onvoldoende fondse + Amount: Bedrag: + + Transaction Fee: + Transaksie fooi: + Send to multiple recipients at once Stuur aan vele ontvangers op eens @@ -374,6 +402,10 @@ SendCoinsEntry + + A&mount: + &Bedrag: + Message: Boodskap: @@ -453,6 +485,10 @@ Transaction ID Transaksie ID + + Transaction + Transaksie + Amount Bedrag diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 8a54f1579..88ce05bbd 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -93,7 +93,11 @@ Exporting Failed فشل التصدير - + + There was an error trying to save the address list to %1. Please try again. + لقد حدث خطأ أثناء حفظ قائمة العناوين إلى %1. يرجى المحاولة مرة أخرى. + + AddressTableModel @@ -333,6 +337,10 @@ Wallet محفظة + + &Send + &ارسل + &Receive &استقبل @@ -377,6 +385,10 @@ &About Bitcoin Core حول bitcoin core + + %1 and %2 + %1 و %2 + Error خطأ @@ -779,6 +791,10 @@ PaymentServer + + Bad response from server %1 + استجابة سيئة من الملقم %1 + PeerTableModel @@ -789,6 +805,14 @@ Amount المبلغ + + %1 h + %1 ساعة + + + %1 m + %1 دقيقة + N/A غير معروف @@ -831,6 +855,10 @@ &Information المعلومات + + Debug window + نافذة المعالجة + General عام @@ -907,6 +935,22 @@ Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة + + %1 B + %1 بايت + + + %1 KB + %1 كيلو بايت + + + %1 MB + %1 ميقا بايت + + + %1 GB + %1 قيقا بايت + Yes نعم @@ -1075,6 +1119,10 @@ Change: تعديل : + + Transaction Fee: + رسوم المعاملة: + Send to multiple recipients at once إرسال إلى عدة مستلمين في وقت واحد @@ -1107,6 +1155,10 @@ Confirm send coins تأكيد الإرسال Coins + + %1 to %2 + %1 الى %2 + Copy quantity نسخ الكمية @@ -1143,6 +1195,10 @@ The amount exceeds your balance. القيمة تتجاوز رصيدك + + The total exceeds your balance when the %1 transaction fee is included. + المجموع يتجاوز رصيدك عندما يتم اضافة %1 رسوم العملية + (no label) (لا وصف) @@ -1150,6 +1206,10 @@ SendCoinsEntry + + A&mount: + &القيمة + Pay &To: ادفع &الى : @@ -1178,6 +1238,10 @@ Message: الرسائل + + Pay To: + ادفع &الى : + ShutdownWindow @@ -1297,10 +1361,22 @@ TransactionDesc + + Open until %1 + مفتوح حتى %1 + conflicted يتعارض + + %1/offline + %1 غير متواجد + + + %1/unconfirmed + غير مؤكدة/%1 + %1 confirmations تأكيد %1 @@ -1411,6 +1487,10 @@ Type النوع + + Open until %1 + مفتوح حتى %1 + This block was not received by any other nodes and will probably not be accepted! لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة! @@ -1427,6 +1507,10 @@ Label وصف + + Conflicted + يتعارض + Received with استقبل مع diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index 3343781b7..2709ff37e 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -798,7 +798,7 @@ command-line options опцыі каманднага радка - + Intro @@ -843,6 +843,10 @@ MB Мб + + W&allet + Гаманец + OverviewPage @@ -869,9 +873,21 @@ RPCConsole + + &Information + Інфармацыя + + + Debug window + Вакно адладкі + ReceiveCoinsDialog + + &Amount: + &Колькасць: + &Label: Метка: @@ -887,6 +903,10 @@ ReceiveRequestDialog + + Copy &Address + Капіяваць адрас + Address Адрас @@ -933,6 +953,10 @@ Send Coins Даслаць Манеты + + Insufficient funds! + Недастаткова сродкаў + Quantity: Колькасць: @@ -1044,6 +1068,14 @@ Alt+P Alt+P + + Message: + Паведамленне: + + + Pay To: + Заплаціць да: + Memo: Памятка: diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index be5aec371..ecd10e546 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -445,6 +445,36 @@ Catching up... Зарежда блокове... + + Date: %1 + + Дата: %1 + + + + Amount: %1 + + Сума: %1 + + + + Type: %1 + + Тип: %1 + + + + Label: %1 + + Етикет: %1 + + + + Address: %1 + + Адрес: %1 + + Sent transaction Изходяща транзакция @@ -776,7 +806,7 @@ command-line options Списък с налични команди - + Intro @@ -833,6 +863,10 @@ MB Мегабайта + + Number of script &verification threads + Брой на скриптове и &нишки за потвърждение + Accept connections from outside Приемай връзки отвън @@ -873,6 +907,10 @@ Expert Експерт + + Enable coin &control features + Позволяване на монетите и &техните възможности + &Spend unconfirmed change &Похарчете непотвърденото ресто @@ -2234,6 +2272,10 @@ Export Transaction History Изнасяне историята на транзакциите + + Watch-only + само гледане + Exporting Failed Грешка при изнасянето @@ -2417,6 +2459,10 @@ Information Информация + + Invalid amount for -maxtxfee=<amount>: '%s' + Невалидна сума за -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Невалидна сума за -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_bg_BG.ts b/src/qt/locale/bitcoin_bg_BG.ts index d1157a8e4..353f6d771 100644 --- a/src/qt/locale/bitcoin_bg_BG.ts +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -60,6 +60,10 @@ Bitcoin Core Биткойн ядро + + About Bitcoin Core + За Биткойн ядрото + Intro diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 5a0e36de9..38e770f18 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP / Màscara de xarxa + + + Banned Until + Bandejat fins + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options Opcions de la línia d'ordres + + UI Options: + Opcions d'interfície d'usuari: + + + Choose data directory on startup (default: %u) + Trieu el directori de dades a l'inici (per defecte: %u) + + + Set language, for example "de_DE" (default: system locale) + Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema) + + + Start minimized + Inicia minimitzat + + + Set SSL root certificates for payment request (default: -system-) + Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema) + + + Show splash screen on startup (default: %u) + Mostra la pantalla de benvinguda a l'inici (per defecte: %u) + + + Reset all settings changes made over the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + Intro @@ -1071,6 +1107,18 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Used for reaching peers via: + Utilitzat per arribar als iguals mitjançant: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra @@ -1457,10 +1505,18 @@ &Peers &Iguals + + Banned peers + Iguals bandejats + Select a peer to view detailed information. Seleccioneu un igual per mostrar informació detallada. + + Whitelisted + A la llista blanca + Direction Direcció @@ -1469,6 +1525,18 @@ Version Versió + + Starting Block + Bloc d'inici + + + Synced Headers + Capçaleres sincronitzades + + + Synced Blocks + Blocs sincronitzats + User Agent Agent d'usuari @@ -1497,6 +1565,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La duració d'un ping més destacat actualment. + + + Ping Wait + Espera de ping + Time Offset Diferència horària @@ -1545,6 +1621,34 @@ Clear console Neteja la consola + + &Disconnect Node + &Desconnecta el node + + + Ban Node for + Bandeja el node durant + + + 1 &hour + 1 &hora + + + 1 &day + 1 &dia + + + 1 &week + 1 &setmana + + + 1 &year + 1 &any + + + &Unban Node + &Desbandeja el node + Welcome to the Bitcoin Core RPC console. Us donem la benviguda a la consola RPC del Bitcoin Core. @@ -1573,6 +1677,10 @@ %1 GB %1 GB + + (node id: %1) + (id del node: %1) + via %1 a través de %1 @@ -1965,6 +2073,10 @@ Copy change Copia el canvi + + Total Amount %1 + Import total %1 + or o @@ -1997,6 +2109,10 @@ Payment request expired. La sol·licitud de pagament ha vençut. + + Pay only the required fee of %1 + Paga només la comissió necessària de %1 + Estimated to begin confirmation within %n block(s). Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. @@ -2779,6 +2895,14 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index 353e80ca1..2c41ec78d 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -433,6 +433,10 @@ No block source available... No hi ha cap font de bloc disponible... + + Processed %n block(s) of transaction history. + Proccessats %n bloc de l'historial de transaccions.Proccessats %n blocs de l'historial de transaccions. + %n hour(s) %n hora%n hores @@ -870,7 +874,7 @@ command-line options Opcions de la línia d'ordes - + Intro @@ -1067,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index bf4be89a0..e6a932ebe 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP / Màscara de xarxa + + + Banned Until + Bandejat fins + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options Opcions de la línia d'ordres + + UI Options: + Opcions d'interfície d'usuari: + + + Choose data directory on startup (default: %u) + Trieu el directori de dades a l'inici (per defecte: %u) + + + Set language, for example "de_DE" (default: system locale) + Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema) + + + Start minimized + Inicia minimitzat + + + Set SSL root certificates for payment request (default: -system-) + Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema) + + + Show splash screen on startup (default: %u) + Mostra la pantalla de benvinguda a l'inici (per defecte: %u) + + + Reset all settings changes made over the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + Intro @@ -1071,6 +1107,18 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Used for reaching peers via: + Utilitzat per arribar als iguals mitjançant: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra @@ -1457,10 +1505,18 @@ &Peers &Iguals + + Banned peers + Iguals bandejats + Select a peer to view detailed information. Seleccioneu un igual per mostrar informació detallada. + + Whitelisted + A la llista blanca + Direction Direcció @@ -1469,6 +1525,18 @@ Version Versió + + Starting Block + Bloc d'inici + + + Synced Headers + Capçaleres sincronitzades + + + Synced Blocks + Blocs sincronitzats + User Agent Agent d'usuari @@ -1497,6 +1565,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La duració d'un ping més destacat actualment. + + + Ping Wait + Espera de ping + Time Offset Diferència horària @@ -1545,6 +1621,34 @@ Clear console Neteja la consola + + &Disconnect Node + &Desconnecta el node + + + Ban Node for + Bandeja el node durant + + + 1 &hour + 1 &hora + + + 1 &day + 1 &dia + + + 1 &week + 1 &setmana + + + 1 &year + 1 &any + + + &Unban Node + &Desbandeja el node + Welcome to the Bitcoin Core RPC console. Us donem la benviguda a la consola RPC del Bitcoin Core. @@ -1573,6 +1677,10 @@ %1 GB %1 GB + + (node id: %1) + (id del node: %1) + via %1 a través de %1 @@ -1965,6 +2073,10 @@ Copy change Copia el canvi + + Total Amount %1 + Import total %1 + or o @@ -1997,6 +2109,10 @@ Payment request expired. La sol·licitud de pagament ha vençut. + + Pay only the required fee of %1 + Paga només la comissió necessària de %1 + Estimated to begin confirmation within %n block(s). Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. @@ -2779,6 +2895,14 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index d791d9d98..ef1903edd 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -874,7 +874,7 @@ command-line options možnosti příkazové řádky - + Intro @@ -1071,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port proxy (např. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru: + &Window O&kno @@ -3323,6 +3327,10 @@ Specify connection timeout in milliseconds (minimum: 1, default: %d) Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d) + + Specify pid file (default: %s) + PID soubor (výchozí: %s) + Spend unconfirmed change when sending transactions (default: %u) Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u) diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts index 026247e7c..cc0c79115 100644 --- a/src/qt/locale/bitcoin_cs_CZ.ts +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -191,6 +191,10 @@ CoinControlDialog + + Amount: + Množství: + Amount Množství @@ -322,6 +326,14 @@ ReceiveCoinsDialog + + &Label: + &Popisek: + + + &Message: + Zpráva: + Copy label Kopírovat popis @@ -341,6 +353,10 @@ Label Popis + + Message + Zpráva + RecentRequestsTableModel @@ -352,6 +368,10 @@ Label Popis + + Message + Zpráva + Amount Množství @@ -363,6 +383,10 @@ SendCoinsDialog + + Amount: + Množství: + Balance: Zůstatek: @@ -378,6 +402,10 @@ SendCoinsEntry + + &Label: + &Popisek: + Message: Zpráva: @@ -417,6 +445,14 @@ Date Datum + + Message + Zpráva + + + Transaction + Transakce + Amount Množství diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index eba036333..c32d236a9 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -347,6 +347,10 @@ CoinControlDialog + + Amount: + Maint + Date Dyddiad @@ -545,6 +549,10 @@ ReceiveRequestDialog + + Copy &Address + &Cyfeiriad Copi + Address Cyfeiriad @@ -583,6 +591,10 @@ Send Coins Anfon arian + + Amount: + Maint + Send to multiple recipients at once Anfon at pobl lluosog ar yr un pryd @@ -626,6 +638,10 @@ Alt+P Alt+P + + Message: + Neges: + ShutdownWindow @@ -761,6 +777,10 @@ bitcoin-core + + Options: + Opsiynau: + Information Gwybodaeth diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index edcd9b3b0..aa2724a1e 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -882,6 +882,34 @@ command-line options kommandolinjetilvalg + + UI Options: + Indstillinger for brugergrænseflade: + + + Choose data directory on startup (default: %u) + Vælg datamappe under opstart (standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Vælg sprog; fx "da_DK" (standard: systemsprog) + + + Start minimized + Start minimeret + + + Set SSL root certificates for payment request (default: -system-) + Opsæt SSL-rodcertifikater til betalingsadmodninger (standard: -system-) + + + Show splash screen on startup (default: %u) + Vis startskærm under opstart (standard: %u) + + + Reset all settings changes made over the GUI + Nulstil alle indstillinger, der er foretaget i den grafiske brugerflade + Intro @@ -925,7 +953,11 @@ %n GB of free space available %n GB fri plads tilgængelig%n GB fri plads tilgængelig - + + (of %n GB needed) + (ud af %n GB behøvet)(ud af %n GB behøvet) + + OpenURIDialog @@ -1473,6 +1505,18 @@ Current number of blocks Nuværende antal blokke + + Memory Pool + Hukommelsespulje + + + Current number of transactions + Aktuelt antal transaktioner + + + Memory usage + Hukommelsesforbrug + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler. @@ -3479,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr under oprettelse af transaktioner (standard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u) @@ -3495,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Udskriv fejlsøgningsinformation (standard: %u, angivelse af <kategori> er valgfri) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Understøt filtrering af blokke og transaktioner med Bloom-filtre (standard: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Den totale længde på netværksversionsstrengen (%i) overstiger maksimallængden (%i). Reducér antaller af eller størrelsen på uacomments. @@ -3511,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Brug separat SOCS5-proxy for at nå knuder via skjulte Tor-tjenester (standard: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Brugernavn og hashet adgangskode for JSON-RPC-forbindelser. Feltet <userpw> er i formatet: <BRUGERNAVN>:<SALT>$<HASH>. Et kanonisk Python-skript inkluderes i share/rpcuser. Dette tilvalg kan angives flere gange + (default: %s) (standard: %s) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 04b4d2301..84de80aff 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -882,6 +882,34 @@ command-line options Kommandozeilenoptionen + + UI Options: + UI Einstellungen: + + + Choose data directory on startup (default: %u) + Datenverzeichnis beim Starten auswählen (Standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Sprache einstellen, zum Beispiel "de_DE" (default: system locale) + + + Start minimized + Minimiert starten + + + Set SSL root certificates for payment request (default: -system-) + SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-) + + + Show splash screen on startup (default: %u) + Startbildschirm beim Starten anzeigen (Standard: %u) + + + Reset all settings changes made over the GUI + Setze alle Einstellungen zurück, die über die grafische Oberfläche geändert wurden. + Intro @@ -1079,6 +1107,14 @@ Port of the proxy (e.g. 9050) Port des Proxies (z.B. 9050) + + Used for reaching peers via: + Benutzt um Gegenstellen zu erreichen über: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Zeigt an, ob der eingegebene Standard SOCKS5 Proxy genutzt wird um Peers mit dem Netzwerktyp zu erreichen. + IPv4 IPv4 @@ -1091,6 +1127,10 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Über einen separaten SOCKS5 Proxy für Tor Services mit dem Bitcoint Netzwerk verbinden. + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen: @@ -1465,6 +1505,18 @@ Current number of blocks Aktuelle Anzahl Blöcke + + Memory Pool + Speicherpool + + + Current number of transactions + Aktuelle Anzahl der Transaktionen + + + Memory usage + Speichernutzung + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern. @@ -1489,6 +1541,10 @@ Select a peer to view detailed information. Gegenstelle auswählen, um detaillierte Informationen zu erhalten. + + Whitelisted + Zugelassene + Direction Richtung @@ -1497,6 +1553,10 @@ Version Version + + Starting Block + Start Block + Synced Headers Synchronisierte Kopfdaten @@ -1533,6 +1593,14 @@ Ping Time Pingzeit + + The duration of a currently outstanding ping. + Die Laufzeit eines aktuell ausstehenden Ping. + + + Ping Wait + Ping Wartezeit + Time Offset Zeitversatz @@ -1585,6 +1653,10 @@ &Disconnect Node Knoten &trennen + + Ban Node for + Knoten gebannt für + 1 &hour 1 &Stunde @@ -1601,6 +1673,10 @@ 1 &year 1 &Jahr + + &Unban Node + &Node entsperren + Welcome to the Bitcoin Core RPC console. Willkommen in der "Bitcoin Core"-RPC-Konsole. @@ -2700,6 +2776,10 @@ Copy transaction ID Transaktions-ID kopieren + + Copy raw transaction + Kopiere rohe Transaktion + Edit label Bezeichnung bearbeiten @@ -2847,6 +2927,14 @@ Accept command line and JSON-RPC commands Kommandozeilen- und JSON-RPC-Befehle annehmen + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird. + Error: A fatal internal error occurred, see debug.log for details Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details. @@ -2859,6 +2947,10 @@ Run in the background as a daemon and accept commands Als Hintergrunddienst ausführen und Befehle annehmen + + Unable to start HTTP server. See debug log for details. + Kann HTTP Server nicht starten. Siehe debug log für Details. + Accept connections from outside (default: 1 if no -proxy or -connect) Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect) @@ -2951,6 +3043,18 @@ Do you want to rebuild the block database now? Möchten Sie die Blockdatenbank jetzt neu aufbauen? + + Enable publish hash block in <address> + Aktiviere das Veröffentlichen des Hash-Blocks in <address> + + + Enable publish hash transaction in <address> + Aktiviere das Veröffentlichen der Hash-Transaktion in <address> + + + Enable publish raw block in <address> + Aktiviere das Veröffentlichen des Raw-Blocks in <address> + Error initializing block database Fehler beim Initialisieren der Blockdatenbank @@ -3147,6 +3251,10 @@ Attempt to recover private keys from a corrupt wallet.dat on startup Versuchen, private Schlüssel beim Starten aus einer beschädigten wallet.dat wiederherzustellen + + Automatically create Tor hidden service (default: %d) + Automatisch versteckten Tor-Dienst erstellen (Standard: %d) + Cannot resolve -whitebind address: '%s' Kann Adresse in -whitebind nicht auflösen: '%s' @@ -3255,6 +3363,14 @@ This is experimental software. Dies ist experimentelle Software. + + Tor control port password (default: empty) + TOR Kontrollport Passwort (Standard: leer) + + + Tor control port to use if onion listening enabled (default: %s) + Zu benutzender TOR Kontrollport wenn Onion Auflistung aktiv ist (Standard: %s) + Transaction amount too small Transaktionsbetrag zu niedrig @@ -3291,6 +3407,10 @@ Warning Warnung + + Whether to operate in a blocks only mode (default: %u) + Legt fest ob nur Blöcke Modus aktiv sein soll (Standard: %u) + Zapping all transactions from wallet... Lösche alle Transaktionen aus Wallet... @@ -3339,6 +3459,10 @@ -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird. + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Die Transaktion nicht länger im Speicherpool behalten als <n> Stunden (Standard: %u) + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt. @@ -3359,6 +3483,10 @@ Output debugging information (default: %u, supplying <category> is optional) Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional) + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Versucht ausgehenden Datenverkehr unter dem gegebenen Wert zu halten (in MiB pro 24h), 0 = kein Limit (default: %d) + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt. @@ -3399,6 +3527,10 @@ Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) <port> nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u) + + Listen for connections on <port> (default: %u or testnet: %u) + <port> nach Verbindungen abhören (Standard: %u oder Testnetz: %u) + Maintain at most <n> connections to peers (default: %u) Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: %u) diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts index f53a88082..6777961cb 100644 --- a/src/qt/locale/bitcoin_el.ts +++ b/src/qt/locale/bitcoin_el.ts @@ -82,6 +82,14 @@ EditAddressDialog + + &Label + Ετικέτα + + + &Address + Διεύθυνση + FreespaceChecker @@ -109,6 +117,10 @@ OptionsDialog + + W&allet + Πορτοφόλι + OverviewPage @@ -183,6 +195,10 @@ SendCoinsDialog + + Insufficient funds! + Κεφάλαια μη επαρκή + Recommended: Συνίσταται: @@ -202,6 +218,10 @@ SendCoinsEntry + + Message: + Μήνυμα: + ShutdownWindow diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index b62a4756e..90c27c439 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -694,6 +694,10 @@ This label turns red if any recipient receives an amount smaller than %1. Αυτή η ετικέτα γίνεται κόκκινη αν οποιοσδήποτε παραλήπτης λάβει ποσό μικρότερο από %1. + + Can vary +/- %1 satoshi(s) per input. + Μπορεί να διαφέρει +/- %1 Satoshi (ες) ανά εγγραφή. + yes ναι @@ -706,6 +710,10 @@ This means a fee of at least %1 per kB is required. Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB + + Can vary +/- 1 byte per input. + Μπορεί να διαφέρει +/- 1 byte ανά εγγραφή. + Transactions with higher priority are more likely to get included into a block. Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ. @@ -832,7 +840,7 @@ command-line options επιλογής γραμμής εντολών - + Intro @@ -2602,6 +2610,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Μόνο σύνδεση σε κόμβους του δικτύου <net> (ipv4, ipv6 ή onion) + + Set maximum block size in bytes (default: %d) + Ορίστε το μέγιστο μέγεθος block σε bytes (προεπιλογή: %d) + Specify wallet file (within data directory) Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων) @@ -2630,6 +2642,10 @@ Connect through SOCKS5 proxy Σύνδεση μέσω διαμεσολαβητή SOCKS5 + + Copyright (C) 2009-%i The Bitcoin Core Developers + Πνευματικά δικαιώματα 2009-%i Οι προγραμματιστές του Bitcoin Core + Error loading wallet.dat: Wallet requires newer version of Bitcoin Core Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin @@ -2646,6 +2662,10 @@ Initialization sanity check failed. Bitcoin Core is shutting down. Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core. + + Invalid amount for -maxtxfee=<amount>: '%s' + Μη έγκυρο ποσό για την παράμετρο -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s' @@ -2766,6 +2786,14 @@ Invalid -proxy address: '%s' Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s' + + Maintain at most <n> connections to peers (default: %u) + Μέγιστες αριθμός συνδέσεων με τους peers <n> (προεπιλογή: %u) + + + Specify configuration file (default: %s) + Ορίστε αρχείο ρυθμίσεων (προεπιλογή: %s) + Specify connection timeout in milliseconds (minimum: 1, default: %d) Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή: %d) diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 96cdecfe8..bf912d295 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -882,6 +882,34 @@ command-line options command-line options + + UI Options: + UI Options: + + + Choose data directory on startup (default: %u) + Choose data directory on startup (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + + + Start minimized + Start minimised + + + Set SSL root certificates for payment request (default: -system-) + Set SSL root certificates for payment request (default: -system-) + + + Show splash screen on startup (default: %u) + Show splash screen on startup (default: %u) + + + Reset all settings changes made over the GUI + Reset all settings changes made over the GUI + Intro @@ -1477,6 +1505,18 @@ Current number of blocks Current number of blocks + + Memory Pool + Memory Pool + + + Current number of transactions + Current number of transactions + + + Memory usage + Memory usage + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. @@ -3483,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) How thorough the block verification of -checkblocks is (0-4, default: %u) @@ -3499,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Output debugging information (default: %u, supplying <category> is optional) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Support filtering of blocks and transaction with bloom filters (default: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. @@ -3515,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + (default: %s) (default: %s) diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index c17e47765..ab8dd65f8 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -409,10 +409,22 @@ No block source available... Neniu fonto de blokoj trovebla... + + %n day(s) + %n tago%n tagoj + + + %n week(s) + %n semajno%n semajnoj + %1 and %2 %1 kaj %2 + + %n year(s) + %n jaro%n jaroj + %1 behind mankas %1 @@ -445,6 +457,30 @@ Catching up... Ĝisdatigante... + + Date: %1 + + Dato: %1 + + + + Amount: %1 + + Sumo: %1 + + + + Type: %1 + + Tipo: %1 + + + + Label: %1 + + Etikedo: %1 + + Sent transaction Sendita transakcio @@ -776,7 +812,7 @@ command-line options komandliniaj agordaĵoj - + Intro @@ -853,6 +889,14 @@ MB MB + + Accept connections from outside + Akcepti konektojn el ekstere + + + Allow incoming connections + Permesi envenantajn konektojn + Reset all client options to default. Reagordi ĉion al defaŭlataj valoroj. @@ -865,6 +909,10 @@ &Network &Reto + + W&allet + Monujo + Expert Fakulo @@ -889,6 +937,14 @@ Port of the proxy (e.g. 9050) la pordo de la prokurilo (ekz. 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + &Window &Fenestro @@ -976,6 +1032,10 @@ Mined balance that has not yet matured Minita saldo, kiu ankoraŭ ne maturiĝis + + Balances + Saldoj + Total: Totalo: @@ -984,6 +1044,14 @@ Your current total balance via aktuala totala saldo + + Spendable: + Elspezebla: + + + Recent transactions + Lastaj transakcioj + PaymentServer @@ -1045,6 +1113,10 @@ %1 m %1 m + + None + Neniu + N/A neaplikebla @@ -1123,6 +1195,22 @@ Current number of blocks Aktuala nombro de blokoj + + Received + Ricevita + + + Sent + Sendita + + + Version + Versio + + + Services + Servoj + Last block time Horo de la lasta bloko @@ -1375,6 +1463,10 @@ Change: Restmono: + + Transaction Fee: + Krompago: + Send to multiple recipients at once Sendi samtempe al pluraj ricevantoj @@ -2209,10 +2301,18 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo) + + Cannot resolve -whitebind address: '%s' + Ne eblas trovi la adreson -whitebind: '%s' + Information Informoj + + Invalid amount for -maxtxfee=<amount>: '%s' + Nevalida sumo por -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Nevalida sumo por -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index bb7fcb109..936074210 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -23,7 +23,7 @@ C&lose - &Cerrar + C&errar &Copy Address @@ -55,7 +55,7 @@ C&hoose - &Escoger + E&scoger Sending addresses @@ -93,7 +93,11 @@ Exporting Failed Fallo al exportar - + + There was an error trying to save the address list to %1. Please try again. + Hubo un error al tratar de guardar en la lista de direcciones a %1 . Por favor, vuelve a intentarlo . + + AddressTableModel @@ -259,7 +263,7 @@ E&xit - &Salir + S&alir Quit application @@ -878,7 +882,23 @@ command-line options opciones de la consola de comandos - + + Choose data directory on startup (default: %u) + Elegir directorio de datos al iniciar (predeterminado: %u) + + + Set language, for example "de_DE" (default: system locale) + Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) + + + Start minimized + Arrancar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) + + Intro @@ -1087,6 +1107,10 @@ Tor Tor + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima: + &Window &Ventana @@ -2021,6 +2045,10 @@ Copy change Copiar Cambio + + Total Amount %1 + Monto Total %1 + or o @@ -2045,6 +2073,10 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. ¡La transacción fue rechazada! Esto puede haber ocurrido si alguno de los bitcoins de su monedero ya estaba gastado o si ha usado una copia de wallet.dat y los bitcoins estaban gastados en la copia pero no se habían marcado como gastados aqui. + + A fee higher than %1 is considered an absurdly high fee. + Una comisión mayor al %1 se considera demasiado alta. + Payment request expired. Solicitud de pago caducada. @@ -2854,6 +2886,10 @@ Ejecutar en segundo plano como daemon y aceptar comandos + + Unable to start HTTP server. See debug log for details. + No se ha podido comenzar el servidor HTTP. Ver debug log para detalles. + Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) @@ -3074,6 +3110,10 @@ If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u) + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Cantidad no válida para -maxtxfee=<amount>: '%s' (debe ser por lo menos la cuota de comisión mínima de %s para prevenir transacciones atascadas) + Maximum size of data in data carrier transactions we relay and mine (default: %u) El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u) diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index c303007b7..e6d48a29f 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -301,6 +301,10 @@ Bitcoin Core bitcoin core + + %1 and %2 + %1 y %2 + Error Error @@ -351,6 +355,10 @@ Amount: Cantidad: + + Priority: + prioridad: + Amount Cantidad @@ -505,6 +513,10 @@ &Network &Red + + W&allet + Cartera + Expert experto @@ -636,6 +648,10 @@ &Information &Información + + Debug window + Ventana Debug + General General @@ -684,6 +700,10 @@ ReceiveCoinsDialog + + &Amount: + Cantidad: + &Label: &Etiqueta: @@ -761,10 +781,22 @@ Send Coins Enviar monedas + + Insufficient funds! + Fondos insuficientes + Amount: Cantidad: + + Priority: + prioridad: + + + Transaction Fee: + Comisión transacción: + Send to multiple recipients at once Enviar a múltiples destinatarios @@ -848,6 +880,10 @@ Message: Mensaje: + + Pay To: + Pagar a: + ShutdownWindow @@ -902,6 +938,10 @@ Click "Sign Message" to generate signature Click en "Firmar Mensage" para conseguir firma + + The entered address is invalid. + La dirección introducida no es una valida. + Please check the address and try again. Por favor, revise la dirección Bitcoin e inténtelo denuevo @@ -1308,6 +1348,18 @@ Information Información + + Invalid amount for -maxtxfee=<amount>: '%s' + Cantidad inválida para -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Cantidad inválida para -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Cantidad inválida para -mintxfee=<amount>: '%s' + Send trace/debug info to console instead of debug.log file Enviar informacion de seguimiento a la consola en vez del archivo debug.log diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 60347070d..0463c0f6e 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -740,7 +740,7 @@ command-line options opciones de la línea de órdenes - + Intro @@ -829,6 +829,10 @@ &Network &Red + + W&allet + Monedero + Expert Experto @@ -1367,6 +1371,10 @@ Custom change address Dirección propia + + Transaction Fee: + Comisión de transacción: + Send to multiple recipients at once Enviar a múltiples destinatarios de una vez @@ -1518,6 +1526,10 @@ Remove this entry Eliminar esta transacción + + Message: + Mensaje: + Enter a label for this address to add it to the list of used addresses Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas @@ -2220,10 +2232,18 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d) + + Cannot resolve -whitebind address: '%s' + No se puede resolver la dirección de -whitebind: '%s' + Information Información + + Invalid amount for -maxtxfee=<amount>: '%s' + Inválido por el monto -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Inválido por el monto -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index b19387d9e..bdbfed4ec 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -330,6 +330,14 @@ EditAddressDialog + + &Label + Etiqueta + + + &Address + Dirección + FreespaceChecker @@ -369,6 +377,10 @@ ReceiveRequestDialog + + Copy &Address + &Copiar Direccón + Address Dirección diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index e9a80e2f5..fa2b3c062 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -11,7 +11,7 @@ Copy the currently selected address to the system clipboard - Copiar el domicilio seleccionado al portapapeles del sistema + Copiar la dirección seleccionada al portapapeles del sistema &Copy @@ -83,7 +83,7 @@ Comma separated file (*.csv) - Arhchivo separado por comas (*.CSV) + Archivo separado por comas (*.CSV) Exporting Failed @@ -98,7 +98,7 @@ Address - Domicilio + Dirección (no label) @@ -165,7 +165,7 @@ Wallet encryption failed - Encriptación de la cartera fallida + La encriptación de la cartera fallo Wallet encryption failed due to an internal error. Your wallet was not encrypted. @@ -181,7 +181,7 @@ The passphrase entered for the wallet decryption was incorrect. - La contraseña ingresada para la desencriptación de la cartera es incorrecto + La contraseña ingresada para la desencriptación de la cartera es incorrecta Wallet decryption failed @@ -199,7 +199,7 @@ BitcoinGUI Sign &message... - Sign &mensaje + Firmar &mensaje Synchronizing with network... @@ -259,16 +259,20 @@ &Sending addresses... - &Enviando direcciones... + Direcciones de &envío... &Receiving addresses... - &Recibiendo direcciones... + Direcciones de &recepción... Open &URI... Abrir &URL... + + Bitcoin Core client + cliente Bitcoin Core + Importing blocks from disk... Importando bloques desde el disco... @@ -295,12 +299,28 @@ Open debugging and diagnostic console - Abrir la consola de depuración y disgnostico + Abrir consola de depuración y diagnostico &Verify message... &Verificar mensaje... + + Bitcoin + Bitcoin + + + Wallet + Cartera + + + &Send + &Enviar + + + &Receive + &Recibir + &File &Archivo @@ -321,6 +341,10 @@ Bitcoin Core nucleo Bitcoin + + &About Bitcoin Core + Acerca de Bitcoin Core + &Command-line options opciones de la &Linea de comandos @@ -335,7 +359,7 @@ Catching up... - Resiviendo... + Recibiendo... Sent transaction @@ -387,41 +411,45 @@ Confirmed Confirmado + + Priority + Prioridad + Copy address Copiar dirección Copy label - Copiar capa + Copiar etiqueta Copy amount - copiar monto + Copiar monto Copy quantity - copiar cantidad + Copiar cantidad Copy fee - copiar cuota + Copiar cuota Copy after fee - copiar despues de cuota + Copiar después de cuota Copy bytes - copiar bytes + Copiar bytes Copy priority - copiar prioridad + Copiar prioridad Copy change - copiar cambio + Copiar cambio (no label) @@ -444,23 +472,23 @@ New receiving address - Nueva dirección de entregas + Nueva dirección de recepción New sending address - Nueva dirección de entregas + Nueva dirección de envío Edit receiving address - Editar dirección de entregas + Editar dirección de recepción Edit sending address - Editar dirección de envios + Editar dirección de envío The entered address "%1" is already in the address book. - El domicilio ingresado "%1" ya existe en la libreta de direcciones + La dirección ingresada "%1" ya existe en la libreta de direcciones Could not unlock wallet. @@ -482,7 +510,7 @@ version - Versión + versión (%1-bit) @@ -492,6 +520,10 @@ About Bitcoin Core Acerca de Bitcoin Core + + Command-line options + opciones de la Linea de comandos + Usage: Uso: @@ -500,7 +532,7 @@ command-line options Opciones de comando de lineas - + Intro @@ -521,6 +553,10 @@ Active command-line options that override above options: Activar las opciones de linea de comando que sobre escriben las siguientes opciones: + + W&allet + Cartera + OverviewPage @@ -547,13 +583,25 @@ RPCConsole + + Debug window + Depurar ventana + ReceiveCoinsDialog + + &Amount: + Monto: + &Label: &Etiqueta + + &Message: + Mensaje: + 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. Mensaje opcional para agregar a la solicitud de pago, el cual será mostrado cuando la solicitud este abierta. Nota: El mensaje no se manda con el pago a travéz de la red de Bitcoin. @@ -568,18 +616,22 @@ Copy label - Copiar capa + Copiar etiqueta Copy amount - copiar monto + Copiar monto ReceiveRequestDialog + + Copy &Address + &Copiar dirección + Address - Domicilio + Dirección Amount @@ -589,6 +641,10 @@ Label Etiqueta + + Message + Mensaje + RecentRequestsTableModel @@ -600,6 +656,10 @@ Label Etiqueta + + Message + Mensaje + Amount Monto @@ -613,7 +673,7 @@ SendCoinsDialog Send Coins - Mandar monedas + Enviar monedas Bytes: @@ -631,6 +691,10 @@ Fee: Cuota: + + fast + rápido + Send to multiple recipients at once Enviar a múltiples receptores a la vez @@ -645,35 +709,35 @@ Confirm send coins - Confirme para mandar monedas + Confirme para enviar monedas Copy quantity - copiar cantidad + Copiar cantidad Copy amount - copiar monto + Copiar monto Copy fee - copiar cuota + Copiar cuota Copy after fee - copiar despues de cuota + Copiar después de cuota Copy bytes - copiar bytes + Copiar bytes Copy priority - copiar prioridad + Copiar prioridad Copy change - copiar cambio + Copiar cambio or @@ -685,7 +749,7 @@ Transaction creation failed! - ¡La creación de transacion falló! + ¡La creación de la transación falló! The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. @@ -776,12 +840,16 @@ Alt+P Alt+P + + Signature + Firma + SplashScreen Bitcoin Core - nucleo Bitcoin + Bitcoin Core The Bitcoin Core developers @@ -805,14 +873,42 @@ %1 confirmations %1 confirmaciones + + Status + Estado + Date Fecha + + From + De + + + To + Para + + + label + etiqueta + + + Message + Mensaje + + + Comment + Comentario + Transaction ID ID + + Transaction + Transacción + Amount Monto @@ -869,7 +965,7 @@ Received with - Recivido con + Recibido con Sent to @@ -928,7 +1024,7 @@ Received with - Recivido con + Recibido con Sent to @@ -986,6 +1082,10 @@ Exporting Successful Exportacion satisfactoria + + The transaction history was successfully saved to %1. + el historial de transaciones ha sido guardado exitosamente en %1 + Comma separated file (*.csv) Arhchivo separado por comas (*.CSV) @@ -1050,13 +1150,29 @@ There was an error trying to save the wallet data to %1. Ocurrio un error tratando de guardar la información de la cartera %1 + + The wallet data was successfully saved to %1. + La información de la cartera fué guardada exitosamente a %1 + bitcoin-core + + Options: + Opciones: + <category> can be: <categoria> puede ser: + + Verifying blocks... + Verificando bloques... + + + Verifying wallet... + Verificando cartera... + Wallet options: Opciones de cartera: diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 5029333b5..32d433d6e 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -1,22 +1,71 @@ AddressBookPage + + Right-click to edit address or label + Clic derecho para editar dirección o etiqueta + Create a new address Crear una nueva dirección + + &New + Nuevo + Copy the currently selected address to the system clipboard Copia la dirección seleccionada al portapapeles del sistema + + &Copy + Copiar + + + C&lose + Cerrar + + + &Copy Address + Copiar Dirección + + + &Export + Exportar + &Delete &Borrar + + Choose the address to send coins to + Elige una dirección donde enviar monedas a + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + + &Edit + Editar + + + Export Address List + Exportar Lista de Direcciones + Comma separated file (*.csv) Archivos separados por coma (*.csv) + + Exporting Failed + Exportación fallida + AddressTableModel @@ -75,6 +124,14 @@ Confirm wallet encryption Confirme el cifrado del monedero + + Are you sure you wish to encrypt your wallet? + Estas seguro que deseas encriptar tu billetera? + + + Warning: The Caps Lock key is on! + Atención: la tecla Mayusculas esta activa! + Wallet encrypted Monedero cifrado @@ -129,18 +186,58 @@ Browse transaction history Buscar en el historial de transacciones + + E&xit + Salida + Quit application Salir de la aplicacion + + Show information about Qt + Mostrar informacioón sobre + &Options... &Opciones... + + &Backup Wallet... + Respaldar Billetera + + + &Change Passphrase... + Cambiar contraseña + + + &Sending addresses... + Enviando direcciones + + + &Receiving addresses... + Recibiendo direcciones + + + Send coins to a Bitcoin address + Enviar monedas a una dirección BItCoin + Change the passphrase used for wallet encryption Cambie la clave utilizada para el cifrado del monedero + + Bitcoin + Bitcoin + + + Wallet + Billetera + + + &Show / Hide + Mostrar / Ocultar + &File &Archivo @@ -157,6 +254,18 @@ Tabs toolbar Barra de herramientas + + Error + Error + + + Warning + Alerta + + + Information + Información + Up to date A la fecha @@ -165,6 +274,17 @@ Catching up... Ponerse al dia... + + Type: %1 + + Tipo: %1 + + + + Address: %1 + + Dirección: %1 + Sent transaction Transaccion enviada @@ -187,10 +307,38 @@ CoinControlDialog + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + AMonto: + + + Priority: + Prioridad: + + + Change: + Cambio: + Date Fecha + + Confirmed + Confirmado + + + Priority + Prioridad + (no label) (Sin etiqueta) @@ -226,6 +374,10 @@ Edit sending address Editar dirección de envío + + The entered address "%1" is already in the address book. + La dirección introducida "%1" ya está en la libreta de direcciones. + Could not unlock wallet. No se puede abrir el monedero. @@ -243,6 +395,10 @@ Intro + + Error + Error + OpenURIDialog @@ -253,6 +409,10 @@ Options Opciones + + W&allet + Billetera + OverviewPage @@ -275,6 +435,10 @@ RPCConsole + + &Information + Información + ReceiveCoinsDialog @@ -285,6 +449,10 @@ ReceiveRequestDialog + + Copy &Address + Copiar Dirección + Address Direccion @@ -315,6 +483,26 @@ Send Coins Enviar monedas + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + AMonto: + + + Priority: + Prioridad: + + + Change: + Cambio: + Send to multiple recipients at once Enviar a varios destinatarios a la vez @@ -370,6 +558,10 @@ Alt+P Alt+P + + Pay To: + Pagar A: + ShutdownWindow @@ -409,6 +601,10 @@ Date Fecha + + Transaction + Transaccion + unknown desconocido @@ -434,10 +630,18 @@ TransactionView + + Exporting Failed + Exportación fallida + Comma separated file (*.csv) Archivos separados por coma (*.csv) + + Confirmed + Confirmado + Date Fecha @@ -466,8 +670,28 @@ WalletView + + &Export + Exportar + bitcoin-core - + + Options: + Opciones: + + + Information + Información + + + Warning + Alerta + + + Error + Error + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts index f9db05655..582e72884 100644 --- a/src/qt/locale/bitcoin_es_VE.ts +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -85,7 +85,11 @@ Exporting Failed Exportación fallida - + + There was an error trying to save the address list to %1. Please try again. + Hubo un error intentando guardar la lista de direcciones al %1. Por favor intente nuevamente. + + AddressTableModel @@ -233,6 +237,10 @@ Quit application Quitar aplicación + + &Receiving addresses... + Recepción de direcciones + Bitcoin Core client Cliente Bitcoin Core @@ -313,6 +321,14 @@ Bitcoin Core Bitcoin Core + + &About Bitcoin Core + Acerca de Bitcoin Core + + + &Command-line options + Opciones de línea de comandos + %1 and %2 %1 y %2 @@ -684,7 +700,7 @@ command-line options opciones de línea de comandos - + Intro @@ -745,6 +761,10 @@ &Main &Main + + W&allet + Billetera + none ninguno @@ -771,9 +791,21 @@ RPCConsole + + &Information + Información + ReceiveCoinsDialog + + &Amount: + Monto: + + + &Label: + &Etiqueta: + Copy label Copiar etiqueta @@ -785,6 +817,10 @@ ReceiveRequestDialog + + Copy &Address + &Copiar Dirección + Address Dirección @@ -882,6 +918,14 @@ SendCoinsEntry + + A&mount: + Monto: + + + &Label: + &Etiqueta: + ShutdownWindow @@ -905,6 +949,10 @@ Date Fecha + + Transaction + Transacción + Amount Monto @@ -990,6 +1038,14 @@ Backup Failed Copia de seguridad fallida + + There was an error trying to save the wallet data to %1. + Hubo un error intentando guardar los datos de la billetera al %1 + + + The wallet data was successfully saved to %1. + Los datos de la billetera fueron guardados exitosamente al %1 + Backup Successful Copia de seguridad completada diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 1d6d1b89e..945e4cfa5 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -329,6 +329,14 @@ Bitcoin Core Bitcoini tuumik + + &About Bitcoin Core + Kirjeldus Bitcoini Tuumast + + + &Command-line options + Käsurea valikud + %n hour(s) %n tund%n tundi @@ -606,7 +614,7 @@ command-line options käsurea valikud - + Intro @@ -639,6 +647,10 @@ Options Valikud + + &Main + &Peamine + MB MB @@ -809,6 +821,10 @@ &Information &Informatsioon + + Debug window + Debugimise aken + General Üldine @@ -947,6 +963,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopeeri Aadress + Address Aadress @@ -1009,6 +1029,10 @@ Send Coins Müntide saatmine + + Insufficient funds! + Liiga suur summa + Quantity: Kogus: @@ -1021,6 +1045,10 @@ Fee: Tasu: + + Transaction Fee: + Tehingu tasu: + Choose... Vali... @@ -1132,6 +1160,10 @@ Message: Sõnum: + + Pay To: + Maksa : + ShutdownWindow @@ -1283,6 +1315,10 @@ Open until %1 Avatud kuni %1 + + %1/offline + %1/offline'is + %1/unconfirmed %1/kinnitamata @@ -1731,10 +1767,30 @@ Wallet options: Rahakoti valikud: + + (default: %u) + (vaikimisi: %u) + + + Cannot resolve -whitebind address: '%s' + Tundmatu -whitebind aadress: '%s' + Information Informatsioon + + Invalid amount for -maxtxfee=<amount>: '%s' + -maxtxfee=<amount> jaoks vigane kogus: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + -minrelaytxfee=<amount> jaoks vigane kogus: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + -mintxfee=<amount> jaoks vigane kogus: '%s' + RPC server options: RPC serveri valikud: diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index 4da6cc0dc..ca6b6489d 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -249,6 +249,10 @@ &Options... &Aukerak... + + &Receiving addresses... + Helbideak jasotzen + Change the passphrase used for wallet encryption Aldatu zorroa enkriptatzeko erabilitako pasahitza @@ -414,10 +418,18 @@ ReceiveCoinsDialog + + &Amount: + Kopurua + &Label: &Etiketa: + + &Message: + Mezua + Copy label Kopiatu etiketa @@ -425,6 +437,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopiatu helbidea + Address Helbidea @@ -437,6 +453,10 @@ Label Etiketa + + Message + Mezua + RecentRequestsTableModel @@ -448,6 +468,10 @@ Label Etiketa + + Message + Mezua + Amount Kopurua @@ -526,6 +550,10 @@ Message: Mezua + + Pay To: + Ordaindu honi: + ShutdownWindow @@ -573,6 +601,14 @@ Date Data + + Message + Mezua + + + Transaction + Transakzioaren + Amount Kopurua diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 3ef976660..7ab3b77da 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -397,6 +397,10 @@ Show the list of used receiving addresses and labels نمایش لیست آدرس های دریافت و لیبل ها + + &Command-line options + گزینه‌های خط‌فرمان + %n active connection(s) to Bitcoin network %n ارتباط فعال با شبکهٔ بیت‌کوین @@ -417,6 +421,14 @@ %n week(s) %n هفته + + %1 and %2 + %1 و %2 + + + %n year(s) + %n سال + %1 behind %1 عقب‌تر @@ -712,7 +724,7 @@ command-line options گزینه‌های خط فرمان - + Intro @@ -743,6 +755,10 @@ Error خطا + + %n GB of free space available + %n گیگابایت فضا موجود است + OpenURIDialog @@ -769,6 +785,10 @@ &Network &شبکه + + W&allet + کیف پول + Expert استخراج @@ -975,6 +995,10 @@ &Information &اطلاعات + + Debug window + پنجرهٔ اشکالزدایی + Using OpenSSL version نسخهٔ OpenSSL استفاده شده @@ -1066,10 +1090,18 @@ ReceiveCoinsDialog + + &Amount: + مبلغ: + &Label: &برچسب: + + &Message: + پیام: + Show نمایش @@ -1093,6 +1125,10 @@ QR Code کد QR + + Copy &Address + &کپی نشانی + Address نشانی @@ -1147,6 +1183,10 @@ Send Coins ارسال سکه + + Insufficient funds! + بود جه نا کافی + Quantity: تعداد: @@ -1175,6 +1215,10 @@ Change: پول خورد: + + Transaction Fee: + هزینهٔ تراکنش: + fast سریع @@ -1290,6 +1334,10 @@ Message: پیام: + + Pay To: + پرداخت به: + ShutdownWindow @@ -1929,6 +1977,18 @@ Information اطلاعات + + Invalid amount for -maxtxfee=<amount>: '%s' + میزان وجه اشتباه برای maxtxfee=<میزان وجه>: %s + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + میزان وجه اشتباه برای minrelaytxfee=<میزان وجه>: %s + + + Invalid amount for -mintxfee=<amount>: '%s' + میزان وجه اشتباه برای mintxfee=<میزان وجه>: %s + Send trace/debug info to console instead of debug.log file اطلاعات ردگیری/اشکال‌زدایی را به جای فایل لاگ اشکال‌زدایی به کنسول بفرستید diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index fd9de2e04..8bbfc7242 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -249,6 +249,10 @@ &Change Passphrase... تغییر رمز/پَس فرِیز + + &Receiving addresses... + دریافت آدرس ها + Backup wallet to another location گرفتن نسخه پیشتیبان در آدرسی دیگر @@ -391,6 +395,10 @@ Edit sending address ویرایش حساب ارسال کننده + + The entered address "%1" is already in the address book. + حساب وارد شده «%1» از پیش در دفترچه حساب ها موجود است. + The entered address "%1" is not a valid Bitcoin address. آدرس وارد شده "%1" یک آدرس صحیح برای bitcoin نسشت @@ -434,6 +442,14 @@ Options انتخاب/آپشن + + &Network + شبکه + + + W&allet + کیف پول + &OK و تایید @@ -503,10 +519,18 @@ ReceiveCoinsDialog + + &Amount: + میزان وجه: + &Label: و برچسب + + &Message: + پیام: + Copy label برچسب را کپی کنید @@ -518,6 +542,10 @@ ReceiveRequestDialog + + Copy &Address + کپی آدرس + Address حساب @@ -572,6 +600,10 @@ Send Coins سکه های ارسالی + + Insufficient funds! + وجوه ناکافی + Amount: میزان وجه: @@ -685,6 +717,10 @@ Alt+P Alt و P + + Sign &Message + و امضای پیام + SplashScreen @@ -999,6 +1035,18 @@ The transaction amount is too small to send after the fee has been deducted مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد + + Invalid amount for -maxtxfee=<amount>: '%s' + میزان اشتباه است for -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + میزان اشتباه است for -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + میزان اشتباه است for -mintxfee=<amount>: '%s' + RPC server options: گزینه های سرویس دهنده RPC: diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 71ea96644..57987b26e 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Verkon peite + + + Banned Until + Estetty kunnes + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options komentorivi parametrit + + UI Options: + Käyttöliittymän asetukset: + + + Choose data directory on startup (default: %u) + Valitse datahakemisto käynnistyksen yhteydessä (oletus: %u) + + + Set language, for example "de_DE" (default: system locale) + Aseta kieli, esimerkiksi "de_DE" (oletus: järjestelmän kieli) + + + Start minimized + Käynnistä pienennettynä + + + Set SSL root certificates for payment request (default: -system-) + Aseta maksupyynnöille SSL-juurivarmenteet (oletus: -system-) + + + Show splash screen on startup (default: %u) + Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u) + + + Reset all settings changes made over the GUI + Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset + Intro @@ -979,6 +1015,14 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1) + + 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. + Minimoi ikkuna ohjelman sulkemisen sijasta kun ikkuna suljetaan. Kun tämä asetus on käytössä, ohjelma suljetaan vain valittaessa valikosta Poistu. + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + Käyttöliittymän kieli voidaan asettaa tässä. Tämä asetus tulee käyttöön vasta kun Bitcoin Core käynnistetään uudelleen. + 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 |. Ulkopuoliset URL-osoitteet (esim. block explorer,) jotka esiintyvät siirrot-välilehdellä valikossa. %s URL-osoitteessa korvataan siirtotunnuksella. Useampi URL-osoite on eroteltu pystyviivalla |. @@ -1063,6 +1107,34 @@ Port of the proxy (e.g. 9050) Proxyn Portti (esim. 9050) + + Used for reaching peers via: + Vertaisten saavuttamiseen käytettävät verkkotyypit: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Ilmoittaa, mikäli oletetettua SOCKS5-välityspalvelinta käytetään tämän verkkotyypin kautta vertaisten saavuttamiseen. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Yhdistä Bitcoin-verkkoon erillisen SOCKS5-välityspalvelimen kautta piilotettuja Tor-palveluja varten. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Käytä erillistä SOCKS5-välityspalvelinta saavuttaaksesi vertaisia piilotettujen Tor-palveluiden kautta: + &Window &Ikkuna @@ -1433,6 +1505,22 @@ Current number of blocks Nykyinen Lohkojen määrä + + Memory Pool + Muistiallas + + + Current number of transactions + Tämänhetkinen rahansiirtojen määrä + + + Memory usage + Muistin käyttö + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + Avaa Bitcoin Coren debug-loki tämänhetkisestä datahakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille. + Received Vastaanotetut @@ -1445,10 +1533,18 @@ &Peers &Vertaiset + + Banned peers + Estetyt vertaiset + Select a peer to view detailed information. Valitse vertainen eriteltyjä tietoja varten. + + Whitelisted + Sallittu + Direction Suunta @@ -1457,6 +1553,18 @@ Version Versio + + Starting Block + Alkaen lohkosta + + + Synced Headers + Synkronoidut ylätunnisteet + + + Synced Blocks + Synkronoidut lohkot + User Agent Käyttöliittymä @@ -1485,6 +1593,14 @@ Ping Time Vasteaika + + The duration of a currently outstanding ping. + Tämänhetkisen merkittävän yhteyskokeilun kesto. + + + Ping Wait + Yhteyskokeilun odotus + Time Offset Ajan poikkeama @@ -1533,6 +1649,34 @@ Clear console Tyhjennä konsoli + + &Disconnect Node + &Katkaise yhteys solmukohtaan + + + Ban Node for + Estä solmukohta + + + 1 &hour + 1 &tunti + + + 1 &day + 1 &päivä + + + 1 &week + 1 &viikko + + + 1 &year + 1 &vuosi + + + &Unban Node + &Poista solmukohdan esto + Welcome to the Bitcoin Core RPC console. Tervetuloa Bitcoin Coren RPC-konsoliin. @@ -1561,6 +1705,10 @@ %1 GB %1 GB + + (node id: %1) + (solmukohdan id: %1) + via %1 %1 kautta @@ -1941,6 +2089,10 @@ Copy change Kopioi vaihtoraha + + Total Amount %1 + Kokonaismäärä %1 + or tai @@ -1973,10 +2125,22 @@ Payment request expired. Maksupyyntö on vanhentunut. + + Pay only the required fee of %1 + Maksa vain vaadittu kulu kooltaan %1 + + + Estimated to begin confirmation within %n block(s). + Vahvistuminen alkaa arviolta %n lohkon päästä.Vahvistuminen alkaa arviolta %n lohkon päästä. + The recipient address is not valid. Please recheck. Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen. + + Duplicate address found: addresses should only be used once each. + Duplikaattiosoite löytyi: kutakin osoitetta pitäisi käyttää vain kerran. + Warning: Invalid Bitcoin address Varoitus: Virheellinen Bitcoin osoite @@ -2505,6 +2669,10 @@ Whether or not a watch-only address is involved in this transaction. Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei. + + User-defined intent/purpose of the transaction. + Käyttäjän määrittämä käyttötarkoitus rahansiirrolle. + Amount removed from or added to balance. Saldoon lisätty tai siitä vähennetty määrä. @@ -2584,6 +2752,10 @@ Copy transaction ID Kopioi siirtotunnus + + Copy raw transaction + Kopioi rahansiirron raakavedos + Edit label Muokkaa nimeä @@ -2731,10 +2903,22 @@ Accept command line and JSON-RPC commands Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt + + If <category> is not supplied or if <category> = 1, output all debugging information. + Jos <category> on toimittamatta tai jos <category> = 1, tulosta kaikki debug-tieto. + + + Error: A fatal internal error occurred, see debug.log for details + Virhe: Kriittinen sisäinen virhe kohdattiin, katso debug.log lisätietoja varten + Run in the background as a daemon and accept commands Aja taustalla daemonina ja hyväksy komennot + + Unable to start HTTP server. See debug log for details. + HTTP-palvelinta ei voitu käynnistää. Katso debug-lokista lisätietoja. + Accept connections from outside (default: 1 if no -proxy or -connect) Hyväksy yhteyksiä ulkopuolelta (vakioasetus: 1 jos -proxy tai -connect ei määritelty) @@ -2759,6 +2943,18 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Käytä UPnP:ta kuuntelevan portin kartoitukseen (oletus: 1 kun kuunnellaan ja -proxy ei käytössä) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + VAROITUS: epätavallisen monta lohkoa generoitu, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + VAROITUS: tarkista verkkoyhteytesi, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varoitus: Tietoverkko ei ole sovussa! Luohijat näyttävät kokevan virhetilanteita. @@ -2771,6 +2967,10 @@ Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta. + + -maxmempool must be at least %d MB + -maxmempool on oltava vähintään %d MB + <category> can be: <category> voi olla: @@ -2803,6 +3003,10 @@ Do you want to rebuild the block database now? Haluatko uudelleenrakentaa lohkotietokannan nyt? + + Enable publish raw transaction in <address> + Ota rahansiirtojen raakavedosten julkaisu käyttöön osoitteessa <address> + Error initializing block database Virhe alustaessa lohkotietokantaa @@ -2919,6 +3123,10 @@ Activating best chain... Aktivoidaan parhainta ketjua... + + Attempt to recover private keys from a corrupt wallet.dat on startup + Yritä palauttaa yksityiset avaimet korruptoituneesta wallet.dat-tiedostosta käynnistyksen yhteydessä + Cannot resolve -whitebind address: '%s' -whitebind -osoitetta '%s' ei voida jäsentää @@ -2943,6 +3151,10 @@ Information Tietoa + + Invalid amount for -maxtxfee=<amount>: '%s' + Virheellinen määrä -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Virheellinen määrä -minrelaytxfee=<amount>: '%s' @@ -2963,6 +3175,10 @@ Receive and display P2P network alerts (default: %u) Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u) + + Rescan the block chain for missing wallet transactions on startup + Uudelleenskannaa lohkoketju käynnistyksen yhteydessä puuttuvien lompakon rahansiirtojen vuoksi + Send trace/debug info to console instead of debug.log file Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan @@ -2979,10 +3195,22 @@ Signing transaction failed Siirron vahvistus epäonnistui + + The transaction amount is too small to pay the fee + Rahansiirron määrä on liian pieni kattaakseen maksukulun + This is experimental software. Tämä on ohjelmistoa kokeelliseen käyttöön. + + Tor control port password (default: empty) + Tor-hallintaportin salasana (oletus: tyhjä) + + + Tor control port to use if onion listening enabled (default: %s) + Tor-hallintaportti jota käytetään jos onion-kuuntelu on käytössä (oletus: %s) + Transaction amount too small Siirtosumma liian pieni @@ -2991,10 +3219,18 @@ Transaction amounts must be positive Siirtosumman tulee olla positiivinen + + Transaction too large for fee policy + Rahansiirto on liian suuri maksukulukäytännölle + Transaction too large Siirtosumma liian iso + + Upgrade wallet to latest format on startup + Päivitä lompakko viimeisimpään formaattiin käynnistyksen yhteydessä + Username for JSON-RPC connections Käyttäjätunnus JSON-RPC-yhteyksille @@ -3007,10 +3243,18 @@ Warning Varoitus + + Whether to operate in a blocks only mode (default: %u) + Toimitaanko tilassa jossa ainoastaan lohkot sallitaan (oletus: %u) + Zapping all transactions from wallet... Tyhjennetään kaikki rahansiirrot lompakosta.... + + ZeroMQ notification options: + ZeroMQ-ilmoitusasetukset: + wallet.dat corrupt, salvage failed wallet.dat -lompakkotiedosto korruptoitunut, korjaaminen epäonnistui @@ -3039,6 +3283,14 @@ Error loading wallet.dat: Wallet corrupted Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Älä pidä rahansiirtoja muistivarannoissa kauemmin kuin <n> tuntia (oletus: %u) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s) @@ -3067,6 +3319,10 @@ Invalid -proxy address: '%s' Virheellinen proxy-osoite '%s' + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Kuuntele JSON-RPC-yhteyksiä portissa <port> (oletus: %u tai testnet: %u) + Listen for connections on <port> (default: %u or testnet: %u) Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u) @@ -3075,6 +3331,18 @@ Make the wallet broadcast transactions Aseta lompakko kuuluttamaan rahansiirtoja + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Maksimi yhteyttä kohden käytettävä vastaanottopuskurin koko, <n>*1000 tavua (oletus: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Maksimi yhteyttä kohden käytettävä lähetyspuskurin koko, <n>*1000 tavua (oletus: %u) + + + Relay and mine data carrier transactions (default: %u) + Välitä ja louhi dataa kantavia rahansiirtoja (oletus: %u) + Relay non-P2SH multisig (default: %u) Välitä ei-P2SH-multisig (oletus: %u) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index d43e08cf9..a0b9feb9a 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/masque réseau + + + Banned Until + Banni jusqu'au + + BitcoinGUI @@ -725,6 +733,10 @@ This label turns red if the priority is smaller than "medium". Cette étiquette devient rouge si la priorité est plus basse que « moyenne ». + + This label turns red if any recipient receives an amount smaller than %1. + Cette étiquette devient rouge si un destinataire reçoit un montant inférieur à %1. + Can vary +/- %1 satoshi(s) per input. Peut varier +/- %1 satoshi(s) par entrée. @@ -870,6 +882,34 @@ command-line options options de ligne de commande + + UI Options: + Options de l'IU : + + + Choose data directory on startup (default: %u) + Choisir un répertoire de données au démarrage (par défaut : %u) + + + Set language, for example "de_DE" (default: system locale) + Définir la langue, par exemple « fr_CA » (par défaut : la langue du système) + + + Start minimized + Démarrer minimisé + + + Set SSL root certificates for payment request (default: -system-) + Définir les certificats SSL racine pour les requêtes de paiement (par défaut : -system-) + + + Show splash screen on startup (default: %u) + Afficher l'écran d'accueil au démarrage (par défaut : %u) + + + Reset all settings changes made over the GUI + Réinitialiser tous les changements de paramètres appliqués à l'IUG + Intro @@ -913,7 +953,11 @@ %n GB of free space available %n Go d'espace libre disponible%n Go d'espace libre disponibles - + + (of %n GB needed) + (sur %n Go nécessaire)(sur %n Go nécessaires) + + OpenURIDialog @@ -1063,6 +1107,34 @@ Port of the proxy (e.g. 9050) Port du serveur mandataire (par ex. 9050) + + Used for reaching peers via: + Utilisé pour rejoindre les pairs par : + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + S'affiche, si le mandataire SOCKS5 par défaut fourni est utilisé pour atteindre les pairs par ce type de réseau. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Se connecter au réseau Bitcoin au travers d'un mandataire SOCKS5 séparé pour les services cachés de Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utiliser un mandataire SOCKS5 séparé pour atteindre les pairs grâce aux services cachés de Tor : + &Window &Fenêtre @@ -1329,7 +1401,7 @@ %1 d - %1 d + %1 j %1 h @@ -1433,6 +1505,18 @@ Current number of blocks Nombre actuel de blocs + + Memory Pool + Réserve de mémoire + + + Current number of transactions + Nombre actuel de transactions + + + Memory usage + Utilisation de la mémoire + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation. @@ -1449,10 +1533,18 @@ &Peers &Pairs + + Banned peers + Pairs bannis + Select a peer to view detailed information. Choisir un pair pour voir l'information détaillée. + + Whitelisted + Dans la liste blanche + Direction Direction @@ -1461,6 +1553,18 @@ Version Version + + Starting Block + Bloc de départ + + + Synced Headers + En-têtes synchronisés + + + Synced Blocks + Blocs synchronisés + User Agent Agent utilisateur @@ -1489,6 +1593,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La durée d'un ping actuellement en cours. + + + Ping Wait + Attente du ping + Time Offset Décalage temporel @@ -1537,6 +1649,34 @@ Clear console Nettoyer la console + + &Disconnect Node + &Déconnecter le nœud + + + Ban Node for + Bannir le nœud pendant + + + 1 &hour + 1 &heure + + + 1 &day + 1 &jour + + + 1 &week + 1 &semaine + + + 1 &year + 1 &an + + + &Unban Node + &Réhabiliter le nœud + Welcome to the Bitcoin Core RPC console. Bienvenue dans le console RPC de Bitcoin Core. @@ -1565,6 +1705,10 @@ %1 GB %1 Go + + (node id: %1) + (ID de nœud : %1) + via %1 par %1 @@ -1957,6 +2101,10 @@ Copy change Copier la monnaie + + Total Amount %1 + Montant total %1 + or ou @@ -1989,6 +2137,10 @@ Payment request expired. Demande de paiement expirée. + + Pay only the required fee of %1 + Payer seulement les frais exigés de %1 + Estimated to begin confirmation within %n block(s). Il est estimé que la confirmation commencera dans %n bloc.Il est estimé que la confirmation commencera dans %n blocs. @@ -2624,6 +2776,10 @@ Copy transaction ID Copier l'ID de la transaction + + Copy raw transaction + Copier la transaction brute + Edit label Modifier l’étiquette @@ -2771,14 +2927,54 @@ Accept command line and JSON-RPC commands Accepter les commandes de JSON-RPC et de la ligne de commande + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si <category> n'est pas indiqué ou si <category> = 1, extraire toutes les données de débogage. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Frais totaux maximaux (en %s) à utiliser en une seule transaction de portefeuille. Les définir trop bas pourrait interrompre les grosses transactions (par défaut : %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Veuillez vérifier que l'heure et la date de votre ordinateur sont justes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + L'élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Élagage : la dernière synchronisation de portefeuille va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode est incompatible avec -txindex et -rescan. Avertissement : ramener ce paramètre à sa valeur antérieure exige un nouveau téléchargement de la chaîne de blocs en entier (par défaut : 0 = désactiver l'élagage des blocs, >%u = taille cible en Mio à utiliser pour les fichiers de blocs). + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Les rebalayages sont impossibles en mode élagage. Vous devrez utiliser -reindex, ce qui téléchargera de nouveau la chaîne de blocs en entier. + Error: A fatal internal error occurred, see debug.log for details Erreur : une erreur interne fatale s'est produite. Voir debug.log pour plus de détails + + Fee (in %s/kB) to add to transactions you send (default: %s) + Les frais (en %s/ko) à ajouter aux transactions que vous envoyez (par défaut : %s) + + + Pruning blockstore... + Élagage du magasin de blocs... + Run in the background as a daemon and accept commands Fonctionner en arrière-plan en tant que démon et accepter les commandes + + Unable to start HTTP server. See debug log for details. + Impossible de démarrer le serveur HTTP. Voir le journal de débogage pour plus de détails. + Accept connections from outside (default: 1 if no -proxy or -connect) Accepter les connexions entrantes (par défaut : 1 si aucun -proxy ou -connect ) @@ -2789,7 +2985,7 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage + Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de blocs avec -rescan au démarrage Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. @@ -2803,6 +2999,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) + + 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 + La base de données de blocs contient un bloc qui semble provenir du futur. Cela pourrait être causé par la date et l'heure erronées de votre ordinateur. Ne reconstruisez la base de données de blocs que si vous êtes certain que la date et l'heure de votre ordinateur sont justes. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes @@ -2811,6 +3011,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus) @@ -2835,6 +3039,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois. + + -maxmempool must be at least %d MB + -maxmempool doit être d'au moins %d Mo + <category> can be: <category> peut être : @@ -2867,6 +3075,22 @@ Do you want to rebuild the block database now? Voulez-vous reconstruire la base de données des blocs maintenant ? + + Enable publish hash block in <address> + Activer la publication du bloc de hachage dans <address> + + + Enable publish hash transaction in <address> + Activer la publication de la transaction de hachage dans <address> + + + Enable publish raw block in <address> + Activer la publication du bloc brut dans <address> + + + Enable publish raw transaction in <address> + Activer la publication de la transaction brute dans <address> + Error initializing block database Erreur lors de l'initialisation de la base de données des blocs @@ -2903,6 +3127,10 @@ Invalid -onion address: '%s' Adresse -onion invalide : « %s » + + Keep the transaction memory pool below <n> megabytes (default: %u) + Garder la réserve de mémoire transactionnelle sous <n> mégaoctets (par défaut : %u) + Not enough file descriptors available. Pas assez de descripteurs de fichiers proposés. @@ -2931,10 +3159,26 @@ Specify wallet file (within data directory) Spécifiez le fichier de portefeuille (dans le répertoire de données) + + Unsupported argument -benchmark ignored, use -debug=bench. + Argument non pris en charge -benchmark ignoré, utiliser -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argument non pris en charge -debugnet ignoré, utiliser -debug=net. + + + Unsupported argument -tor found, use -onion. + Argument non pris en charge -tor trouvé, utiliser -onion + Use UPnP to map the listening port (default: %u) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u) + + User Agent comment (%s) contains unsafe characters. + Le commentaire d'agent utilisateur (%s) contient des caractères dangereux. + Verifying blocks... Vérification des blocs en cours... @@ -2991,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relais, le minage et la création de transactions (par défaut : %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions commencent la confirmation en moyenne avant n blocs (par défaut : %u) @@ -3047,6 +3295,18 @@ Activating best chain... Activation de la meilleure chaîne... + + Always relay transactions received from whitelisted peers (default: %d) + Toujours relayer les transactions reçues des pairs de la liste blanche (par défaut : %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Tenter de récupérer les clefs privées d'un wallet.dat corrompu lors du démarrage + + + Automatically create Tor hidden service (default: %d) + Créer automatiquement un service caché Tor (par défaut : %d) + Cannot resolve -whitebind address: '%s' Impossible de résoudre l'adresse -whitebind : « %s » @@ -3067,6 +3327,10 @@ Error reading from database, shutting down. Erreur de lecture de la base de données, fermeture en cours. + + Imports blocks from external blk000??.dat file on startup + Importe des blocs depuis un fichier blk000??.dat externe lors du démarrage + Information Informations @@ -3119,6 +3383,14 @@ Receive and display P2P network alerts (default: %u) Recevoir et afficher les alertes du réseau poste à poste (%u par défaut) + + Reducing -maxconnections from %d to %d, because of system limitations. + Réduction de -maxconnections de %d à %d, due aux restrictions du système + + + Rescan the block chain for missing wallet transactions on startup + Réanalyser la chaîne de blocs au démarrage, à la recherche de transactions de portefeuille manquantes + Send trace/debug info to console instead of debug.log file Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log @@ -3147,6 +3419,14 @@ This is experimental software. Ceci est un logiciel expérimental. + + Tor control port password (default: empty) + Mot de passe du port de contrôle Tor (par défaut : vide) + + + Tor control port to use if onion listening enabled (default: %s) + Port de contrôle Tor à utiliser si l'écoute onion est activée (par défaut :%s) + Transaction amount too small Montant de la transaction trop bas @@ -3167,6 +3447,10 @@ Unable to bind to %s on this computer (bind returned error %s) Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s) + + Upgrade wallet to latest format on startup + Mettre à niveau le portefeuille au démarrage vers le format le plus récent + Username for JSON-RPC connections Nom d'utilisateur pour les connexions JSON-RPC @@ -3179,10 +3463,18 @@ Warning Avertissement + + Whether to operate in a blocks only mode (default: %u) + Faut-il fonctionner en mode blocs seulement (par défaut : %u) + Zapping all transactions from wallet... Supprimer toutes les transactions du portefeuille... + + ZeroMQ notification options: + Options de notification ZeroMQ + wallet.dat corrupt, salvage failed wallet.dat corrompu, la récupération a échoué @@ -3215,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés en une seule transaction. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Ne pas conserver de transactions dans la réserve de mémoire plus de <n> heures (par défaut : %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement, mais les données transactionnelles ou les entrées du carnet d'adresses sont peut-être manquantes ou incorrectes. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u) @@ -3231,10 +3543,30 @@ Output debugging information (default: %u, supplying <category> is optional) Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Prendre en charge le filtrage des blocs et des transactions avec les filtres bloom (par défaut : %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + La taille totale de la chaîne de version de réseau (%i) dépasse la longueur maximale (%i). Réduire le nombre ou la taille des commentaires uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Tente de garder le trafic sortant sous la cible donnée (en Mio par 24 h), 0 = sans limite (par défaut : %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + L'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les mandataires SOCKS5 sont pris en charge. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nom d'utilisateur et mot de passe haché pour les connexions JSON-RPC. Le champ <userpw> vient au format : <USERNAME>:<SALT>$<HASH>. Un script python canonique est inclus dans share/rpcuser. Cette option peut être spécifiée plusieurs fois. + (default: %s) (par défaut : %s) @@ -3307,6 +3639,10 @@ Set minimum block size in bytes (default: %u) Définir la taille de bloc minimale en octets (par défaut : %u) + + Set the number of threads to service RPC calls (default: %d) + Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d) + Specify configuration file (default: %s) Spécifier le fichier de configuration (par défaut : %s) diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index 75f970f55..7e6925f96 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -13,6 +13,10 @@ &Delete &Supprimer + + Sending addresses + envoyer adresse de reception + Comma separated file (*.csv) Fichier séparé par une virgule (*.csv) @@ -75,6 +79,14 @@ CoinControlDialog + + (un)select all + Toute sélectionner + + + Copy address + copier l'adresse + (no label) (pas de record) @@ -82,6 +94,14 @@ EditAddressDialog + + &Label + Record + + + &Address + Addresse + FreespaceChecker @@ -91,6 +111,10 @@ Intro + + Welcome + Bienvenue + OpenURIDialog @@ -178,6 +202,10 @@ TransactionView + + Copy address + copier l'adresse + Comma separated file (*.csv) Fichier séparé par une virgule (*.csv) diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index c55b08b64..df6324335 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -362,10 +362,18 @@ ReceiveCoinsDialog + + &Amount: + Montant : + &Label: &Étiquette : + + &Message: + Message : + Copy label Copier l'étiquette @@ -427,6 +435,10 @@ Send Coins Envoyer des pièces + + Insufficient funds! + Fonds insuffisants + Amount: Montant : @@ -494,6 +506,10 @@ Message: Message : + + Pay To: + Payer à : + ShutdownWindow @@ -520,6 +536,10 @@ Enter the message you want to sign here Entrez ici le message que vous désirez signer + + Sign &Message + &Signer le message + SplashScreen diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 0b0800e74..96d4adeba 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -261,6 +261,10 @@ &Change Passphrase... &Cambiar contrasinal... + + &Receiving addresses... + Direccións para recibir + Importing blocks from disk... Importando bloques de disco... @@ -369,6 +373,10 @@ Open a bitcoin: URI or payment request Abrir un bitcoin: URI ou solicitude de pago + + &Command-line options + Opcións da liña de comandos + No block source available... Non hai orixe de bloques dispoñible... @@ -696,7 +704,7 @@ command-line options opcións da liña de comandos - + Intro @@ -765,6 +773,10 @@ &Network &Rede + + W&allet + Moedeiro + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Abrir automáticamente o porto do cliente Bitcoin no router. Esto so funciona se o teu router soporta UPnP e está habilitado. @@ -967,6 +979,10 @@ &Information &Información + + Debug window + Ventana de Depuración + Using OpenSSL version Usar versión OpenSSL @@ -1187,6 +1203,10 @@ Send Coins Moedas Enviadas + + Insufficient funds! + Fondos insuficientes + Quantity: Cantidade: @@ -1211,6 +1231,10 @@ Change: Cambiar: + + Transaction Fee: + Tarifa de transacción: + Send to multiple recipients at once Enviar a múltiples receptores á vez @@ -1350,6 +1374,10 @@ Remove this entry Eliminar esta entrada + + Message: + Mensaxe: + Enter a label for this address to add it to the list of used addresses Introduce unha etiqueta para esta dirección para engadila á listaxe de direccións empregadas @@ -2041,10 +2069,18 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe) + + Cannot resolve -whitebind address: '%s' + Non se pode resolver dirección -whitebind: '%s' + Information Información + + Invalid amount for -maxtxfee=<amount>: '%s' + Cantidade inválida para -maxtxfee=<cantidade>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Cantidade inválida para -minrelaytxfee=<cantidade>: '%s' diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 7db2a9dd3..926d20620 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -417,6 +417,10 @@ %1 and %2 %1 ו%2 + + %1 behind + %1 מאחור + Last received block was generated %1 ago. המקטע האחרון שהתקבל נוצר לפני %1. @@ -623,6 +627,10 @@ lowest הנמוך ביותר + + (%1 locked) + (%1 נעול) + none ללא @@ -772,7 +780,7 @@ command-line options אפשרויות שורת פקודה - + Intro @@ -1659,6 +1667,10 @@ Custom change address כתובת לעודף מותאמת אישית + + Transaction Fee: + עמלת העברה: + Send to multiple recipients at once שליחה למספר מוטבים בו־זמנית @@ -2653,6 +2665,10 @@ Initialization sanity check failed. Bitcoin Core is shutting down. בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת. + + Invalid amount for -maxtxfee=<amount>: '%s' + כמות לא תקינה עבור -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' כמות לא תקינה עבור -paytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index fbdaf1ba7..377ff3a3f 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -334,6 +334,10 @@ Options विकल्प + + W&allet + वॉलेट + &OK &ओके @@ -385,6 +389,10 @@ ReceiveCoinsDialog + + &Amount: + राशि : + &Label: लेबल: @@ -400,6 +408,10 @@ ReceiveRequestDialog + + Copy &Address + &पता कॉपी करे + Address पता @@ -501,6 +513,10 @@ Alt+P Alt-P + + Pay To: + प्राप्तकर्ता: + ShutdownWindow diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index 624cbbbc2..413dc2185 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -774,7 +774,7 @@ command-line options opcije programa u naredbenoj liniji - + Intro @@ -1013,6 +1013,10 @@ &Information &Informacije + + Debug window + Konzola za dijagnostiku + Using OpenSSL version OpenSSL verzija u upotrebi @@ -1213,6 +1217,10 @@ Send Coins Slanje novca + + Insufficient funds! + Nedovoljna sredstva + Quantity: Količina: @@ -1237,6 +1245,10 @@ Change: Vraćeno: + + Transaction Fee: + Naknada za transakciju: + Send to multiple recipients at once Pošalji novce većem broju primatelja u jednoj transakciji @@ -1366,6 +1378,10 @@ Signature Potpis + + Sign &Message + &Potpišite poruku + Clear &All Obriši &sve @@ -1374,6 +1390,10 @@ &Verify Message &Potvrdite poruku + + Verify &Message + &Potvrdite poruku + Wallet unlock was cancelled. Otključavanje novčanika je otkazano. @@ -1779,6 +1799,18 @@ Information Informacija + + Invalid amount for -maxtxfee=<amount>: '%s' + Nevaljali iznos za opciju -maxtxfee=<iznos>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Nevaljali iznos za opciju -minrelaytxfee=<iznos>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Nevaljali iznos za opciju -mintxfee=<iznos>: '%s' + Send trace/debug info to console instead of debug.log file Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 9825a2854..ab4517ccf 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -866,7 +866,7 @@ command-line options parancssoros opciók - + Intro @@ -1011,6 +1011,18 @@ Port of the proxy (e.g. 9050) Proxy portja (pl.: 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &Ablak @@ -1277,6 +1289,10 @@ Current number of blocks Aktuális blokkok száma + + Memory usage + Memóriahasználat + Received Fogadott @@ -1365,6 +1381,22 @@ Clear console Konzol törlése + + 1 &hour + 1 &óra + + + 1 &day + 1 &nap + + + 1 &week + 1 &hét + + + 1 &year + 1 &év + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt. @@ -1621,6 +1653,14 @@ Hide Elrejtés + + Recommended: + Ajánlott: + + + Custom: + Egyéni: + normal normál @@ -1773,6 +1813,10 @@ Message: Üzenet: + + Pay To: + Címzett: + Memo: Jegyzet: @@ -1843,6 +1887,10 @@ &Verify Message Üzenet ellenőrzése + + Verify &Message + Üzenet ellenőrzése + The entered address is invalid. A megadott cím nem érvényes. @@ -2185,6 +2233,10 @@ Show transaction details Tranzakciós részletek megjelenítése + + Watch-only + Csak megfigyelés + Exporting Failed Az exportálás sikertelen volt @@ -2372,6 +2424,10 @@ You need to rebuild the database using -reindex to change -txindex Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex). + + Cannot resolve -whitebind address: '%s' + Külső cím (-whitebind address) feloldása nem sikerült: '%s' + Copyright (C) 2009-%i The Bitcoin Core Developers Copyright (C) 2009-%i A Bitcoin Core Fejlesztői @@ -2384,6 +2440,10 @@ Information Információ + + Invalid amount for -maxtxfee=<amount>: '%s' + Érvénytelen -maxtxfee=<amount>: '%s' összeg + Invalid amount for -minrelaytxfee=<amount>: '%s' Érvénytelen -minrelaytxfee=<amount>: '%s' összeg diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 4124ef095..1b626fbf2 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -253,6 +253,10 @@ &Options... &Pilihan... + + &Encrypt Wallet... + &Enkripsi Dompet... + &Backup Wallet... &Cadangkan Dompet... @@ -794,6 +798,10 @@ About Bitcoin Core Mengenai Bitcoin Core + + Command-line options + pilihan Perintah-baris + Usage: Penggunaan: @@ -802,7 +810,7 @@ command-line options pilihan perintah-baris - + Intro @@ -1555,6 +1563,10 @@ Custom change address Alamat uang kembali yang kustom + + Transaction Fee: + Biaya Transaksi: + Recommended: Disarankan @@ -1583,6 +1595,10 @@ Clear all fields of the form. Hapus informasi dari form. + + Clear &All + Hapus &Semua + Balance: Saldo: @@ -1804,6 +1820,10 @@ Reset all sign message fields Hapus semua bidang penanda pesan + + Clear &All + Hapus &Semua + &Verify Message &Verifikasi Pesan @@ -2453,6 +2473,10 @@ Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Tidak bisa mengunci data directory %s. Kemungkinan Bitcoin Core sudah mulai. + + Cannot resolve -whitebind address: '%s' + Tidak dapat menyelesaikan alamat -whitebind: '%s' + Connect through SOCKS5 proxy Hubungkan melalui proxy SOCKS5 @@ -2461,6 +2485,10 @@ Information Informasi + + Invalid amount for -maxtxfee=<amount>: '%s' + Nilai salah untuk -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Nilai yang salah untuk -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 5ec6e480b..d510b1063 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Bannato fino a + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options opzioni della riga di comando + + UI Options: + Opzioni interfaccia: + + + Choose data directory on startup (default: %u) + Seleziona la directory dei dati all'avvio (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Imposta la lingua, ad esempio "it_IT" (default: locale di sistema) + + + Start minimized + Avvia ridotto a icona + + + Set SSL root certificates for payment request (default: -system-) + Imposta un certificato SSL root per le richieste di pagamento (default: -system-) + + + Show splash screen on startup (default: %u) + Mostra schermata iniziale all'avvio (default: %u) + + + Reset all settings changes made over the GUI + Reset di tutte le modifiche alle impostazioni eseguite da interfaccia grafica + Intro @@ -913,7 +949,11 @@ Error Errore - + + (of %n GB needed) + (di %nGB richiesti)(%n GB richiesti) + + OpenURIDialog @@ -1064,6 +1104,34 @@ Per specificare più URL separarli con una barra verticale "|". Port of the proxy (e.g. 9050) Porta del proxy (ad es. 9050) + + Used for reaching peers via: + Utilizzata per connettersi attraverso: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra se la proxy SOCKS5 fornita viene utilizzata per raggiungere i peers attraverso questo tipo di rete. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Connette alla rete Bitcoin attraverso un proxy SOCKS5 separato per Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usa un proxy SOCKS5 separato per connettersi ai peers attraverso Tor: + &Window &Finestra @@ -1434,6 +1502,18 @@ Per specificare più URL separarli con una barra verticale "|". Current number of blocks Numero attuale di blocchi + + Memory Pool + Memory Pool + + + Current number of transactions + Numero attuale di transazioni + + + Memory usage + Utilizzo memoria + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Apre il file log di debug di Bitcoin Core dalla cartella dati attuale. Questa azione può richiedere alcuni secondi per file log di grandi dimensioni. @@ -1450,10 +1530,18 @@ Per specificare più URL separarli con una barra verticale "|". &Peers &Peer + + Banned peers + Peers bannati + Select a peer to view detailed information. Seleziona un peer per visualizzare informazioni più dettagliate. + + Whitelisted + Whitelisted/sicuri + Direction Direzione @@ -1462,6 +1550,18 @@ Per specificare più URL separarli con una barra verticale "|". Version Versione + + Starting Block + Blocco di partenza + + + Synced Headers + Headers sincronizzati + + + Synced Blocks + Blocchi sincronizzati + User Agent User Agent @@ -1490,6 +1590,14 @@ Per specificare più URL separarli con una barra verticale "|". Ping Time Tempo di Ping + + The duration of a currently outstanding ping. + La durata di un ping attualmente in corso. + + + Ping Wait + Attesa ping + Time Offset Scarto Temporale @@ -1538,6 +1646,34 @@ Per specificare più URL separarli con una barra verticale "|". Clear console Cancella console + + &Disconnect Node + &Nodo Disconnesso + + + Ban Node for + Nodo Bannato perché + + + 1 &hour + 1 &ora + + + 1 &day + 1 &giorno + + + 1 &week + 1 &settimana + + + 1 &year + 1 &anno + + + &Unban Node + &Elimina Ban Nodo + Welcome to the Bitcoin Core RPC console. Benvenuto nella console RPC di Bitcoin Core. @@ -1566,6 +1702,10 @@ Per specificare più URL separarli con una barra verticale "|". %1 GB %1 GB + + (node id: %1) + (id nodo: %1) + via %1 via %1 @@ -1958,6 +2098,10 @@ Per specificare più URL separarli con una barra verticale "|". Copy change Copia resto + + Total Amount %1 + Ammontare Totale %1 + or o @@ -1990,6 +2134,14 @@ Per specificare più URL separarli con una barra verticale "|". Payment request expired. Richiesta di pagamento scaduta. + + Pay only the required fee of %1 + Paga solamente la commissione richiesta di %1 + + + Estimated to begin confirmation within %n block(s). + Inizio delle conferme stimato entro %n blocco.Inizio delle conferme stimato entro %n blocchi. + The recipient address is not valid. Please recheck. L'indirizzo del beneficiario non è valido. Si prega di ricontrollare. @@ -2621,6 +2773,10 @@ Per specificare più URL separarli con una barra verticale "|". Copy transaction ID Copia l'ID transazione + + Copy raw transaction + Copia la transazione raw + Edit label Modifica l'etichetta @@ -2768,14 +2924,54 @@ Per specificare più URL separarli con una barra verticale "|". Accept command line and JSON-RPC commands Accetta comandi da riga di comando e JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Se <category> non è specificato oppure se <category> = 1, mostra tutte le informazioni di debug. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Totale massimo di commissioni (in %s) da usare in una singola transazione del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Per favore controllate che la data del computer e l'ora siano corrette. Se il vostro orologio è sbagliato Bitcoin non funzionerà correttamente. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune: l'ultima sincronizzazione del wallet risulta essere oltre la riduzione dei dati. È necessario eseguire un -reindex (scaricare nuovamente la blockchain in caso di nodo pruned) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità è incompatibile con l'opzione -txindex e -rescan. Attenzione: ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (default: 0 = disabilita il pruning, >%u = dimensione desiderata in MiB per i file dei blocchi) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Non è possibile un Rescan in modalità pruned. Sarà necessario utilizzare -reindex che farà scaricare nuovamente tutta la blockchain. + Error: A fatal internal error occurred, see debug.log for details Errore: si è presentato un errore interno fatale, consulta il file debug.log per maggiori dettagli + + Fee (in %s/kB) to add to transactions you send (default: %s) + Commissione (in %s/kB) da aggiungere alle transazioni inviate (default: %s) + + + Pruning blockstore... + Pruning del blockstore... + Run in the background as a daemon and accept commands Esegui in background come demone ed accetta i comandi + + Unable to start HTTP server. See debug log for details. + Impossibile avviare il server HTTP. Dettagli nel log di debug. + Accept connections from outside (default: 1 if no -proxy or -connect) Accetta connessioni dall'esterno (predefinito: 1 se -proxy o -connect non sono utilizzati) @@ -2800,6 +2996,10 @@ Per specificare più URL separarli con una barra verticale "|". Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, <0 = lascia questo numero di core liberi, predefinito: %d) + + 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 + Il database dei blocchi contiene un blocco che sembra provenire dal futuro. Questo può essere dovuto alla data e ora del tuo computer impostate in modo scorretto. Ricostruisci il database dei blocchi se sei certo che la data e l'ora sul tuo computer siano corrette + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio @@ -2808,6 +3008,10 @@ Per specificare più URL separarli con una barra verticale "|". Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti) @@ -2832,6 +3036,10 @@ Per specificare più URL separarli con una barra verticale "|". Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte. + + -maxmempool must be at least %d MB + -maxmempool deve essere almeno %d MB + <category> can be: Valori possibili per <category>: @@ -2864,6 +3072,22 @@ Per specificare più URL separarli con una barra verticale "|". Do you want to rebuild the block database now? Vuoi ricostruire ora il database dei blocchi? + + Enable publish hash block in <address> + Abilita pubblicazione hash blocco in <address> + + + Enable publish hash transaction in <address> + Abilità pubblicazione hash transazione in <address> + + + Enable publish raw block in <address> + Abilita pubblicazione blocchi raw in <address> + + + Enable publish raw transaction in <address> + Abilita pubblicazione transazione raw in <address> + Error initializing block database Errore durante l'inizializzazione del database dei blocchi @@ -2900,6 +3124,10 @@ Per specificare più URL separarli con una barra verticale "|". Invalid -onion address: '%s' Indirizzo -onion non valido: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + Mantieni la memory pool delle transazioni al di sotto di <n> megabytes (default: %u) + Not enough file descriptors available. Non ci sono abbastanza descrittori di file disponibili. @@ -2928,10 +3156,26 @@ Per specificare più URL separarli con una barra verticale "|". Specify wallet file (within data directory) Specifica il file del portamonete (all'interno della cartella dati) + + Unsupported argument -benchmark ignored, use -debug=bench. + Ignorata opzione -benchmark non supportata, utilizzare -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argomento -debugnet ignorato in quanto non supportato, usare -debug=net. + + + Unsupported argument -tor found, use -onion. + Rilevato argomento -tor non supportato, utilizzare -onion. + Use UPnP to map the listening port (default: %u) Usa UPnP per mappare la porta di ascolto (predefinito: %u) + + User Agent comment (%s) contains unsafe characters. + Il commento del User Agent (%s) contiene caratteri non sicuri. + Verifying blocks... Verifica blocchi... @@ -2988,6 +3232,10 @@ Per specificare più URL separarli con una barra verticale "|". Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Esegue un comando in caso di ricezione di un allarme pertinente o se si rileva un fork molto lungo (%s in cmd è sostituito dal messaggio) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per trasmissione, mining e creazione della transazione (default: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Nel caso in cui paytxfee non sia impostato, include una commissione tale da ottenere un avvio delle conferme entro una media di n blocchi (predefinito: %u) @@ -3044,6 +3292,18 @@ Per specificare più URL separarli con una barra verticale "|". Activating best chain... Attivazione della blockchain migliore... + + Always relay transactions received from whitelisted peers (default: %d) + Trasmetti sempre le transazioni ricevute da peers whitelisted (default: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Prova a recuperare le chiavi private da un wallet corrotto all'avvio + + + Automatically create Tor hidden service (default: %d) + Crea automaticamente il servizio Tor (default: %d) + Cannot resolve -whitebind address: '%s' Impossibile risolvere indirizzo -whitebind: '%s' @@ -3064,6 +3324,10 @@ Per specificare più URL separarli con una barra verticale "|". Error reading from database, shutting down. Errore durante lalettura del database. Arresto in corso. + + Imports blocks from external blk000??.dat file on startup + Importa blocchi da un file blk000??.dat esterno all'avvio + Information Informazioni @@ -3116,6 +3380,14 @@ Per specificare più URL separarli con una barra verticale "|". Receive and display P2P network alerts (default: %u) Ricevi e visualizza gli alerts della rete P2P (default: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Riduzione -maxconnections da %d a %d a causa di limitazioni di sistema. + + + Rescan the block chain for missing wallet transactions on startup + Ripete la scansione della block chain per individuare le transazioni che mancano dal wallet all'avvio + Send trace/debug info to console instead of debug.log file Invia le informazioni di trace/debug alla console invece che al file debug.log @@ -3144,6 +3416,14 @@ Per specificare più URL separarli con una barra verticale "|". This is experimental software. Questo è un software sperimentale. + + Tor control port password (default: empty) + Password porta controllo Tor (default: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Porta di controllo Tor da usare se in ascolto su onion (default: %s) + Transaction amount too small Importo transazione troppo piccolo @@ -3164,6 +3444,10 @@ Per specificare più URL separarli con una barra verticale "|". Unable to bind to %s on this computer (bind returned error %s) Impossibile associarsi a %s su questo computer (l'associazione ha restituito l'errore %s) + + Upgrade wallet to latest format on startup + Aggiorna il wallet all'ultimo formato all'avvio + Username for JSON-RPC connections Nome utente per connessioni JSON-RPC @@ -3176,10 +3460,18 @@ Per specificare più URL separarli con una barra verticale "|". Warning Attenzione + + Whether to operate in a blocks only mode (default: %u) + Imposta se operare in modalità solo blocchi (default: %u) + Zapping all transactions from wallet... Eliminazione dal portamonete di tutte le transazioni... + + ZeroMQ notification options: + Opzioni di notifica ZeroMQ + wallet.dat corrupt, salvage failed wallet.dat corrotto, recupero fallito @@ -3212,6 +3504,26 @@ Per specificare più URL separarli con una barra verticale "|". (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee è impostato molto alto! Commissioni così alte possono venir pagate anche su una singola transazione. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Non mantenere le transazioni nella mempool più a lungo di <n> ore (default: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per la creazione della transazione (default: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u) @@ -3228,10 +3540,30 @@ Per specificare più URL separarli con una barra verticale "|". Output debugging information (default: %u, supplying <category> is optional) Emette informazioni di debug (predefinito: %u, fornire <category> è opzionale) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Supporta filtraggio di blocchi e transazioni con filtri bloom (default: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + La lunghezza totale della stringa di network version (%i) eccede la lunghezza massima (%i). Ridurre il numero o la dimensione di uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Cerca di mantenere il traffico in uscita al di sotto della soglia scelta (in MiB ogni 24h), 0 = nessun limite (default: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Username e hash password per connessioni JSON-RPC. Il campo <userpw> utilizza il formato: <USERNAME>:<SALT>$<HASH>. Uno script python standard è incluso in share/rpcuser. Questa opzione può essere specificata più volte + (default: %s) (predefinito: %s) diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 37306da5a..4344fd043 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -882,6 +882,34 @@ command-line options コマンドライン オプション + + UI Options: + UIオプション: + + + Choose data directory on startup (default: %u) + 起動時にデータ ディレクトリを選ぶ (初期値: %u) + + + Set language, for example "de_DE" (default: system locale) + 言語設定 例: "de_DE" (初期値: システムの言語) + + + Start minimized + 最小化された状態で起動する + + + Set SSL root certificates for payment request (default: -system-) + 支払いリクエスト用にSSLルート証明書を設定する (デフォルト:-system-) + + + Show splash screen on startup (default: %u) + 起動時にスプラッシュ画面を表示する (初期値: %u) + + + Reset all settings changes made over the GUI + GUI 経由で行われた設定の変更を全てリセット + Intro @@ -1477,6 +1505,18 @@ Current number of blocks 現在のブロック数 + + Memory Pool + メモリ・プール + + + Current number of transactions + 現在のトランザクション数 + + + Memory usage + メモリ使用量 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。 @@ -3484,6 +3524,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. wallet.dat の読み込みエラー! すべてのキーは正しく読み取れますが、取引データやアドレス帳のエントリが失われたか、正しくない可能性があります。 + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + トランザクション作成の際、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) -checkblocks のブロックの検証レベル (0-4, 初期値: %u) @@ -3500,6 +3544,10 @@ Output debugging information (default: %u, supplying <category> is optional) デバッグ情報を出力する (初期値: %u, <category> の指定は任意です) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Bloomフィルタによる、ブロックおよびトランザクションのフィルタリングを有効化する (初期値: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. ネットワークバージョン文字 (%i) の長さが最大の長さ (%i) を超えています。UAコメントの数や長さを削減してください。 @@ -3516,6 +3564,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Tor 秘匿サービスを通し、別々の SOCKS5 プロキシを用いることでピアに到達する (初期値: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC接続時のユーザ名とハッシュ化されたパスワード。<userpw> フィールドのフォーマットは <USERNAME>:<SALT>$<HASH>。標準的な Python スクリプトが share/rpcuser 内に含まれています。このオプションは複数回指定できます。 + (default: %s) (デフォルト: %s) diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 68666cfb2..11c73ec76 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -748,7 +748,7 @@ command-line options კომანდების ზოლის ოპციები - + Intro @@ -763,6 +763,10 @@ As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. ეს პროგრამის პირველი გაშვებაა; შეგიძლიათ მიუთითოთ, სად შეინახოს მონაცემები Bitcoin Core-მ. + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Bitcoin Core გადმოტვირთავს და შეინახავს Bitcoin-ის ბლოკთა ჯაჭვს. მითითებულ კატალოგში დაგროვდება სულ ცოტა %1 გბ მონაცემები, და მომავალში უფრო გაიზრდება. საფულეც ამავე კატალოგში შეინახება. + Use the default data directory ნაგულისხმევი კატალოგის გამოყენება @@ -1431,6 +1435,10 @@ Custom change address ხურდის მისამართი + + Transaction Fee: + ტრანსაქციის საფასური - საკომისიო: + Send to multiple recipients at once გაგზავნა რამდენიმე რეციპიენტთან ერთდროულად @@ -1507,6 +1515,10 @@ The amount exceeds your balance. თანხა აღემატება თქვენს ბალანსს + + The total exceeds your balance when the %1 transaction fee is included. + საკომისიო %1-ის დამატების შემდეგ თანხა აჭარბებს თქვენს ბალანსს + Transaction creation failed! შეცდომა ტრანსაქციის შექმნისას! @@ -2325,10 +2337,18 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d) + + Cannot resolve -whitebind address: '%s' + ვერ ხერხდება -whitebind მისამართის გარკვევა: '%s' + Information ინფორმაცია + + Invalid amount for -maxtxfee=<amount>: '%s' + დაუშვებელი მნიშვნელობა -pmaxtxfee<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' დაუშვებელი მნიშვნელობა -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index 4de8f1b57..cfa19d13f 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -230,6 +230,10 @@ EditAddressDialog + + &Label + таңба + &Address Адрес @@ -253,6 +257,10 @@ OptionsDialog + + W&allet + Әмиян + OverviewPage @@ -275,9 +283,17 @@ RPCConsole + + &Information + Информация + ReceiveCoinsDialog + + &Amount: + Саны + ReceiveRequestDialog @@ -342,6 +358,10 @@ SendCoinsEntry + + A&mount: + Саны + ShutdownWindow diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 81677b473..ce48ce249 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -810,7 +810,7 @@ command-line options 명령줄 옵션 - + Intro @@ -1175,6 +1175,14 @@ Enter a Bitcoin address (e.g. %1) 비트코인 주소를 입력하기 (예. %1) + + %1 h + %1 시간 + + + %1 m + %1 분 + %1 s %1 초 @@ -1333,6 +1341,22 @@ Type <b>help</b> for an overview of available commands. 사용할 수 있는 명령을 둘러보려면 <b>help</b>를 입력하십시오. + + %1 B + %1 바이트 + + + %1 KB + %1 킬로바이트 + + + %1 MB + %1 메가바이트 + + + %1 GB + %1 기가바이트 + ReceiveCoinsDialog @@ -2200,6 +2224,10 @@ Export Transaction History 거래 기록 내보내기 + + Watch-only + 모니터링 지갑 + Exporting Failed 내보내기 실패 @@ -2391,6 +2419,10 @@ Error initializing block database 블록 데이터베이스를 초기화하는데 오류 + + Error initializing wallet database environment %s! + 지갑 데이터베이스 환경 초기화하는데 오류 %s + Error loading block database 블록 데이터베이스를 불러오는데 오류 @@ -2467,10 +2499,18 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d) + + Cannot resolve -whitebind address: '%s' + -whitebind 주소를 확인할 수 없습니다: '%s' + Information 정보 + + Invalid amount for -maxtxfee=<amount>: '%s' + -maxtxfee=<amount>에 대한 양이 잘못되었습니다: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' 노드로 전달하기 위한 최저 거래 수수료가 부족합니다. - minrelaytxfee=<amount>: '%s' - diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 495f11b1f..51efd519c 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -125,6 +125,10 @@ &Network &Тармак + + W&allet + Капчык + &Port: &Порт: @@ -175,6 +179,10 @@ General Жалпы + + Network + &Тармак + Name Аты @@ -194,6 +202,10 @@ ReceiveCoinsDialog + + &Message: + Билдирүү: + ReceiveRequestDialog diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index f77500205..e3dcd505f 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -305,6 +305,10 @@ Bitcoin Core Bitcoin Nucleus + + &Command-line options + Optiones mandati initiantis + No block source available... Nulla fons frustorum absens... @@ -476,7 +480,7 @@ command-line options Optiones mandati intiantis - + Intro @@ -513,6 +517,10 @@ &Network &Rete + + W&allet + Cassidile + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Aperi per se portam clientis Bitcoin in itineratore. Hoc tantum effectivum est si itineratrum tuum supportat UPnP et id activum est. @@ -655,6 +663,10 @@ &Information &Informatio + + Debug window + Fenestra Debug + Using OpenSSL version Utens OpenSSL versione @@ -714,10 +726,18 @@ ReceiveCoinsDialog + + &Amount: + Quantitas: + &Label: &Titulus: + + &Message: + Nuntius: + Copy label Copia titulum @@ -729,6 +749,10 @@ ReceiveRequestDialog + + Copy &Address + &Copia Inscriptionem + Address Inscriptio @@ -783,10 +807,18 @@ Send Coins Mitte Nummos + + Insufficient funds! + Inopia nummorum + Amount: Quantitas: + + Transaction Fee: + Transactionis merces: + Send to multiple recipients at once Mitte pluribus accipientibus simul @@ -870,6 +902,10 @@ Message: Nuntius: + + Pay To: + Pensa Ad: + ShutdownWindow @@ -1461,10 +1497,18 @@ Verifying wallet... Verificante cassidilem... + + Cannot resolve -whitebind address: '%s' + Non posse resolvere -whitebind inscriptionem: '%s' + Information Informatio + + Invalid amount for -maxtxfee=<amount>: '%s' + Quantitas non valida pro -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Quantitas non valida pro -minrelaytxfee=<amount>: '%s' diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index c125d1b72..b98976dfe 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -190,7 +190,11 @@ BanTableModel - + + Banned Until + Užblokuotas iki + + BitcoinGUI @@ -357,6 +361,10 @@ &About Bitcoin Core &Apie Bitcoin Core + + &Command-line options + Komandinės eilutės parametrai + Error Klaida @@ -551,7 +559,11 @@ (no label) (nėra žymės) - + + (change) + (Graža) + + EditAddressDialog @@ -632,7 +644,7 @@ command-line options komandinės eilutės parametrai - + Intro @@ -665,10 +677,26 @@ &Main &Pagrindinės + + MB + MB + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Proxy IP adresas (Pvz. IPv4: 127.0.0.1 / IPv6: ::1) + + + &Reset Options + &Atstatyti Parinktis + &Network &Tinklas + + W&allet + Piniginė + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Automatiškai atidaryti Bitcoin kliento prievadą maršrutizatoriuje. Tai veikia tik tada, kai jūsų maršrutizatorius palaiko UPnP ir ji įjungta. @@ -689,6 +717,18 @@ Port of the proxy (e.g. 9050) Tarpinio serverio preivadas (pvz, 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &Langas @@ -741,6 +781,14 @@ Confirm options reset Patvirtinti nustatymų atstatymą + + Client restart required to activate changes. + Kliento perkrovimas reikalingas nustatymų aktyvavimui + + + This change would require a client restart. + Šis pakeitimas reikalautų kliento perkrovimo + The supplied proxy address is invalid. Nurodytas tarpinio serverio adresas negalioja. @@ -756,6 +804,10 @@ Available: Galimi: + + Your current spendable balance + Jūsų dabartinis išleidžiamas balansas + Pending: Laukiantys: @@ -779,10 +831,18 @@ URI handling URI apdorojimas + + Invalid payment address %1 + Neteisingas mokėjimo adresas %1 + Payment request rejected Mokėjimo siuntimas atmestas + + Payment request expired. + Mokėjimo siuntimas pasibaigė + Network request error Tinklo užklausos klaida @@ -812,11 +872,19 @@ QRImageWidget + + &Copy Image + Kopijuoti nuotrauką + Save QR Code Įrašyti QR kodą - + + PNG Image (*.png) + PNG paveikslėlis (*.png) + + RPCConsole @@ -835,6 +903,10 @@ &Information &Informacija + + Debug window + Derinimo langas + Using OpenSSL version Naudojama OpenSSL versija @@ -847,6 +919,10 @@ Network Tinklas + + Name + Pavadinimas + Number of connections Prisijungimų kiekis @@ -883,6 +959,10 @@ &Console &Konsolė + + &Clear + Išvalyti + Totals Viso: @@ -919,13 +999,29 @@ never Niekada + + Yes + Taip + + + No + Ne + ReceiveCoinsDialog + + &Amount: + Suma: + &Label: Ž&ymė: + + &Message: + Žinutė: + Clear Išvalyti @@ -945,6 +1041,10 @@ QR Code QR kodas + + Copy &Address + &Kopijuoti adresą + Payment information Mokėjimo informacija @@ -999,6 +1099,10 @@ Send Coins Siųsti monetas + + Insufficient funds! + Nepakanka lėšų + Quantity: Kiekis: @@ -1027,6 +1131,10 @@ Change: Graža: + + Transaction Fee: + Sandorio mokestis: + Send to multiple recipients at once Siųsti keliems gavėjams vienu metu @@ -1091,6 +1199,10 @@ The total exceeds your balance when the %1 transaction fee is included. Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą. + + Payment request expired. + Mokėjimo siuntimas pasibaigė + (no label) (nėra žymės) @@ -1130,6 +1242,10 @@ Message: Žinutė: + + Pay To: + Mokėti gavėjui: + ShutdownWindow @@ -1176,6 +1292,10 @@ Verify the message to ensure it was signed with the specified Bitcoin address Patikrinkite žinutę, jog įsitikintumėte, kad ją pasirašė nurodytas Bitcoin adresas + + Verify &Message + &Patikrinti žinutę + Click "Sign Message" to generate signature Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą @@ -1629,6 +1749,18 @@ Information Informacija + + Invalid amount for -maxtxfee=<amount>: '%s' + Neteisinga suma -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Neteisinga suma -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Neteisinga suma -mintxfee=<amount>: '%s' + Send trace/debug info to console instead of debug.log file Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 2d3eab339..e01d4c812 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -720,6 +720,10 @@ About Bitcoin Core Par Bitcoin Core + + Command-line options + Komandrindas iespējas + Usage: Lietojums: @@ -728,7 +732,7 @@ command-line options komandrindas izvēles - + Intro @@ -1375,6 +1379,10 @@ Custom change address Pielāgota atlikuma adrese + + Transaction Fee: + Transakcijas maksa: + Send to multiple recipients at once Sūtīt vairākiem saņēmējiem uzreiz @@ -2157,10 +2165,26 @@ Wallet options: Maciņa iespējas: + + Cannot resolve -whitebind address: '%s' + Nevar atrisināt -whitebind adresi: '%s' + Information Informācija + + Invalid amount for -maxtxfee=<amount>: '%s' + Nederīgs daudzums priekš -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Nederīgs daudzums priekš -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Nederīgs daudzums priekš -mintxfee=<amount>: '%s' + RPC server options: RPC servera iestatījumi: diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts index 269b06f83..b7797063b 100644 --- a/src/qt/locale/bitcoin_mk_MK.ts +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -912,10 +912,18 @@ SendCoinsEntry + + A&mount: + Сума: + &Label: &Етикета: + + Message: + Порака: + ShutdownWindow @@ -1015,6 +1023,10 @@ bitcoin-core + + Options: + Опции: + Warning Предупредување diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index d1a597622..b79001006 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -233,6 +233,10 @@ &Change Passphrase... &Нууц Үгийг Солих... + + &Receiving addresses... + Хүлээн авах хаяг + Change the passphrase used for wallet encryption Түрүйвчийг цоожлох нууц үгийг солих @@ -269,6 +273,10 @@ Error Алдаа + + Information + Мэдээллэл + Up to date Шинэчлэгдсэн @@ -421,6 +429,14 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) проксигийн IP хаяг (жишээ нь: IPv4: 127.0.0.1 / IPv6: ::1) + + &Network + Сүлжээ + + + W&allet + Түрүйвч + Client restart required to activate changes. Ѳѳрчлѳлтүүдийг идэвхижүүлхийн тулд клиентийг ахин эхлүүлэх шаардлагтай @@ -522,10 +538,18 @@ ReceiveCoinsDialog + + &Amount: + Хэмжээ: + &Label: &Шошго: + + &Message: + Зурвас: + Show Харуул @@ -553,6 +577,10 @@ ReceiveRequestDialog + + Copy &Address + Хаягийг &Хуулбарлах + Address Хаяг @@ -714,6 +742,10 @@ Message: Зурвас: + + Pay To: + Тѳлѳх хаяг: + ShutdownWindow @@ -1033,6 +1065,10 @@ Wallet options: Түрүйвчийн сонголтууд: + + Information + Мэдээллэл + Loading addresses... Хаягуудыг ачааллаж байна... diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index 8f6676e48..df98dd839 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -121,6 +121,10 @@ ReceiveRequestDialog + + Copy &Address + &Salin Alamat + Address Alamat diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 554ac21a0..9236ac86f 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -882,6 +882,34 @@ command-line options kommandolinjevalg + + UI Options: + Grensesnittvalg: + + + Choose data directory on startup (default: %u) + Velg datakatalog for oppstart (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Sett språk, for eksempel "nb_NO" (default: system-«locale») + + + Start minimized + Begynn minimert + + + Set SSL root certificates for payment request (default: -system-) + Sett SSL-rootsertifikat for betalingshenvendelser (default: -system-) + + + Show splash screen on startup (default: %u) + Vis velkomstbilde ved oppstart (default: %u) + + + Reset all settings changes made over the GUI + Nullstill alle oppsettendringer gjort via det grafiske grensesnittet + Intro @@ -1477,6 +1505,18 @@ Current number of blocks Nåværende antall blokker + + Memory Pool + Minnepool + + + Current number of transactions + Nåværende antall transaksjoner + + + Memory usage + Minnebruk + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler. @@ -2919,6 +2959,10 @@ Error: A fatal internal error occurred, see debug.log for details Feil: En fatal intern feil oppstod, se debug.log for detaljer + + Fee (in %s/kB) to add to transactions you send (default: %s) + Gebyr (i %s/kB) for å legge til i transaksjoner du sender (standardverdi: %s) + Pruning blockstore... Beskjærer blokklageret... @@ -3479,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Gebyrer (i %s/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u) @@ -3495,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av <category> er valgfritt) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Støtte filtrering av blokker og transaksjoner med bloomfiltre (standardverdi: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Total lengde av nettverks-versionstreng (%i) er over maks lengde (%i). Reduser tallet eller størrelsen av uacomments. @@ -3511,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Brukernavn og hashet passord for JSON-RPC tilkoblinger. Feltet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Et Python-skript er inkludert i share/rpcuser. Dette alternativet kan angis flere ganger + (default: %s) (standardverdi: %s) diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index be2ec9ac4..8457a9ab5 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -59,7 +59,7 @@ Sending addresses - Verstuur adressen + Verstuuradressen Receiving addresses @@ -67,11 +67,11 @@ These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verzendt. + Dit zijn uw Bitcoinadressen om betalingen mee te doen. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verstuurt. These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dit zijn uw Bitcoin-adressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. + Dit zijn uw Bitcoinadressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. Copy &Label @@ -157,7 +157,7 @@ Confirm wallet encryption - Bevestig versleuteling van de portemonnee + Bevestig versleuteling van uw portemonnee Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! @@ -177,7 +177,7 @@ Warning: The Caps Lock key is on! - Waarschuwing: De Caps-Lock-toets staat aan! + Waarschuwing: De Caps Locktoets staat aan! Wallet encrypted @@ -222,6 +222,10 @@ BanTableModel + + IP/Netmask + IP/Netmasker + Banned Until Geband tot @@ -255,11 +259,11 @@ Browse transaction history - Blader door transactieverleden + Blader door transactiegescheidenis E&xit - &Afsluiten + A&fsluiten Quit application @@ -275,7 +279,7 @@ &Options... - O&pties... + &Opties... &Encrypt Wallet... @@ -291,11 +295,11 @@ &Sending addresses... - V&erstuur adressen... + &Verstuuradressen... &Receiving addresses... - O&ntvang adressen... + &Ontvang adressen... Open &URI... @@ -303,7 +307,7 @@ Bitcoin Core client - Bitcoin Kern applicatie + Bitcoin Coreapplicatie Importing blocks from disk... @@ -347,7 +351,7 @@ &Send - &Versturen + &Verstuur &Receive @@ -355,7 +359,7 @@ Show information about Bitcoin Core - Toon informatie over bitcoin kern + Toon informatie over Bitcoin Core &Show / Hide @@ -395,11 +399,11 @@ Bitcoin Core - Bitcoin Kern + Bitcoin Core Request payments (generates QR codes and bitcoin: URIs) - Vraag betaling aan (genereert QR codes en bitcoin: URIs) + Vraag betaling aan (genereert QR-codes en bitcoin: URI's) &About Bitcoin Core @@ -411,7 +415,7 @@ Show the list of used sending addresses and labels - Toon de lijst met gebruikt verzend adressen en labels + Toon de lijst met gebruikte verstuuradressen en -labels Show the list of used receiving addresses and labels @@ -423,15 +427,15 @@ &Command-line options - &Commandoregel-opties + &Opdrachytregelopties Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoin commandoregelopties + Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoinopdrachtregelopties %n active connection(s) to Bitcoin network - %n actieve connectie naar Bitcoin netwerk%n actieve connecties naar Bitcoin netwerk + %n actieve verbinding met Bitcoinnetwerk%n actieve verbindingen met Bitcoinnetwerk No block source available... @@ -439,11 +443,11 @@ Processed %n block(s) of transaction history. - %n blok aan transactie geschiedenis verwerkt.%n blokken aan transactie geschiedenis verwerkt. + %n blok aan transactiegeschiedenis verwerkt.%n blokken aan transactiegeschiedenis verwerkt. %n hour(s) - %n uur%n uur + %n uur%n uren %n day(s) @@ -459,7 +463,7 @@ %n year(s) - %n jaar%n jaar + %n jaar%n jaren %1 behind @@ -525,7 +529,7 @@ Sent transaction - Verzonden transactie + Verstuurde transactie Incoming transaction @@ -571,7 +575,7 @@ Fee: - Vergoeding: + Transactiekosten: Dust: @@ -579,7 +583,7 @@ After Fee: - Na vergoeding: + Naheffing: Change: @@ -655,11 +659,11 @@ Copy fee - Kopieer vergoeding + Kopieerkosten Copy after fee - Kopieer na vergoeding + Kopieernaheffing Copy bytes @@ -747,15 +751,15 @@ This means a fee of at least %1 per kB is required. - Dit betekent dat een vergoeding van minimaal %1 per kB nodig is. + Dit betekent dat kosten van minimaal %1 per kB aan verbonden zijn. Can vary +/- 1 byte per input. - Kan +/- byte per invoer variëren. + Kan +/- 1 byte per invoer variëren. Transactions with higher priority are more likely to get included into a block. - Transacties met een hogere prioriteit zullen eerder in een block gezet worden. + Transacties met een hogere prioriteit zullen eerder in een blok gezet worden. (no label) @@ -786,7 +790,7 @@ The address associated with this address list entry. This can only be modified for sending addresses. - Het adres dat bij dit adres item hoort. Dit kan alleen bewerkt worden voor verstuur adressen. + Het adres dat bij dit adresitem hoort. Dit kan alleen bewerkt worden voor verstuuradressen. &Address @@ -798,7 +802,7 @@ New sending address - Nieuw adres om naar te verzenden + Nieuw adres om naar te versturen Edit receiving address @@ -806,7 +810,7 @@ Edit sending address - Bewerk adres om naar te verzenden + Bewerk adres om naar te versturen The entered address "%1" is already in the address book. @@ -841,7 +845,7 @@ Path already exists, and is not a directory. - Communicatiepad bestaat al, en is geen folder. + Communicatiepad bestaat al, en is geen map. Cannot create data directory here. @@ -852,7 +856,7 @@ HelpMessageDialog Bitcoin Core - Bitcoin Kern + Bitcoin Core version @@ -868,7 +872,7 @@ Command-line options - Commandoregel-opties + Opdrachtregelopties Usage: @@ -876,7 +880,35 @@ command-line options - commandoregel-opties + opdrachtregelopties + + + UI Options: + UI-opties: + + + Choose data directory on startup (default: %u) + Kies gegevensmap bij opstarten (standaard: %u) + + + Set language, for example "de_DE" (default: system locale) + Stel taal in, bijvoorbeeld "nl_NL" (standaard: systeemlocale) + + + Start minimized + Geminimaliseerd starten + + + Set SSL root certificates for payment request (default: -system-) + Zet SSL-rootcertificaat voor betalingsverzoeken (standaard: -systeem-) + + + Show splash screen on startup (default: %u) + Toon opstartscherm bij opstarten (standaard: %u) + + + Reset all settings changes made over the GUI + Reset alle wijzigingen aan instellingen gedaan met de GUI @@ -895,7 +927,7 @@ Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core zal een kopie van de Bitcoin blokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. + Bitcoin Core zal een kopie van de Bitcoinblokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. Use the default data directory @@ -907,7 +939,7 @@ Bitcoin Core - Bitcoin Kern + Bitcoin Core Error: Specified data directory "%1" cannot be created. @@ -919,7 +951,7 @@ %n GB of free space available - %n GB aan vrije oplsagruimte beschikbaar%n GB aan vrije oplsagruimte beschikbaar + %n GB aan vrije opslagruimte beschikbaar%n GB aan vrije opslagruimte beschikbaar (of %n GB needed) @@ -961,7 +993,7 @@ Size of &database cache - Grootte van de &database cache + Grootte van de &databasecache MB @@ -993,7 +1025,7 @@ 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 |. - Derde partijen URL's (bijvoorbeeld block explorer) dat in de transacties tab verschijnen als contextmenu elementen. %s in de URL is vervangen door transactie hash. Verscheidene URL's zijn gescheiden door een verticale streep |. + URL's van derden (bijvoorbeeld block explorer) die in de transacties tab verschijnen als contextmenuelementen. %s in de URL is vervangen door transactiehash. Verscheidene URL's zijn gescheiden door een verticale streep |. Third party transaction URLs @@ -1001,7 +1033,7 @@ Active command-line options that override above options: - Actieve commandoregelopties die bovenstaande opties overschrijven: + Actieve opdrachtregelopties die bovenstaande opties overschrijven: Reset all client options to default. @@ -1017,11 +1049,11 @@ Automatically start Bitcoin Core after logging in to the system. - Bitcoin Kern automatisch starten bij inloggen. + Bitcoin Core automatisch starten bij inloggen. &Start Bitcoin Core on system login - &Start Bitcoin Kern tijdens login. + &Start Bitcoin Core tijdens login. (0 = auto, <0 = leave that many cores free) @@ -1049,7 +1081,7 @@ Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat. + Open de Bitcoinpoort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat. Map port using &UPnP @@ -1057,7 +1089,7 @@ Connect to the Bitcoin network through a SOCKS5 proxy. - Verbind met het Bitcoin netwerk via een SOCKS5 proxy. + Verbind met het Bitcoinnetwerk via een SOCKS5 proxy. &Connect through SOCKS5 proxy (default proxy): @@ -1075,6 +1107,14 @@ Port of the proxy (e.g. 9050) Poort van de proxy (bijv. 9050) + + Used for reaching peers via: + Gebruikt om peers te bereiken via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Vertoningen, als de opgegeven standaard SOCKS5-proxy is gebruikt om peers te benaderen via dit type netwerk. + IPv4 IPv4 @@ -1087,13 +1127,21 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Maak verbinding met Bitcoinnetwerk door een aparte SOCKS5-proxy voor verborgen diensten van Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Gebruikt aparte SOCKS5-proxy om peers te bereiken via verborgen diensten van Tor: + &Window &Scherm Show only a tray icon after minimizing the window. - Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is + Laat alleen een systeemvakicoon zien wanneer het venster geminimaliseerd is &Minimize to the tray instead of the taskbar @@ -1101,7 +1149,7 @@ M&inimize on close - Minimaliseer bij sluiten van het &venster + M&inimaliseer bij sluiten van het venster &Display @@ -1117,7 +1165,7 @@ Choose the default subdivision unit to show in the interface and when sending coins. - Kies de standaard onderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten + Kies de standaardonderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten Whether to show coin control features or not. @@ -1129,7 +1177,7 @@ &Cancel - Ann&uleren + &Annuleren default @@ -1275,7 +1323,7 @@ URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters. + URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoinadres of misvormde URI-parameters. Payment request file handling @@ -1283,7 +1331,7 @@ Payment request file cannot be read! This can be caused by an invalid payment request file. - Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand. + Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand. Payment request expired. @@ -1334,7 +1382,7 @@ Node/Service - Node/Service + Node/Dienst Ping Time @@ -1349,11 +1397,11 @@ Enter a Bitcoin address (e.g. %1) - Voer een Bitcoin-adres in (bijv. %1) + Voer een Bitcoinadres in (bijv. %1) %1 d - %1d + %1 d %1 h @@ -1365,7 +1413,7 @@ %1 s - %1s + %1 s None @@ -1457,9 +1505,21 @@ Current number of blocks Huidig aantal blokken + + Memory Pool + Geheugenpoel + + + Current number of transactions + Huidig aantal transacties + + + Memory usage + Geheugengebruik + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden. + Open het Bitcoin Core debuglogbestand van de huidige gegevensmap. Dit kan enkele seconden duren voor grote logbestanden. Received @@ -1473,10 +1533,18 @@ &Peers &Peers + + Banned peers + Gebande peers + Select a peer to view detailed information. Selecteer een peer om gedetailleerde informatie te bekijken. + + Whitelisted + Toegestaan + Direction Directie @@ -1485,6 +1553,10 @@ Version Versie + + Starting Block + Start Blok + Synced Headers Gesynchroniseerde headers @@ -1499,7 +1571,7 @@ Services - Services + Diensten Ban Score @@ -1525,6 +1597,14 @@ The duration of a currently outstanding ping. De tijdsduur van een op het moment openstaande ping. + + Ping Wait + Pingwachttijd + + + Time Offset + Tijdcompensatie + Last block time Tijd laatste blok @@ -1563,12 +1643,20 @@ Debug log file - Debug-logbestand + Debuglogbestand Clear console Maak console leeg + + &Disconnect Node + &Verbreek Verbinding Node + + + Ban Node for + Ban Node voor + 1 &hour 1 &uur @@ -1585,6 +1673,10 @@ 1 &year 1 &jaar + + &Unban Node + &Maak Ban Ongedaan voor Node + Welcome to the Bitcoin Core RPC console. Welkom op de Bitcoin Core RPC console. @@ -1595,7 +1687,7 @@ Type <b>help</b> for an overview of available commands. - Typ <b>help</b> voor een overzicht van de beschikbare commando's. + Typ <b>help</b> voor een overzicht van de beschikbare opdrachten. %1 B @@ -1613,6 +1705,10 @@ %1 GB %1 Gb + + (node id: %1) + (node id: %1) + via %1 via %1 @@ -1666,7 +1762,7 @@ 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. - Een optioneel bericht om bij te voegen aan het betalingsverzoek, dewelke zal getoond worden wanneer het verzoek is geopend. Opermerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoin netwerk. + Een optioneel bericht om bij te voegen aan het betalingsverzoek, welke zal getoond worden wanneer het verzoek is geopend. Opmerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoinnetwerk. An optional label to associate with the new receiving address. @@ -1815,7 +1911,7 @@ SendCoinsDialog Send Coins - Verstuur munten + Verstuurde munten Coin Control Features @@ -1851,11 +1947,11 @@ Fee: - Vergoeding: + Kosten: After Fee: - Na vergoeding: + Naheffing: Change: @@ -1863,7 +1959,7 @@ If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verzonden naar een nieuw gegenereerd adres. + Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verstuurd naar een nieuw gegenereerd adres. Custom change address @@ -1879,7 +1975,7 @@ collapse fee-settings - Transactiekosteninstellingen verbergen + verberg kosteninstellingen per kilobyte @@ -1915,7 +2011,7 @@ (Smart fee not initialized yet. This usually takes a few blocks...) - (Slimme vergoeding is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...) + (Slimme transactiekosten is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...) Confirmation time: @@ -1931,7 +2027,7 @@ Send as zero-fee transaction if possible - Verstuur als transactie zonder verzendkosten indien mogelijk + Indien mogelijk, verstuur zonder transactiekosten (confirmation may take longer) @@ -1939,7 +2035,7 @@ Send to multiple recipients at once - Verstuur aan verschillende ontvangers ineens + Verstuur in een keer aan verschillende ontvangers Add &Recipient @@ -1967,7 +2063,7 @@ S&end - &Verstuur + V&erstuur Confirm send coins @@ -1987,11 +2083,11 @@ Copy fee - Kopieer vergoeding + Kopieerkosten Copy after fee - Kopieer na vergoeding + Kopieernaheffing Copy bytes @@ -2033,10 +2129,22 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet. + + A fee higher than %1 is considered an absurdly high fee. + Transactiekosten van meer dan %1 wordt beschouwd als een absurd hoge transactiekosten. + Payment request expired. Betalingsverzoek verlopen. + + Pay only the required fee of %1 + Betaal alleen de verplichte transactiekosten van %1 + + + Estimated to begin confirmation within %n block(s). + Schatting is dat bevestiging begint over %n blok.Schatting is dat bevestiging begint over %n blokken. + The recipient address is not valid. Please recheck. Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren.. @@ -2047,7 +2155,7 @@ Warning: Invalid Bitcoin address - Waarschuwing: Ongeldig Bitcoin adres + Waarschuwing: Ongeldig Bitcoinadres (no label) @@ -2063,7 +2171,7 @@ Are you sure you want to send? - Weet u zeker dat u wilt verzenden? + Weet u zeker dat u wilt versturen? added as transaction fee @@ -2074,7 +2182,7 @@ SendCoinsEntry A&mount: - Bedra&g: + B&edrag: Pay &To: @@ -2098,7 +2206,7 @@ The Bitcoin address to send the payment to - Het Bitcoin adres om betaling aan te voldoen + Het Bitcoinadres om betaling aan te versturen Alt+A @@ -2118,11 +2226,11 @@ 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. - De vergoeding zal worden afgetrokken van het bedrag dat verzonden wordt. De ontvangers zullen minder bitcoins ontvangen dan ingevoerd is in het hoeveelheids veld. Als er meerdere ontvangers geselecteerd zijn, dan wordt de vergoeding gelijk verdeeld. + De transactiekosten zal worden afgetrokken van het bedrag dat verstuurd wordt. De ontvangers zullen minder bitcoins ontvangen dan ingevoerd is in het hoeveelheidsveld. Als er meerdere ontvangers geselecteerd zijn, dan worden de transactiekosten gelijk verdeeld. S&ubtract fee from amount - Trek de vergoeding af van het bedrag. + Trek de transactiekosten a&f van het bedrag. Message: @@ -2142,7 +2250,7 @@ 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. - Een bericht dat werd toegevoegd aan de bitcoin: URI dewelke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoin netwerk. + Een bericht dat werd toegevoegd aan de bitcoin: URI welke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoinnetwerk. Pay To: @@ -2168,19 +2276,19 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Handtekeningen - Onderteken een bericht / Verifiëer een handtekening + Handtekeningen – Onderteken een bericht / Verifiëer een handtekening &Sign Message - O&nderteken Bericht + &Onderteken Bericht 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. - U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishing-aanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat. + U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishingaanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat. The Bitcoin address to sign the message with - Het Bitcoin adres om bericht mee te ondertekenen + Het Bitcoinadres om bericht mee te ondertekenen Choose previously used address @@ -2236,7 +2344,7 @@ The Bitcoin address the message was signed with - Het Bitcoin adres waarmee het bericht ondertekend is + Het Bitcoinadres waarmee het bericht ondertekend is Verify the message to ensure it was signed with the specified Bitcoin address @@ -2307,11 +2415,11 @@ SplashScreen Bitcoin Core - Bitcoin Kern + Bitcoin Core The Bitcoin Core developers - De Bitcoin Core ontwikkelaars + De Bitcoin Core-ontwikkelaars [testnet] @@ -2441,7 +2549,7 @@ Debug information - Debug-informatie + Debuginformatie Transaction @@ -2499,7 +2607,7 @@ Immature (%1 confirmations, will be available after %2) - immatuur (%1 bevestigingen, zal beschikbaar zijn na %2) + Premature (%1 bevestigingen, zal beschikbaar zijn na %2) Open for %n more block(s) @@ -2551,7 +2659,7 @@ Sent to - Verzonden aan + Verstuurd aan Payment to yourself @@ -2585,6 +2693,10 @@ Whether or not a watch-only address is involved in this transaction. Of er een alleen-bekijken adres is betrokken bij deze transactie. + + User-defined intent/purpose of the transaction. + Door gebruiker gedefinieerde intentie/doel van de transactie + Amount removed from or added to balance. Bedrag verwijderd van of toegevoegd aan saldo @@ -2626,7 +2738,7 @@ Sent to - Verzonden aan + Verstuurd aan To yourself @@ -2666,7 +2778,7 @@ Copy raw transaction - Kopieer + Kopieer ruwe transactie Edit label @@ -2678,7 +2790,7 @@ Export Transaction History - Exporteer Transactieverleden + Exporteer Transactiegeschiedenis Watch-only @@ -2690,7 +2802,7 @@ There was an error trying to save the transaction history to %1. - Er is een fout opgetreden bij het opslaan van het transactieverleden naar %1. + Er is een fout opgetreden bij het opslaan van het transactiegeschiedenis naar %1. Exporting Successful @@ -2698,7 +2810,7 @@ The transaction history was successfully saved to %1. - Het transactieverleden was succesvol bewaard in %1. + Het transactiegeschiedenis was succesvol bewaard in %1. Comma separated file (*.csv) @@ -2755,7 +2867,7 @@ WalletModel Send Coins - Verstuur munten + Verstuur Munten @@ -2774,7 +2886,7 @@ Wallet Data (*.dat) - Portemonnee-data (*.dat) + Portemonneedata (*.dat) Backup Failed @@ -2782,7 +2894,7 @@ There was an error trying to save the wallet data to %1. - Er is een fout opgetreden bij het wegschrijven van de portemonnee-data naar %1. + Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1. The wallet data was successfully saved to %1. @@ -2813,19 +2925,55 @@ Accept command line and JSON-RPC commands - Aanvaard commandoregel- en JSON-RPC-commando's + Aanvaard opdrachtregel- en JSON-RPC-opdrachten If <category> is not supplied or if <category> = 1, output all debugging information. - Als er geen <category> is opgegeven of als de <category> 1 is, laat dan alle debugging informatie zien. + Als er geen <categorie> is opgegeven of als de <categorie> 1 is, laat dan alle debugginginformatie zien. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Maximum totale transactiekosten (in %s) om te gebruiken voor een enkele portemonneetransactie; als dit te laag is ingesteld kan het grote transacties verhinderen (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Check a.u.b. of de datum en tijd van uw computer correct zijn! Als uw klok verkeerd staat zal Bitcoin Core niet correct werken. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Snoeien is geconfigureerd on het minimum van %d MiB. Gebruik a.u.b. een hoger aantal. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Snoei: laatste portemoneesynchronisatie gaat verder dan de gesnoeide data. U moet -reindex gebruiken (download opnieuw de gehele blokketen voor een weggesnoeide node) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Beperk benodigde opslag door snoeien (verwijderen) van oude blokken. Deze modus is niet-compatibele met -txindex en -rescan. Waarschuwing: Terugzetten van deze instellingen vereist opnieuw downloaden van gehele de blokketen. (standaard:0 = uitzetten snoeimodus, >%u = doelgrootte in MiB voor blokbestanden) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Herscannen is niet mogelijk in de snoeimodus. U moet -reindex gebruiken dat de hele blokketen opnieuw zal downloaden. Error: A fatal internal error occurred, see debug.log for details Fout: er is een fout opgetreden, zie debug.log voor details + + Fee (in %s/kB) to add to transactions you send (default: %s) + Transactiekosten (in %s/kB) toevoegen aan transacties die u doet (standaard: %s) + + + Pruning blockstore... + Snoei blokopslag... + Run in the background as a daemon and accept commands - Draai in de achtergrond als daemon en aanvaard commando's + Draai in de achtergrond als daemon en aanvaard opdrachten + + + Unable to start HTTP server. See debug log for details. + Niet mogelijk ok HTTP-server te starten. Zie debuglogboek voor details. Accept connections from outside (default: 1 if no -proxy or -connect) @@ -2837,11 +2985,11 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blockchain door -rescan tijdens het opstarten + Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blokketen door -rescan tijdens het opstarten Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. - Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. + Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) @@ -2849,16 +2997,28 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) - Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) + Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) + + + 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 + De blokdatabase bevat een blok dat lijkt uit de toekomst te komen. Dit kan gebeuren omdat de datum en tijd van uw computer niet goed staat. Herbouw de blokdatabase pas nadat u de datum en tijd van uw computer correct heeft ingesteld. This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Dit is een pre-release testversie - gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden + Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden Unable to bind to %s on this computer. Bitcoin Core is probably already running. Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + WAARSCHUWING: abnormaal hoog aantal blokken is gegenereerd, %d blokken ontvangen in de laatste %d uren (%d verwacht) + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht) @@ -2879,9 +3039,13 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Goedgekeurde peers die verbinden van het ingegeven netmask of IP adres. Kan meerdere keren gespecificeerd worden. + + -maxmempool must be at least %d MB + -maxmempool moet tenminste %d MB zijn + <category> can be: - <category> kan zijn: + <categorie> kan zijn: Block creation options: @@ -2911,6 +3075,22 @@ Do you want to rebuild the block database now? Wilt u de blokkendatabase nu herbouwen? + + Enable publish hash block in <address> + Sta toe om hashblok te publiceren in <adres> + + + Enable publish hash transaction in <address> + Stat toe om hashtransactie te publiceren in <adres> + + + Enable publish raw block in <address> + Sta toe rauw blok te publiceren in <adres> + + + Enable publish raw transaction in <address> + Sta toe ruwe transacties te publiceren in <adres> + Error initializing block database Fout bij intialisatie blokkendatabase @@ -2941,12 +3121,16 @@ Incorrect or no genesis block found. Wrong datadir for network? - Incorrect of geen genesis-blok gevonden. Verkeerde datamap voor het netwerk? + Incorrect of geen genesisblok gevonden. Verkeerde datamap voor het netwerk? Invalid -onion address: '%s' Ongeldig -onion adres '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + De transactiegeheugenpool moet onder de <n> megabytes blijven (standaard: %u) + Not enough file descriptors available. Niet genoeg file descriptors beschikbaar. @@ -2955,6 +3139,14 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion) + + Prune cannot be configured with a negative value. + Snoeien kan niet worden geconfigureerd met een negatieve waarde. + + + Prune mode is incompatible with -txindex. + Snoeimodus is niet-compatibel met -txindex + Set database cache size in megabytes (%d to %d, default: %d) Zet database cache grootte in megabytes (%d tot %d, standaard: %d) @@ -2967,10 +3159,26 @@ Specify wallet file (within data directory) Specificeer het portemonnee bestand (vanuit de gegevensmap) + + Unsupported argument -benchmark ignored, use -debug=bench. + Niet-ondersteund argument -benchmark genegeerd, gebruik -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Niet-ondersteund argument -debugnet genegeerd, gebruik -debug=net + + + Unsupported argument -tor found, use -onion. + Niet-ondersteund argument -tor gevonden, gebruik -onion. + Use UPnP to map the listening port (default: %u) Gebruik UPnP om de luisterende poort te mappen (standaard: %u) + + User Agent comment (%s) contains unsafe characters. + User Agentcommentaar (%s) bevat onveilige karakters. + Verifying blocks... Blokken aan het controleren... @@ -2993,7 +3201,7 @@ You need to rebuild the database using -reindex to change -txindex - Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex. + Om -txindex te kunnen veranderen dient u de database herbouwen met gebruik van -reindex. Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3015,30 +3223,41 @@ Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit) + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Ontdek eigen IP-adressen (standaard: 1 voor luisteren en geen -externalip of -proxy) + Error: Listening for incoming connections failed (listen returned error %s) Fout: luisteren naar binnenkomende verbindingen mislukt (luisteren gaf foutmelding %s) Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) - Voer commando uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in commando wordt vervangen door bericht) + Voer opdracht uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in opdracht wordt vervangen door bericht) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Transactiekosten (in %s/kB) kleiner dan dit worden beschouw dat geen transactiekosten in rekening worden gebracht voor doorgeven, mijnen en transactiecreatie (standaard: %s) If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) - Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u) + Als paytxfee niet is ingesteld, voeg voldoende transactiekosten toe zodat transacties starten met bevestigingen binnen in n blokken (standaard: %u) Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - ongeldig bedrag voor -maxtxfee=<amount>: '%s' (moet ten minste de minrelay vergoeding van %s het voorkomen geplakt transacties voorkomen) + ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' (moet ten minste de minimale doorgeeftransactiekosten van %s het voorkomen geplakt transacties voorkomen) Maximum size of data in data carrier transactions we relay and mine (default: %u) - Maximale grootte va n de gegevens in gegevensdrager transacties we relais en de mijnen -(default: %u) + Maximale grootte va n de gegevens in gegevensdragertransacties die we doorgeven en mijnen (standaard: %u) Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) - Query voor peer- adressen via DNS- lookup , als laag op adressen (default: 1 unless -connect) + Query voor peeradressen via DNS- lookup , als laag op adressen (standaard: 1 unless -connect) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Gebruik willekeurige inloggegevens voor elke proxyverbinding. Dit maakt streamislatie voor Tor mogelijk (standaard: %u) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) @@ -3050,7 +3269,7 @@ The transaction amount is too small to send after the fee has been deducted - Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht + Het transactiebedrag is te klein om te versturen nadat de transactiekosten in mindering zijn gebracht This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. @@ -3058,7 +3277,11 @@ Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway - Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway + Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgegeven, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokkketen opnieuw downloaden. (default: %u) @@ -3066,12 +3289,24 @@ Accept public REST requests (default: %u) - Accepteer publieke REST-requests (standaard: %u) + Accepteer publieke REST-verzoeken (standaard: %u) Activating best chain... Beste reeks activeren... + + Always relay transactions received from whitelisted peers (default: %d) + Geef transacties altijd door aan goedgekeurde peers (standaard: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Probeer privésleutels te herstellen van een corrupte wallet.dat bij opstarten + + + Automatically create Tor hidden service (default: %d) + Creëer automatisch verborgen dienst van Tor (standaard:%d) + Cannot resolve -whitebind address: '%s' Kan -whitebind adres niet herleiden: '%s' @@ -3092,6 +3327,10 @@ Error reading from database, shutting down. Fout bij het lezen van de database, afsluiten. + + Imports blocks from external blk000??.dat file on startup + Importeer blokken van externe blk000??.dat-bestand bij opstarten + Information Informatie @@ -3102,7 +3341,7 @@ Invalid amount for -maxtxfee=<amount>: '%s' - Ongeldig bedrag voor -maxtxfee=<amount>: '%s' + Ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' Invalid amount for -minrelaytxfee=<amount>: '%s' @@ -3130,19 +3369,35 @@ Node relay options: - Node relay opties: + Nodedoorgeefopties: RPC server options: RPC server opties: + + Rebuild block chain index from current blk000??.dat files on startup + Herbouwen blokketenindex vanuit huidige blk000??.dat-bestanden bij opstarten? + + + Receive and display P2P network alerts (default: %u) + Ontvang en toon P2P-netwerkwaarschuwingen (standaard: %u) + + + Reducing -maxconnections from %d to %d, because of system limitations. + Verminder -maxconnections van %d naar %d, vanwege systeembeperkingen. + + + Rescan the block chain for missing wallet transactions on startup + Herscan de blokketen voor missende portemonneetransacties bij opstarten + Send trace/debug info to console instead of debug.log file - Stuur trace/debug-info naar de console in plaats van het debug.log bestand + Verzend trace/debug-info naar de console in plaats van het debug.log-bestand Send transactions as zero-fee transactions if possible (default: %u) - Verstuur transacties zonder verzendkosten indien mogelijk (standaard: %u) + Indien mogelijk, verstuur zonder transactiekosten (standaard: %u) Show all debugging options (usage: --help -help-debug) @@ -3158,12 +3413,20 @@ The transaction amount is too small to pay the fee - Het transactiebedrag is te klein om de vergoeding te betalen + Het transactiebedrag is te klein om transactiekosten in rekening te brengen This is experimental software. Dit is experimentele software. + + Tor control port password (default: empty) + Tor bepaalt poortwachtwoord (standaard: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Tor bepaalt welke poort te gebruiken als luisteren naar onion wordt gebruikt (standaard: %s) + Transaction amount too small Transactiebedrag te klein @@ -3174,7 +3437,7 @@ Transaction too large for fee policy - De transactie is te groot voor het toeslagenbeleid + De transactie is te groot voor het transactiekostenbeleid Transaction too large @@ -3184,6 +3447,10 @@ Unable to bind to %s on this computer (bind returned error %s) Niet in staat om aan %s te binden op deze computer (bind gaf error %s) + + Upgrade wallet to latest format on startup + Upgrade portemonee naar laatste formaat bij opstarten + Username for JSON-RPC connections Gebruikersnaam voor JSON-RPC-verbindingen @@ -3196,10 +3463,18 @@ Warning Waarschuwing + + Whether to operate in a blocks only mode (default: %u) + Om in alleen een blokmodus te opereren (standaard: %u) + Zapping all transactions from wallet... Bezig met het zappen van alle transacties van de portemonnee... + + ZeroMQ notification options: + ZeroMQ notificatieopties: + wallet.dat corrupt, salvage failed wallet.dat corrupt, veiligstellen mislukt @@ -3210,7 +3485,7 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) - Voer commando uit zodra het beste blok verandert (%s in cmd wordt vervangen door blockhash) + Voer opdracht uit zodra het beste blok verandert (%s in cmd wordt vervangen door blokhash) This help message @@ -3232,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee staat zeer hoog! Transactiekosten van de grootte kunnen worden gebruikt in een enkele transactie. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee staat zeer hoog! Dit is de transactiekosten die u betaalt als u een transactie doet. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Bewaar transactie niet langer dan <n> uren in de geheugenpool (standaard: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Fout tijdens lezen van wallet.dat! Alle sleutels zijn correct te lezen, maar de transactiondatabase of adresboekingangen zijn mogelijk verdwenen of incorrect. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Transactiekosten (in %s/kB) kleiner dan dit worden beschouwd dat geen transactiekosten in rekening worden gebracht voor transactiecreatie (standaard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u) @@ -3246,11 +3541,35 @@ Output debugging information (default: %u, supplying <category> is optional) - Output extra debugginginformatie (standaard: %u, het leveren van <category> is optioneel) + Output extra debugginginformatie (standaard: %u, het leveren van <categorie> is optioneel) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + Ondersteun filtering van blokken en transacties met bloomfilters (standaard: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Totale lengte van netwerkversiestring (%i) overschrijdt maximale lengte (%i). Verminder het aantal of grootte van uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Pogingen om uitgaand verkeer onder een bepaald doel te houden (in MiB per 24u), 0 = geen limiet (standaard: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Niet-ondersteund argument -socks gevonden. Instellen van SOCKS-versie is niet meer mogelijk, alleen SOCKS5-proxies worden ondersteund. Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) - Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: %s) + Gebruik een aparte SOCKS5 proxy om verborgen diensten van Tor te bereiken (standaard: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Gebruikersnaam en gehasht wachtwoord voor JSON-RPC-verbindingen. De velden <userpw> is in het formaat: <GEBRUIKERSNAAM>:<SALT>$<HASH>. Een kanoniek Pythonscript is inbegrepen in de share/rpcuser. Deze optie kan meerdere keren worden meegegeven + + + (default: %s) + (standaard: %s) Always query for peer addresses via DNS lookup (default: %u) @@ -3278,7 +3597,7 @@ Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) - Luister naar JSON-RPC-verbindingen op poort <port> (standaard: %u of testnet: %u) + Luister naar JSON-RPC-verbindingen op <poort> (standaard: %u of testnet: %u) Listen for connections on <port> (default: %u or testnet: %u) @@ -3298,7 +3617,7 @@ Maximum per-connection send buffer, <n>*1000 bytes (default: %u) - Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: %u) + Maximum per-connectie verstuurbuffer, <n>*1000 bytes (standaard: %u) Prepend debug output with timestamp (default: %u) @@ -3306,15 +3625,15 @@ Relay and mine data carrier transactions (default: %u) - Gegevensdrager transacties relay en de mijnen (default: %u) + Geef gegevensdragertransacties door en mijn ze ook (standaard: %u) Relay non-P2SH multisig (default: %u) - Relay non-P2SH multisig (default: %u) + Geef non-P2SH multisig door (standaard: %u) Set key pool size to <n> (default: %u) - Stel sleutelpoelgrootte in op <&> (standaard: %u) + Stel sleutelpoelgrootte in op <n> (standaard: %u) Set minimum block size in bytes (default: %u) @@ -3326,7 +3645,7 @@ Specify configuration file (default: %s) - Specificeer configuratie bestand (standaard: %s) + Specificeer configuratiebestand (standaard: %s) Specify connection timeout in milliseconds (minimum: 1, default: %d) @@ -3338,7 +3657,7 @@ Spend unconfirmed change when sending transactions (default: %u) - Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u) + Besteed onbevestigd wisselgeld bij het doen van transacties (standaard: %u) Threshold for disconnecting misbehaving peers (default: %u) @@ -3386,7 +3705,7 @@ Rescanning... - Blokketen aan het doorzoeken... + Blokketen aan het herscannen... Done loading diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index ec99a1f57..233918ff2 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -249,6 +249,10 @@ &Change Passphrase... &Alilan ing Passphrase... + + &Receiving addresses... + Address king pamag-Tanggap + Send coins to a Bitcoin address Magpadalang barya king Bitcoin address @@ -309,6 +313,10 @@ Bitcoin Core Kapilubluban ning Bitcoin + + &Command-line options + Pipamilian command-line + Last received block was generated %1 ago. Ing tatauling block a metanggap, me-generate ya %1 ing milabas @@ -363,6 +371,10 @@ CoinControlDialog + + Amount: + Alaga: + Amount Alaga @@ -464,7 +476,7 @@ command-line options pipamilian command-line - + Intro @@ -639,6 +651,10 @@ &Information &Impormasion + + Debug window + I-Debug ing awang + Using OpenSSL version Gagamit bersion na ning OpenSSL @@ -717,6 +733,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopyan ing address + Address Address @@ -763,6 +783,18 @@ Send Coins Magpadalang Barya + + Insufficient funds! + Kulang a pondo + + + Amount: + Alaga: + + + Transaction Fee: + Bayad king Transaksion: + Send to multiple recipients at once Misanang magpadala kareng alialiuang tumanggap @@ -842,6 +874,14 @@ Alt+P Alt+P + + Message: + Mensayi: + + + Pay To: + Ibayad kang: + ShutdownWindow @@ -1365,10 +1405,26 @@ Failed to listen on any port. Use -listen=0 if you want this. Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini. + + Cannot resolve -whitebind address: '%s' + Eya me-resolve ing -whitebind address: '%s' + Information &Impormasion + + Invalid amount for -maxtxfee=<amount>: '%s' + Eya maliari ing alaga keng -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Eya maliari ing alaga keng -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Eya maliari ing alaga keng -mintxfee=<amount>: '%s' + Send trace/debug info to console instead of debug.log file Magpadalang trace/debug info okeng console kesa keng debug.log file diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index a351552b6..8a8c37748 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -878,6 +878,34 @@ command-line options opcje konsoli + + UI Options: + Opcje interfejsu + + + Choose data directory on startup (default: %u) + Katalog danych używany podczas uruchamiania programu (domyślny: %u) + + + Set language, for example "de_DE" (default: system locale) + Wybierz język, na przykład "de_DE" (domyślnie: język systemowy) + + + Start minimized + Uruchom zminimalizowany + + + Set SSL root certificates for payment request (default: -system-) + Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-) + + + Show splash screen on startup (default: %u) + Wyświetl okno powitalne podczas uruchamiania (domyślnie: %u) + + + Reset all settings changes made over the GUI + Ustaw jako domyślne wszystkie ustawienia interfejsu + Intro @@ -1075,6 +1103,10 @@ Port of the proxy (e.g. 9050) Port proxy (np. 9050) + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Pokazuje, czy wspierane domyślnie proxy SOCKS5 jest używane do łączenia się z peerami w tej sieci + IPv4 IPv4 @@ -1087,6 +1119,10 @@ Tor Tor + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor: + &Window &Okno @@ -1457,6 +1493,14 @@ Current number of blocks Aktualna liczba bloków + + Current number of transactions + Obecna liczba transakcji + + + Memory usage + Zużycie pamięci + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach. @@ -1481,6 +1525,10 @@ Select a peer to view detailed information. Wybierz węzeł żeby zobaczyć szczegóły. + + Whitelisted + Biała lista + Direction Kierunek @@ -1489,6 +1537,18 @@ Version Wersja + + Starting Block + Blok startowy + + + Synced Headers + Zsynchronizowane nagłówki + + + Synced Blocks + Zsynchronizowane bloki + User Agent Aplikacja kliencka @@ -1517,6 +1577,10 @@ Ping Time Czas odpowiedzi + + Ping Wait + Czas odpowiedzi + Time Offset Przesunięcie czasu @@ -1601,6 +1665,10 @@ %1 GB %1 GB + + (node id: %1) + (id węzła: %1) + via %1 przez %1 @@ -1648,6 +1716,10 @@ Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. Użyj jednego z poprzednio użytych adresów odbiorczych. Podczas ponownego używania adresów występują problemy z bezpieczeństwem i prywatnością. Nie korzystaj z tej opcji, chyba że odtwarzasz żądanie płatności wykonane już wcześniej. + + R&euse an existing receiving address (not recommended) + U&żyj ponownie istniejącego adresu odbiorczego (niepolecane) + 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. Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin. @@ -1989,6 +2061,10 @@ Copy change Skopiuj resztę + + Total Amount %1 + Łączna kwota %1 + or lub @@ -2656,6 +2732,10 @@ Copy transaction ID Skopiuj ID transakcji + + Copy raw transaction + Skopiuj surowe dane transakcji + Edit label Zmień etykietę @@ -2807,6 +2887,10 @@ Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log + + Fee (in %s/kB) to add to transactions you send (default: %s) + Prowizja (w %s/kB) dodawana do wysyłanych transakcji (domyślnie: %s) + Pruning blockstore... Przycinanie zapisu bloków... @@ -2815,6 +2899,10 @@ Run in the background as a daemon and accept commands Uruchom w tle jako daemon i przyjmuj polecenia + + Unable to start HTTP server. See debug log for details. + Uruchomienie serwera HTTP nie powiodło się. Zobacz dziennik debugowania, aby uzyskać więcej szczegółów. + Accept connections from outside (default: 1 if no -proxy or -connect) Akceptuj połączenia z zewnątrz (domyślnie: 1 jeśli nie ustawiono -proxy lub -connect) @@ -2967,6 +3055,14 @@ Specify wallet file (within data directory) Określ plik portfela (w obrębie folderu danych) + + Unsupported argument -benchmark ignored, use -debug=bench. + Niewspierany argument -benchmark zignorowany, użyj -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Niewspierany argument -debugnet zignorowany, użyj -debug=net. + Use UPnP to map the listening port (default: %u) Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u) @@ -3075,6 +3171,18 @@ Activating best chain... Aktywuje najlepszy łańcuch + + Always relay transactions received from whitelisted peers (default: %d) + Zawsze przekazuj informacje o transakcjach otrzymanych od osób z białej listy (domyślnie: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Próbuj podczas uruchamiania programu odzyskać klucze prywatne z uszkodzonego pliku wallet.dat + + + Automatically create Tor hidden service (default: %d) + Stwórz automatycznie ukrytą usługę Tora (domyślnie: %d) + Cannot resolve -whitebind address: '%s' Nie można rozwiązać adresu -whitebind: '%s' @@ -3095,6 +3203,10 @@ Error reading from database, shutting down. Błąd odczytu z bazy danych, wyłączam się. + + Imports blocks from external blk000??.dat file on startup + Importuj bloki z zewnętrznego pliku blk000??.dat podczas uruchamiania programu + Information Informacja @@ -3127,6 +3239,10 @@ Keep at most <n> unconnectable transactions in memory (default: %u) Przechowuj w pamięci maksymalnie <n> transakcji nie możliwych do połączenia (domyślnie: %u) + + Need to specify a port with -whitebind: '%s' + Musisz określić port z -whitebind: '%s' + Node relay options: Opcje przekaźnikowe węzła: @@ -3143,6 +3259,10 @@ Receive and display P2P network alerts (default: %u) Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u) + + Rescan the block chain for missing wallet transactions on startup + Przeskanuj podczas ładowania programu łańcuch bloków w poszukiwaniu zaginionych transakcji portfela + Send trace/debug info to console instead of debug.log file Wyślij informację/raport do konsoli zamiast do pliku debug.log. @@ -3171,6 +3291,10 @@ This is experimental software. To oprogramowanie eksperymentalne. + + Tor control port password (default: empty) + Hasło zabezpieczające portu kontrolnego Tora (domyślnie: puste) + Transaction amount too small Zbyt niska kwota transakcji @@ -3191,6 +3315,10 @@ Unable to bind to %s on this computer (bind returned error %s) Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s) + + Upgrade wallet to latest format on startup + Zaktualizuj portfel do najnowszego formatu podczas ładowania programu + Username for JSON-RPC connections Nazwa użytkownika dla połączeń JSON-RPC @@ -3239,6 +3367,14 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane) + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Nie trzymaj w pamięci transakcji starszych niż <n> godzin (domyślnie: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe. + How thorough the block verification of -checkblocks is (0-4, default: %u) Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u) @@ -3255,6 +3391,10 @@ Output debugging information (default: %u, supplying <category> is optional) Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne) + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Znaleziono niewspierany argument -socks. Wybieranie wersji SOCKS nie jest już możliwe, wsparcie programu obejmuje tylko proxy SOCKS5 + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index bb6de064d..5cea349fb 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -441,6 +441,10 @@ No block source available... Nenhum servidor disponível... + + Processed %n block(s) of transaction history. + %n bloco processado do histórico de transações.%n blocos processados do histórico de transações. + %n hour(s) %n hora%n horas @@ -878,6 +882,34 @@ command-line options opções da linha de comando + + UI Options: + Opções de Interface: + + + Choose data directory on startup (default: %u) + Escolher diretório de dados na inicialização (padrão: %u) + + + Set language, for example "de_DE" (default: system locale) + Definir idioma, por exemplo "de_DE" (padrão: idioma do sistema) + + + Start minimized + Iniciar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Definir certificados de root SSL para requisições de pagamento (padrão: -sistema-) + + + Show splash screen on startup (default: %u) + Exibir tela de abertura na inicialização (padrão: %u) + + + Reset all settings changes made over the GUI + Desfazer todas as mudanças de configuração feitas na interface + Intro @@ -1079,6 +1111,10 @@ Used for reaching peers via: Usado para alcançar participantes via: + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Exibe, caso o proxy padrão SOCKS5 fornecido seja usado para se conectar a peers através deste tipo de rede. + IPv4 IPv4 @@ -1469,6 +1505,18 @@ Current number of blocks Quantidade atual de blocos + + Memory Pool + Pool de Memória + + + Current number of transactions + Número atual de transações + + + Memory usage + Uso de memória + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes. @@ -2883,14 +2931,26 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Se <category> não for suprida ou se <category> = 1, mostrar toda informação de depuração. + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Total máximo de comissão (em %s) que será usado em uma única transação; um valor muito baixo pode cancelar uma transação grande (padrão: %s) + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. Por favor verifique se a data e horário estão corretos no seu computador! Se o seu relógio estiver incorreto, a Carteira Bitcoin não irá funcionar corretamente. + + Prune configured below the minimum of %d MiB. Please use a higher number. + Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto. + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente) + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduza os requerimentos de armazenamento de dados (cortando) deletando blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilita o corte de blocos, >%u = tamanho alvo em MiB para o uso de blocos cortados) + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. @@ -3175,14 +3235,38 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Comissões (em %s/kB) menores serão consideradas como zero para relaying, mineração e criação de transação (padrão %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + Se paytxfee não estiver definida, incluir comissão suficiente para que as transações comecem a ter confirmações em média dentro de N blocos (padrão %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Valor inválido para -maxtxfee = <valor>: '%s'( precisa ser pelo menos a comissão mínima de %s para prevenir travamento de transações) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Tamanho máximo de dados em transações de dados de operadora (padrão %u) + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) Buscar por endereços de peers via busca DNS, se estiver baixo em endereços (padrão: 1 a não ser que -connect) + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Gerar credenciais aleatórias para cada conexão por proxy. Isto habilita o isolamento de stream do Tor (padrão: %u) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Define o tamanho máximo de alta-prioridade por taxa baixa nas transações em bytes (padrão: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Determina o número de núcleos para a geração de moedas se ativado (-1 = todos os núcleos, padrão: %d) + The transaction amount is too small to send after the fee has been deducted A quantia da transação é muito pequena para mandar @@ -3191,6 +3275,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit<https://www.openssl.org/> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + Peers permitidos não podem ser banidos do DoS e suas transações sempre são transmitidas, até mesmo se eles já estão no pool de memória, útil, por exemplo, para um gateway + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain. @@ -3199,10 +3287,26 @@ (default: %u) (padrão: %u) + + Accept public REST requests (default: %u) + Aceitar pedidos restantes públicas (padrão: %u) + Activating best chain... Ativando a melhor sequência... + + Always relay transactions received from whitelisted peers (default: %d) + Sempre transmitir transações recebidas de peers confiáveis (padrão: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Tentar recuperar na inicialização chaves privadas de um arquivo wallet.dat corrompido + + + Automatically create Tor hidden service (default: %d) + Criar automaticamente serviços ocultos do Tor (padrão: %d) + Cannot resolve -whitebind address: '%s' Impossível resolver endereço -whitebind: '%s' @@ -3223,10 +3327,18 @@ Error reading from database, shutting down. Erro ao ler o banco de dados. Finalizando. + + Imports blocks from external blk000??.dat file on startup + Importar blocos a partir de arquivo externo blk000??.dat durante a inicialização + Information Informação + + Initialization sanity check failed. Bitcoin Core is shutting down. + O teste de integridade da inicialização falhou. O Core do Bitcoin está sendo desligado. + Invalid amount for -maxtxfee=<amount>: '%s' Quantidade inválida para -maxtxfee=<quantidade>: '%s' @@ -3247,6 +3359,10 @@ Invalid netmask specified in -whitelist: '%s' Máscara de rede especificada em -whitelist: '%s' é inválida + + Keep at most <n> unconnectable transactions in memory (default: %u) + Manter ao máximo <n> transações inconectáveis na memória (padrão: %u) + Need to specify a port with -whitebind: '%s' Necessário informar uma porta com -whitebind: '%s' @@ -3259,9 +3375,13 @@ RPC server options: Opções do servidor RPC: + + Rebuild block chain index from current blk000??.dat files on startup + Reconstruir índice de cadeia de bloco a partir dos arquivos blk000??.dat atuais durante a inicialização + Receive and display P2P network alerts (default: %u) - Receba e mostre P2P alerta de rede (default: %u) + Receba e mostre P2P alerta de rede (padrão: %u) Send trace/debug info to console instead of debug.log file @@ -3355,6 +3475,14 @@ Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira corrompida + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Comissões (em %s/kB) menores serão consideradas como zero para criação de transação (padrão %s) + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor (padrão: %s) + (default: %s) (padrão: %s) @@ -3399,13 +3527,21 @@ Make the wallet broadcast transactions Fazer a carteira transmitir transações + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Buffer máximo de recebimento por conexão, <n>*1000 bytes (padrão: %u) + Prepend debug output with timestamp (default: %u) - Adiciona timestamp como prefixo no debug (default: %u) + Adiciona timestamp como prefixo no debug (padrão: %u) Relay non-P2SH multisig (default: %u) - Retransmitir P2SH não multisig (default: %u) + Retransmitir P2SH não multisig (padrão: %u) + + + Set key pool size to <n> (default: %u) + Defina o tamanho da chave para piscina<n> (padrão: %u) Set minimum block size in bytes (default: %u) @@ -3425,7 +3561,7 @@ Specify pid file (default: %s) - Especificar aqrquivo pid (default: %s) + Especificar aqrquivo pid (padrão: %s) Spend unconfirmed change when sending transactions (default: %u) diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index b5ede206d..ffed44a61 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -874,7 +874,7 @@ command-line options opções da linha de comandos - + Intro @@ -2916,6 +2916,10 @@ (default: %u) (por defeito: %u) + + Cannot resolve -whitebind address: '%s' + Não foi possível resolver o endereço -whitebind: '%s' + Copyright (C) 2009-%i The Bitcoin Core Developers Copyright (C) 2009-%i Os Programadores do Bitcoin Core @@ -2928,6 +2932,10 @@ Information Informação + + Invalid amount for -maxtxfee=<amount>: '%s' + Quantia inválida para -maxtxfee=<quantidade>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Quantia inválida para -minrelaytxfee=<quantidade>: '%s' @@ -3004,6 +3012,10 @@ Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira danificada + + (default: %s) + (por defeito: %s) + Error loading wallet.dat Erro ao carregar wallet.dat diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index c88908263..8bccf037a 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -709,6 +709,10 @@ lowest cea mai scăzută + + (%1 locked) + (%1 blocat) + none nimic @@ -737,6 +741,10 @@ no nu + + This means a fee of at least %1 per kB is required. + Aceasta înseamnă o taxă de cel puţin %1 pe kB necesar. + Can vary +/- 1 byte per input. Poate varia +/- 1 octet pentru fiecare intrare. @@ -866,7 +874,7 @@ command-line options Opţiuni linie de comandă - + Intro @@ -881,6 +889,10 @@ As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. Dacă aceasta este prima dată cînd programul este lansat, puteţi alege unde Nucleul Bitcoin va stoca datele. + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Nucleul Bitcoin se va descărca şi va stoca o copie a lanţului blocului Bitcoin. Cel puţin %1GB de date vor fi stocate în acest dosar şi se va mări în timp. Portofelul va fi, de asemenea, stocat în acest dosar. + Use the default data directory Foloseşte dosarul de date implicit @@ -2335,6 +2347,10 @@ , has not been successfully broadcast yet , nu s-a propagat încă + + Open for %n more block(s) + Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri + unknown necunoscut @@ -2365,6 +2381,10 @@ Immature (%1 confirmations, will be available after %2) Imatur (%1 confirmări, va fi disponibil după %2) + + Open for %n more block(s) + Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri + Open until %1 Deschis până la %1 @@ -2847,10 +2867,18 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Acest produs include programe dezvoltate de către Proiectul OpenSSL pentru a fi folosite în OpenSSL Toolkit <https://www.openssl.org/> şi programe criptografice scrise de către Eric Young şi programe UPnP scrise de către Thomas Bernard. + + (default: %u) + (implicit: %u) + Accept public REST requests (default: %u) Acceptă cererile publice REST (implicit: %u) + + Cannot resolve -whitebind address: '%s' + Nu se poate rezolva adresa -whitebind: '%s' + Connect through SOCKS5 proxy Conectare prin proxy SOCKS5 diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index ea577694a..00dfd833a 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -93,7 +93,11 @@ Exporting Failed Экспорт не удался - + + There was an error trying to save the address list to %1. Please try again. + Произошла ошибка при попытке сохранить список адресов, %1. Пожалуйста, попробуйте еще раз. + + AddressTableModel @@ -878,6 +882,34 @@ command-line options параметры командной строки + + UI Options: + Настройки интерфейса: + + + Choose data directory on startup (default: %u) + Выбрать каталог данных при запуске (по умолчанию: %u) + + + Set language, for example "de_DE" (default: system locale) + Выберите язык, например "de_DE" (по умолчанию: как в системе) + + + Start minimized + Запускать свёрнутым + + + Set SSL root certificates for payment request (default: -system-) + Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-) + + + Show splash screen on startup (default: %u) + Показывать экран-заставку при запуске (по умолчанию: %u) + + + Reset all settings changes made over the GUI + Сбросить все настройки сделанные через графический интерфейс + Intro @@ -1473,6 +1505,18 @@ Current number of blocks Текущее число блоков + + Memory Pool + Пул памяти + + + Current number of transactions + Текущее число транзакций + + + Memory usage + Использование памяти + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. @@ -2093,6 +2137,14 @@ Payment request expired. Запрос платежа просрочен. + + Pay only the required fee of %1 + Заплатить только обязательную комиссию %1 + + + Estimated to begin confirmation within %n block(s). + Подтверждение ожидается через %n блок.Подтверждение ожидается через %n блока.Подтверждение ожидается через %n блоков.Подтверждение ожидается через %n блоков. + The recipient address is not valid. Please recheck. Адрес получателя неверный. Пожалуйста, перепроверьте. @@ -2589,6 +2641,10 @@ Unconfirmed Неподтверждено + + Confirming (%1 of %2 recommended confirmations) + Подтверждено(%1 подтверждений, рекомендуется %2 подтверждений) + Conflicted В противоречии @@ -3467,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Ошибка чтения wallet.dat! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми при создании транзакций (по умолчанию: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u) @@ -3483,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Выводить отладочную информацию (по умолчанию: %u, указание <category> необязательно) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Поддерживать фильтрацию блоков и транзакций с помощью фильтра Блума (по умолчанию: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Текущая длина строки версии сети (%i) превышает максимальную длину (%i). Увеливается количество или размер uacomments. @@ -3499,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Имя пользователя и хэш пароля для JSON-RPC соединений. Поле <userpw> использует формат: <USERNAME>:<SALT>$<HASH>. Каноничный пример скрипта на питоне включен в "share/rpcuser". Эта опция может быть указана несколько раз + (default: %s) (по умолчанию: %s) @@ -3567,6 +3635,10 @@ Set key pool size to <n> (default: %u) Установить размер пула ключей в <n> (по умолчанию: %u) + + Set minimum block size in bytes (default: %u) + Задать минимальный размер блока в байтах (по умолчанию: %u) + Set the number of threads to service RPC calls (default: %d) Задать число потоков выполнения запросов RPC (по умолчанию: %d) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index fa42dfaaa..53a1c1d8a 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -17,6 +17,14 @@ Bitcoin Core Bitcoin Core + + &About Bitcoin Core + О Bitcoin Core + + + &Command-line options + Опции командной строки + Error Ошибка @@ -88,6 +96,10 @@ Command-line options Опции командной строки + + command-line options + Опции командной строки + Intro @@ -131,6 +143,10 @@ RPCConsole + + &Information + Информация + ReceiveCoinsDialog diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 0451b1485..8c779cbe9 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -874,7 +874,7 @@ command-line options voľby príkazového riadku - + Intro @@ -1071,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port proxy (napr. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor: + &Window Okno @@ -3161,6 +3165,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Error loading wallet.dat Chyba načítania wallet.dat + + Generate coins (default: %u) + Generovať mince (predvolené: %u) + How many blocks to check at startup (default: %u, 0 = all) Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky) diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index f26e35054..c62c8cf27 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -874,7 +874,7 @@ command-line options možnosti ukazne vrstice - + Intro @@ -917,7 +917,11 @@ %n GB of free space available %n GiB prostega prostora na voljo%n GiB prostega prostora na voljo%n GiB prostega prostora na voljo%n GiB prostega prostora na voljo - + + (of %n GB needed) + (od potrebnih %n GiB)(od potrebnih %n GiB)(od potrebnih %n GiB)(od potrebnih %n GiB) + + OpenURIDialog @@ -1067,6 +1071,10 @@ Port of the proxy (e.g. 9050) Vrata posredniškega strežnika (npr. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5: + &Window O&kno @@ -3019,6 +3027,18 @@ Information Informacije + + Invalid amount for -maxtxfee=<amount>: '%s' + Neveljavna količina za -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Neveljavna količina za -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Neveljavna količina za -mintxfee=<amount>: '%s' + Need to specify a port with -whitebind: '%s' Pri opciji -whitebind morate navesti vrata: %s diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 769b45b56..994b06599 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -201,6 +201,10 @@ &Options... &Opsione + + &Receiving addresses... + Duke marr adresen + Change the passphrase used for wallet encryption Ndrysho frazkalimin e përdorur per enkriptimin e portofolit @@ -421,6 +425,10 @@ Options Opsionet + + W&allet + Portofol + OverviewPage @@ -447,6 +455,10 @@ RPCConsole + + &Information + Informacion + &Open &Hap @@ -466,13 +478,25 @@ ReceiveCoinsDialog + + &Amount: + Shuma: + &Label: &Etiketë: + + Clear + Pastro + ReceiveRequestDialog + + Copy &Address + &Kopjo adresen + Address Adresë @@ -511,6 +535,10 @@ Send Coins Dërgo Monedha + + Insufficient funds! + Fonde te pamjaftueshme + Amount: Shuma: @@ -570,6 +598,10 @@ Alt+P Alt+P + + Pay To: + Paguaj drejt: + ShutdownWindow @@ -621,6 +653,10 @@ Date Data + + Transaction + transaksionit + Amount Sasia @@ -757,6 +793,10 @@ bitcoin-core + + Options: + Opsionet: + Information Informacion diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 425c077b2..b6ba896b3 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -221,6 +221,10 @@ Tabs toolbar Трака са картицама + + &About Bitcoin Core + O Bitcoin Coru + Up to date Ажурно @@ -337,6 +341,10 @@ Options Поставке + + W&allet + новчаник + &Unit to show amounts in: &Јединица за приказивање износа: @@ -374,10 +382,18 @@ ReceiveCoinsDialog + + &Amount: + Iznos: + &Label: &Етикета + + &Message: + Poruka: + Copy label kopiraj naziv @@ -389,6 +405,10 @@ ReceiveRequestDialog + + Copy &Address + Kopirajte adresu + Address Адреса @@ -401,6 +421,10 @@ Label Етикета + + Message + Poruka + RecentRequestsTableModel @@ -412,6 +436,10 @@ Label Етикета + + Message + Poruka + Amount iznos @@ -450,6 +478,10 @@ SendCoinsEntry + + A&mount: + Iznos: + &Label: &Етикета @@ -513,6 +545,14 @@ label етикета + + Message + Poruka + + + Transaction + transakcije + Amount iznos diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 18f096b84..756114351 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -738,6 +738,10 @@ Var vänlig och försök igen. This label turns red if any recipient receives an amount smaller than %1. Denna etikett blir röd om någon mottagare får ett belopp mindre än %1. + + Can vary +/- %1 satoshi(s) per input. + Kan variera +/- %1 satoshi per inmatning. + yes ja @@ -879,6 +883,34 @@ Var vänlig och försök igen. command-line options kommandoradsalternativ + + UI Options: + UI-inställningar: + + + Choose data directory on startup (default: %u) + Välj datakatalog vid uppstart (standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Ange språk, till exempel "de_DE" (standard: systemspråk) + + + Start minimized + Starta minimerad + + + Set SSL root certificates for payment request (default: -system-) + Ange SSL rotcertifikat för betalningsansökan (standard: -system-) + + + Show splash screen on startup (default: %u) + Visa startbild vid uppstart (standard: %u) + + + Reset all settings changes made over the GUI + Återställ alla inställningar som gjorts över GUI + Intro @@ -1474,6 +1506,18 @@ Var vänlig och försök igen. Current number of blocks Aktuellt antal block + + Memory Pool + Minnespool + + + Current number of transactions + Nuvarande antal transaktioner + + + Memory usage + Minnesåtgång + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor. @@ -1697,6 +1741,10 @@ Var vänlig och försök igen. ReceiveCoinsDialog + + &Amount: + &Belopp: + &Label: &Etikett: @@ -2181,6 +2229,10 @@ Var vänlig och försök igen. 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. Avgiften dras från beloppet som skickas. Mottagaren kommer att få mindre bitcoins än du angivit i belopp-fältet. Om flera mottagare valts kommer avgiften delas jämt. + + S&ubtract fee from amount + S&ubtrahera avgiften från beloppet + Message: Meddelande: @@ -3212,6 +3264,10 @@ Var vänlig och försök igen. Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Ange antalet trådar för myntgenerering om påslagen (-1= alla kärnor, förval: %d) + The transaction amount is too small to send after the fee has been deducted Transaktionen är för liten att skicka efter det att avgiften har dragits @@ -3468,6 +3524,10 @@ Var vänlig och försök igen. Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdata eller adressbokens poster kanske saknas eller är felaktiga. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Avgifter (i %s/kB) mindre än detta anses vara nollavgifter vid skapande av transaktion (standard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u) @@ -3484,6 +3544,10 @@ Var vänlig och försök igen. Output debugging information (default: %u, supplying <category> is optional) Skriv ut avlusningsinformation (förvalt: %u, att ange <category> är frivilligt) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Stöd filtrering av block och transaktioner med bloomfilter (standard: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Total längd på strängen för nätverksversion (%i) överskrider maxlängden (%i). Minska numret eller storleken på uacomments. @@ -3500,6 +3564,10 @@ Var vänlig och försök igen. Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Användarnamn och hashat lösenord för JSON-RPC-anslutningar. Fältet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Ett kanoniskt pythonskript finns inkluderat i share/rpcuser. Detta alternativ kan anges flera gånger + (default: %s) (förvalt: %s) diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 75fdfc5bd..79a55cdd5 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -282,6 +282,10 @@ ReceiveCoinsDialog + + &Label: + &ชื่อ: + ReceiveRequestDialog @@ -318,6 +322,10 @@ SendCoinsEntry + + &Label: + &ชื่อ: + ShutdownWindow @@ -385,5 +393,9 @@ bitcoin-core + + Options: + ตัวเลือก: + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 36ca1ab6f..96fca8bb2 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Ağ maskesi + + + Banned Until + Şu vakte kadar yasaklı: + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options komut satırı seçenekleri + + UI Options: + Arayüz Seçenekleri: + + + Choose data directory on startup (default: %u) + Başlangıçta veri klasörü seç (varsayılan: %u) + + + Set language, for example "de_DE" (default: system locale) + Lisan belirt, mesela "de_De" (varsayılan: sistem dili) + + + Start minimized + Küçültülmüş olarak başlat + + + Set SSL root certificates for payment request (default: -system-) + Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-) + + + Show splash screen on startup (default: %u) + Başlatıldığında başlangıç ekranını göster (varsayılan: %u) + + + Reset all settings changes made over the GUI + Arayüzde yapılan tüm seçenek değişikliklerini sıfırla + Intro @@ -1071,6 +1107,34 @@ Port of the proxy (e.g. 9050) Vekil sunucunun portu (mesela 9050) + + Used for reaching peers via: + Eşlere ulaşmak için kullanılır, şu yoluyla: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Bu şebeke türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Bitcoin şebekesine gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu vasıtasıyla bağlan. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan: + &Window &Pencere @@ -1441,6 +1505,18 @@ Current number of blocks Güncel blok sayısı + + Memory Pool + Bellek Alanı + + + Current number of transactions + Güncel muamele sayısı + + + Memory usage + Bellek kullanımı + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Güncel veri klasöründen Bitcoin Çekirdeği hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir. @@ -1457,10 +1533,18 @@ &Peers &Eşler + + Banned peers + Yasaklı eşler + Select a peer to view detailed information. Ayrıntılı bilgi görmek için bir eş seçin. + + Whitelisted + Beyaz listedekiler + Direction Yön @@ -1469,6 +1553,18 @@ Version Sürüm + + Starting Block + Başlangıç Bloku + + + Synced Headers + Eşleşmiş Başlıklar + + + Synced Blocks + Eşleşmiş Bloklar + User Agent Kullanıcı Yazılımı @@ -1497,6 +1593,14 @@ Ping Time Ping Süresi + + The duration of a currently outstanding ping. + Güncel olarak göze çarpan bir ping'in süresi. + + + Ping Wait + Ping Beklemesi + Time Offset Saat Farkı @@ -1545,6 +1649,34 @@ Clear console Konsolu temizle + + &Disconnect Node + Düğümle Bağlantıyı &Kes + + + Ban Node for + Düğümü şu süre için yasakla: + + + 1 &hour + 1 &saat + + + 1 &day + 1 &gün + + + 1 &week + 1 &hafta + + + 1 &year + 1 &yıl + + + &Unban Node + Düğümün Yasağını Kald&ır + Welcome to the Bitcoin Core RPC console. Bitcoin Çekirdeği RPC konsoluna hoş geldiniz. @@ -1573,6 +1705,10 @@ %1 GB %1 GB + + (node id: %1) + (düğüm kimliği: %1) + via %1 %1 vasıtasıyla @@ -1965,6 +2101,10 @@ Copy change Para üstünü kopyala + + Total Amount %1 + Toplam Meblağ %1 + or veya @@ -1997,6 +2137,14 @@ Payment request expired. Ödeme talebinin ömrü doldu. + + Pay only the required fee of %1 + Sadece gerekli ücret olan %1 tutarını öde + + + Estimated to begin confirmation within %n block(s). + Tahmini olarak %n blok içinde teyide başlanacaktır.Tahmini olarak %n blok içinde teyide başlanacaktır. + The recipient address is not valid. Please recheck. Alıcı adresi geçerli değildir. Lütfen denetleyiniz. @@ -2628,6 +2776,10 @@ Copy transaction ID Muamele kimliğini kopyala + + Copy raw transaction + Ham muameleyi kopyala + Edit label Etiketi düzenle @@ -2775,10 +2927,54 @@ Accept command line and JSON-RPC commands Komut satırı ve JSON-RPC komutlarını kabul et + + If <category> is not supplied or if <category> = 1, output all debugging information. + Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Tek cüzdan muamelesinde kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontol ediniz! Saatinizde gecikme varsa Bitcoin Çekirdeği doğru şekilde çalışamaz. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Prune, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Budama: son cüzdan eşleşmesi budanmış verilerin ötesine gitmektedir. -reindex kullanmanız gerekmektedir (Budanmış düğüm ise tüm blok zincirini tekrar indirmeniz gerekir.) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Depolama gerekliliğini eski blokları budayarak (silerek) düşür. Bu kip -txindex ve -rescan ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, >%u = MiB olarak blok dosyaları için kullanılacak hedef boyut) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Tekrar taramalar budanmış kipte mümkün değildir. Tüm blok zincirini tekrar indirecek olan -reindex seçeneğini kullanmanız gerekecektir. + + + Error: A fatal internal error occurred, see debug.log for details + Hata: Ölümcül dahili bir hata meydana geldi, ayrıntılar için debug.log dosyasına bakınız + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Yolladığınız muamelelere eklenecek ücret (%s/kB olarak) (varsayılan: %s) + + + Pruning blockstore... + Blockstore budanıyor... + Run in the background as a daemon and accept commands Arka planda daemon (servis) olarak çalış ve komutları kabul et + + Unable to start HTTP server. See debug log for details. + HTTP sunucusu başlatılamadı. Ayrıntılar için debug.log dosyasına bakınız. + Accept connections from outside (default: 1 if no -proxy or -connect) Dışarıdan gelen bağlantıları kabul et (varsayılan: -proxy veya -connect yoksa 1) @@ -2803,6 +2999,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) + + 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 + Blok veritabanı gelecekten gibi görünen bir blok içermektedir. Bu, bilgisayarınızın saat ve tarihinin yanlış ayarlanmış olmasından kaynaklanabilir. Blok veritabanını sadece bilgisayarınızın tarih ve saatinin doğru olduğundan eminseniz yeniden derleyin. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız @@ -2811,6 +3011,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu) @@ -2835,6 +3039,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir. + + -maxmempool must be at least %d MB + -maxmempool asgari %d MB olmalıdır + <category> can be: <kategori> şunlar olabilir: @@ -2867,6 +3075,22 @@ Do you want to rebuild the block database now? Blok veritabanını şimdi yeniden inşa etmek istiyor musunuz? + + Enable publish hash block in <address> + Blok karma değerinin <adres>te yayınlanmasını etkinleştir + + + Enable publish hash transaction in <address> + Karma değer muamelesinin <adres>te yayınlanmasını etkinleştir + + + Enable publish raw block in <address> + Ham blokun <adres>te yayınlanmasını etkinleştir + + + Enable publish raw transaction in <address> + Ham muamelenin <adres>te yayınlanmasını etkinleştir + Error initializing block database Blok veritabanını başlatılırken bir hata meydana geldi @@ -2903,6 +3127,10 @@ Invalid -onion address: '%s' Geçersiz -onion adresi: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u) + Not enough file descriptors available. Kafi derecede dosya tanımlayıcıları mevcut değil. @@ -2931,10 +3159,26 @@ Specify wallet file (within data directory) Cüzdan dosyası belirtiniz (veri klasörünün içinde) + + Unsupported argument -benchmark ignored, use -debug=bench. + Desteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız. + + + Unsupported argument -debugnet ignored, use -debug=net. + Desteklenmeyen -debugnet argümanı görmezden gelindi, debug=net kullanınız. + + + Unsupported argument -tor found, use -onion. + Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız. + Use UPnP to map the listening port (default: %u) Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u) + + User Agent comment (%s) contains unsafe characters. + Kullanıcı Aracı açıklaması (%s) güvensiz karakterler içermektedir. + Verifying blocks... Bloklar kontrol ediliyor... @@ -2991,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) İlgili bir uyarı alındığında ya da gerçekten uzun bir çatallama gördüğümüzde komutu çalıştır (komuttaki %s mesaj ile değiştirilir) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve muamele yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u) @@ -3047,6 +3295,18 @@ Activating best chain... En iyi zincir etkinleştiriliyor... + + Always relay transactions received from whitelisted peers (default: %d) + Beyaz listedeki eşlerden gelen muameleleri daima aktar (varsayılan: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Başlangıçta bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene + + + Automatically create Tor hidden service (default: %d) + Otomatik olarak gizli Tor servisi oluştur (varsayılan: %d) + Cannot resolve -whitebind address: '%s' -whitebind adresi çözümlenemedi: '%s' @@ -3067,6 +3327,10 @@ Error reading from database, shutting down. Veritabanından okumada hata, kapatılıyor. + + Imports blocks from external blk000??.dat file on startup + Başlangıçta harici blk000??.dat dosyasından blokları içe aktarır + Information Bilgi @@ -3119,6 +3383,14 @@ Receive and display P2P network alerts (default: %u) P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Sistem sınırlamaları sebebiyle -maxconnections %d değerinden %d değerine düşürülmüştür. + + + Rescan the block chain for missing wallet transactions on startup + Başlangıçta blok zincirini eksik cüzdan muameleleri için tekrar tara + Send trace/debug info to console instead of debug.log file Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder @@ -3147,6 +3419,14 @@ This is experimental software. Bu, deneysel bir yazılımdır. + + Tor control port password (default: empty) + Tor kontrol portu parolası (varsayılan: boş) + + + Tor control port to use if onion listening enabled (default: %s) + Eğer onion dinlenmesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s) + Transaction amount too small Muamele meblağı çok düşük @@ -3167,6 +3447,10 @@ Unable to bind to %s on this computer (bind returned error %s) Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi) + + Upgrade wallet to latest format on startup + Başlangıçta cüzdanı en yeni biçime güncelle + Username for JSON-RPC connections JSON-RPC bağlantıları için kullanıcı ismi @@ -3179,10 +3463,18 @@ Warning Uyarı + + Whether to operate in a blocks only mode (default: %u) + Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u) + Zapping all transactions from wallet... Cüzdandaki tüm muameleler kaldırılıyor... + + ZeroMQ notification options: + ZeroMQ bildirim seçenekleri: + wallet.dat corrupt, salvage failed wallet.dat bozuk, geri kazanım başarısız oldu @@ -3215,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) -checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u) @@ -3231,10 +3543,30 @@ Output debugging information (default: %u, supplying <category> is optional) Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Blokların ve muamelelerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Şebeke sürümü zincirinin toplam boyutu (%i) azami boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Giden trafiği belirtilen hedefin altında tutmaya çalışır (24 saat başı MiB olarak), 0 = sınırsız (varsayılan: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Desteklenmeyen -socks argümanı bulundu. SOCKS sürümünün ayarlanması artık mümkün değildir, sadece SOCKS5 vekilleri desteklenmektedir. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC bağlantıları için kullanıcı ismi ve karmalanmış parola. <userpw> alanı şu biçimdedir: <USERNAME>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Bu seçenek birden çok kez belirtilebilir. + (default: %s) (varsayılan: %s) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index bca64ba05..10866b011 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -117,6 +117,10 @@ BitcoinGUI + + &Receiving addresses... + Alış adresleri + ClientModel @@ -130,6 +134,14 @@ EditAddressDialog + + &Label + Etiket + + + &Address + Adres + FreespaceChecker @@ -169,6 +181,10 @@ ReceiveRequestDialog + + Copy &Address + &Adresi Kopyala + Address Adres diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 5e2a06c73..ea783aa85 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -882,6 +882,34 @@ command-line options параметри командного рядка + + UI Options: + Параметри інтерфейсу: + + + Choose data directory on startup (default: %u) + Обирати каталог даних під час запуску (типово: %u) + + + Set language, for example "de_DE" (default: system locale) + Встановити мову (наприклад: "de_DE") (типово: системна) + + + Start minimized + Запускати згорнутим + + + Set SSL root certificates for payment request (default: -system-) + Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-) + + + Show splash screen on startup (default: %u) + Показувати заставку під час запуску (типово: %u) + + + Reset all settings changes made over the GUI + Скинути налаштування, які було змінено через графічний інтерфейс користувача + Intro @@ -1083,6 +1111,10 @@ Used for reaching peers via: Приєднуватися до учасників через: + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Вказує на використання наявного типового проксі SOCKS5, що використувується задля встановлення зв'язку з пірами через мережу такого типу. + IPv4 IPv4 @@ -1473,6 +1505,18 @@ Current number of blocks Поточне число блоків + + Memory Pool + Пул пам'яті + + + Current number of transactions + Поточне число транзакцій + + + Memory usage + Використання пам'яті + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів. @@ -2057,6 +2101,10 @@ Copy change Копіювати решту + + Total Amount %1 + Всього %1 + or або @@ -2089,6 +2137,10 @@ Payment request expired. Запит платежу прострочено. + + Pay only the required fee of %1 + Сплатіть лише мінімальну комісію у розмірі %1 + Estimated to begin confirmation within %n block(s). Перше підтвердження очікується протягом %n блоку.Перше підтвердження очікується протягом %n блоків.Перше підтвердження очікується протягом %n блоків. @@ -2724,6 +2776,10 @@ Copy transaction ID Скопіювати ID транзакції + + Copy raw transaction + Скопіювати RAW транзакцію + Edit label Редагувати мітку @@ -2887,6 +2943,10 @@ Prune configured below the minimum of %d MiB. Please use a higher number. Встановлений розмір ланцюжка блоків є замалим (меншим за %d МіБ). Будь ласка, виберіть більше число. + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Операція відсікання: остання синхронізація вмісту гаманцю не обмежується діями над скороченими данними. Вам необхідно зробити переіндексацію -reindex (заново завантажити веcь ланцюжок блоків в разі появи скороченого ланцюга) + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим несумісний з параметрами -txindex та -rescan. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ) @@ -3015,6 +3075,22 @@ Do you want to rebuild the block database now? Ви хочете перебудувати базу даних блоків зараз? + + Enable publish hash block in <address> + Дозволено введення хеш блоку в рядок <address> + + + Enable publish hash transaction in <address> + Дозволено введення хеш транзакції в рядок <address> + + + Enable publish raw block in <address> + Дозволено введення RAW блоку в рядок <address> + + + Enable publish raw transaction in <address> + Дозволено введення RAW транзакції в рядок <address> + Error initializing block database Помилка ініціалізації бази даних блоків @@ -3159,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Виконати команду при надходженні важливого сповіщення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для зміни, аналізу та створення транзакцій (типово: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u) @@ -3215,6 +3295,18 @@ Activating best chain... Активація найкращого ланцюжка... + + Always relay transactions received from whitelisted peers (default: %d) + Завжди передавайте транзакції отримані від пірів з білого списку (типово: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Спочатку спробуйте відновити приватні ключі в пошкодженому wallet.dat + + + Automatically create Tor hidden service (default: %d) + Автоматичне з'єднання з прихованим сервісом Tor (типово: %d) + Cannot resolve -whitebind address: '%s' Не вдалося розпізнати адресу для -whitebind: «%s» @@ -3235,6 +3327,10 @@ Error reading from database, shutting down. Помилка читання бази даних, припиняю роботу. + + Imports blocks from external blk000??.dat file on startup + Спочатку імпортує блоки з зовнішнього файлу blk000??.dat + Information Інформація @@ -3291,6 +3387,10 @@ Reducing -maxconnections from %d to %d, because of system limitations. Зменшення значення -maxconnections з %d до %d із-за обмежень системи. + + Rescan the block chain for missing wallet transactions on startup + Спочатку переглянте ланцюжок блоків на наявність втрачених транзакцій гаманця + Send trace/debug info to console instead of debug.log file Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log @@ -3319,6 +3419,14 @@ This is experimental software. Це програмне забезпечення є експериментальним. + + Tor control port password (default: empty) + Пароль управління порт протоколом Tor (типово: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Скористайтесь управлінням порт протоколом Tor, в разі перехоплення обміну цибулевої маршрутизації (типово: %s) + Transaction amount too small Сума транзакції занадто мала @@ -3339,6 +3447,10 @@ Unable to bind to %s on this computer (bind returned error %s) Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s) + + Upgrade wallet to latest format on startup + Спочатку оновіть гаманець до останньої версії + Username for JSON-RPC connections Ім'я користувача для JSON-RPC-з'єднань @@ -3351,6 +3463,10 @@ Warning Попередження + + Whether to operate in a blocks only mode (default: %u) + Чи слід працювати в режимі тільки блоки (типово: %u) + Zapping all transactions from wallet... Видалення всіх транзакцій з гаманця... @@ -3407,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Помилка читання wallet.dat! Всі ключі прочитано коректно, але дані транзакцій чи записи адресної книги можуть бути пропущені або пошкоджені. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для створення транзакцій (типово: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Рівень ретельності перевірки блоків (0-4, типово: %u) @@ -3423,10 +3543,18 @@ Output debugging information (default: %u, supplying <category> is optional) Виводити налагоджувальну інформацію (типово: %u, вказання <category> необов'язкове) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Фільтрація блоків та транзакцій з допомогою фільтрів Блума (типово: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Загальна довжина рядку мережевої версії (%i) перевищує максимально допустиму (%i). Зменшіть число чи розмір коментарів клієнта користувача. + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Намагається зберегти вихідний трафік відповідно до зданого значення (в MIB за 24 години), 0 = без обмежень (типово: %d) + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Параметр -socks не підтримується. Можливість вказувати версію SOCKS було видалено, так як підтримується лише SOCKS5. @@ -3435,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor (типово: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Логін та хешований пароль для зв'язків JSON-RPC. Поле <userpw> має формат: <USERNAME>:<SALT>$<HASH>. Класичний Python script додано до share/rpcuser. Цей параметр може бути застосований декілька разів. + (default: %s) (типово: %s) diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index db5cca3cc..e37c87baa 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -123,6 +123,10 @@ CoinControlDialog + + Amount: + رقم: + Amount رقم @@ -138,6 +142,14 @@ EditAddressDialog + + &Label + چٹ + + + &Address + پتہ + FreespaceChecker @@ -185,6 +197,10 @@ ReceiveRequestDialog + + Copy &Address + کاپی پتہ + Address پتہ @@ -219,6 +235,14 @@ SendCoinsDialog + + Insufficient funds! + ناکافی فنڈز + + + Amount: + رقم: + Balance: بیلنس: diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 4350d0ac8..86724564f 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -792,6 +792,10 @@ About Bitcoin Core Bitcoin Core ҳақида + + Command-line options + Буйруқлар сатри мосламалари + Usage: Фойдаланиш: @@ -800,7 +804,7 @@ command-line options буйруқлар қатори орқали мослаш - + Intro @@ -905,6 +909,10 @@ &Network Тармоқ + + W&allet + Ҳамён + Proxy &IP: Прокси &IP рақами: @@ -1690,6 +1698,10 @@ Message: Хабар + + Pay To: + Тўлов олувчи: + ShutdownWindow @@ -2018,6 +2030,10 @@ Export Transaction History Ўтказмалар тарихини экспорт қилиш + + Watch-only + Фақат кўришга + Exporting Failed Экспорт қилиб бўлмади @@ -2137,6 +2153,10 @@ Loading addresses... Манзиллар юкланмоқда... + + Insufficient funds + Кам миқдор + Loading block index... Тўсиқ индекси юкланмоқда... diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 7a7c68c4b..47745a3bc 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -59,6 +59,10 @@ CoinControlDialog + + Amount: + Số lượng: + Amount Số lượng @@ -70,6 +74,14 @@ EditAddressDialog + + &Label + Nhãn dữ liệu + + + &Address + Địa chỉ + FreespaceChecker @@ -113,6 +125,10 @@ ReceiveRequestDialog + + Copy &Address + Sao chép địa chỉ + Address Địa chỉ @@ -143,6 +159,10 @@ SendCoinsDialog + + Amount: + Số lượng: + (no label) (chưa có nhãn) diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index c55aecd82..d55fa6188 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -165,6 +165,10 @@ Show information about Qt Xem thông tin về Qt + + &Receiving addresses... + Địa chỉ nhận + Open &URI... Mở &URI... @@ -354,6 +358,14 @@ EditAddressDialog + + &Label + Nhãn + + + &Address + Địa chỉ + FreespaceChecker @@ -417,6 +429,10 @@ MB MB + + W&allet + + &Display &Hiển thị @@ -467,6 +483,10 @@ RPCConsole + + &Information + Thông tin + General Nhìn Chung @@ -490,6 +510,10 @@ ReceiveCoinsDialog + + &Amount: + Lượng: + Copy label Copy nhãn @@ -501,6 +525,10 @@ ReceiveRequestDialog + + Copy &Address + &Copy Địa Chỉ + Address Địa chỉ @@ -535,6 +563,10 @@ SendCoinsDialog + + Insufficient funds! + Không đủ tiền + Quantity: Lượng: @@ -570,6 +602,10 @@ SendCoinsEntry + + A&mount: + Lượng: + ShutdownWindow @@ -673,6 +709,14 @@ bitcoin-core + + Options: + Lựa chọn: + + + (default: %u) + (mặc định: %u) + Information Thông tin diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts index 288c1c5f2..aeb4faa71 100644 --- a/src/qt/locale/bitcoin_zh.ts +++ b/src/qt/locale/bitcoin_zh.ts @@ -87,6 +87,10 @@ SendCoinsDialog + + Insufficient funds! + 余额不足 + Choose... 选择... diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 778462e68..0ae2c95c6 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -23,7 +23,7 @@ C&lose - 关闭(&C) + 关闭(&l) &Copy Address @@ -133,7 +133,7 @@ Encrypt wallet - 钱包加密 + 加密钱包 This operation needs your wallet passphrase to unlock the wallet. @@ -226,7 +226,11 @@ IP/Netmask IP/网络掩码 - + + Banned Until + 在此之前禁止: + + BitcoinGUI @@ -267,7 +271,7 @@ About &Qt - 关于 &Qt + 关于Qt(&Q) Show information about Qt @@ -303,7 +307,7 @@ Bitcoin Core client - 比特币核心钱包 + 比特币核心钱包客户端 Importing blocks from disk... @@ -311,7 +315,7 @@ Reindexing blocks on disk... - 正在为数据块建立索引... + 正在为数据块重建索引... Send coins to a Bitcoin address @@ -878,6 +882,34 @@ command-line options 命令行选项 + + UI Options: + 界面选项: + + + Choose data directory on startup (default: %u) + 在启动时选择目录(默认%u) + + + Set language, for example "de_DE" (default: system locale) + 设置语言, 例如“zh-CN”(默认:系统语言) + + + Start minimized + 启动时最小化 + + + Set SSL root certificates for payment request (default: -system-) + 设置付款请求的SSL根证书(默认:-系统-) + + + Show splash screen on startup (default: %u) + 显示启动画面(默认:%u) + + + Reset all settings changes made over the GUI + 重置所有图形界面所做的更改 + Intro @@ -1075,6 +1107,14 @@ Port of the proxy (e.g. 9050) 代理端口(例如 9050) + + Used for reaching peers via: + 连接到同伴的方式: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + 如果默认的SOCKS5代理被用于在该网络下连接同伴,则显示 + IPv4 IPv4 @@ -1087,6 +1127,14 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + 在Tor匿名网络下通过不同的SOCKS5代理连接比特币网络 + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 + &Window 窗口(&W) @@ -1457,6 +1505,18 @@ Current number of blocks 当前数据块数量 + + Memory Pool + 资金池 + + + Current number of transactions + 当前交易数量 + + + Memory usage + 内存使用 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。 @@ -1473,6 +1533,10 @@ &Peers 同伴(&P) + + Banned peers + 节点黑名单 + Select a peer to view detailed information. 选择节点查看详细信息。 @@ -1489,6 +1553,10 @@ Version 版本 + + Starting Block + 正在启动数据块 + Synced Headers 同步区块头 @@ -1525,6 +1593,10 @@ Ping Time Ping 时间 + + Ping Wait + Ping等待 + Time Offset 时间偏移 @@ -1573,6 +1645,14 @@ Clear console 清空控制台 + + &Disconnect Node + (&D)断开节点连接 + + + Ban Node for + 禁止节点连接时长: + 1 &hour 1 小时(&H) @@ -1589,6 +1669,10 @@ 1 &year 1 年(&Y) + + &Unban Node + (&U)允许节点连接 + Welcome to the Bitcoin Core RPC console. 欢迎使用 比特币核心 RPC 控制台。 @@ -2013,6 +2097,10 @@ Copy change 复制零钱 + + Total Amount %1 + 总金额 %1 + or @@ -2045,6 +2133,10 @@ Payment request expired. 支付请求已过期。 + + Pay only the required fee of %1 + 只支付必要费用 %1 + Estimated to begin confirmation within %n block(s). 预计 %n 个数据块后被确认。 @@ -2680,6 +2772,10 @@ Copy transaction ID 复制交易编号 + + Copy raw transaction + 复制原始交易 + Edit label 编辑标签 @@ -2830,10 +2926,34 @@ 接受命令行和 JSON-RPC 命令 + + If <category> is not supplied or if <category> = 1, output all debugging information. + 如果<category>未提供或<category> = 1,输出所有调试信息。 + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + 最大单次转账费用(%s),设置太低可能导致大宗交易失败(默认:%s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + 警请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。 + + + Prune configured below the minimum of %d MiB. Please use a higher number. + 修剪值被设置为低于最小值%d MiB,请使用更大的数值。 + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + 无法在开启修剪的状态下重扫描,请使用 -reindex重新下载完整的区块链。 + Error: A fatal internal error occurred, see debug.log for details 错误:发生了致命的内部错误,详情见 debug.log 文件 + + Fee (in %s/kB) to add to transactions you send (default: %s) + 为付款交易添加交易费 (%s/kB) (默认: %s) + Pruning blockstore... 正在修剪区块存储... @@ -2844,6 +2964,10 @@ + + Unable to start HTTP server. See debug log for details. + 无法启动HTTP服务,查看日志获取更多信息 + Accept connections from outside (default: 1 if no -proxy or -connect) 接受来自外部的连接 (缺省: 如果不带 -proxy or -connect 参数设置为1) @@ -2868,6 +2992,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d) + + 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 + 区块数据库包含未来的交易,这可能是由本机错误的日期时间引起。若确认本机日期时间正确,请重新建立区块数据库。 + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 这是测试用的预发布版本 - 请谨慎使用 - 不要用来挖矿,或者在正式商用环境下使用 @@ -2876,6 +3004,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. 无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。 + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + 使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) 警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个) @@ -2900,6 +3032,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 节点白名单,网络掩码或IP址。可多次指定。 + + -maxmempool must be at least %d MB + -maxmempool 最小为%d MB + <category> can be: <category> 可能是: @@ -2932,6 +3068,22 @@ Do you want to rebuild the block database now? 你想现在就重建块数据库吗? + + Enable publish hash block in <address> + 允许在<address>广播哈希区块 + + + Enable publish hash transaction in <address> + 允许在<address>广播哈希交易 + + + Enable publish raw block in <address> + 允许在<address>广播原始区块 + + + Enable publish raw transaction in <address> + 允许在<address>广播原始交易 + Error initializing block database 初始化数据块数据库出错 @@ -2968,6 +3120,10 @@ Invalid -onion address: '%s' 无效的 -onion 地址:“%s” + + Keep the transaction memory pool below <n> megabytes (default: %u) + 保持交易内存池大小低于<n>MB(默认:%u) + Not enough file descriptors available. 没有足够的文件描述符可用。 @@ -2996,6 +3152,18 @@ Specify wallet file (within data directory) 指定钱包文件(数据目录内) + + Unsupported argument -benchmark ignored, use -debug=bench. + 忽略不支持的选项 -benchmark,使用 -debug=bench + + + Unsupported argument -debugnet ignored, use -debug=net. + 忽略不支持的选项 -debugnet,使用 -debug=net。 + + + Unsupported argument -tor found, use -onion. + 忽略不支持的选项 -tor,使用 -oinon + Use UPnP to map the listening port (default: %u) 使用UPnp映射监听端口 (默认: %u) @@ -3160,6 +3328,10 @@ Invalid netmask specified in -whitelist: '%s' -whitelist: '%s' 指定的网络掩码无效 + + Keep at most <n> unconnectable transactions in memory (default: %u) + 内存中最多保留 <n> 笔孤立的交易 (默认: %u) + Need to specify a port with -whitebind: '%s' -whitebind: '%s' 需要指定一个端口 @@ -3180,6 +3352,10 @@ Receive and display P2P network alerts (default: %u) 收到并且显示P2P网络的告警(默认:%u) + + Rescan the block chain for missing wallet transactions on startup + 重新扫描区块链以查找遗漏的钱包交易 + Send trace/debug info to console instead of debug.log file 跟踪/调试信息输出到控制台,不输出到 debug.log 文件 @@ -3228,6 +3404,10 @@ Unable to bind to %s on this computer (bind returned error %s) 无法在此计算机上绑定 %s (绑定返回错误 %s) + + Upgrade wallet to latest format on startup + 程序启动时升级钱包到最新格式 + Username for JSON-RPC connections JSON-RPC 连接用户名 @@ -3240,6 +3420,10 @@ Warning 警告 + + Whether to operate in a blocks only mode (default: %u) + 是否用块方进行 (%u) + Zapping all transactions from wallet... Zapping all transactions from wallet... @@ -3298,6 +3482,10 @@ Output debugging information (default: %u, supplying <category> is optional) 输出调试信息 (默认: %u, 提供 <category> 是可选项) + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + 尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s) @@ -3306,6 +3494,10 @@ (default: %s) (默认: %s) + + Always query for peer addresses via DNS lookup (default: %u) + 始终通过 DNS 查询节点地址 (默认: %u) + Error loading wallet.dat wallet.dat 钱包文件加载出错 diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 67fb692ea..402609592 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -882,6 +882,34 @@ command-line options 命令列選項 + + UI Options: + 使用介面選項: + + + Choose data directory on startup (default: %u) + 啓動時選擇資料目錄(預設值: %u) + + + Set language, for example "de_DE" (default: system locale) + 設定語言,比如說 de_DE (預設值: 系統語系) + + + Start minimized + 啓動時縮到最小 + + + Set SSL root certificates for payment request (default: -system-) + 設定付款請求時所使用的 SSL 根憑證(預設值: 系統憑證庫) + + + Show splash screen on startup (default: %u) + 顯示啓動畫面(預設值: %u) + + + Reset all settings changes made over the GUI + 重置所有在使用界面更改的設定 + Intro @@ -1477,6 +1505,18 @@ Current number of blocks 目前區塊數 + + Memory Pool + 記憶體暫存池 + + + Current number of transactions + 目前交易數目 + + + Memory usage + 記憶體使用量 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 @@ -2101,6 +2141,10 @@ Pay only the required fee of %1 只付必要的手續費 %1 + + Estimated to begin confirmation within %n block(s). + 預計可在 %n 個區塊內開始確認。 + The recipient address is not valid. Please recheck. 收款位址無效。請再檢查看看。 @@ -3128,6 +3172,10 @@ Unsupported argument -tor found, use -onion. 找到不再支援的 -tor 參數,請改用 -onion 參數。 + + Use UPnP to map the listening port (default: %u) + 使用通用隨插即用 (UPnP) 協定來設定對應的服務連接埠(預設值: %u) + User Agent comment (%s) contains unsafe characters. 使用者代理註解(%s)中含有不安全的字元。 @@ -3230,7 +3278,7 @@ Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway - 在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。 + 在白名單中的節點不會因為偵測到阻斷服務攻擊(DoS)而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。 You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain @@ -3470,12 +3518,16 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) - 不要讓交易留在記憶體暫存池中超過 <n> 個小時(預設值: %u) + 不要讓交易留在記憶池中超過 <n> 個小時(預設值: %u) Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. 讀取錢包檔 wallet.dat 時發生錯誤!所有的密鑰都正確讀取了,但是交易資料或位址簿資料可能會缺少或不正確。 + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + 當製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) 使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u) @@ -3492,6 +3544,10 @@ Output debugging information (default: %u, supplying <category> is optional) 輸出除錯資訊(預設值: %u, 不一定要指定 <category>) + + Support filtering of blocks and transaction with bloom filters (default: %u) + 支援用布倫過濾器來過濾區塊和交易(預設值: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. 網路版本字串的總長度(%i)超過最大長度(%i)了。請減少 uacomment 參數的數目或長度。 @@ -3508,6 +3564,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟其他節點聯絡(預設值: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC 連線要用的使用者名稱和雜湊密碼。<userpw> 的格式是:<使用者名稱>:<調味值>$<雜湊值>。在 share/rpcuser 目錄下有一個示範的 python 程式。這個選項可以給很多次。 + (default: %s) (預設值: %s) From fada0c90b655226ddf79cd49dadb0d193f76edad Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 02:06:04 +0100 Subject: [PATCH 0100/1223] [travis] Fail when documentation is outdated --- .travis.yml | 1 + contrib/devtools/README.md | 6 +++++ contrib/devtools/check-doc.py | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100755 contrib/devtools/check-doc.py diff --git a/.travis.yml b/.travis.yml index e2d43d633..1a389a404 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,5 +70,6 @@ script: - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$RUN_TESTS" = "true" ]; then make check; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi + - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi after_script: - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index a58b8733a..1647d3ee3 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -2,6 +2,12 @@ Contents ======== This directory contains tools for developers working on this repository. +check-doc.py +============ + +Check if all command line args are documented. The return value indicates the +number of undocumented args. + clang-format.py =============== diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py new file mode 100755 index 000000000..bc4ad5349 --- /dev/null +++ b/contrib/devtools/check-doc.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +''' +This checks if all command line args are documented. +Return value is 0 to indicate no error. + +Author: @MarcoFalke +''' + +from subprocess import check_output +import re + +FOLDER_GREP = 'src' +FOLDER_TEST = 'src/test/' +CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/%s' % FOLDER_GREP +CMD_GREP_ARGS = r"egrep -r -I '(map(Multi)?Args(\.count\(|\[)|Get(Bool)?Arg\()\"\-[^\"]+?\"' %s | grep -v '%s'" % (CMD_ROOT_DIR, FOLDER_TEST) +CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_ROOT_DIR) +REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') +REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') +# list unsupported, deprecated and duplicate args as they need no documentation +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet']) + +def main(): + used = check_output(CMD_GREP_ARGS, shell=True) + docd = check_output(CMD_GREP_DOCS, shell=True) + + args_used = set(re.findall(REGEX_ARG,used)) + args_docd = set(re.findall(REGEX_DOC,docd)).union(SET_DOC_OPTIONAL) + args_need_doc = args_used.difference(args_docd) + args_unknown = args_docd.difference(args_used) + + print "Args used : %s" % len(args_used) + print "Args documented : %s" % len(args_docd) + print "Args undocumented: %s" % len(args_need_doc) + print args_need_doc + print "Args unknown : %s" % len(args_unknown) + print args_unknown + + exit(len(args_need_doc)) + +if __name__ == "__main__": + main() From fa3c7e644f427329bcffa1a5600fdbd7e97c837f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 5 Jan 2016 00:38:12 +0100 Subject: [PATCH 0101/1223] [wallet] Add regression test for vValue sort order --- src/wallet/test/wallet_tests.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index ee4f228a0..a13893127 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -328,6 +328,24 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } +BOOST_AUTO_TEST_CASE(sorting_in_ApproximateBestSet) +{ + CoinSet setCoinsRet; + CAmount nValueRet; + + LOCK(wallet.cs_wallet); + + empty_wallet(); + + for (int i = 0; i < 1000; i++) + add_coin(1000 * COIN); + add_coin(3 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); +} + BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet) { CoinSet setCoinsRet; From 995b9f385b935e4e9b9fa46e82f642204cc85cba Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 5 Jan 2016 13:10:19 -0500 Subject: [PATCH 0102/1223] Always respect GetRequiredFee for wallet txs --- src/wallet/wallet.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 444bd88f8..244bc37e7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2223,14 +2223,9 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge if (nFeeNeeded == 0) { int estimateFoundTarget = nConfirmTarget; nFeeNeeded = pool.estimateSmartFee(nConfirmTarget, &estimateFoundTarget).GetFee(nTxBytes); - // ... unless we don't have enough mempool data for our desired target - // so we make sure we're paying at least minTxFee - if (nFeeNeeded == 0 || (unsigned int)estimateFoundTarget > nConfirmTarget) - nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes)); } - // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee - if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) - nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); + // prevent user from paying a fee below minRelayTxFee or minTxFee + nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes)); // But always obey the maximum if (nFeeNeeded > maxTxFee) nFeeNeeded = maxTxFee; From e420a1b15e3be8c9d862173d9d554563405b34a7 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 5 Jan 2016 13:11:34 -0500 Subject: [PATCH 0103/1223] Add sane fallback for fee estimation Add new commandline option "-fallbackfee" to use when fee estimation does not have sufficient data. --- src/init.cpp | 11 +++++++++++ src/qt/sendcoinsdialog.cpp | 6 ++++-- src/wallet/wallet.cpp | 9 +++++++++ src/wallet/wallet.h | 3 +++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index c768ca75b..ba85a7972 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -393,6 +393,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), @@ -947,6 +949,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) else return InitError(strprintf(_("Invalid amount for -mintxfee=: '%s'"), mapArgs["-mintxfee"])); } + if (mapArgs.count("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); + if (nFeePerK > nHighTransactionFeeWarning) + InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); + } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 31c9028c4..c834c3b56 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -640,13 +640,15 @@ void SendCoinsDialog::updateSmartFeeLabel() CFeeRate feeRate = mempool.estimateSmartFee(nBlocksToConfirm, &estimateFoundAtBlocks); if (feeRate <= CFeeRate(0)) // not enough data => minfee { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::GetRequiredFee(1000)) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(CWallet::fallbackFee.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...) ui->labelFeeEstimation->setText(""); } else { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(feeRate.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->hide(); ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", estimateFoundAtBlocks)); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 244bc37e7..581c688fc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -47,6 +47,12 @@ bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; * Override with -mintxfee */ CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE); +/** + * If fee estimation does not have enough data to provide estimates, use this fee instead. + * Has no effect if not using fee estimation + * Override with -fallbackfee + */ +CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE); /** @defgroup mapWallet * @@ -2223,6 +2229,9 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge if (nFeeNeeded == 0) { int estimateFoundTarget = nConfirmTarget; nFeeNeeded = pool.estimateSmartFee(nConfirmTarget, &estimateFoundTarget).GetFee(nTxBytes); + // ... unless we don't have enough mempool data for estimatefee, then use fallbackFee + if (nFeeNeeded == 0) + nFeeNeeded = fallbackFee.GetFee(nTxBytes); } // prevent user from paying a fee below minRelayTxFee or minTxFee nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes)); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 53a2b9669..ce57f4dae 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -41,6 +41,8 @@ static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -fallbackfee default +static const CAmount DEFAULT_FALLBACK_FEE = 20000; //! -mintxfee default static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; //! -maxtxfee default @@ -666,6 +668,7 @@ public: bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb); static CFeeRate minTxFee; + static CFeeRate fallbackFee; /** * Estimate the minimum fee considering user set parameters * and the required fee From faf3299b73ccb5044b7eaced229ac0c904aa25f5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 29 Dec 2015 15:38:38 +0100 Subject: [PATCH 0104/1223] [qt] Intro: Display required space Required space depends on the user's choice: -prune=0 -prune= --- src/qt/intro.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index ab63e98d4..412d34264 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -15,9 +15,15 @@ #include #include -/* Minimum free space (in bytes) needed for data directory */ +#include + static const uint64_t GB_BYTES = 1000000000LL; -static const uint64_t BLOCK_CHAIN_SIZE = 20LL * GB_BYTES; +/* Minimum free space (in GB) needed for data directory */ +static const uint64_t BLOCK_CHAIN_SIZE = 80; +/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ +static const uint64_t CHAIN_STATE_SIZE = 2; +/* Total required space (in GB) depending on user choice (prune, not prune) */ +static uint64_t requiredSpace; /* Check free space asynchronously to prevent hanging the UI thread. @@ -112,7 +118,11 @@ Intro::Intro(QWidget *parent) : signalled(false) { ui->setupUi(this); - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(BLOCK_CHAIN_SIZE/GB_BYTES)); + uint64_t pruneTarget = std::max(0, GetArg("-prune", 0)); + requiredSpace = BLOCK_CHAIN_SIZE; + if (pruneTarget) + requiredSpace = CHAIN_STATE_SIZE + std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); + ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(requiredSpace)); startThread(); } @@ -216,9 +226,9 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable ui->freeSpace->setText(""); } else { QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES); - if(bytesAvailable < BLOCK_CHAIN_SIZE) + if(bytesAvailable < requiredSpace * GB_BYTES) { - freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES); + freeString += " " + tr("(of %n GB needed)", "", requiredSpace); ui->freeSpace->setStyleSheet("QLabel { color: #800000 }"); } else { ui->freeSpace->setStyleSheet(""); From faf538bfdbb4ecebde73e95c80718c2d9ecee1f5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 5 Jan 2016 20:35:17 +0100 Subject: [PATCH 0105/1223] [trivial] Merge test cases and replace CENT with COIN --- src/wallet/test/wallet_tests.cpp | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a13893127..e0dea2da2 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } -BOOST_AUTO_TEST_CASE(sorting_in_ApproximateBestSet) +BOOST_AUTO_TEST_CASE(ApproximateBestSubset) { CoinSet setCoinsRet; CAmount nValueRet; @@ -336,7 +336,8 @@ BOOST_AUTO_TEST_CASE(sorting_in_ApproximateBestSet) LOCK(wallet.cs_wallet); empty_wallet(); - + + // Test vValue sort order for (int i = 0; i < 1000; i++) add_coin(1000 * COIN); add_coin(3 * COIN); @@ -344,25 +345,19 @@ BOOST_AUTO_TEST_CASE(sorting_in_ApproximateBestSet) BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); -} - -BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet) -{ - CoinSet setCoinsRet; - CAmount nValueRet; - - LOCK(wallet.cs_wallet); empty_wallet(); - for (int i = 0; i < 100; i++) - add_coin(10 * CENT); - for (int i = 0; i < 100; i++) - add_coin(1000 * CENT); - BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + // Test trimming + for (int i = 0; i < 100; i++) + add_coin(10 * COIN); + for (int i = 0; i < 100; i++) + add_coin(1000 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); // We need all 100 larger coins and exactly one small coin. - // Superfluous small coins must be pruned: - BOOST_CHECK_EQUAL(nValueRet, 100010 * CENT); + // Superfluous small coins must be trimmed from the set: + BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); } From fa7e4c0919e159eaf11c3de3dc5f4ab9306283bd Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 5 Jan 2014 21:03:23 +0100 Subject: [PATCH 0106/1223] Bump copyright headers to 2014 --- src/noui.h | 2 +- src/qt/coincontroltreewidget.h | 2 +- src/qt/csvmodelwriter.cpp | 2 +- src/qt/csvmodelwriter.h | 2 +- src/qt/editaddressdialog.cpp | 2 +- src/qt/macnotificationhandler.h | 2 +- src/qt/notificator.cpp | 2 +- src/qt/openuridialog.cpp | 2 +- src/qt/transactiondesc.h | 2 +- src/qt/transactiondescdialog.cpp | 2 +- src/qt/transactiondescdialog.h | 2 +- src/qt/transactionfilterproxy.cpp | 2 +- src/qt/transactionfilterproxy.h | 2 +- src/qt/transactionrecord.h | 2 +- src/qt/walletmodeltransaction.h | 2 +- src/test/multisig_tests.cpp | 2 +- src/threadsafety.h | 2 +- src/undo.h | 2 +- src/zmq/zmqconfig.h | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/noui.h b/src/noui.h index 15cd30a63..ff16cc9aa 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index 98a7d32f0..62645fcdb 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index 55c595708..8a1a49bb0 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index a2bf379f4..edea369ad 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 1c22594cd..5f45031e9 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index bd66b96b2..d4749b3d5 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 5a564248e..a45afde56 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 1c843aecb..5a6616134 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 5467348ee..01b90b130 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index fadaa98f4..f7b6995b2 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index 54374e359..f1371b385 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 7981eb7c9..9dcb72f55 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index acea9a1e3..7db02cd61 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index a5bc37571..49753ee31 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 7765fea4a..64922efad 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index b65c299ad..edf1650ca 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/threadsafety.h b/src/threadsafety.h index d01c50abb..61e63dbc7 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin Core developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/undo.h b/src/undo.h index 1c4ed95bf..d4fc84c90 100644 --- a/src/undo.h +++ b/src/undo.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h index 6057f5d1a..610d7fbda 100644 --- a/src/zmq/zmqconfig.h +++ b/src/zmq/zmqconfig.h @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From fa60d05a4e194b9e3d2991ee2636c40c68737052 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 5 Jan 2015 21:40:24 +0100 Subject: [PATCH 0107/1223] Add missing copyright headers --- qa/rpc-tests/bip65-cltv-p2p.py | 2 +- qa/rpc-tests/bipdersig-p2p.py | 2 +- qa/rpc-tests/invalidblockrequest.py | 2 +- qa/rpc-tests/invalidtxrequest.py | 2 +- qa/rpc-tests/maxblocksinflight.py | 2 +- qa/rpc-tests/p2p-acceptblock.py | 2 +- qa/rpc-tests/p2p-fullblocktest.py | 3 +-- qa/rpc-tests/sendheaders.py | 2 +- qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/comptool.py | 2 +- qa/rpc-tests/test_framework/coverage.py | 6 ++++++ src/addrman.cpp | 1 + src/addrman.h | 1 + src/chainparamsseeds.h | 4 ++++ src/consensus/merkle.cpp | 4 ++++ src/httprpc.cpp | 4 ++++ src/prevector.h | 4 ++++ src/qt/bitcoinstrings.cpp | 4 +++- src/qt/receiverequestdialog.cpp | 2 +- src/test/test_bitcoin.h | 4 ++++ src/test/univalue_tests.cpp | 1 + src/torcontrol.cpp | 4 ++++ 22 files changed, 47 insertions(+), 13 deletions(-) diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 5bb41df1a..a2326d105 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index ec1678cc2..0f5db9ef7 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index a74ecb128..23ea67441 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index d17b3d098..08da176c1 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index 1a9ae480a..0313bce73 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 23872d849..bf355780c 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index a6525e679..09346a6ef 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -1,6 +1,5 @@ #!/usr/bin/env python2 - -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index e6e26dbce..12559ead3 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 59aa8c15c..d7527d3fc 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -1,5 +1,5 @@ # blocktools.py - utilities for manipulating blocks and transactions -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index badbc0a1f..a4cd4d0a8 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index 50f066a85..d21a001b6 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -1,3 +1,9 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + """ This module contains utilities for doing coverage analysis on the RPC interface. diff --git a/src/addrman.cpp b/src/addrman.cpp index 078b9e168..f88d9c47c 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2012 Pieter Wuille +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/addrman.h b/src/addrman.h index 1123caabf..cccecd146 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,4 +1,5 @@ // Copyright (c) 2012 Pieter Wuille +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 423362859..740e4718c 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -1,3 +1,7 @@ +// Copyright (c) 2014-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_CHAINPARAMSSEEDS_H #define BITCOIN_CHAINPARAMSSEEDS_H /** diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 9a8afa8a3..22eb7159a 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "merkle.h" #include "hash.h" #include "utilstrencodings.h" diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 2920aa26f..4739fa8e2 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "httprpc.h" #include "base58.h" diff --git a/src/prevector.h b/src/prevector.h index 8992e305b..1da459bcf 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef _BITCOIN_PREVECTOR_H_ #define _BITCOIN_PREVECTOR_H_ diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 6b5f24366..41f1d5841 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -1,4 +1,6 @@ - +// Copyright (c) 2013-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #include diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 75108e0a1..a1e9156ee 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 273bfdd7f..c62392088 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_TEST_TEST_BITCOIN_H #define BITCOIN_TEST_TEST_BITCOIN_H diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 945c1acbe..45d480c81 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,4 +1,5 @@ // Copyright 2014 BitPay, Inc. +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 4ebcb9b66..e164b4e9f 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "torcontrol.h" #include "utilstrencodings.h" #include "net.h" From 96efcadfc0d8a84066982533c676072d3b5d8314 Mon Sep 17 00:00:00 2001 From: Murch Date: Mon, 7 Dec 2015 18:35:29 +0100 Subject: [PATCH 0108/1223] Improved readability of sorting for coin selection. Future proofing added lines --- src/wallet/wallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d23d54e67..0e1425640 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1701,7 +1701,8 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int } // Solve subset sum by stochastic approximation - sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + std::sort(vValue.begin(), vValue.end(), CompareValueOnly()); + std::reverse(vValue.begin(), vValue.end()); vector vfBest; CAmount nBest; From 76ac35f36d87078da62f95b4a1167ec296e37363 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 5 Jan 2016 15:58:48 -0500 Subject: [PATCH 0109/1223] c++11: detect and correct for boost builds with an incompatible abi This is ugly, but temporary. boost::filesystem will likely be dropped soon after c++11 is enabled. Otherwise, we could simply roll our own copy_file. I've fixed this at the buildsystem level for now in order to avoid mixing in functional changes. Explanation: If boost (prior to 1.57) was built without c++11, it emulated scoped enums using c++98 constructs. Unfortunately, this implementation detail leaked into the abi. This was fixed in 1.57. When building against that installed version using c++11, the headers pick up on the native c++11 scoped enum support and enable it, however it will fail to link. This can be worked around by disabling c++11 scoped enums if linking will fail. Add an autoconf test to determine incompatibility. At build-time, if native enums are being used (a c++11 build), and force-disabling them causes a successful link, we can be sure that there's an incompatibility and enable the work-around. --- configure.ac | 25 +++++++++++++++++++++++++ src/wallet/walletdb.cpp | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/configure.ac b/configure.ac index 9161e2b2c..07f9a4a6f 100644 --- a/configure.ac +++ b/configure.ac @@ -619,6 +619,31 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" +TEMP_LIBS="$LIBS" +LIBS="$BOOST_LIBS $LIBS" +TEMP_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +AC_MSG_CHECKING([for mismatched boost c++11 scoped enums]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include "boost/config.hpp" + #include "boost/version.hpp" + #if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700 + #define BOOST_NO_SCOPED_ENUMS + #define BOOST_NO_CXX11_SCOPED_ENUMS + #define CHECK + #endif + #include "boost/filesystem.hpp" + ]],[[ + #if defined(CHECK) + boost::filesystem::copy_file("foo", "bar"); + #else + choke; + #endif + ]])], + [AC_MSG_RESULT(mismatched); AC_DEFINE(FORCE_BOOST_EMULATED_SCOPED_ENUMS, 1, [Define this symbol if boost scoped enums are emulated])], [AC_MSG_RESULT(ok)]) +LIBS="$TEMP_LIBS" +CPPFLAGS="$TEMP_CPPFLAGS" + dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if dnl a working version is available, else fall back to sleep. sleep was removed diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 88dc3102d..f0e177695 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -15,6 +15,12 @@ #include "utiltime.h" #include "wallet/wallet.h" +#if defined(FORCE_BOOST_EMULATED_SCOPED_ENUMS) +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#include #include #include #include From 89f71c68c0fecf63059f6055ebdd25f1eba4c982 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 5 Jan 2016 16:10:13 -0500 Subject: [PATCH 0110/1223] c++11: don't throw from the reverselock destructor noexcept is default for destructors as of c++11. By throwing in reverselock's destructor if it's lock has been tampered with, the likely result is std::terminate being called. Indeed that happened before this change. Once reverselock has taken another lock (its ctor didn't throw), it makes no sense to try to grab or lock the parent lock. That is be broken/undefined behavior depending on the parent lock's implementation, but it shouldn't cause the reverselock to fail to re-lock when destroyed. To avoid those problems, simply swap the parent lock's contents with a dummy for the duration of the lock. That will ensure that any undefined behavior is caught at the call-site rather than the reverse lock's destruction. Barring a failed mutex unlock which would be indicative of a larger problem, the destructor should now never throw. --- src/reverselock.h | 5 ++++- src/test/reverselock_tests.cpp | 16 ++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/reverselock.h b/src/reverselock.h index 567636e16..fac1ccb79 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -15,10 +15,12 @@ public: explicit reverse_lock(Lock& lock) : lock(lock) { lock.unlock(); + lock.swap(templock); } ~reverse_lock() { - lock.lock(); + templock.lock(); + templock.swap(lock); } private: @@ -26,6 +28,7 @@ private: reverse_lock& operator=(reverse_lock const&); Lock& lock; + Lock templock; }; #endif // BITCOIN_REVERSELOCK_H diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index e7e627ae0..8bdff9700 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors) BOOST_CHECK(failed); BOOST_CHECK(!lock.owns_lock()); - // Make sure trying to lock a lock after it has been reverse locked fails - failed = false; - bool locked = false; + // Locking the original lock after it has been taken by a reverse lock + // makes no sense. Ensure that the original lock no longer owns the lock + // after giving it to a reverse one. lock.lock(); BOOST_CHECK(lock.owns_lock()); - - try { + { reverse_lock > rlock(lock); - lock.lock(); - locked = true; - } catch(...) { - failed = true; + BOOST_CHECK(!lock.owns_lock()); } - BOOST_CHECK(locked && failed); + BOOST_CHECK(failed); BOOST_CHECK(lock.owns_lock()); } From 57d2f62c99e7ec2c1c95809f0f8f7441c3201423 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 5 Jan 2016 16:25:42 -0500 Subject: [PATCH 0111/1223] c++11: CAccountingEntry must be defined before use in a list c++11ism. This fixes builds against libc++. --- src/wallet/wallet.h | 164 +++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 84 deletions(-) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 53a2b9669..a9d0c3f60 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -59,7 +59,6 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; -class CAccountingEntry; class CBlockIndex; class CCoinControl; class COutput; @@ -445,6 +444,86 @@ public: } }; +/** + * Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + CAmount nCreditDebit; + int64_t nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64_t nOrderPos; //! position in ordered transaction list + uint64_t nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + nEntryNo = 0; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + //! Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(LIMITED_STRING(strOtherAccount, 65536)); + + if (!ser_action.ForRead()) + { + WriteOrderPos(nOrderPos, mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + strComment.append(ss.str()); + } + } + + READWRITE(LIMITED_STRING(strComment, 65536)); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (ser_action.ForRead()) + { + mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> mapValue; + _ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(nOrderPos, mapValue); + } + if (std::string::npos != nSepPos) + strComment.erase(nSepPos); + + mapValue.erase("n"); + } + +private: + std::vector _ssExtra; +}; /** @@ -840,87 +919,4 @@ public: } }; - - -/** - * Internal transfers. - * Database key is acentry. - */ -class CAccountingEntry -{ -public: - std::string strAccount; - CAmount nCreditDebit; - int64_t nTime; - std::string strOtherAccount; - std::string strComment; - mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list - uint64_t nEntryNo; - - CAccountingEntry() - { - SetNull(); - } - - void SetNull() - { - nCreditDebit = 0; - nTime = 0; - strAccount.clear(); - strOtherAccount.clear(); - strComment.clear(); - nOrderPos = -1; - nEntryNo = 0; - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - //! Note: strAccount is serialized as part of the key, not here. - READWRITE(nCreditDebit); - READWRITE(nTime); - READWRITE(LIMITED_STRING(strOtherAccount, 65536)); - - if (!ser_action.ForRead()) - { - WriteOrderPos(nOrderPos, mapValue); - - if (!(mapValue.empty() && _ssExtra.empty())) - { - CDataStream ss(nType, nVersion); - ss.insert(ss.begin(), '\0'); - ss << mapValue; - ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); - strComment.append(ss.str()); - } - } - - READWRITE(LIMITED_STRING(strComment, 65536)); - - size_t nSepPos = strComment.find("\0", 0, 1); - if (ser_action.ForRead()) - { - mapValue.clear(); - if (std::string::npos != nSepPos) - { - CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); - ss >> mapValue; - _ssExtra = std::vector(ss.begin(), ss.end()); - } - ReadOrderPos(nOrderPos, mapValue); - } - if (std::string::npos != nSepPos) - strComment.erase(nSepPos); - - mapValue.erase("n"); - } - -private: - std::vector _ssExtra; -}; - #endif // BITCOIN_WALLET_WALLET_H From 3968922b9623af9da9959adc49a779d6837e1f0c Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 5 Jan 2016 16:27:42 -0500 Subject: [PATCH 0112/1223] c++11: fix libbdb build against libc++ in c++11 mode atomic_init clashes with --- depends/packages/bdb.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 68841afdb..e2f85ad4f 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -12,7 +12,8 @@ $(package)_config_opts_linux=--with-pic endef define $(package)_preprocess_cmds - sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h + sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \ + sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c endef define $(package)_config_cmds From bebe58b748532157958f9055e4517e280684006c Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 5 Jan 2016 17:47:04 -0500 Subject: [PATCH 0113/1223] SQUASHME: Fix rpc tests that assumed fallback to minRelayTxFee --- qa/rpc-tests/fundrawtransaction.py | 9 +++++++++ qa/rpc-tests/mempool_limit.py | 2 ++ 2 files changed, 11 insertions(+) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index d6493dbb8..dda916615 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -30,6 +30,11 @@ class RawTransactionsTest(BitcoinTestFramework): print "Mining blocks..." min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] + # This test is not meant to test fee estimation and we'd like + # to be sure all txs are sent at a consistent desired feerate + for node in self.nodes: + node.settxfee(min_relay_tx_fee) + # if the fee's positive delta is higher than this value tests will fail, # neg. delta always fail the tests. # The size of the signature of every input may be at most 2 bytes larger @@ -447,6 +452,10 @@ class RawTransactionsTest(BitcoinTestFramework): wait_bitcoinds() self.nodes = start_nodes(4, self.options.tmpdir) + # This test is not meant to test fee estimation and we'd like + # to be sure all txs are sent at a consistent desired feerate + for node in self.nodes: + node.settxfee(min_relay_tx_fee) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index 3ba17ac4f..a8cf6360e 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -33,7 +33,9 @@ class MempoolLimitTest(BitcoinTestFramework): inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] outputs = {self.nodes[0].getnewaddress() : 0.0001} tx = self.nodes[0].createrawtransaction(inputs, outputs) + self.nodes[0].settxfee(self.relayfee) # specifically fund this tx with low fee txF = self.nodes[0].fundrawtransaction(tx) + self.nodes[0].settxfee(0) # return to automatic fee selection txFS = self.nodes[0].signrawtransaction(txF['hex']) txid = self.nodes[0].sendrawtransaction(txFS['hex']) self.nodes[0].lockunspent(True, [us0]) From fa4f4b6974cedd0689726a7eb791eb8f2d1d66ed Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 6 Jan 2016 15:26:56 +0100 Subject: [PATCH 0114/1223] Add clang-format-diff.py from the LLVM svn ------------------------------------------------------------------------ r249567 | djasper | 2015-10-07 19:00:20 +0200 (Wed, 07 Oct 2015) | 2 lines clang-format: Add include sorting capabilities to sublime, emacs and clang-format-diff.py. ------------------------------------------------------------------------ r231926 | djasper | 2015-03-11 15:58:38 +0100 (Wed, 11 Mar 2015) | 3 lines clang-format: Recognize the .ts (TypeScript) extension as JavaScript. Patch by Martin Probst. Thank you. ------------------------------------------------------------------------ r223685 | djasper | 2014-12-08 20:39:03 +0100 (Mon, 08 Dec 2014) | 1 line clang-format: Make clang-format-diff.py format java files. ------------------------------------------------------------------------ r221990 | djasper | 2014-11-14 14:27:28 +0100 (Fri, 14 Nov 2014) | 4 lines clang-format: Give clang-format-diff.py a -v option. With it, it prints the file being formatted. Apparently people are formatting thousands of files and some progress indication is helpful. ------------------------------------------------------------------------ r216945 | ed | 2014-09-02 22:59:13 +0200 (Tue, 02 Sep 2014) | 6 lines Use /usr/bin/env python instead of /usr/bin/python. On operating systems like the BSDs, it is typically the case that /usr/bin/python does not exist. We should therefore use /usr/bin/env instead. This is also done in various other scripts in tools/. ------------------------------------------------------------------------ r208766 | djasper | 2014-05-14 11:36:11 +0200 (Wed, 14 May 2014) | 1 line clang-format: Add clang-format-diff usage examples for SVN. ------------------------------------------------------------------------ r199750 | djasper | 2014-01-21 16:40:01 +0100 (Tue, 21 Jan 2014) | 3 lines clang-format: Enable formatting for .proto and .protodevel files. Support for protocol buffer files seems complete enough. ------------------------------------------------------------------------ r197668 | djasper | 2013-12-19 11:21:37 +0100 (Thu, 19 Dec 2013) | 1 line Fix usage description of clang-format-diff.py. ------------------------------------------------------------------------ r197608 | alp | 2013-12-18 22:34:07 +0100 (Wed, 18 Dec 2013) | 7 lines clang-format-diff.py: fix -regex/-iregex matching While debating the finer points of file extension matching, we somehow missed the bigger problem that the current code will match anything starting with the default or user-specified pattern (e.g. lit.site.cfg.in). Fix this by doing what find(1) does, implicitly wrapping the pattern with ^$. ------------------------------------------------------------------------ r197542 | alp | 2013-12-18 01:58:58 +0100 (Wed, 18 Dec 2013) | 3 lines clang-format-diff.py: add the OpenCL file extension It's handled correctly as a C-family language. ------------------------------------------------------------------------ r197378 | alexfh | 2013-12-16 11:57:30 +0100 (Mon, 16 Dec 2013) | 14 lines Added -iregex for case-insensitive regex to filter file names. Summary: -regex and -iregex both mimic options of the find utility. Made the default list of extensions case-insensitive, so that it's not only C and CPP extensions are accepted in upper case. Reviewers: djasper Reviewed By: djasper CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2415 ------------------------------------------------------------------------ r196917 | alp | 2013-12-10 14:51:53 +0100 (Tue, 10 Dec 2013) | 10 lines clang-format-diff.py: Support -regex filter and more filename extensions Add support for more filename extensions based on the list in the clang plus JavaScript. Also adds a -regex option so users can override defaults if they have unusual file extensions or want to format everything in the diff. Keeping with tradition the flag is modelled on Unix conventions, this time matching the semantics of find(1). ------------------------------------------------------------------------ r196484 | alp | 2013-12-05 09:14:54 +0100 (Thu, 05 Dec 2013) | 4 lines clang-format-diff.py: pass through errors to stderr, not stdout Also use write() for unified diff output to avoid further processing by the print function (e.g. trailing newline). ------------------------------------------------------------------------ r196336 | alp | 2013-12-04 01:48:22 +0100 (Wed, 04 Dec 2013) | 3 lines clang-format-diff.py: Fix 'beintroduced' in help output Also update docs to reflect recently changed -i inplace edit behaviour. ------------------------------------------------------------------------ r192505 | alexfh | 2013-10-11 23:32:01 +0200 (Fri, 11 Oct 2013) | 17 lines Changed clang-format-diff.py to output diff by default. Added -i option to apply changes to files instead. Summary: "svn diff|clang-format-diff.py" will just output the diff. Now it's possible to use: svn diff|clang-format-diff.py|patch -p0 as an equivalent to: svn diff|clang-format-diff.py -i ;) Reviewers: djasper Reviewed By: djasper CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1840 ------------------------------------------------------------------------ r192184 | djasper | 2013-10-08 17:54:36 +0200 (Tue, 08 Oct 2013) | 7 lines clang-format: Don't exit with failure on empty files. Also let clang-format-diff.py detect errors based on clang-format's return code. Otherwise messages like "Can't find usable .clang-format, falling back to LLVM style" can make it fail, which might be undesired. Patch by Alp Toker. Thank you! ------------------------------------------------------------------------ r191820 | djasper | 2013-10-02 15:59:03 +0200 (Wed, 02 Oct 2013) | 18 lines clang-format: Fix clang-format-diff.py according to diff specification. Patch by Alp Toker. Many thanks! Original descriptions: clang-format-diff incorrectly modifies unchanged lines due to an error in diff parsing. The unified diff format has a default line change count of 1, and 0 may be specified to indicate that no lines have been added. This patch updates the parser to accurately reflect the diff specification. This also has the benefit of stabilising the operation so it will produce the same output when run multiple times on the same changeset, which was previously not the case. No tests added because this script is not currently tested (though we should look into that!) ------------------------------------------------------------------------ r191137 | djasper | 2013-09-21 12:05:02 +0200 (Sat, 21 Sep 2013) | 3 lines Fix clang-format-diff.py to accept -style again. Copy and paste error in r190935.. ------------------------------------------------------------------------ r190935 | djasper | 2013-09-18 14:14:09 +0200 (Wed, 18 Sep 2013) | 3 lines Simplify clang-format-diff.py using new clang-format options. clang-format's -lines parameter makes this significantly easier. ------------------------------------------------------------------------ r189765 | alexfh | 2013-09-02 18:39:23 +0200 (Mon, 02 Sep 2013) | 2 lines Added WebKit style to the BasedOnStyle handling and to the relevant help messages. ------------------------------------------------------------------------ r182923 | djasper | 2013-05-30 13:50:20 +0200 (Thu, 30 May 2013) | 4 lines Fix default value of clang-format-diff's -p option. This way, it has the same default as 'patch' and also the example in the code makes more sense as it is explicitly setting -p 1. ------------------------------------------------------------------------ r179676 | djasper | 2013-04-17 09:55:02 +0200 (Wed, 17 Apr 2013) | 2 lines Small improvements to clang-format documentation and integration scripts. ------------------------------------------------------------------------ r179377 | djasper | 2013-04-12 15:42:36 +0200 (Fri, 12 Apr 2013) | 1 line Fix clang-format-diff.py script. ------------------------------------------------------------------------ r179098 | djasper | 2013-04-09 17:23:04 +0200 (Tue, 09 Apr 2013) | 5 lines Improvements to clang-format integrations. This adds an emacs editor integration (thanks to Ami Fischman). Also pulls out the style into a variable for the vi integration and just uses clang-formats defaults style in clang-format-diff.py. ------------------------------------------------------------------------ r177506 | djasper | 2013-03-20 10:53:23 +0100 (Wed, 20 Mar 2013) | 1 line Add clang-format binary to cfe. ------------------------------------------------------------------------ s --- contrib/devtools/clang-format-diff.py | 124 ++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 contrib/devtools/clang-format-diff.py diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py new file mode 100755 index 000000000..9e02bb093 --- /dev/null +++ b/contrib/devtools/clang-format-diff.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# + +r""" +ClangFormat Diff Reformatter +============================ + +This script reads input from a unified diff and reformats all the changed +lines. This is useful to reformat all the lines touched by a specific patch. +Example usage for git/svn users: + + git diff -U0 HEAD^ | clang-format-diff.py -p1 -i + svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i + +""" + +import argparse +import difflib +import re +import string +import subprocess +import StringIO +import sys + + +# Change this to the full path if clang-format is not on the path. +binary = 'clang-format' + + +def main(): + parser = argparse.ArgumentParser(description= + 'Reformat changed lines in diff. Without -i ' + 'option just output the diff that would be ' + 'introduced.') + parser.add_argument('-i', action='store_true', default=False, + help='apply edits to files instead of displaying a diff') + parser.add_argument('-p', metavar='NUM', default=0, + help='strip the smallest prefix containing P slashes') + parser.add_argument('-regex', metavar='PATTERN', default=None, + help='custom pattern selecting file paths to reformat ' + '(case sensitive, overrides -iregex)') + parser.add_argument('-iregex', metavar='PATTERN', default= + r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|ts|proto' + r'|protodevel|java)', + help='custom pattern selecting file paths to reformat ' + '(case insensitive, overridden by -regex)') + parser.add_argument('-sort-includes', action='store_true', default=False, + help='let clang-format sort include blocks') + parser.add_argument('-v', '--verbose', action='store_true', + help='be more verbose, ineffective without -i') + parser.add_argument( + '-style', + help= + 'formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)') + args = parser.parse_args() + + # Extract changed lines for each file. + filename = None + lines_by_file = {} + for line in sys.stdin: + match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + if match: + filename = match.group(2) + if filename == None: + continue + + if args.regex is not None: + if not re.match('^%s$' % args.regex, filename): + continue + else: + if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): + continue + + match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + if match: + start_line = int(match.group(1)) + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + if line_count == 0: + continue + end_line = start_line + line_count - 1; + lines_by_file.setdefault(filename, []).extend( + ['-lines', str(start_line) + ':' + str(end_line)]) + + # Reformat files containing changes in place. + for filename, lines in lines_by_file.iteritems(): + if args.i and args.verbose: + print 'Formatting', filename + command = [binary, filename] + if args.i: + command.append('-i') + if args.sort_includes: + command.append('-sort-includes') + command.extend(lines) + if args.style: + command.extend(['-style', args.style]) + p = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=None, stdin=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + sys.exit(p.returncode); + + if not args.i: + with open(filename) as f: + code = f.readlines() + formatted_code = StringIO.StringIO(stdout).readlines() + diff = difflib.unified_diff(code, formatted_code, + filename, filename, + '(before formatting)', '(after formatting)') + diff_string = string.join(diff, '') + if len(diff_string) > 0: + sys.stdout.write(diff_string) + +if __name__ == '__main__': + main() From fa074a6fd098153c75ba0e76b7dd94eab82ae599 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 6 Jan 2016 16:11:31 +0100 Subject: [PATCH 0115/1223] [contrib] Prepare clang-format-diff for usage --- contrib/devtools/README.md | 12 ++++++ contrib/devtools/clang-format-diff.py | 54 +++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 240ab6d9e..978f26b08 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -7,6 +7,18 @@ clang-format.py A script to format cpp source code according to [.clang-format](../../src/.clang-format). This should only be applied to new files or files which are currently not actively developed on. Also, git subtrees are not subject to formatting. +clang-format-diff.py +=================== + +A script to format unified git diffs according to [.clang-format](../../src/.clang-format). + +For instance, to format the last commit with 0 lines of context, +the script should be called from the git root folder as follows. + +``` +git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v +``` + fix-copyright-headers.py ======================== diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py index 9e02bb093..13d2573b9 100755 --- a/contrib/devtools/clang-format-diff.py +++ b/contrib/devtools/clang-format-diff.py @@ -5,7 +5,52 @@ # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# License. +# +# ============================================================ +# +# University of Illinois/NCSA +# Open Source License +# +# Copyright (c) 2007-2015 University of Illinois at Urbana-Champaign. +# All rights reserved. +# +# Developed by: +# +# LLVM Team +# +# University of Illinois at Urbana-Champaign +# +# http://llvm.org +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal with +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimers. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimers in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of the LLVM Team, University of Illinois at +# Urbana-Champaign, nor the names of its contributors may be used to +# endorse or promote products derived from this Software without specific +# prior written permission. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +# SOFTWARE. +# +# ============================================================ # #===------------------------------------------------------------------------===# @@ -56,10 +101,6 @@ def main(): help='let clang-format sort include blocks') parser.add_argument('-v', '--verbose', action='store_true', help='be more verbose, ineffective without -i') - parser.add_argument( - '-style', - help= - 'formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)') args = parser.parse_args() # Extract changed lines for each file. @@ -101,8 +142,7 @@ def main(): if args.sort_includes: command.append('-sort-includes') command.extend(lines) - if args.style: - command.extend(['-style', args.style]) + command.extend(['-style=file', '-fallback-style=none']) p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, stdin=subprocess.PIPE) stdout, stderr = p.communicate() From 2dfeaa1ad03e7768fb28bfde7f929ac57dfff120 Mon Sep 17 00:00:00 2001 From: ptschip Date: Fri, 16 Oct 2015 18:18:16 -0700 Subject: [PATCH 0116/1223] limitfreerelay edge case bugfix: If a new transaction will cause limitfreerelay to be exceeded it should not be accepted into the memory pool and the byte counter should be updated only after the fact. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 41fc0b809..08a95aff2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1016,7 +1016,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB - if (dFreeCount >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) + if (dFreeCount + nSize >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; From f61766b37beb2fecbe3915a72a814cbdb107be0a Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Wed, 6 Jan 2016 17:24:30 -0500 Subject: [PATCH 0117/1223] Make sure conflicted wallet tx's update balances --- src/wallet/wallet.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 444bd88f8..1904361ba 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -811,6 +811,13 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) } iter++; } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } } } } From fac11ea3106ff29ec884dfe9d9b287fd1beda5fc Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 18:55:24 +0100 Subject: [PATCH 0118/1223] [init] Fix error message of maxtxfee invalid amount --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 3b17e1123..379870954 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -975,7 +975,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", mapArgs["-maptxfee"])); + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); if (nMaxFee > nHighTransactionMaxFeeWarning) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; From fa6ab96799f9d7946200fb646fefe35c6daab9b2 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 18:50:17 +0100 Subject: [PATCH 0119/1223] [init] Add missing help for args --- src/init.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 379870954..6ec7dc99b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -312,7 +312,8 @@ std::string HelpMessage(HelpMessageMode mode) // When adding new options to the categories, please keep and ensure alphabetical ordering. // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators. string strUsage = HelpMessageGroup(_("Options:")); - strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-?", _("Print this help message and exit")); + strUsage += HelpMessageOpt("-version", _("Print version and exit")); strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS)); strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); @@ -421,8 +422,11 @@ std::string HelpMessage(HelpMessageMode mode) #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); + strUsage += HelpMessageOpt("-uacomment=", _("Append comment to the user agent string")); if (showDebug) { + strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool. (default: %u)", Params().DefaultConsistencyChecks())); + strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions. (default: %u)", Params().DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); #ifdef ENABLE_WALLET strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); @@ -445,6 +449,8 @@ std::string HelpMessage(HelpMessageMode mode) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied or if = 1, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); + if (showDebug) + strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0"); strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE)); strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS)); strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); @@ -453,6 +459,7 @@ std::string HelpMessage(HelpMessageMode mode) if (showDebug) { strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); + strUsage += HelpMessageOpt("-mocktime=", "Replace actual time with (default: 0)"); strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); @@ -488,6 +495,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), DEFAULT_REST_ENABLE)); strUsage += HelpMessageOpt("-rpcbind=", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); + strUsage += HelpMessageOpt("-rpccookiefile=", _("Location of the auth cookie (default: data dir)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcauth=", _("Username and hashed password for JSON-RPC connections. The field comes in the format: :$. A canonical python script is included in share/rpcuser. This option can be specified multiple times")); From faa572a3296c0955dcb2cc0bd9b925c2a31e7892 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 19:17:42 +0100 Subject: [PATCH 0120/1223] [init] Help Msg: Use Params(CBaseChainParams::MAIN) --- src/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 6ec7dc99b..a812895f0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -425,8 +425,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-uacomment=", _("Append comment to the user agent string")); if (showDebug) { - strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool. (default: %u)", Params().DefaultConsistencyChecks())); - strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions. (default: %u)", Params().DefaultConsistencyChecks())); + strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); + strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); #ifdef ENABLE_WALLET strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); From 82a0ce09b45ab9c09ce4f516be5b9b413dcec470 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Jan 2016 09:22:20 -0500 Subject: [PATCH 0121/1223] Add race-condition debugging tool to mininode --- qa/rpc-tests/test_framework/mininode.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 8e49b5656..ca65fb6e7 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1004,6 +1004,18 @@ class msg_reject(object): class NodeConnCB(object): def __init__(self): self.verack_received = False + # deliver_sleep_time is helpful for debugging race conditions in p2p + # tests; it causes message delivery to sleep for the specified time + # before acquiring the global lock and delivering the next message. + self.deliver_sleep_time = None + + def set_deliver_sleep_time(self, value): + with mininode_lock: + self.deliver_sleep_time = value + + def get_deliver_sleep_time(self): + with mininode_lock: + return self.deliver_sleep_time # Spin until verack message is received from the node. # Tests may want to use this as a signal that the test can begin. @@ -1017,6 +1029,9 @@ class NodeConnCB(object): time.sleep(0.05) def deliver(self, conn, message): + deliver_sleep = self.get_deliver_sleep_time() + if deliver_sleep is not None: + time.sleep(deliver_sleep) with mininode_lock: try: getattr(self, 'on_' + message.command)(conn, message) From 168915e6dec88b31793d4ee4b60b94d4149de36c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Jan 2016 09:23:05 -0500 Subject: [PATCH 0122/1223] Eliminate race condition in sendheaders.py test Clear the last block announcement before mining new blocks. --- qa/rpc-tests/sendheaders.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index e6e26dbce..7572bc277 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -220,18 +220,20 @@ class SendHeadersTest(BitcoinTestFramework): # mine count blocks and return the new tip def mine_blocks(self, count): + # Clear out last block announcement from each p2p listener + [ x.clear_last_announcement() for x in self.p2p_connections ] self.nodes[0].generate(count) return int(self.nodes[0].getbestblockhash(), 16) # mine a reorg that invalidates length blocks (replacing them with # length+1 blocks). - # peers is the p2p nodes we're using; we clear their state after the + # Note: we clear the state of our p2p connections after the # to-be-reorged-out blocks are mined, so that we don't break later tests. # return the list of block hashes newly mined - def mine_reorg(self, length, peers): + def mine_reorg(self, length): self.nodes[0].generate(length) # make sure all invalidated blocks are node0's sync_blocks(self.nodes, wait=0.1) - [x.clear_last_announcement() for x in peers] + [x.clear_last_announcement() for x in self.p2p_connections] tip_height = self.nodes[1].getblockcount() hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1)) @@ -245,6 +247,8 @@ class SendHeadersTest(BitcoinTestFramework): inv_node = InvNode() test_node = TestNode() + self.p2p_connections = [inv_node, test_node] + connections = [] connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], inv_node)) # Set nServices to 0 for test_node, so no block download will occur outside of @@ -303,7 +307,6 @@ class SendHeadersTest(BitcoinTestFramework): prev_tip = int(self.nodes[0].getbestblockhash(), 16) test_node.get_headers(locator=[prev_tip], hashstop=0L) test_node.sync_with_ping() - test_node.clear_last_announcement() # Clear out empty headers response # Now that we've synced headers, headers announcements should work tip = self.mine_blocks(1) @@ -352,8 +355,6 @@ class SendHeadersTest(BitcoinTestFramework): # broadcast it) assert_equal(inv_node.last_inv, None) assert_equal(inv_node.last_headers, None) - inv_node.clear_last_announcement() - test_node.clear_last_announcement() tip = self.mine_blocks(1) assert_equal(inv_node.check_last_announcement(inv=[tip]), True) assert_equal(test_node.check_last_announcement(headers=[tip]), True) @@ -368,7 +369,7 @@ class SendHeadersTest(BitcoinTestFramework): # getheaders or inv from peer. for j in xrange(2): # First try mining a reorg that can propagate with header announcement - new_block_hashes = self.mine_reorg(length=7, peers=[test_node, inv_node]) + new_block_hashes = self.mine_reorg(length=7) tip = new_block_hashes[-1] assert_equal(inv_node.check_last_announcement(inv=[tip]), True) assert_equal(test_node.check_last_announcement(headers=new_block_hashes), True) @@ -376,7 +377,7 @@ class SendHeadersTest(BitcoinTestFramework): block_time += 8 # Mine a too-large reorg, which should be announced with a single inv - new_block_hashes = self.mine_reorg(length=8, peers=[test_node, inv_node]) + new_block_hashes = self.mine_reorg(length=8) tip = new_block_hashes[-1] assert_equal(inv_node.check_last_announcement(inv=[tip]), True) assert_equal(test_node.check_last_announcement(inv=[tip]), True) @@ -407,7 +408,6 @@ class SendHeadersTest(BitcoinTestFramework): test_node.get_headers(locator=[fork_point], hashstop=new_block_hashes[1]) test_node.get_data([tip]) test_node.wait_for_block(tip) - test_node.clear_last_announcement() elif i == 2: test_node.get_data([tip]) test_node.wait_for_block(tip) From 9e697172542e2b01517e4025df2c23d0ed5447f4 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 7 Jan 2016 16:31:12 -0500 Subject: [PATCH 0123/1223] Make wallet descendant searching more efficient --- src/wallet/wallet.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1904361ba..448c9bada 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -784,14 +784,14 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) // Do not flush the wallet here for performance reasons CWalletDB walletdb(strWalletFile, "r+", false); - std::deque todo; + std::set todo; std::set done; - todo.push_back(hashTx); + todo.insert(hashTx); while (!todo.empty()) { - uint256 now = todo.front(); - todo.pop_front(); + uint256 now = *todo.begin(); + todo.erase(now); done.insert(now); assert(mapWallet.count(now)); CWalletTx& wtx = mapWallet[now]; @@ -807,7 +807,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0)); while (iter != mapTxSpends.end() && iter->first.hash == now) { if (!done.count(iter->second)) { - todo.push_back(iter->second); + todo.insert(iter->second); } iter++; } From db198d51a651086744871c972637f3856675a2ed Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 8 Jan 2016 10:11:25 +0100 Subject: [PATCH 0124/1223] Fix RPCTimerInterface ordering issue Dispatching a QThread from a non Qt thread is not allowed. Always use the HTTPRPCTimerInterface (non QT) to dispatch RPCRunLater threads. --- src/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index bc419d14d..de60bb6b1 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -563,7 +563,7 @@ void RPCRunLater(const std::string& name, boost::function func, int6 if (timerInterfaces.empty()) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces[0]; + RPCTimerInterface* timerInterface = timerInterfaces.back(); LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } From 8a7f0001be88122256b1a8dc29b066210dc85625 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 8 Jan 2016 11:03:52 +0100 Subject: [PATCH 0125/1223] [RPC] remove the option of having multiple timer interfaces --- src/httprpc.cpp | 4 ++-- src/qt/rpcconsole.cpp | 6 ++++-- src/rpcserver.cpp | 22 +++++++++++++--------- src/rpcserver.h | 10 ++++++---- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 2920aa26f..1466dc0cb 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -226,7 +226,7 @@ bool StartHTTPRPC() assert(EventBase()); httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase()); - RPCRegisterTimerInterface(httpRPCTimerInterface); + RPCSetTimerInterface(httpRPCTimerInterface); return true; } @@ -240,7 +240,7 @@ void StopHTTPRPC() LogPrint("rpc", "Stopping HTTP RPC server\n"); UnregisterHTTPHandler("/", true); if (httpRPCTimerInterface) { - RPCUnregisterTimerInterface(httpRPCTimerInterface); + RPCUnsetTimerInterface(httpRPCTimerInterface); delete httpRPCTimerInterface; httpRPCTimerInterface = 0; } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 4c869b9ac..7178bc00e 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -278,7 +278,9 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : #endif // Register RPC timer interface rpcTimerInterface = new QtRPCTimerInterface(); - RPCRegisterTimerInterface(rpcTimerInterface); + // avoid accidentally overwriting an existing, non QTThread + // based timer interface + RPCSetTimerInterfaceIfUnset(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -293,7 +295,7 @@ RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); Q_EMIT stopExecutor(); - RPCUnregisterTimerInterface(rpcTimerInterface); + RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index de60bb6b1..78d6898bc 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -33,7 +33,7 @@ static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; /* Timer-creating functions */ -static std::vector timerInterfaces; +static RPCTimerInterface* timerInterface = NULL; /* Map of name to timer. * @note Can be changed to std::unique_ptr when C++11 */ static std::map > deadlineTimers; @@ -546,24 +546,28 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } -void RPCRegisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface) { - timerInterfaces.push_back(iface); + if (!timerInterface) + timerInterface = iface; } -void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterface(RPCTimerInterface *iface) { - std::vector::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); - assert(i != timerInterfaces.end()); - timerInterfaces.erase(i); + timerInterface = iface; +} + +void RPCUnsetTimerInterface(RPCTimerInterface *iface) +{ + if (timerInterface == iface) + timerInterface = NULL; } void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds) { - if (timerInterfaces.empty()) + if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces.back(); LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } diff --git a/src/rpcserver.h b/src/rpcserver.h index f85ab42f0..9dce31887 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -100,10 +100,12 @@ public: virtual RPCTimerBase* NewTimer(boost::function& func, int64_t millis) = 0; }; -/** Register factory function for timers */ -void RPCRegisterTimerInterface(RPCTimerInterface *iface); -/** Unregister factory function for timers */ -void RPCUnregisterTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timers */ +void RPCSetTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timer, but only, if unset */ +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface); +/** Unset factory function for timers */ +void RPCUnsetTimerInterface(RPCTimerInterface *iface); /** * Run func nSeconds from now. From c0cf48d1ac5b661aa1dfbcd284c773f8f5bbe806 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 8 Jan 2016 13:31:55 -0500 Subject: [PATCH 0126/1223] c++11: add scoped enum fallbacks to CPPFLAGS rather than defining them locally Due to include ordering, defining in one place was not enough to ensure correct usage. Use global defines so that we don't have to worry abou this ordering. Also add a comment in configure about the test. --- configure.ac | 13 ++++++++++++- src/wallet/walletdb.cpp | 5 ----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 07f9a4a6f..347016064 100644 --- a/configure.ac +++ b/configure.ac @@ -619,6 +619,17 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" + +dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums +dnl using c++98 constructs. Unfortunately, this implementation detail leaked into +dnl the abi. This was fixed in 1.57. + +dnl When building against that installed version using c++11, the headers pick up +dnl on the native c++11 scoped enum support and enable it, however it will fail to +dnl link. This can be worked around by disabling c++11 scoped enums if linking will +dnl fail. +dnl BOOST_NO_SCOPED_ENUMS was changed to BOOST_NO_CXX11_SCOPED_ENUMS in 1.51. + TEMP_LIBS="$LIBS" LIBS="$BOOST_LIBS $LIBS" TEMP_CPPFLAGS="$CPPFLAGS" @@ -640,7 +651,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ choke; #endif ]])], - [AC_MSG_RESULT(mismatched); AC_DEFINE(FORCE_BOOST_EMULATED_SCOPED_ENUMS, 1, [Define this symbol if boost scoped enums are emulated])], [AC_MSG_RESULT(ok)]) + [AC_MSG_RESULT(mismatched); BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS"], [AC_MSG_RESULT(ok)]) LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 5266946ca..67511976d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -15,11 +15,6 @@ #include "utiltime.h" #include "wallet/wallet.h" -#if defined(FORCE_BOOST_EMULATED_SCOPED_ENUMS) -#define BOOST_NO_SCOPED_ENUMS -#define BOOST_NO_CXX11_SCOPED_ENUMS -#endif - #include #include #include From 0331aa350c04253f3b94604a0152042646fc94bb Mon Sep 17 00:00:00 2001 From: calebogden Date: Fri, 8 Jan 2016 13:31:42 -0800 Subject: [PATCH 0127/1223] Fixing typos on security-check.py and torcontrol.cpp --- contrib/devtools/security-check.py | 2 +- src/torcontrol.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index e96eaa9c3..fe5dc9ad8 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,7 +1,7 @@ #!/usr/bin/python2 ''' Perform basic ELF security checks on a series of executables. -Exit status will be 0 if succesful, and the program will be silent. +Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. Needs `readelf` (for ELF) and `objdump` (for PE). ''' diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 4ebcb9b66..9a783b970 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -79,7 +79,7 @@ public: /** * Connect to a Tor control port. * target is address of the form host:port. - * connected is the handler that is called when connection is succesfully established. + * connected is the handler that is called when connection is successfully established. * disconnected is a handler that is called when the connection is broken. * Return true on success. */ @@ -177,7 +177,7 @@ void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ct { TorControlConnection *self = (TorControlConnection*)ctx; if (what & BEV_EVENT_CONNECTED) { - LogPrint("tor", "tor: Succesfully connected!\n"); + LogPrint("tor", "tor: Successfully connected!\n"); self->connected(*self); } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { if (what & BEV_EVENT_ERROR) @@ -380,7 +380,7 @@ private: void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply); /** Callback for PROTOCOLINFO result */ void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply); - /** Callback after succesful connection */ + /** Callback after successful connection */ void connected_cb(TorControlConnection& conn); /** Callback after connection lost or failed connection attempt */ void disconnected_cb(TorControlConnection& conn); @@ -419,7 +419,7 @@ TorController::~TorController() void TorController::add_onion_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: ADD_ONION succesful\n"); + LogPrint("tor", "tor: ADD_ONION successful\n"); BOOST_FOREACH(const std::string &s, reply.lines) { std::map m = ParseTorReplyMapping(s); std::map::iterator i; @@ -448,7 +448,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: Authentication succesful\n"); + LogPrint("tor", "tor: Authentication successful\n"); // Now that we know Tor is running setup the proxy for onion addresses // if -onion isn't set to something else. @@ -501,7 +501,7 @@ static std::vector ComputeResponse(const std::string &key, const std::v void TorController::authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: SAFECOOKIE authentication challenge succesful\n"); + LogPrint("tor", "tor: SAFECOOKIE authentication challenge successful\n"); std::pair l = SplitTorReplyLine(reply.lines[0]); if (l.first == "AUTHCHALLENGE") { std::map m = ParseTorReplyMapping(l.second); From fa461df685063e6b12664fe6928362484f690f01 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 9 Jan 2016 13:59:25 +0100 Subject: [PATCH 0128/1223] Clarify mocktime help message --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index a812895f0..ac416d0bf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -459,7 +459,7 @@ std::string HelpMessage(HelpMessageMode mode) if (showDebug) { strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); - strUsage += HelpMessageOpt("-mocktime=", "Replace actual time with (default: 0)"); + strUsage += HelpMessageOpt("-mocktime=", "Replace actual time with seconds since epoch (default: 0)"); strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); From fa1cb1ae15e74e6149ff7fd8aae6cba216914e4c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 8 Jan 2016 13:12:16 +0100 Subject: [PATCH 0129/1223] [qa] Test walletpassphrase timeout --- qa/rpc-tests/keypool.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index c300bbc57..95d0d6832 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -70,9 +70,11 @@ class KeyPoolTest(BitcoinTestFramework): assert(e.error['code']==-12) # refill keypool with three new addresses - nodes[0].walletpassphrase('test', 12000) + nodes[0].walletpassphrase('test', 1) nodes[0].keypoolrefill(3) - nodes[0].walletlock() + # test walletpassphrase timeout + time.sleep(1.1) + assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0) # drain them by mining nodes[0].generate(1) From 3a9dfe9d14bd8159a3b3dd66533c1b730c2158ea Mon Sep 17 00:00:00 2001 From: paveljanik Date: Sun, 10 Jan 2016 17:33:54 +0100 Subject: [PATCH 0130/1223] Fix typo, wrong information in gettxout help text. --- src/rpcblockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index edaa71e79..b76b0ca40 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -472,8 +472,8 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nReturns details about an unspent transaction output.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" - "2. n (numeric, required) vout value\n" - "3. includemempool (boolean, optional) Whether to included the mem pool\n" + "2. n (numeric, required) vout number\n" + "3. includemempool (boolean, optional) Whether to include the mem pool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" From 94bdd71f9b4768c9803ffd133aa7781b19bfa6f9 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Fri, 18 Dec 2015 14:07:48 -0500 Subject: [PATCH 0131/1223] Added help text for chainwork value --- src/rpcblockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ee04636ce..0216e8ec6 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -384,6 +384,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n" " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" "}\n" From e86756193ebdbf71504e2a1a8db43e38d57f9673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Mon, 30 Nov 2015 00:46:49 +0100 Subject: [PATCH 0132/1223] MOVEONLY: non-consensus: from pow to chain: - GetBlockProof - GetBlockProofEquivalentTime --- src/chain.cpp | 32 ++++++++++++++++++++++++++++++++ src/chain.h | 4 ++++ src/pow.cpp | 32 -------------------------------- src/pow.h | 5 ----- 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index 3450ed6c3..32f6480f8 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -110,3 +110,35 @@ void CBlockIndex::BuildSkip() if (pprev) pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); } + +arith_uint256 GetBlockProof(const CBlockIndex& block) +{ + arith_uint256 bnTarget; + bool fNegative; + bool fOverflow; + bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); + if (fNegative || fOverflow || bnTarget == 0) + return 0; + // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 + // as it's too large for a arith_uint256. However, as 2**256 is at least as large + // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, + // or ~bnTarget / (nTarget+1) + 1. + return (~bnTarget / (bnTarget + 1)) + 1; +} + +int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) +{ + arith_uint256 r; + int sign = 1; + if (to.nChainWork > from.nChainWork) { + r = to.nChainWork - from.nChainWork; + } else { + r = from.nChainWork - to.nChainWork; + sign = -1; + } + r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); + if (r.bits() > 63) { + return sign * std::numeric_limits::max(); + } + return sign * r.GetLow64(); +} diff --git a/src/chain.h b/src/chain.h index 01be2d6e5..0c152a5ea 100644 --- a/src/chain.h +++ b/src/chain.h @@ -282,6 +282,10 @@ public: const CBlockIndex* GetAncestor(int height) const; }; +arith_uint256 GetBlockProof(const CBlockIndex& block); +/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */ +int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&); + /** Used to marshal pointers into hashes for db storage. */ class CDiskBlockIndex : public CBlockIndex { diff --git a/src/pow.cpp b/src/pow.cpp index 5ace3fbc9..dc58e21e1 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -102,35 +102,3 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& return true; } - -arith_uint256 GetBlockProof(const CBlockIndex& block) -{ - arith_uint256 bnTarget; - bool fNegative; - bool fOverflow; - bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); - if (fNegative || fOverflow || bnTarget == 0) - return 0; - // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a arith_uint256. However, as 2**256 is at least as large - // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, - // or ~bnTarget / (nTarget+1) + 1. - return (~bnTarget / (bnTarget + 1)) + 1; -} - -int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) -{ - arith_uint256 r; - int sign = 1; - if (to.nChainWork > from.nChainWork) { - r = to.nChainWork - from.nChainWork; - } else { - r = from.nChainWork - to.nChainWork; - sign = -1; - } - r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); - if (r.bits() > 63) { - return sign * std::numeric_limits::max(); - } - return sign * r.GetLow64(); -} diff --git a/src/pow.h b/src/pow.h index e864a474c..a80a33517 100644 --- a/src/pow.h +++ b/src/pow.h @@ -13,16 +13,11 @@ class CBlockHeader; class CBlockIndex; class uint256; -class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); -arith_uint256 GetBlockProof(const CBlockIndex& block); - -/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */ -int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&); #endif // BITCOIN_POW_H From 01e06d1fa365cedb7f5d5e17e6bdf0b526e700c5 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 7 Jan 2016 16:31:27 -0500 Subject: [PATCH 0133/1223] Add new rpc call: abandontransaction Unconfirmed transactions that are not in your mempool either due to eviction or other means may be unlikely to be mined. abandontransaction gives the wallet a way to no longer consider as spent the coins that are inputs to such a transaction. All dependent transactions in the wallet will also be marked as abandoned. --- src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + src/wallet/rpcwallet.cpp | 34 +++++++++++++++ src/wallet/wallet.cpp | 90 +++++++++++++++++++++++++++++++++++----- src/wallet/wallet.h | 11 ++++- 5 files changed, 125 insertions(+), 12 deletions(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index bc419d14d..43104b665 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -346,6 +346,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, { "wallet", "gettransaction", &gettransaction, false }, + { "wallet", "abandontransaction", &abandontransaction, false }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, { "wallet", "getwalletinfo", &getwalletinfo, false }, { "wallet", "importprivkey", &importprivkey, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index f85ab42f0..babf7c8d2 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -221,6 +221,7 @@ extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); extern UniValue listaccounts(const UniValue& params, bool fHelp); extern UniValue listsinceblock(const UniValue& params, bool fHelp); extern UniValue gettransaction(const UniValue& params, bool fHelp); +extern UniValue abandontransaction(const UniValue& params, bool fHelp); extern UniValue backupwallet(const UniValue& params, bool fHelp); extern UniValue keypoolrefill(const UniValue& params, bool fHelp); extern UniValue walletpassphrase(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 374f2fd40..9e7d9cc98 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1764,6 +1764,40 @@ UniValue gettransaction(const UniValue& params, bool fHelp) return entry; } +UniValue abandontransaction(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "abandontransaction \"txid\"\n" + "\nMark in-wallet transaction as abandoned\n" + "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" + "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" + "It only works on transactions which are not included in a block and are not currently in the mempool.\n" + "It has no effect on transactions which are already conflicted or abandoned.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + if (!pwalletMain->AbandonTransaction(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); + + return NullUniValue; +} + UniValue backupwallet(const UniValue& params, bool fHelp) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 448c9bada..68e3b2fe5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -48,6 +48,8 @@ bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; */ CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE); +const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); + /** @defgroup mapWallet * * @{ @@ -455,8 +457,11 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const { const uint256& wtxid = it->second; std::map::const_iterator mit = mapWallet.find(wtxid); - if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) - return true; // Spent + if (mit != mapWallet.end()) { + int depth = mit->second.GetDepthInMainChain(); + if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) + return true; // Spent + } } return false; } @@ -610,7 +615,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD BOOST_FOREACH(const CTxIn& txin, wtx.vin) { if (mapWallet.count(txin.prevout.hash)) { CWalletTx& prevtx = mapWallet[txin.prevout.hash]; - if (prevtx.nIndex == -1 && !prevtx.hashBlock.IsNull()) { + if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { MarkConflicted(prevtx.hashBlock, wtx.GetHash()); } } @@ -631,7 +636,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); wtx.nTimeSmart = wtx.nTimeReceived; - if (!wtxIn.hashBlock.IsNull()) + if (!wtxIn.hashUnset()) { if (mapBlockIndex.count(wtxIn.hashBlock)) { @@ -681,7 +686,13 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD if (!fInsertedNew) { // Merge - if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock) + if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + // If no longer abandoned, update + if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned()) { wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; @@ -768,6 +779,63 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl return false; } +bool CWallet::AbandonTransaction(const uint256& hashTx) +{ + LOCK2(cs_main, cs_wallet); + + // Do not flush the wallet here for performance reasons + CWalletDB walletdb(strWalletFile, "r+", false); + + std::set todo; + std::set done; + + // Can't mark abandoned if confirmed or in mempool + assert(mapWallet.count(hashTx)); + CWalletTx& origtx = mapWallet[hashTx]; + if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { + return false; + } + + todo.insert(hashTx); + + while (!todo.empty()) { + uint256 now = *todo.begin(); + todo.erase(now); + done.insert(now); + assert(mapWallet.count(now)); + CWalletTx& wtx = mapWallet[now]; + int currentconfirm = wtx.GetDepthInMainChain(); + // If the orig tx was not in block, none of its spends can be + assert(currentconfirm <= 0); + // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon} + if (currentconfirm == 0 && !wtx.isAbandoned()) { + // If the orig tx was not in block/mempool, none of its spends can be in mempool + assert(!wtx.InMempool()); + wtx.nIndex = -1; + wtx.setAbandoned(); + wtx.MarkDirty(); + wtx.WriteToDisk(&walletdb); + // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too + TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0)); + while (iter != mapTxSpends.end() && iter->first.hash == now) { + if (!done.count(iter->second)) { + todo.insert(iter->second); + } + iter++; + } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } + } + } + + return true; +} + void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) { LOCK2(cs_main, cs_wallet); @@ -976,7 +1044,7 @@ int CWalletTx::GetRequestCount() const if (IsCoinBase()) { // Generated block - if (!hashBlock.IsNull()) + if (!hashUnset()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -992,7 +1060,7 @@ int CWalletTx::GetRequestCount() const nRequests = (*mi).second; // How about the block it's in? - if (nRequests == 0 && !hashBlock.IsNull()) + if (nRequests == 0 && !hashUnset()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -1166,7 +1234,7 @@ void CWallet::ReacceptWalletTransactions() int nDepth = wtx.GetDepthInMainChain(); - if (!wtx.IsCoinBase() && nDepth == 0) { + if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) { mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx)); } } @@ -1186,7 +1254,7 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { - if (GetDepthInMainChain() == 0) { + if (GetDepthInMainChain() == 0 && !isAbandoned()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -2927,8 +2995,9 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const { - if (hashBlock.IsNull()) + if (hashUnset()) return 0; + AssertLockHeld(cs_main); // Find the block it claims to be in @@ -2956,4 +3025,3 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) CValidationState state; return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee); } - diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 53a2b9669..1ab173bad 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -155,6 +155,10 @@ struct COutputEntry /** A transaction with a merkle branch linking it to the block chain. */ class CMerkleTx : public CTransaction { +private: + /** Constant used in hashBlock to indicate tx has been abandoned */ + static const uint256 ABANDON_HASH; + public: uint256 hashBlock; @@ -206,6 +210,9 @@ public: bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); + bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } + bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } + void setAbandoned() { hashBlock = ABANDON_HASH; } }; /** @@ -486,7 +493,6 @@ private: /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */ void MarkConflicted(const uint256& hashBlock, const uint256& hashTx); - void SyncMetaData(std::pair); public: @@ -783,6 +789,9 @@ public: bool GetBroadcastTransactions() const { return fBroadcastTransactions; } /** Set whether this wallet broadcasts transactions. */ void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } + + /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ + bool AbandonTransaction(const uint256& hashTx); }; /** A key allocated from the key pool. */ From df0e2226d998483d247c0245170f6b8ff6433b1d Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 8 Jan 2016 11:39:24 -0500 Subject: [PATCH 0134/1223] Add RPC test for abandoned and conflicted transactions. --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/abandonconflict.py | 153 ++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100755 qa/rpc-tests/abandonconflict.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 669c508cc..e7173fda0 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -105,6 +105,7 @@ testScripts = [ 'prioritise_transaction.py', 'invalidblockrequest.py', 'invalidtxrequest.py', + 'abandonconflict.py', ] testScriptsExt = [ 'bip65-cltv.py', diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py new file mode 100755 index 000000000..38028df07 --- /dev/null +++ b/qa/rpc-tests/abandonconflict.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class AbandonConflictTest(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-logtimemicros"])) + connect_nodes(self.nodes[0], 1) + + def run_test(self): + self.nodes[1].generate(100) + sync_blocks(self.nodes) + balance = self.nodes[0].getbalance() + txA = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + txB = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + txC = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + sync_mempools(self.nodes) + self.nodes[1].generate(1) + + sync_blocks(self.nodes) + newbalance = self.nodes[0].getbalance() + assert(balance - newbalance < Decimal("0.001")) #no more than fees lost + balance = newbalance + + url = urlparse.urlparse(self.nodes[1].url) + self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) + + # Identify the 10btc outputs + nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10")) + nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10")) + nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10")) + + inputs =[] + # spend 10btc outputs from txA and txB + inputs.append({"txid":txA, "vout":nA}) + inputs.append({"txid":txB, "vout":nB}) + outputs = {} + + outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998") + outputs[self.nodes[1].getnewaddress()] = Decimal("5") + signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs)) + txAB1 = self.nodes[0].sendrawtransaction(signed["hex"]) + + # Identify the 14.99998btc output + nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998")) + + #Create a child tx spending AB1 and C + inputs = [] + inputs.append({"txid":txAB1, "vout":nAB}) + inputs.append({"txid":txC, "vout":nC}) + outputs = {} + outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996") + signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs)) + txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"]) + + # In mempool txs from self should increase balance from change + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("30") + Decimal("24.9996")) + balance = newbalance + + # Restart the node with a higher min relay fee so the parent tx is no longer in mempool + # TODO: redo with eviction + # Note had to make sure tx did not have AllowFree priority + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + + # Verify txs no longer in mempool + assert(len(self.nodes[0].getrawmempool()) == 0) + + # Not in mempool txs from self should only reduce balance + # inputs are still spent, but change not received + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("24.9996")) + balance = newbalance + + # Abandon original transaction and verify inputs are available again + # including that the child tx was also abandoned + self.nodes[0].abandontransaction(txAB1) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance + Decimal("30")) + balance = newbalance + + # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]) + assert(len(self.nodes[0].getrawmempool()) == 0) + assert(self.nodes[0].getbalance() == balance) + + # But if its received again then it is unabandoned + # And since now in mempool, the change is available + # But its child tx remains abandoned + self.nodes[0].sendrawtransaction(signed["hex"]) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("20") + Decimal("14.99998")) + balance = newbalance + + # Send child tx again so its unabandoned + self.nodes[0].sendrawtransaction(signed2["hex"]) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) + balance = newbalance + + # Remove using high relay fee again + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + assert(len(self.nodes[0].getrawmempool()) == 0) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("24.9996")) + balance = newbalance + + # Create a double spend of AB1 by spending again from only A's 10 output + # Mine double spend from node 1 + inputs =[] + inputs.append({"txid":txA, "vout":nA}) + outputs = {} + outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999") + tx = self.nodes[0].createrawtransaction(inputs, outputs) + signed = self.nodes[0].signrawtransaction(tx) + self.nodes[1].sendrawtransaction(signed["hex"]) + self.nodes[1].generate(1) + + connect_nodes(self.nodes[0], 1) + sync_blocks(self.nodes) + + # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance + Decimal("20")) + balance = newbalance + + # There is currently a minor bug around this and so this test doesn't work. See Issue #7315 + # Invalidate the block with the double spend and B's 10 BTC output should no longer be available + # Don't think C's should either + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + newbalance = self.nodes[0].getbalance() + #assert(newbalance == balance - Decimal("10")) + print "If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer" + print "conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315" + print balance , " -> " , newbalance , " ?" + +if __name__ == '__main__': + AbandonConflictTest().main() From d11fc1695c0453ef22a633e516726f82717dd1d9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 11 Jan 2016 11:15:41 +0100 Subject: [PATCH 0135/1223] [Wallet] Call notification signal when a transaction is abandoned --- src/wallet/wallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 68e3b2fe5..78371ee30 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -815,6 +815,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) wtx.setAbandoned(); wtx.MarkDirty(); wtx.WriteToDisk(&walletdb); + NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED); // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0)); while (iter != mapTxSpends.end() && iter->first.hash == now) { From fa989fbf572e93c60173d743230f53e216ea044c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 16:54:43 +0100 Subject: [PATCH 0136/1223] [qt] coincontrol workaround is still needed in qt5.4 (fixed in qt5.5) --- src/qt/coincontroldialog.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index a5c2b6d42..7393c83c7 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -408,10 +408,8 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) CoinControlDialog::updateLabels(model, this); } - // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node - // including all children are partially selected. But the parent node should be fully selected - // as well as the children. Children should never be partially selected in the first place. - // Should be fixed in Qt5.4 and above. https://bugreports.qt.io/browse/QTBUG-43473 + // TODO: Remove this temporary qt5 fix after Qt5.3 and Qt5.4 are no longer used. + // Fixed in Qt5.5 and above: https://bugreports.qt.io/browse/QTBUG-43473 #if QT_VERSION >= 0x050000 else if (column == COLUMN_CHECKBOX && item->childCount() > 0) { From 7777994846cdb9b9cf69e391a33eeed30393bbcf Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 2 Dec 2015 18:12:23 +0100 Subject: [PATCH 0137/1223] [qa] Fix pyton syntax in rpc tests --- qa/rpc-tests/bip65-cltv-p2p.py | 2 +- qa/rpc-tests/bip65-cltv.py | 4 +- qa/rpc-tests/bipdersig-p2p.py | 2 +- qa/rpc-tests/bipdersig.py | 4 +- qa/rpc-tests/blockchain.py | 4 +- qa/rpc-tests/disablewallet.py | 1 + qa/rpc-tests/forknotify.py | 2 - qa/rpc-tests/fundrawtransaction.py | 50 +++++++++++------------ qa/rpc-tests/getchaintips.py | 4 +- qa/rpc-tests/httpbasics.py | 14 +++---- qa/rpc-tests/invalidblockrequest.py | 2 - qa/rpc-tests/invalidtxrequest.py | 4 -- qa/rpc-tests/mempool_limit.py | 2 +- qa/rpc-tests/mempool_reorg.py | 8 ++-- qa/rpc-tests/mempool_resurrect_test.py | 2 - qa/rpc-tests/mempool_spendcoinbase.py | 2 - qa/rpc-tests/merkle_blocks.py | 2 - qa/rpc-tests/nodehandling.py | 5 +-- qa/rpc-tests/p2p-fullblocktest.py | 6 +-- qa/rpc-tests/proxy_test.py | 6 +-- qa/rpc-tests/pruning.py | 1 - qa/rpc-tests/rawtransactions.py | 16 ++++---- qa/rpc-tests/reindex.py | 1 - qa/rpc-tests/replace-by-fee.py | 3 +- qa/rpc-tests/rest.py | 14 +++---- qa/rpc-tests/rpcbind_test.py | 7 +--- qa/rpc-tests/sendheaders.py | 3 +- qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/script.py | 8 ++-- qa/rpc-tests/test_framework/util.py | 12 +++--- qa/rpc-tests/txn_clone.py | 4 -- qa/rpc-tests/txn_doublespend.py | 3 -- qa/rpc-tests/wallet.py | 2 +- qa/rpc-tests/zmq_test.py | 7 ++-- 34 files changed, 80 insertions(+), 129 deletions(-) diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 5bb41df1a..9b1fdd935 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -10,7 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP -from binascii import hexlify, unhexlify +from binascii import unhexlify import cStringIO import time diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index e90e11e6a..f666a07c9 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class BIP65Test(BitcoinTestFramework): @@ -46,7 +44,7 @@ class BIP65Test(BitcoinTestFramework): self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=4 blocks") + raise AssertionError("Failed to mine a version=4 blocks") # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index ec1678cc2..9118b8fac 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -10,7 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript -from binascii import hexlify, unhexlify +from binascii import unhexlify import cStringIO import time diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index 5afc9ddde..be9121c45 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class BIP66Test(BitcoinTestFramework): @@ -46,7 +44,7 @@ class BIP66Test(BitcoinTestFramework): self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=3 blocks") + raise AssertionError("Failed to mine a version=3 blocks") # TODO: check that new DERSIG rules are enforced diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 673f1cc54..eccb506e5 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -7,7 +7,7 @@ # Test RPC calls related to blockchain state. # -import decimal +from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -39,7 +39,7 @@ class BlockchainTest(BitcoinTestFramework): node = self.nodes[0] res = node.gettxoutsetinfo() - assert_equal(res[u'total_amount'], decimal.Decimal('8725.00000000')) + assert_equal(res[u'total_amount'], Decimal('8725.00000000')) assert_equal(res[u'transactions'], 200) assert_equal(res[u'height'], 200) assert_equal(res[u'txouts'], 200) diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 2112097af..6964348d5 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -10,6 +10,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class DisableWalletTest (BitcoinTestFramework): def setup_chain(self): diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 2deede0c3..20e6ce961 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class ForkNotifyTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index dda916615..0287965b9 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -5,8 +5,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from pprint import pprint -from time import sleep # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): @@ -53,11 +51,11 @@ class RawTransactionsTest(BitcoinTestFramework): watchonly_amount = 200 self.nodes[3].importpubkey(watchonly_pubkey, "", True) watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) - self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10); + self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) self.sync_all() self.nodes[0].generate(1) @@ -130,7 +128,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 5.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -159,7 +157,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 5.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -189,7 +187,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 1.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -314,7 +312,7 @@ class RawTransactionsTest(BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Insufficient" in errorString, True); + assert("Insufficient" in errorString) @@ -326,11 +324,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1); + txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -341,11 +339,11 @@ class RawTransactionsTest(BitcoinTestFramework): rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendmany("", outputs); + txId = self.nodes[0].sendmany("", outputs) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -368,11 +366,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -401,11 +399,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -424,7 +422,7 @@ class RawTransactionsTest(BitcoinTestFramework): # send 1.2 BTC to msig addr - txId = self.nodes[0].sendtoaddress(mSigObj, 1.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -466,7 +464,7 @@ class RawTransactionsTest(BitcoinTestFramework): error = False try: - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) except: error = True assert(error) @@ -496,13 +494,13 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################### #empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() for i in range(0,20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01); + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -514,11 +512,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[1].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[1].sendmany("", outputs); + txId = self.nodes[1].sendmany("", outputs) signedFee = self.nodes[1].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs @@ -527,13 +525,13 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################# #again, empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() for i in range(0,20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01); + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.sync_all() self.nodes[0].generate(1) self.sync_all() diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index e8d2d8f3f..dd260836b 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework): # Split the network and build two chains of different lengths. self.split_network () - self.nodes[0].generate(10); - self.nodes[2].generate(20); + self.nodes[0].generate(10) + self.nodes[2].generate(20) self.sync_all () tips = self.nodes[1].getchaintips () diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 5b9fa0097..eb548aee9 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -36,13 +36,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); + out2 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! conn.close() @@ -53,13 +53,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); + out2 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! conn.close() @@ -70,7 +70,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, False) #now the connection must be closed after the response @@ -82,7 +82,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on @@ -93,7 +93,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index a74ecb128..5f6b1abed 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -7,9 +7,7 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * from test_framework.comptool import TestManager, TestInstance, RejectResult -from test_framework.mininode import * from test_framework.blocktools import * -import logging import copy import time diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index d17b3d098..b2c0d145f 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -5,12 +5,8 @@ # from test_framework.test_framework import ComparisonTestFramework -from test_framework.util import * from test_framework.comptool import TestManager, TestInstance, RejectResult -from test_framework.mininode import * from test_framework.blocktools import * -import logging -import copy import time diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index a8cf6360e..7914ceea2 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -48,7 +48,7 @@ class MempoolLimitTest(BitcoinTestFramework): # by now, the tx should be evicted, check confirmation state assert(txid not in self.nodes[0].getrawmempool()) - txdata = self.nodes[0].gettransaction(txid); + txdata = self.nodes[0].gettransaction(txid) assert(txdata['confirmations'] == 0) #confirmation should still be 0 if __name__ == '__main__': diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index d96a3f826..ea48e3845 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): @@ -25,7 +23,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.nodes.append(start_node(1, self.options.tmpdir, args)) connect_nodes(self.nodes[1], 0) self.is_network_split = False - self.sync_all + self.sync_all() def create_tx(self, from_txid, to_address, amount): inputs = [{ "txid" : from_txid, "vout" : 0}] @@ -87,11 +85,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.sync_all() - assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, timelock_tx_id ])) + assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, timelock_tx_id}) for node in self.nodes: node.invalidateblock(last_block[0]) - assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, spend_103_1_id ])) + assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, spend_103_1_id}) # Use invalidateblock to re-org back and make all those coinbase spends # immature/invalid: diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 750953ee5..14ca44310 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 35ce76e24..4a6e43609 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -15,8 +15,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolSpendCoinbaseTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 08e5db45f..cce8d8bbf 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class MerkleBlockTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index 3239dd033..c6c8c436e 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -9,7 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import base64 try: import http.client as httplib @@ -54,7 +53,7 @@ class NodeHandlingTest (BitcoinTestFramework): self.nodes[2].setban("127.0.0.0/24", "add") self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds - listBeforeShutdown = self.nodes[2].listbanned(); + listBeforeShutdown = self.nodes[2].listbanned() assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here time.sleep(2) #make 100% sure we expired 192.168.0.1 node time @@ -62,7 +61,7 @@ class NodeHandlingTest (BitcoinTestFramework): stop_node(self.nodes[2], 2) self.nodes[2] = start_node(2, self.options.tmpdir) - listAfterShutdown = self.nodes[2].listbanned(); + listAfterShutdown = self.nodes[2].listbanned() assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) assert_equal("/19" in listAfterShutdown[2]['address'], True) diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index a6525e679..28cc2474f 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -8,14 +8,10 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * from test_framework.comptool import TestManager, TestInstance, RejectResult -from test_framework.mininode import * from test_framework.blocktools import * -import logging -import copy import time -import numbers from test_framework.key import CECKey -from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE +from test_framework.script import CScript, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE class PreviousSpendableOutput(object): def __init__(self, tx = CTransaction(), n = -1): diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 3623c1616..7f77e664d 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -3,9 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import socket -import traceback, sys -from binascii import hexlify -import time, os from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType from test_framework.test_framework import BitcoinTestFramework @@ -34,7 +31,8 @@ addnode connect to onion addnode connect to generic DNS name ''' -class ProxyTest(BitcoinTestFramework): + +class ProxyTest(BitcoinTestFramework): def __init__(self): # Create two proxies on different ports # ... one unauthenticated diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 26ae4af01..b0f4b88ae 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -13,7 +13,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os.path def calc_usage(blockdir): return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index d77b41979..dd9e5e28a 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from pprint import pprint -from time import sleep # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): @@ -43,9 +41,9 @@ class RawTransactionsTest(BitcoinTestFramework): self.sync_all() self.nodes[0].generate(101) self.sync_all() - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0) self.sync_all() self.nodes[0].generate(5) self.sync_all() @@ -64,7 +62,7 @@ class RawTransactionsTest(BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Missing inputs" in errorString, True); + assert("Missing inputs" in errorString) ######################### # RAW TX MULTISIG TESTS # @@ -83,7 +81,7 @@ class RawTransactionsTest(BitcoinTestFramework): bal = self.nodes[2].getbalance() # send 1.2 BTC to msig adr - txId = self.nodes[0].sendtoaddress(mSigObj, 1.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -105,7 +103,7 @@ class RawTransactionsTest(BitcoinTestFramework): mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) mSigObjValid = self.nodes[2].validateaddress(mSigObj) - txId = self.nodes[0].sendtoaddress(mSigObj, 2.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) decTx = self.nodes[0].gettransaction(txId) rawTx = self.nodes[0].decoderawtransaction(decTx['hex']) sPK = rawTx['vout'][0]['scriptPubKey']['hex'] @@ -123,7 +121,7 @@ class RawTransactionsTest(BitcoinTestFramework): for outpoint in rawTx['vout']: if outpoint['value'] == Decimal('2.20000000'): vout = outpoint - break; + break bal = self.nodes[0].getbalance() inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}] diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index d90177a02..321c2fe42 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -8,7 +8,6 @@ # from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os.path class ReindexTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 734db33b5..ba1956853 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -54,8 +54,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): tx2.vout = [CTxOut(amount, scriptPubKey)] tx2.rehash() - tx2_hex = binascii.hexlify(tx2.serialize()).decode('utf-8') - #print tx2_hex + binascii.hexlify(tx2.serialize()).decode('utf-8') signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8')) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 682c53169..8c8353650 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -12,9 +12,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from struct import * import binascii -import json import StringIO -import decimal try: import http.client as httplib @@ -143,9 +141,9 @@ class RESTTest (BitcoinTestFramework): binaryRequest = b'\x01\x02' binaryRequest += binascii.unhexlify(txid) - binaryRequest += pack("i", n); - binaryRequest += binascii.unhexlify(vintx); - binaryRequest += pack("i", 0); + binaryRequest += pack("i", n) + binaryRequest += binascii.unhexlify(vintx) + binaryRequest += pack("i", 0) bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) output = StringIO.StringIO() @@ -206,7 +204,7 @@ class RESTTest (BitcoinTestFramework): json_request = '/checkmempool/' for x in range(0, 15): json_request += txid+'-'+str(n)+'/' - json_request = json_request.rstrip("/"); + json_request = json_request.rstrip("/") response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) assert_equal(response.status, 200) #must be a 500 because we exceeding the limits @@ -254,7 +252,7 @@ class RESTTest (BitcoinTestFramework): response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) response_header_json_str = response_header_json.read() - json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal) + json_obj = json.loads(response_header_json_str, parse_float=Decimal) assert_equal(len(json_obj), 1) #ensure that there is one header in the json response assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same @@ -282,7 +280,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(len(json_obj), 5) #now we should have 5 header objects # do tx test - tx_hash = block_json_obj['tx'][0]['txid']; + tx_hash = block_json_obj['tx'][0]['txid'] json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json") json_obj = json.loads(json_string) assert_equal(json_obj['txid'], tx_hash) diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 5f409ad61..10a48b555 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -5,13 +5,8 @@ # Test for -rpcbind, as well as -rpcallowip and -rpcconnect -# Add python-bitcoinrpc to module search path: -import os -import sys +# TODO extend this test from the test framework (like all other tests) -import json -import shutil -import subprocess import tempfile import traceback diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 7572bc277..172506715 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -7,7 +7,6 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import time from test_framework.blocktools import create_block, create_coinbase ''' @@ -445,7 +444,7 @@ class SendHeadersTest(BitcoinTestFramework): inv_node.sync_with_ping() # Make sure blocks are processed test_node.last_getdata = None - test_node.send_header_for_blocks(blocks); + test_node.send_header_for_blocks(blocks) test_node.sync_with_ping() # should not have received any getdata messages with mininode_lock: diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 59aa8c15c..88f553a7f 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -5,7 +5,7 @@ # from mininode import * -from script import CScript, CScriptOp, OP_TRUE, OP_CHECKSIG +from script import CScript, OP_TRUE, OP_CHECKSIG # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 008887602..bf5e25fb2 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -14,7 +14,8 @@ Functionality to build scripts, as well as SignatureHash(). from __future__ import absolute_import, division, print_function, unicode_literals -from test_framework.mininode import CTransaction, CTxOut, hash256 +from .mininode import CTransaction, CTxOut, hash256 +from binascii import hexlify import sys bchr = chr @@ -24,10 +25,9 @@ if sys.version > '3': bchr = lambda x: bytes([x]) bord = lambda x: x -import copy import struct -from test_framework.bignum import bn2vch +from .bignum import bn2vch MAX_SCRIPT_SIZE = 10000 MAX_SCRIPT_ELEMENT_SIZE = 520 @@ -777,7 +777,7 @@ class CScript(bytes): # need to change def _repr(o): if isinstance(o, bytes): - return "x('%s')" % binascii.hexlify(o).decode('utf8') + return "x('%s')" % hexlify(o).decode('utf8') else: return repr(o) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 0388e0811..15fd50363 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -102,12 +102,12 @@ def initialize_datadir(dirname, n): if not os.path.isdir(datadir): os.makedirs(datadir) with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: - f.write("regtest=1\n"); - f.write("rpcuser=rt\n"); - f.write("rpcpassword=rt\n"); - f.write("port="+str(p2p_port(n))+"\n"); - f.write("rpcport="+str(rpc_port(n))+"\n"); - f.write("listenonion=0\n"); + f.write("regtest=1\n") + f.write("rpcuser=rt\n") + f.write("rpcpassword=rt\n") + f.write("port="+str(p2p_port(n))+"\n") + f.write("rpcport="+str(rpc_port(n))+"\n") + f.write("listenonion=0\n") return datadir def initialize_chain(test_dir): diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index bad090bcb..3092f09ec 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -8,11 +8,7 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import AuthServiceProxy, JSONRPCException -from decimal import Decimal from test_framework.util import * -import os -import shutil class TxnMallTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 05a3a3478..8d7f6e505 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -9,9 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from decimal import Decimal -import os -import shutil class TxnMallTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 43ec621a4..2c0a009ca 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -145,7 +145,7 @@ class WalletTest (BitcoinTestFramework): sync_blocks(self.nodes) relayed = self.nodes[0].resendwallettransactions() - assert_equal(set(relayed), set([txid1, txid2])) + assert_equal(set(relayed), {txid1, txid2}) sync_mempools(self.nodes) assert(txid1 in self.nodes[3].getrawmempool()) diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index bcb132321..88532541a 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -11,7 +11,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import zmq import binascii -from test_framework.mininode import hash256 try: import http.client as httplib @@ -42,7 +41,7 @@ class ZMQTest (BitcoinTestFramework): def run_test(self): self.sync_all() - genhashes = self.nodes[0].generate(1); + genhashes = self.nodes[0].generate(1) self.sync_all() print "listen..." @@ -58,7 +57,7 @@ class ZMQTest (BitcoinTestFramework): assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq n = 10 - genhashes = self.nodes[1].generate(n); + genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] @@ -76,7 +75,7 @@ class ZMQTest (BitcoinTestFramework): hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() - #now we should receive a zmq msg because the tx was broadcastet + # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = str(msg[0]) body = msg[1] From 30cdacea3c356acda32ab77238f07c1c40b1f1b5 Mon Sep 17 00:00:00 2001 From: crowning- Date: Wed, 13 Jan 2016 21:17:08 +0100 Subject: [PATCH 0138/1223] [Wallet] Transaction View: LastMonth calculation fixed --- src/qt/transactionview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 28928d821..4a9a19821 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -267,7 +267,7 @@ void TransactionView::chooseDate(int idx) break; case LastMonth: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1).addMonths(-1)), QDateTime(QDate(current.year(), current.month(), 1))); break; case ThisYear: From 3503a78670d0eacf39c618b45b08581dfb3ed68f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 13 Jan 2016 22:20:00 -0500 Subject: [PATCH 0139/1223] release: remove libc6 dependency from the osx signing descriptor It is unneeded after the last toolchain update, and missing from Trusty. --- contrib/gitian-descriptors/gitian-osx-signer.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index 5b52c492f..4c4e3ff82 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -5,7 +5,6 @@ suites: architectures: - "amd64" packages: -- "libc6:i386" - "faketime" reference_datetime: "2016-01-01 00:00:00" remotes: From 4d10d2e16fb837abe304e0a5d3bc0a41941d917a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 14 Jan 2016 20:35:21 -0500 Subject: [PATCH 0140/1223] Eliminate race condition in mempool_packages test --- qa/rpc-tests/mempool_packages.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 063308d39..47c1028b9 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -87,9 +87,18 @@ class MempoolPackagesTest(BitcoinTestFramework): print "too-long-ancestor-chain successfully rejected" # Check that prioritising a tx before it's added to the mempool works + # First clear the mempool by mining a block. self.nodes[0].generate(1) + sync_blocks(self.nodes) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + # Prioritise a transaction that has been mined, then add it back to the + # mempool by using invalidateblock. self.nodes[0].prioritisetransaction(chain[-1], 0, 2000) self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + # Keep node1's tip synced with node0 + self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) + + # Now check that the transaction is in the mempool, with the right modified fee mempool = self.nodes[0].getrawmempool(True) descendant_fees = 0 From 2adf7e2c90b22d89308f36355f8a6de395e24c36 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 15 Jan 2016 04:34:02 +0000 Subject: [PATCH 0141/1223] Bugfix: The var is LIBUNIVALUE,not LIBBITCOIN_UNIVALUE --- src/Makefile.bench.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index d660a3a74..00a80ae81 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -14,7 +14,7 @@ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bench_bench_bitcoin_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_COMMON) \ - $(LIBBITCOIN_UNIVALUE) \ + $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ From ab22705a7b7796362ad7c6ec8f7465d3a450977f Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 14 Jan 2016 00:26:23 +0000 Subject: [PATCH 0142/1223] Build against system UniValue when available --- configure.ac | 50 ++++++++++++++++++++++++++++++++++++++- src/Makefile.am | 19 ++++++++++----- src/Makefile.test.include | 2 ++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 63a745393..9819c2493 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,12 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=$enableval], [use_glibc_compat=no]) +AC_ARG_WITH([system-univalue], + [AS_HELP_STRING([--without-system-univalue], + [Build with system UniValue (default is auto)])], + [system_univalue=$withval], + [system_univalue=auto] +) AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], @@ -742,6 +748,44 @@ else fi fi +dnl univalue check + +if test x$system_univalue != xno ; then + found_univalue=no + if test x$use_pkgconfig = xyes; then + : #NOP + m4_ifdef( + [PKG_CHECK_MODULES], + [ + PKG_CHECK_MODULES([UNIVALUE],[libunivalue],[found_univalue=yes],[true]) + ] + ) + else + AC_CHECK_HEADER([univalue.h],[ + AC_CHECK_LIB([univalue], [main],[ + UNIVALUE_LIBS=-lunivalue + found_univalue=yes + ],[true]) + ],[true]) + fi + + if test x$found_univalue = xyes ; then + system_univalue=yes + elif test x$system_univalue = xyes ; then + AC_MSG_ERROR([univalue not found]) + else + system_univalue=no + fi +fi + +if test x$system_univalue = xno ; then + UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' + UNIVALUE_LIBS='univalue/libunivalue.la' +fi +AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$system_univalue = xno]) +AC_SUBST(UNIVALUE_CFLAGS) +AC_SUBST(UNIVALUE_LIBS) + CXXFLAGS_TEMP="$CXXFLAGS" LIBS_TEMP="$LIBS" CXXFLAGS="$CXXFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" @@ -958,8 +1002,12 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" +if test x$system_univalue = xno; then + AC_CONFIG_SUBDIRS([src/univalue]) +fi + ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" -AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue]) +AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index bb627a544..97593bfe8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,20 @@ -DIST_SUBDIRS = secp256k1 univalue +DIST_SUBDIRS = secp256k1 AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(HARDENED_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) +if EMBEDDED_UNIVALUE +DIST_SUBDIRS += univalue + +LIBUNIVALUE = univalue/libunivalue.la + +$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) +else +LIBUNIVALUE = $(UNIVALUE_LIBS) +endif + if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv @@ -23,7 +34,7 @@ BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include -BITCOIN_INCLUDES += -I$(srcdir)/univalue/include +BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS) LIBBITCOIN_SERVER=libbitcoin_server.a LIBBITCOIN_WALLET=libbitcoin_wallet.a @@ -33,13 +44,9 @@ LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBBITCOINQT=qt/libbitcoinqt.a LIBSECP256K1=secp256k1/libsecp256k1.la -LIBUNIVALUE=univalue/libunivalue.la $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) - -$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 4d0894b71..6cf0205dd 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -130,7 +130,9 @@ check-local: @echo "Running test/bitcoin-util-test.py..." $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check +if EMBEDDED_UNIVALUE $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check +endif %.json.h: %.json @$(MKDIR_P) $(@D) From 5d3b29bc00b85c99b07e1ca78ae8cc565f01edcc Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 15 Jan 2016 02:19:28 +0000 Subject: [PATCH 0143/1223] doc: Add UniValue to build instructions --- doc/build-unix.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index 159a14060..0f7b5a5f7 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -46,6 +46,7 @@ Optional dependencies: qt | GUI | GUI toolkit (only needed when GUI enabled) protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) + univalue | Utility | JSON parsing and encoding (if missing, bundled version will be used) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x) For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. From b07b103e8af14cd3fca44dca7bc694d2c3bffcc1 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 15 Jan 2016 07:45:39 +0000 Subject: [PATCH 0144/1223] Update project URL --- README.md | 2 +- contrib/debian/control | 2 +- share/setup.nsi.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5bf56947d..77d30db69 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Bitcoin Core integration/staging tree [![Build Status](https://travis-ci.org/bitcoin/bitcoin.svg?branch=master)](https://travis-ci.org/bitcoin/bitcoin) -https://www.bitcoin.org +https://bitcoincore.org What is Bitcoin? ---------------- diff --git a/contrib/debian/control b/contrib/debian/control index 490b2571c..fce6bc011 100644 --- a/contrib/debian/control +++ b/contrib/debian/control @@ -23,7 +23,7 @@ Build-Depends: debhelper, libprotobuf-dev, protobuf-compiler, python Standards-Version: 3.9.2 -Homepage: https://www.bitcoin.org/ +Homepage: https://bitcoincore.org/ Vcs-Git: git://github.com/bitcoin/bitcoin.git Vcs-Browser: https://github.com/bitcoin/bitcoin diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 6c0e895bb..62db88c27 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -7,7 +7,7 @@ SetCompressor /SOLID lzma !define REGKEY "SOFTWARE\$(^Name)" !define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ !define COMPANY "Bitcoin Core project" -!define URL http://www.bitcoin.org/ +!define URL https://bitcoincore.org/ # MUI Symbol Definitions !define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" From fabcee1972f13bc77249bd23e8a1c16ce69aaae1 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 16 Jan 2016 15:32:35 +0100 Subject: [PATCH 0145/1223] Remove copyright header from autogenerated chainparamsseeds.h --- src/chainparamsseeds.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 740e4718c..423362859 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -1,7 +1,3 @@ -// Copyright (c) 2014-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - #ifndef BITCOIN_CHAINPARAMSSEEDS_H #define BITCOIN_CHAINPARAMSSEEDS_H /** From 9d263bd17c2bdd5ba9e31bd5fb110c332eb80691 Mon Sep 17 00:00:00 2001 From: Chris Wheeler Date: Sun, 17 Jan 2016 11:03:56 +0000 Subject: [PATCH 0146/1223] Typo fixes in comments --- qa/rpc-tests/merkle_blocks.py | 2 +- src/net.cpp | 2 +- src/netbase.cpp | 2 +- src/policy/fees.cpp | 2 +- src/policy/fees.h | 6 +++--- src/qt/clientmodel.cpp | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/test/merkle_tests.cpp | 2 +- src/torcontrol.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet_ismine.h | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 08e5db45f..94775f84c 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -72,7 +72,7 @@ class MerkleBlockTest(BitcoinTestFramework): txid_spent = txin_spent["txid"] txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2 - # We cant find the block from a fully-spent tx + # We can't find the block from a fully-spent tx assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent]) # ...but we can if we specify the block assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) diff --git a/src/net.cpp b/src/net.cpp index 84582484e..db8f97abc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2177,7 +2177,7 @@ bool CNode::OutboundTargetReached(bool historicalBlockServingLimit) if (historicalBlockServingLimit) { - // keep a large enought buffer to at least relay each block once + // keep a large enough buffer to at least relay each block once uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE; if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) diff --git a/src/netbase.cpp b/src/netbase.cpp index 4e1f26760..7f79dd02c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -140,7 +140,7 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign return false; do { - // Should set the timeout limit to a resonable value to avoid + // Should set the timeout limit to a reasonable value to avoid // generating unnecessary checking call during the polling loop, // while it can still response to stop request quick enough. // 2 seconds looks fine in our situation. diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 980ecf10d..de3c060d6 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -87,7 +87,7 @@ double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, int maxbucketindex = buckets.size() - 1; // requireGreater means we are looking for the lowest fee/priority such that all higher - // values pass, so we start at maxbucketindex (highest fee) and look at succesively + // values pass, so we start at maxbucketindex (highest fee) and look at successively // smaller buckets until we reach failure. Otherwise, we are looking for the highest // fee/priority such that all lower values fail, and we go in the opposite direction. unsigned int startbucket = requireGreater ? maxbucketindex : 0; diff --git a/src/policy/fees.h b/src/policy/fees.h index 7a293267d..3fa31c39e 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -29,7 +29,7 @@ class CTxMemPool; * included in blocks before transactions of lower fee/priority. So for * example if you wanted to know what fee you should put on a transaction to * be included in a block within the next 5 blocks, you would start by looking - * at the bucket with with the highest fee transactions and verifying that a + * at the bucket with the highest fee transactions and verifying that a * sufficiently high percentage of them were confirmed within 5 blocks and * then you would look at the next highest fee bucket, and so on, stopping at * the last bucket to pass the test. The average fee of transactions in this @@ -87,13 +87,13 @@ private: // Count the total # of txs in each bucket // Track the historical moving average of this total over blocks std::vector txCtAvg; - // and calcuate the total for the current block to update the moving average + // and calculate the total for the current block to update the moving average std::vector curBlockTxCt; // Count the total # of txs confirmed within Y blocks in each bucket // Track the historical moving average of theses totals over blocks std::vector > confAvg; // confAvg[Y][X] - // and calcuate the totals for the current block to update the moving averages + // and calculate the totals for the current block to update the moving averages std::vector > curBlockConf; // curBlockConf[Y][X] // Sum the total priority/fee of all tx's in each bucket diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index b4ac69639..fb502b3c8 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -112,7 +112,7 @@ double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const void ClientModel::updateTimer() { // no locking required at this point - // the following calls will aquire the required lock + // the following calls will acquire the required lock Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage()); Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 31c9028c4..95d4bd56f 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -789,7 +789,7 @@ void SendCoinsDialog::coinControlUpdateLabels() if (model->getOptionsModel()->getCoinControlFeatures()) { - // enable minium absolute fee UI controls + // enable minimum absolute fee UI controls ui->radioCustomAtLeast->setVisible(true); // only enable the feature if inputs are selected diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index 1e31f2e67..b40ab848d 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(merkle_test) int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation. if (duplicate2 >= ntx1) break; int ntx2 = ntx1 + duplicate2; - int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the the third mutation. + int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the third mutation. if (duplicate3 >= ntx2) break; int ntx3 = ntx2 + duplicate3; // Build a block with ntx different transactions. diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 4ebcb9b66..2fd20ae42 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -303,7 +303,7 @@ static std::map ParseTorReplyMapping(const std::string /** Read full contents of a file and return them in a std::string. * Returns a pair . - * If an error occured, status will be false, otherwise status will be true and the data will be returned in string. + * If an error occurred, status will be false, otherwise status will be true and the data will be returned in string. * * @param maxsize Puts a maximum size limit on the file that is read. If the file is larger than this, truncated data * (with len > maxsize) will be returned. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 374f2fd40..12e80f4c2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1424,7 +1424,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions. Negative confirmations indicate the\n" - " transation conflicts with the block chain\n" + " transaction conflicts with the block chain\n" " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 93cdf6ab8..51afd1b14 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -17,7 +17,7 @@ class CScript; enum isminetype { ISMINE_NO = 0, - //! Indicates that we dont know how to create a scriptSig that would solve this if we were given the appropriate private keys + //! Indicates that we don't know how to create a scriptSig that would solve this if we were given the appropriate private keys ISMINE_WATCH_UNSOLVABLE = 1, //! Indicates that we know how to create a scriptSig that would solve this if we were given the appropriate private keys ISMINE_WATCH_SOLVABLE = 2, From bd34174ebca239e6796f0eb2015ddc2f218aac3c Mon Sep 17 00:00:00 2001 From: Prayag Verma Date: Sun, 17 Jan 2016 23:38:11 +0530 Subject: [PATCH 0147/1223] Update license year range to 2016 --- COPYING | 2 +- configure.ac | 2 +- contrib/debian/copyright | 2 +- src/clientversion.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/COPYING b/COPYING index 314d2e2ff..c6be8e547 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2009-2015 The Bitcoin Core developers +Copyright (c) 2009-2016 The Bitcoin Core developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/configure.ac b/configure.ac index 07f9a4a6f..0342777fb 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) -define(_COPYRIGHT_YEAR, 2015) +define(_COPYRIGHT_YEAR, 2016) AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 83ce560a7..bbaa5b163 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2015, Bitcoin Core Developers +Copyright: 2009-2016, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, as well as the numerous contributors to the project. diff --git a/src/clientversion.h b/src/clientversion.h index c832663a7..40361660e 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -26,7 +26,7 @@ * Copyright year (2009-this) * Todo: update this when changing our copyright comments in the source */ -#define COPYRIGHT_YEAR 2015 +#define COPYRIGHT_YEAR 2016 #endif //HAVE_CONFIG_H From fa6a59dd397e62e850fc57df05cd6d117fbdcd82 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 17 Jan 2016 17:55:53 +0100 Subject: [PATCH 0148/1223] [qt] Windows: Make rpcconsole monospace font larger --- src/qt/rpcconsole.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 30e551de1..cc377c4ff 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -472,7 +472,11 @@ void RPCConsole::clear() // Set default style sheet QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont()); // Try to make fixed font adequately large on different OS +#ifdef WIN32 + QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 10 / 8); +#else QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9); +#endif ui->messagesWidget->document()->setDefaultStyleSheet( QString( "table { }" From 99fda26de0661afcbe43d5e862c382e3c2e3aa5e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 19 Nov 2015 13:11:50 +0100 Subject: [PATCH 0149/1223] doc: Make networking work inside builder in gitian-building.md These are changes I needed to get gitian building to work with Debian 8.2, which is the version we tell to use. - Set up NAT, so that container can access network beyond host - Remove explicit cgroup setup - these are mounted automatically now --- doc/gitian-building.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 019e85169..dd98c038a 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -262,12 +262,12 @@ Then set up LXC and the rest with the following, which is a complex jumble of se # the version of lxc-start in Debian 7.4 needs to run as root, so make sure # that the build script can execute it without providing a password echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc -# add cgroup for LXC -echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab # make /etc/rc.local script that sets up bridge between guest and host echo '#!/bin/sh -e' > /etc/rc.local echo 'brctl addbr br0' >> /etc/rc.local echo 'ifconfig br0 10.0.3.2/24 up' >> /etc/rc.local +echo 'iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE' >> /etc/rc.local +echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/rc.local echo 'exit 0' >> /etc/rc.local # make sure that USE_LXC is always set when logging in as debian, # and configure LXC IP addresses From 3b468a0e609147c7d7afd8ed97bf271f2356daef Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 19 Nov 2015 13:25:08 +0100 Subject: [PATCH 0150/1223] gitian: Need `ca-certificates` and `python` for LXC builds --- contrib/gitian-descriptors/gitian-linux.yml | 2 ++ contrib/gitian-descriptors/gitian-osx.yml | 2 ++ contrib/gitian-descriptors/gitian-win.yml | 2 ++ doc/gitian-building.md | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index ee852ff13..04b9b0177 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -15,6 +15,8 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" +- "ca-certificates" +- "python" reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 7e40803a0..c2d8b9baa 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -18,6 +18,8 @@ packages: - "libcap-dev" - "libz-dev" - "libbz2-dev" +- "ca-certificates" +- "python" reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index c8fbe32ee..361842920 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -18,6 +18,8 @@ packages: - "g++-mingw-w64" - "nsis" - "zip" +- "ca-certificates" +- "python" reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" diff --git a/doc/gitian-building.md b/doc/gitian-building.md index dd98c038a..e3fb94438 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -259,7 +259,7 @@ adduser debian sudo Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds: ```bash -# the version of lxc-start in Debian 7.4 needs to run as root, so make sure +# the version of lxc-start in Debian needs to run as root, so make sure # that the build script can execute it without providing a password echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc # make /etc/rc.local script that sets up bridge between guest and host From faeda0e67792855cdafa2f6eaf43ad74de89b18b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 19:29:03 +0100 Subject: [PATCH 0151/1223] [travis] Run contrib/devtools/check-doc.py early --- .travis.yml | 2 +- contrib/devtools/check-doc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1a389a404..71cee9925 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,12 +64,12 @@ script: - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir PACKAGE=bitcoin VERSION=$HOST + - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi - cd bitcoin-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$RUN_TESTS" = "true" ]; then make check; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi - - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi after_script: - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index bc4ad5349..9c589e6e6 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. From 4a0487937877484f14476716c3643de7a31c32da Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 18 Jan 2016 09:17:48 -0500 Subject: [PATCH 0152/1223] Fix error in blockchain.py introduced in merge --- qa/rpc-tests/blockchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index daf6fb57a..b0fc7b017 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -80,7 +80,7 @@ class BlockchainTest(BitcoinTestFramework): assert isinstance(header['mediantime'], int) assert isinstance(header['nonce'], int) assert isinstance(header['version'], int) - assert isinstance(header['difficulty'], decimal.Decimal) + assert isinstance(header['difficulty'], Decimal) if __name__ == '__main__': BlockchainTest().main() From facd288c31c387bb3582c32f767a730ece6e408a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 16 Jan 2016 23:07:18 +0100 Subject: [PATCH 0153/1223] [qa] wallet: Print maintenance --- qa/rpc-tests/wallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 2c0a009ca..43ba1d977 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -3,7 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. - from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -265,6 +264,7 @@ class WalletTest (BitcoinTestFramework): '-salvagewallet', ] for m in maintenance: + print "check " + m stop_nodes(self.nodes) wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) From 3cae14056a1cd8f01dc4943fa0b78315734d741a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 19 Jan 2016 08:42:05 +0000 Subject: [PATCH 0154/1223] Bugfix: Actually use _COPYRIGHT_HOLDERS_SUBSTITUTION everywhere --- configure.ac | 3 ++- share/qt/extract_strings_qt.py | 2 ++ src/Makefile.qt.include | 2 +- src/util.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 5d4468e51..c90187845 100644 --- a/configure.ac +++ b/configure.ac @@ -915,7 +915,8 @@ AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release]) AC_DEFINE(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS", [Copyright holder(s) before %s replacement]) -define(_COPYRIGHT_HOLDERS_FINAL, patsubst(_COPYRIGHT_HOLDERS, [%s], [AC_PACKAGE_NAME])) +AC_DEFINE(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION", [Replacement for %s in copyright holders string]) +define(_COPYRIGHT_HOLDERS_FINAL, patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])) AC_DEFINE(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL", [Copyright holder(s)]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 470d1f2b4..2a6e4b930 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -72,6 +72,8 @@ f.write(""" f.write('static const char UNUSED *bitcoin_strings[] = {\n') f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('PACKAGE_NAME'),)) f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('COPYRIGHT_HOLDERS'),)) +if os.getenv('COPYRIGHT_HOLDERS_SUBSTITUTION') != os.getenv('PACKAGE_NAME'): + f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('COPYRIGHT_HOLDERS_SUBSTITUTION'),)) messages.sort(key=operator.itemgetter(0)) for (msgid, msgstr) in messages: if msgid != EMPTY: diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 2d5e715ee..c2ecaa787 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -382,7 +382,7 @@ SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" - $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" ../share/qt/extract_strings_qt.py $^ + $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" ../share/qt/extract_strings_qt.py $^ translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" diff --git a/src/util.cpp b/src/util.cpp index 66dd45dc8..0439ead47 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -839,5 +839,5 @@ std::string CopyrightHolders() std::string strCopyrightHolders = _(COPYRIGHT_HOLDERS); if (strCopyrightHolders.find("%s") == strCopyrightHolders.npos) return strCopyrightHolders; - return strprintf(strCopyrightHolders, _(PACKAGE_NAME)); + return strprintf(strCopyrightHolders, _(COPYRIGHT_HOLDERS_SUBSTITUTION)); } From eaa8d2754b48b62cdd07255fc3028feecad0c095 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 16 Dec 2015 14:57:54 -0500 Subject: [PATCH 0155/1223] RPC: indicate which transactions are replaceable Add "bip125-replaceable" output field to listtransactions and gettransaction which indicates if an unconfirmed transaction, or any unconfirmed parent, is signaling opt-in RBF according to BIP 125. --- qa/rpc-tests/listtransactions.py | 109 +++++++++++++++++++++++++++++++ src/Makefile.am | 2 + src/policy/rbf.cpp | 46 +++++++++++++ src/policy/rbf.h | 20 ++++++ src/wallet/rpcwallet.cpp | 22 +++++++ 5 files changed, 199 insertions(+) create mode 100644 src/policy/rbf.cpp create mode 100644 src/policy/rbf.h diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 56c5a71fe..45ede8f04 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -7,7 +7,15 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import CTransaction +import cStringIO +import binascii +def txFromHex(hexstring): + tx = CTransaction() + f = cStringIO.StringIO(binascii.unhexlify(hexstring)) + tx.deserialize(f) + return tx def check_array_result(object_array, to_match, expected): """ @@ -108,6 +116,107 @@ class ListTransactionsTest(BitcoinTestFramework): {"category":"receive","amount":Decimal("0.1")}, {"txid":txid, "account" : "watchonly"} ) + self.run_rbf_opt_in_test() + + # Check that the opt-in-rbf flag works properly, for sent and received + # transactions. + def run_rbf_opt_in_test(self): + # Check whether a transaction signals opt-in RBF itself + def is_opt_in(node, txid): + rawtx = node.getrawtransaction(txid, 1) + for x in rawtx["vin"]: + if x["sequence"] < 0xfffffffe: + return True + return False + + # Find an unconfirmed output matching a certain txid + def get_unconfirmed_utxo_entry(node, txid_to_match): + utxo = node.listunspent(0, 0) + for i in utxo: + if i["txid"] == txid_to_match: + return i + return None + + # 1. Chain a few transactions that don't opt-in. + txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) + assert(not is_opt_in(self.nodes[0], txid_1)) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + + # Tx2 will build off txid_1, still not opting in to RBF. + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1) + + # Create tx2 using createrawtransaction + inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[0].getnewaddress(): 0.999} + tx2 = self.nodes[1].createrawtransaction(inputs, outputs) + tx2_signed = self.nodes[1].signrawtransaction(tx2)["hex"] + txid_2 = self.nodes[1].sendrawtransaction(tx2_signed) + + # ...and check the result + assert(not is_opt_in(self.nodes[1], txid_2)) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + + # Tx3 will opt-in to RBF + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2) + inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[1].getnewaddress(): 0.998} + tx3 = self.nodes[0].createrawtransaction(inputs, outputs) + tx3_modified = txFromHex(tx3) + tx3_modified.vin[0].nSequence = 0 + tx3 = binascii.hexlify(tx3_modified.serialize()).decode('utf-8') + tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex'] + txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) + + assert(is_opt_in(self.nodes[0], txid_3)) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + + # Tx4 will chain off tx3. Doesn't signal itself, but depends on one + # that does. + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3) + inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[0].getnewaddress(): 0.997} + tx4 = self.nodes[1].createrawtransaction(inputs, outputs) + tx4_signed = self.nodes[1].signrawtransaction(tx4)["hex"] + txid_4 = self.nodes[1].sendrawtransaction(tx4_signed) + + assert(not is_opt_in(self.nodes[1], txid_4)) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + + # Replace tx3, and check that tx4 becomes unknown + tx3_b = tx3_modified + tx3_b.vout[0].nValue -= 0.004*100000000 # bump the fee + tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') + tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] + txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) + assert(is_opt_in(self.nodes[0], txid_3b)) + + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + + # Check gettransaction as well: + for n in self.nodes[0:2]: + assert_equal(n.gettransaction(txid_1)["bip125-replaceable"], "no") + assert_equal(n.gettransaction(txid_2)["bip125-replaceable"], "no") + assert_equal(n.gettransaction(txid_3)["bip125-replaceable"], "yes") + assert_equal(n.gettransaction(txid_3b)["bip125-replaceable"], "yes") + assert_equal(n.gettransaction(txid_4)["bip125-replaceable"], "unknown") + + # After mining a transaction, it's no longer BIP125-replaceable + self.nodes[0].generate(1) + assert(txid_3b not in self.nodes[0].getrawmempool()) + assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no") + assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown") + + if __name__ == '__main__': ListTransactionsTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index 5da1a873d..5d7fbb13d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -122,6 +122,7 @@ BITCOIN_CORE_H = \ noui.h \ policy/fees.h \ policy/policy.h \ + policy/rbf.h \ pow.h \ prevector.h \ primitives/block.h \ @@ -239,6 +240,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/wallet.cpp \ wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ + policy/rbf.cpp \ $(BITCOIN_CORE_H) # crypto primitives library diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp new file mode 100644 index 000000000..98b1a1ba4 --- /dev/null +++ b/src/policy/rbf.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2016 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "policy/rbf.h" + +bool SignalsOptInRBF(const CTransaction &tx) +{ + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + if (txin.nSequence < std::numeric_limits::max()-1) { + return true; + } + } + return false; +} + +bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool) +{ + AssertLockHeld(pool.cs); + + CTxMemPool::setEntries setAncestors; + + // First check the transaction itself. + if (SignalsOptInRBF(entry.GetTx())) { + return true; + } + + // If this transaction is not in our mempool, then we can't be sure + // we will know about all its inputs. + if (!pool.exists(entry.GetTx().GetHash())) { + throw std::runtime_error("Cannot determine RBF opt-in signal for non-mempool transaction\n"); + } + + // If all the inputs have nSequence >= maxint-1, it still might be + // signaled for RBF if any unconfirmed parents have signaled. + uint64_t noLimit = std::numeric_limits::max(); + std::string dummy; + pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); + + BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) { + if (SignalsOptInRBF(it->GetTx())) { + return true; + } + } + return false; +} diff --git a/src/policy/rbf.h b/src/policy/rbf.h new file mode 100644 index 000000000..925ce0d9b --- /dev/null +++ b/src/policy/rbf.h @@ -0,0 +1,20 @@ +// Copyright (c) 2016 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_POLICY_RBF_H +#define BITCOIN_POLICY_RBF_H + +#include "txmempool.h" + +// Check whether the sequence numbers on this transaction are signaling +// opt-in to replace-by-fee, according to BIP 125 +bool SignalsOptInRBF(const CTransaction &tx); + +// Determine whether an in-mempool transaction is signaling opt-in to RBF +// according to BIP 125 +// This involves checking sequence numbers of the transaction, as well +// as the sequence numbers of all in-mempool ancestors. +bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool); + +#endif // BITCOIN_POLICY_RBF_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a977b5abd..f7a1ca0fe 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -11,6 +11,7 @@ #include "main.h" #include "net.h" #include "netbase.h" +#include "policy/rbf.h" #include "rpcserver.h" #include "timedata.h" #include "util.h" @@ -76,6 +77,23 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("walletconflicts", conflicts)); entry.push_back(Pair("time", wtx.GetTxTime())); entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); + + // Add opt-in RBF status + std::string rbfStatus = "no"; + if (confirms <= 0) { + LOCK(mempool.cs); + if (!mempool.exists(hash)) { + if (SignalsOptInRBF(wtx)) { + rbfStatus = "yes"; + } else { + rbfStatus = "unknown"; + } + } else if (IsRBFOptIn(*mempool.mapTx.find(hash), mempool)) { + rbfStatus = "yes"; + } + } + entry.push_back(Pair("bip125-replaceable", rbfStatus)); + BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) entry.push_back(Pair(item.first, item.second)); } @@ -1439,6 +1457,8 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n" " from (for receiving funds, positive amounts), or went to (for sending funds,\n" " negative amounts).\n" + " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" " }\n" "]\n" @@ -1707,6 +1727,8 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"txid\" : \"transactionid\", (string) The transaction id.\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" + " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" " \"details\" : [\n" " {\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" From fa6d4cc09575de30386bfbc5c8c3858cd7a2f42a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 20 Jan 2016 09:51:02 +0100 Subject: [PATCH 0156/1223] [walletdb] Fix syntax error in key parser --- src/wallet/db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index d18250b76..50b0f40a6 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -205,7 +205,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector Date: Tue, 19 Jan 2016 09:53:26 +0100 Subject: [PATCH 0157/1223] devtools: replace github-merge with python version This is meant to be a direct translation of the bash script, with the difference that it retrieves the PR title from github, thus creating pull messages like: Merge #12345: Expose transaction temperature over RPC --- contrib/README.md | 4 +- contrib/devtools/README.md | 4 +- contrib/devtools/github-merge.py | 223 +++++++++++++++++++++++++++++++ contrib/devtools/github-merge.sh | 185 ------------------------- 4 files changed, 227 insertions(+), 189 deletions(-) create mode 100755 contrib/devtools/github-merge.py delete mode 100755 contrib/devtools/github-merge.sh diff --git a/contrib/README.md b/contrib/README.md index 125594312..b6e572102 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -11,10 +11,10 @@ Repository Tools ### [Developer tools](/contrib/devtools) ### Specific tools for developers working on this repository. -Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. +Contains the script `github-merge.py` for merging github pull requests securely and signing them using GPG. ### [Verify-Commits](/contrib/verify-commits) ### -Tool to verify that every merge commit was signed by a developer using the above `github-merge.sh` script. +Tool to verify that every merge commit was signed by a developer using the above `github-merge.py` script. ### [Linearize](/contrib/linearize) ### Construct a linear, no-fork, best version of the blockchain. diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index fcb2275fc..1103ca86c 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -56,14 +56,14 @@ Usage: `git-subtree-check.sh DIR COMMIT` `COMMIT` may be omitted, in which case `HEAD` is used. -github-merge.sh +github-merge.py =============== A small script to automate merging pull-requests securely and sign them with GPG. For example: - ./github-merge.sh bitcoin/bitcoin 3077 + ./github-merge.py 3077 (in any git repository) will help you merge pull request #3077 for the bitcoin/bitcoin repository. diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py new file mode 100755 index 000000000..33d33b700 --- /dev/null +++ b/contrib/devtools/github-merge.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python2 +# Copyright (c) 2016 Bitcoin Core Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# This script will locally construct a merge commit for a pull request on a +# github repository, inspect it, sign it and optionally push it. + +# The following temporary branches are created/overwritten and deleted: +# * pull/$PULL/base (the current master we're merging onto) +# * pull/$PULL/head (the current state of the remote pull request) +# * pull/$PULL/merge (github's merge) +# * pull/$PULL/local-merge (our merge) + +# In case of a clean merge that is accepted by the user, the local branch with +# name $BRANCH is overwritten with the merged result, and optionally pushed. +from __future__ import division,print_function,unicode_literals +import os,sys +from sys import stdin,stdout,stderr +import argparse +import subprocess + +# External tools (can be overridden using environment) +GIT = os.getenv('GIT','git') +BASH = os.getenv('BASH','bash') + +def git_config_get(option, default=None): + ''' + Get named configuration option from git repository. + ''' + try: + return subprocess.check_output([GIT,'config','--get',option]).rstrip() + except subprocess.CalledProcessError as e: + return default + +def retrieve_pr_title(repo,pull): + ''' + Retrieve pull request title from github. + Return None if no title can be found, or an error happens. + ''' + import urllib2,json + try: + req = urllib2.Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) + result = urllib2.urlopen(req) + result = json.load(result) + return result['title'] + except Exception as e: + print('Warning: unable to retrieve pull title from github: %s' % e) + return None + +def ask_prompt(text): + print(text,end=" ",file=stderr) + reply = stdin.readline().rstrip() + print("",file=stderr) + return reply + +def parse_arguments(branch): + epilog = ''' + In addition, you can set the following git configuration variables: + githubmerge.repository (mandatory), + user.signingkey (mandatory), + githubmerge.host (default: git@github.com), + githubmerge.branch (default: master), + githubmerge.testcmd (default: none). + ''' + parser = argparse.ArgumentParser(description='Utility to merge, sign and push github pull requests', + epilog=epilog) + parser.add_argument('pull', metavar='PULL', type=int, nargs=1, + help='Pull request ID to merge') + parser.add_argument('branch', metavar='BRANCH', type=str, nargs='?', + default=branch, help='Branch to merge against (default: '+branch+')') + return parser.parse_args() + +def main(): + # Extract settings from git repo + repo = git_config_get('githubmerge.repository') + host = git_config_get('githubmerge.host','git@github.com') + branch = git_config_get('githubmerge.branch','master') + testcmd = git_config_get('githubmerge.testcmd') + signingkey = git_config_get('user.signingkey') + if repo is None: + print("ERROR: No repository configured. Use this command to set:", file=stderr) + print("git config githubmerge.repository /", file=stderr) + exit(1) + if signingkey is None: + print("ERROR: No GPG signing key set. Set one using:",file=stderr) + print("git config --global user.signingkey ",file=stderr) + exit(1) + + host_repo = host+":"+repo # shortcut for push/pull target + + # Extract settings from command line + args = parse_arguments(branch) + pull = str(args.pull[0]) + branch = args.branch + + # Initialize source branches + head_branch = 'pull/'+pull+'/head' + base_branch = 'pull/'+pull+'/base' + merge_branch = 'pull/'+pull+'/merge' + local_merge_branch = 'pull/'+pull+'/local-merge' + + devnull = open(os.devnull,'w') + try: + subprocess.check_call([GIT,'checkout','-q',branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot check out branch %s." % (branch), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*']) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+merge_branch], stdout=devnull, stderr=stdout) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/heads/'+branch+':refs/heads/'+base_branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find branch %s on %s." % (branch,host_repo), file=stderr) + exit(3) + subprocess.check_call([GIT,'checkout','-q',base_branch]) + subprocess.call([GIT,'branch','-q','-D',local_merge_branch], stderr=devnull) + subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) + + try: + # Create unsigned merge commit. + title = retrieve_pr_title(repo,pull) + if title: + firstline = 'Merge #%s: %s' % (pull,title) + else: + firstline = 'Merge #%s' % (pull,) + message = firstline + '\n\n' + message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]) + try: + subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message,head_branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot be merged cleanly.",file=stderr) + subprocess.check_call([GIT,'merge','--abort']) + exit(4) + logmsg = subprocess.check_output([GIT,'log','--pretty=format:%s','-n','1']) + if logmsg.rstrip() != firstline.rstrip(): + print("ERROR: Creating merge failed (already merged?).",file=stderr) + exit(4) + + # Run test command if configured. + if testcmd: + # Go up to the repository's root. + toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']) + os.chdir(toplevel) + if subprocess.call(testcmd,shell=True): + print("ERROR: Running %s failed." % testcmd,file=stderr) + exit(5) + + # Show the created merge. + diff = subprocess.check_output([GIT,'diff',merge_branch+'..'+local_merge_branch]) + subprocess.check_call([GIT,'diff',base_branch+'..'+local_merge_branch]) + if diff: + print("WARNING: merge differs from github!",file=stderr) + reply = ask_prompt("Type 'ignore' to continue.") + if reply.lower() == 'ignore': + print("Difference with github ignored.",file=stderr) + else: + exit(6) + reply = ask_prompt("Press 'd' to accept the diff.") + if reply.lower() == 'd': + print("Diff accepted.",file=stderr) + else: + print("ERROR: Diff rejected.",file=stderr) + exit(6) + else: + # Verify the result manually. + print("Dropping you on a shell so you can try building/testing the merged source.",file=stderr) + print("Run 'git diff HEAD~' to show the changes being merged.",file=stderr) + print("Type 'exit' when done.",file=stderr) + if os.path.isfile('/etc/debian_version'): # Show pull number on Debian default prompt + os.putenv('debian_chroot',pull) + subprocess.call([BASH,'-i']) + reply = ask_prompt("Type 'm' to accept the merge.") + if reply.lower() == 'm': + print("Merge accepted.",file=stderr) + else: + print("ERROR: Merge rejected.",file=stderr) + exit(7) + + # Sign the merge commit. + reply = ask_prompt("Type 's' to sign off on the merge.") + if reply == 's': + try: + subprocess.check_call([GIT,'commit','-q','--gpg-sign','--amend','--no-edit']) + except subprocess.CalledProcessError as e: + print("Error signing, exiting.",file=stderr) + exit(1) + else: + print("Not signing off on merge, exiting.",file=stderr) + exit(1) + + # Put the result in branch. + subprocess.check_call([GIT,'checkout','-q',branch]) + subprocess.check_call([GIT,'reset','-q','--hard',local_merge_branch]) + finally: + # Clean up temporary branches. + subprocess.call([GIT,'checkout','-q',branch]) + subprocess.call([GIT,'branch','-q','-D',head_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',base_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',merge_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',local_merge_branch],stderr=devnull) + + # Push the result. + reply = ask_prompt("Type 'push' to push the result to %s, branch %s." % (host_repo,branch)) + if reply.lower() == 'push': + subprocess.check_call([GIT,'push',host_repo,'refs/heads/'+branch]) + +if __name__ == '__main__': + main() + diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh deleted file mode 100755 index afb53f039..000000000 --- a/contrib/devtools/github-merge.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/bash - -# This script will locally construct a merge commit for a pull request on a -# github repository, inspect it, sign it and optionally push it. - -# The following temporary branches are created/overwritten and deleted: -# * pull/$PULL/base (the current master we're merging onto) -# * pull/$PULL/head (the current state of the remote pull request) -# * pull/$PULL/merge (github's merge) -# * pull/$PULL/local-merge (our merge) - -# In case of a clean merge that is accepted by the user, the local branch with -# name $BRANCH is overwritten with the merged result, and optionally pushed. - -REPO="$(git config --get githubmerge.repository)" -if [[ "d$REPO" == "d" ]]; then - echo "ERROR: No repository configured. Use this command to set:" >&2 - echo "git config githubmerge.repository /" >&2 - echo "In addition, you can set the following variables:" >&2 - echo "- githubmerge.host (default git@github.com)" >&2 - echo "- githubmerge.branch (default master)" >&2 - echo "- githubmerge.testcmd (default none)" >&2 - exit 1 -fi - -HOST="$(git config --get githubmerge.host)" -if [[ "d$HOST" == "d" ]]; then - HOST="git@github.com" -fi - -BRANCH="$(git config --get githubmerge.branch)" -if [[ "d$BRANCH" == "d" ]]; then - BRANCH="master" -fi - -TESTCMD="$(git config --get githubmerge.testcmd)" - -PULL="$1" - -if [[ "d$PULL" == "d" ]]; then - echo "Usage: $0 pullnumber [branch]" >&2 - exit 2 -fi - -if [[ "d$2" != "d" ]]; then - BRANCH="$2" -fi - -# Initialize source branches. -git checkout -q "$BRANCH" -if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then - if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then - echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2 - exit 3 - fi - if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then - echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2 - exit 3 - fi -else - echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2 - exit 3 -fi -if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then - true -else - echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2 - exit 3 -fi -git checkout -q pull/"$PULL"/base -git branch -q -D pull/"$PULL"/local-merge 2>/dev/null -git checkout -q -b pull/"$PULL"/local-merge -TMPDIR="$(mktemp -d -t ghmXXXXX)" - -function cleanup() { - git checkout -q "$BRANCH" - git branch -q -D pull/"$PULL"/head 2>/dev/null - git branch -q -D pull/"$PULL"/base 2>/dev/null - git branch -q -D pull/"$PULL"/merge 2>/dev/null - git branch -q -D pull/"$PULL"/local-merge 2>/dev/null - rm -rf "$TMPDIR" -} - -# Create unsigned merge commit. -( - echo "Merge pull request #$PULL" - echo "" - git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head -)>"$TMPDIR/message" -if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then - if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then - echo "ERROR: Creating merge failed (already merged?)." >&2 - cleanup - exit 4 - fi -else - echo "ERROR: Cannot be merged cleanly." >&2 - git merge --abort - cleanup - exit 4 -fi - -# Run test command if configured. -if [[ "d$TESTCMD" != "d" ]]; then - # Go up to the repository's root. - while [ ! -d .git ]; do cd ..; done - if ! $TESTCMD; then - echo "ERROR: Running $TESTCMD failed." >&2 - cleanup - exit 5 - fi - # Show the created merge. - git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff - git diff pull/"$PULL"/base..pull/"$PULL"/local-merge - if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then - echo "WARNING: merge differs from github!" >&2 - read -p "Type 'ignore' to continue. " -r >&2 - if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then - echo "Difference with github ignored." >&2 - else - cleanup - exit 6 - fi - fi - read -p "Press 'd' to accept the diff. " -n 1 -r >&2 - echo - if [[ "d$REPLY" =~ ^d[dD]$ ]]; then - echo "Diff accepted." >&2 - else - echo "ERROR: Diff rejected." >&2 - cleanup - exit 6 - fi -else - # Verify the result. - echo "Dropping you on a shell so you can try building/testing the merged source." >&2 - echo "Run 'git diff HEAD~' to show the changes being merged." >&2 - echo "Type 'exit' when done." >&2 - if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt - export debian_chroot="$PULL" - fi - bash -i - read -p "Press 'm' to accept the merge. " -n 1 -r >&2 - echo - if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then - echo "Merge accepted." >&2 - else - echo "ERROR: Merge rejected." >&2 - cleanup - exit 7 - fi -fi - -# Sign the merge commit. -read -p "Press 's' to sign off on the merge. " -n 1 -r >&2 -echo -if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then - if [[ "$(git config --get user.signingkey)" == "" ]]; then - echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2 - echo "git config --global user.signingkey " >&2 - cleanup - exit 1 - else - if ! git commit -q --gpg-sign --amend --no-edit; then - echo "Error signing, exiting." - cleanup - exit 1 - fi - fi -else - echo "Not signing off on merge, exiting." - cleanup - exit 1 -fi - -# Clean up temporary branches, and put the result in $BRANCH. -git checkout -q "$BRANCH" -git reset -q --hard pull/"$PULL"/local-merge -cleanup - -# Push the result. -read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2 -if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then - git push "$HOST":"$REPO" refs/heads/"$BRANCH" -fi From dd2dc400eed7c4e8521d1264d652ee32070d2c47 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 7 Jan 2016 08:33:49 +0100 Subject: [PATCH 0158/1223] [RPC, Wallet] Move RPC dispatch table registration to wallet/ code Allow extending the rpc dispatch table by appending commands when server is not running. --- src/Makefile.am | 1 + src/init.cpp | 2 ++ src/rpcserver.cpp | 67 +++++++++------------------------------ src/rpcserver.h | 50 ++++++----------------------- src/test/test_bitcoin.cpp | 1 + src/wallet/rpcwallet.cpp | 67 +++++++++++++++++++++++++++++++++++++++ src/wallet/rpcwallet.h | 10 ++++++ src/wallet/wallet.h | 1 + 8 files changed, 106 insertions(+), 93 deletions(-) create mode 100644 src/wallet/rpcwallet.h diff --git a/src/Makefile.am b/src/Makefile.am index 5da1a873d..74ffc7e2c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -164,6 +164,7 @@ BITCOIN_CORE_H = \ version.h \ wallet/crypter.h \ wallet/db.h \ + wallet/rpcwallet.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ diff --git a/src/init.cpp b/src/init.cpp index 374e756ab..1314afb7c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -926,6 +926,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); + if (!fDisableWallet) + walletRegisterRPCCommands(); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 53c368b27..b638598f7 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -309,9 +309,6 @@ static const CRPCCommand vRPCCommands[] = { "rawtransactions", "getrawtransaction", &getrawtransaction, true }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ -#ifdef ENABLE_WALLET - { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, -#endif /* Utility functions */ { "util", "createmultisig", &createmultisig, true }, @@ -326,54 +323,6 @@ static const CRPCCommand vRPCCommands[] = { "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true }, { "hidden", "setmocktime", &setmocktime, true }, -#ifdef ENABLE_WALLET - { "hidden", "resendwallettransactions", &resendwallettransactions, true}, -#endif - -#ifdef ENABLE_WALLET - /* Wallet */ - { "wallet", "addmultisigaddress", &addmultisigaddress, true }, - { "wallet", "backupwallet", &backupwallet, true }, - { "wallet", "dumpprivkey", &dumpprivkey, true }, - { "wallet", "dumpwallet", &dumpwallet, true }, - { "wallet", "encryptwallet", &encryptwallet, true }, - { "wallet", "getaccountaddress", &getaccountaddress, true }, - { "wallet", "getaccount", &getaccount, true }, - { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, - { "wallet", "getbalance", &getbalance, false }, - { "wallet", "getnewaddress", &getnewaddress, true }, - { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, - { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, - { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, - { "wallet", "gettransaction", &gettransaction, false }, - { "wallet", "abandontransaction", &abandontransaction, false }, - { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, - { "wallet", "getwalletinfo", &getwalletinfo, false }, - { "wallet", "importprivkey", &importprivkey, true }, - { "wallet", "importwallet", &importwallet, true }, - { "wallet", "importaddress", &importaddress, true }, - { "wallet", "importpubkey", &importpubkey, true }, - { "wallet", "keypoolrefill", &keypoolrefill, true }, - { "wallet", "listaccounts", &listaccounts, false }, - { "wallet", "listaddressgroupings", &listaddressgroupings, false }, - { "wallet", "listlockunspent", &listlockunspent, false }, - { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, - { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, - { "wallet", "listsinceblock", &listsinceblock, false }, - { "wallet", "listtransactions", &listtransactions, false }, - { "wallet", "listunspent", &listunspent, false }, - { "wallet", "lockunspent", &lockunspent, true }, - { "wallet", "move", &movecmd, false }, - { "wallet", "sendfrom", &sendfrom, false }, - { "wallet", "sendmany", &sendmany, false }, - { "wallet", "sendtoaddress", &sendtoaddress, false }, - { "wallet", "setaccount", &setaccount, true }, - { "wallet", "settxfee", &settxfee, true }, - { "wallet", "signmessage", &signmessage, true }, - { "wallet", "walletlock", &walletlock, true }, - { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, - { "wallet", "walletpassphrase", &walletpassphrase, true }, -#endif // ENABLE_WALLET }; CRPCTable::CRPCTable() @@ -396,6 +345,20 @@ const CRPCCommand *CRPCTable::operator[](const std::string &name) const return (*it).second; } +bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd) +{ + if (IsRPCRunning()) + return false; + + // don't allow overwriting for now + map::const_iterator it = mapCommands.find(name); + if (it != mapCommands.end()) + return false; + + mapCommands[name] = pcmd; + return true; +} + bool StartRPC() { LogPrint("rpc", "Starting RPC\n"); @@ -573,4 +536,4 @@ void RPCRunLater(const std::string& name, boost::function func, int6 deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } -const CRPCTable tableRPC; +CRPCTable tableRPC; diff --git a/src/rpcserver.h b/src/rpcserver.h index 29f503658..219d0422d 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -144,9 +144,17 @@ public: * @throws an exception (UniValue) when an error happens. */ UniValue execute(const std::string &method, const UniValue ¶ms) const; + + + /** + * Appends a CRPCCommand to the dispatch table. + * Returns false if RPC server is already running (dump concurrency protection). + * Commands cannot be overwritten (returns false). + */ + bool appendCommand(const std::string& name, const CRPCCommand* pcmd); }; -extern const CRPCTable tableRPC; +extern CRPCTable tableRPC; /** * Utilities: convert hex-encoded Values @@ -178,13 +186,6 @@ extern UniValue setban(const UniValue& params, bool fHelp); extern UniValue listbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp); -extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp -extern UniValue importprivkey(const UniValue& params, bool fHelp); -extern UniValue importaddress(const UniValue& params, bool fHelp); -extern UniValue importpubkey(const UniValue& params, bool fHelp); -extern UniValue dumpwallet(const UniValue& params, bool fHelp); -extern UniValue importwallet(const UniValue& params, bool fHelp); - extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp extern UniValue setgenerate(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp); @@ -198,45 +199,13 @@ extern UniValue estimatepriority(const UniValue& params, bool fHelp); extern UniValue estimatesmartfee(const UniValue& params, bool fHelp); extern UniValue estimatesmartpriority(const UniValue& params, bool fHelp); -extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp -extern UniValue getaccountaddress(const UniValue& params, bool fHelp); -extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp); -extern UniValue setaccount(const UniValue& params, bool fHelp); -extern UniValue getaccount(const UniValue& params, bool fHelp); -extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp); -extern UniValue sendtoaddress(const UniValue& params, bool fHelp); -extern UniValue signmessage(const UniValue& params, bool fHelp); extern UniValue verifymessage(const UniValue& params, bool fHelp); -extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp); -extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp); -extern UniValue getbalance(const UniValue& params, bool fHelp); -extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp); -extern UniValue movecmd(const UniValue& params, bool fHelp); -extern UniValue sendfrom(const UniValue& params, bool fHelp); -extern UniValue sendmany(const UniValue& params, bool fHelp); -extern UniValue addmultisigaddress(const UniValue& params, bool fHelp); extern UniValue createmultisig(const UniValue& params, bool fHelp); -extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp); -extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp); -extern UniValue listtransactions(const UniValue& params, bool fHelp); -extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); -extern UniValue listaccounts(const UniValue& params, bool fHelp); -extern UniValue listsinceblock(const UniValue& params, bool fHelp); -extern UniValue gettransaction(const UniValue& params, bool fHelp); -extern UniValue abandontransaction(const UniValue& params, bool fHelp); -extern UniValue backupwallet(const UniValue& params, bool fHelp); -extern UniValue keypoolrefill(const UniValue& params, bool fHelp); -extern UniValue walletpassphrase(const UniValue& params, bool fHelp); -extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp); -extern UniValue walletlock(const UniValue& params, bool fHelp); -extern UniValue encryptwallet(const UniValue& params, bool fHelp); extern UniValue validateaddress(const UniValue& params, bool fHelp); extern UniValue getinfo(const UniValue& params, bool fHelp); -extern UniValue getwalletinfo(const UniValue& params, bool fHelp); extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); extern UniValue setmocktime(const UniValue& params, bool fHelp); -extern UniValue resendwallettransactions(const UniValue& params, bool fHelp); extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp extern UniValue listunspent(const UniValue& params, bool fHelp); @@ -245,7 +214,6 @@ extern UniValue listlockunspent(const UniValue& params, bool fHelp); extern UniValue createrawtransaction(const UniValue& params, bool fHelp); extern UniValue decoderawtransaction(const UniValue& params, bool fHelp); extern UniValue decodescript(const UniValue& params, bool fHelp); -extern UniValue fundrawtransaction(const UniValue& params, bool fHelp); extern UniValue signrawtransaction(const UniValue& params, bool fHelp); extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); extern UniValue gettxoutproof(const UniValue& params, bool fHelp); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index f81050b15..0416d0c92 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -54,6 +54,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha const CChainParams& chainparams = Params(); #ifdef ENABLE_WALLET bitdb.MakeMock(); + walletRegisterRPCCommands(); #endif ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e68d64609..7509afdb9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2475,3 +2475,70 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) return result; } + +extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue importprivkey(const UniValue& params, bool fHelp); +extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue importpubkey(const UniValue& params, bool fHelp); +extern UniValue dumpwallet(const UniValue& params, bool fHelp); +extern UniValue importwallet(const UniValue& params, bool fHelp); + +const CRPCCommand vWalletRPCCommands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, + { "hidden", "resendwallettransactions", &resendwallettransactions, true }, + { "wallet", "abandontransaction", &abandontransaction, false }, + { "wallet", "addmultisigaddress", &addmultisigaddress, true }, + { "wallet", "backupwallet", &backupwallet, true }, + { "wallet", "dumpprivkey", &dumpprivkey, true }, + { "wallet", "dumpwallet", &dumpwallet, true }, + { "wallet", "encryptwallet", &encryptwallet, true }, + { "wallet", "getaccountaddress", &getaccountaddress, true }, + { "wallet", "getaccount", &getaccount, true }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, + { "wallet", "getbalance", &getbalance, false }, + { "wallet", "getnewaddress", &getnewaddress, true }, + { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, + { "wallet", "gettransaction", &gettransaction, false }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, + { "wallet", "getwalletinfo", &getwalletinfo, false }, + { "wallet", "importprivkey", &importprivkey, true }, + { "wallet", "importwallet", &importwallet, true }, + { "wallet", "importaddress", &importaddress, true }, + { "wallet", "importpubkey", &importpubkey, true }, + { "wallet", "keypoolrefill", &keypoolrefill, true }, + { "wallet", "listaccounts", &listaccounts, false }, + { "wallet", "listaddressgroupings", &listaddressgroupings, false }, + { "wallet", "listlockunspent", &listlockunspent, false }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, + { "wallet", "listsinceblock", &listsinceblock, false }, + { "wallet", "listtransactions", &listtransactions, false }, + { "wallet", "listunspent", &listunspent, false }, + { "wallet", "lockunspent", &lockunspent, true }, + { "wallet", "move", &movecmd, false }, + { "wallet", "sendfrom", &sendfrom, false }, + { "wallet", "sendmany", &sendmany, false }, + { "wallet", "sendtoaddress", &sendtoaddress, false }, + { "wallet", "setaccount", &setaccount, true }, + { "wallet", "settxfee", &settxfee, true }, + { "wallet", "signmessage", &signmessage, true }, + { "wallet", "walletlock", &walletlock, true }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, + { "wallet", "walletpassphrase", &walletpassphrase, true }, +}; + +void walletRegisterRPCCommands() +{ + unsigned int vcidx; + for (vcidx = 0; vcidx < ARRAYLEN(vWalletRPCCommands); vcidx++) + { + const CRPCCommand *pcmd; + + pcmd = &vWalletRPCCommands[vcidx]; + tableRPC.appendCommand(pcmd->name, pcmd); + } +} diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h new file mode 100644 index 000000000..42e8021af --- /dev/null +++ b/src/wallet/rpcwallet.h @@ -0,0 +1,10 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_RPCWALLET_H +#define BITCOIN_WALLET_RPCWALLET_H + +void walletRegisterRPCCommands(); + +#endif //BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 2176a5ff6..ffc7dcbd2 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -15,6 +15,7 @@ #include "wallet/crypter.h" #include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" +#include "wallet/rpcwallet.h" #include #include From fa8e2a6925a07cc00a8748fcda52c0ca5c6c3732 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 6 Dec 2015 20:24:02 +0100 Subject: [PATCH 0159/1223] [qa] Change default block priority size to 0 --- qa/rpc-tests/invalidtxrequest.py | 2 +- qa/rpc-tests/mempool_reorg.py | 12 ++++++------ qa/rpc-tests/mempool_resurrect_test.py | 4 ++-- qa/rpc-tests/mempool_spendcoinbase.py | 2 +- qa/rpc-tests/merkle_blocks.py | 6 +++--- qa/rpc-tests/test_framework/util.py | 3 +-- qa/rpc-tests/wallet.py | 9 ++++----- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index b2c0d145f..6ab112d75 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -63,7 +63,7 @@ class InvalidTxRequestTest(ComparisonTestFramework): # chr(100) is OP_NOTIF # Transaction will be rejected with code 16 (REJECT_INVALID) - tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000) + tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000 - 12000) yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) # TODO: test further transactions... diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index ea48e3845..40684e7fb 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -52,12 +52,12 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # and make sure the mempool code behaves correctly. b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 50) - spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 50) - spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 50) + spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 49.99) + spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 49.99) + spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 49.99) # Create a block-height-locked transaction which will be invalid after reorg - timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 50}) + timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99}) # Set the time lock timelock_tx = timelock_tx.replace("ffffffff", "11111111", 1) timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" @@ -71,8 +71,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework): assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: - spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50) - spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50) + spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 49.98) + spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 49.98) # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 14ca44310..9fcc88a2a 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -43,13 +43,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework): b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends1_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] blocks = [] blocks.extend(self.nodes[0].generate(1)) - spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ] + spends2_raw = [ self.create_tx(txid, node0_address, 49.98) for txid in spends1_id ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] blocks.extend(self.nodes[0].generate(1)) diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 4a6e43609..16f512db3 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -44,7 +44,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): # is too immature to spend. b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index ed9a9b01b..eb718f39e 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -42,9 +42,9 @@ class MerkleBlockTest(BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 0) node0utxos = self.nodes[0].listunspent(1) - tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50}) + tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"]) - tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50}) + tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"]) assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1]) @@ -62,7 +62,7 @@ class MerkleBlockTest(BitcoinTestFramework): assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist) txin_spent = self.nodes[1].listunspent(1).pop() - tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 50}) + tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 49.98}) self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"]) self.nodes[0].generate(1) self.sync_all() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index bf89805f1..8c472a518 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -240,8 +240,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= datadir = os.path.join(dirname, "node"+str(i)) if binary is None: binary = os.getenv("BITCOIND", "bitcoind") - # RPC tests still depend on free transactions - args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000", "-mocktime="+str(get_mocktime()) ] + args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) devnull = open(os.devnull, "w") diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 43ba1d977..6cd879e4a 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -49,7 +49,6 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 0) # Send 21 BTC from 0 to 2 using sendtoaddress call. - # Second transaction will be child of first, and will require a fee self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) @@ -81,7 +80,7 @@ class WalletTest (BitcoinTestFramework): inputs = [] outputs = {} inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) - outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] + outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3 raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx)) @@ -94,8 +93,8 @@ class WalletTest (BitcoinTestFramework): self.sync_all() assert_equal(self.nodes[0].getbalance(), 0) - assert_equal(self.nodes[2].getbalance(), 100) - assert_equal(self.nodes[2].getbalance("from1"), 100-21) + assert_equal(self.nodes[2].getbalance(), 94) + assert_equal(self.nodes[2].getbalance("from1"), 94-21) # Send 10 BTC normal address = self.nodes[0].getnewaddress("test") @@ -104,7 +103,7 @@ class WalletTest (BitcoinTestFramework): txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) self.nodes[2].generate(1) self.sync_all() - node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('90'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), Decimal('10')) # Send 10 BTC with subtract fee from amount From df6e8e17e4c31d97c986bafb9d5695dbaa8197b7 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 20 Jan 2016 14:57:28 +0100 Subject: [PATCH 0160/1223] [Qt] rename "amount" to "requested amount" in receive coins table --- src/qt/receivecoinsdialog.cpp | 1 + src/qt/receivecoinsdialog.h | 2 +- src/qt/recentrequeststablemodel.cpp | 9 ++------- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index b1f82023b..0b355837a 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -82,6 +82,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) tableView->setSelectionMode(QAbstractItemView::ContiguousSelection); tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH); tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH); + tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); connect(tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 543854a2f..226fd65cf 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -36,7 +36,7 @@ public: enum ColumnWidths { DATE_COLUMN_WIDTH = 130, LABEL_COLUMN_WIDTH = 120, - AMOUNT_MINIMUM_COLUMN_WIDTH = 160, + AMOUNT_MINIMUM_COLUMN_WIDTH = 180, MINIMUM_COLUMN_WIDTH = 130 }; diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index ef9422506..2335d6b28 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -83,7 +83,7 @@ QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) cons } case Amount: if (rec->recipient.amount == 0 && role == Qt::DisplayRole) - return tr("(no amount)"); + return tr("(no amount requested)"); else if (role == Qt::EditRole) return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount, false, BitcoinUnits::separatorNever); else @@ -125,12 +125,7 @@ void RecentRequestsTableModel::updateAmountColumnTitle() /** Gets title for amount column including current display unit if optionsModel reference available. */ QString RecentRequestsTableModel::getAmountTitle() { - QString amountTitle = tr("Amount"); - if (this->walletModel->getOptionsModel() != NULL) - { - amountTitle += " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")"; - } - return amountTitle; + return (this->walletModel->getOptionsModel() != NULL) ? tr("Requested") + " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : ""; } QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const From a0eaff8a1d18ebba33cdea4cd1efaddeb55519e7 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 15 Jan 2016 11:55:17 +1100 Subject: [PATCH 0161/1223] move rpc* to rpc/ --- src/Makefile.am | 22 +++--- src/bitcoin-cli.cpp | 4 +- src/bitcoind.cpp | 3 +- src/httprpc.cpp | 4 +- src/httpserver.cpp | 2 +- src/init.cpp | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/rpcconsole.cpp | 4 +- src/rest.cpp | 2 +- src/{rpcblockchain.cpp => rpc/blockchain.cpp} | 2 +- src/{rpcclient.cpp => rpc/client.cpp} | 5 +- src/{rpcclient.h => rpc/client.h} | 0 src/{rpcmining.cpp => rpc/mining.cpp} | 2 +- src/{rpcmisc.cpp => rpc/misc.cpp} | 2 +- src/{rpcnet.cpp => rpc/net.cpp} | 2 +- src/{rpcprotocol.cpp => rpc/protocol.cpp} | 2 +- src/{rpcprotocol.h => rpc/protocol.h} | 0 .../rawtransaction.cpp} | 2 +- src/{rpcserver.cpp => rpc/server.cpp} | 2 +- src/{rpcserver.h => rpc/server.h} | 2 +- src/test/rpc_tests.cpp | 6 +- src/test/rpc_wallet_tests.cpp | 4 +- src/wallet/rpcdump.cpp | 2 +- src/wallet/rpcwallet.cpp | 72 +++++++++---------- 24 files changed, 74 insertions(+), 76 deletions(-) rename src/{rpcblockchain.cpp => rpc/blockchain.cpp} (99%) rename src/{rpcclient.cpp => rpc/client.cpp} (98%) rename src/{rpcclient.h => rpc/client.h} (100%) rename src/{rpcmining.cpp => rpc/mining.cpp} (99%) rename src/{rpcmisc.cpp => rpc/misc.cpp} (99%) rename src/{rpcnet.cpp => rpc/net.cpp} (99%) rename src/{rpcprotocol.cpp => rpc/protocol.cpp} (99%) rename src/{rpcprotocol.h => rpc/protocol.h} (100%) rename src/{rpcrawtransaction.cpp => rpc/rawtransaction.cpp} (99%) rename src/{rpcserver.cpp => rpc/server.cpp} (99%) rename src/{rpcserver.h => rpc/server.h} (99%) diff --git a/src/Makefile.am b/src/Makefile.am index 948d12424..9a6b4fd66 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -131,9 +131,9 @@ BITCOIN_CORE_H = \ pubkey.h \ random.h \ reverselock.h \ - rpcclient.h \ - rpcprotocol.h \ - rpcserver.h \ + rpc/client.h \ + rpc/protocol.h \ + rpc/server.h \ scheduler.h \ script/interpreter.h \ script/script.h \ @@ -203,12 +203,12 @@ libbitcoin_server_a_SOURCES = \ policy/policy.cpp \ pow.cpp \ rest.cpp \ - rpcblockchain.cpp \ - rpcmining.cpp \ - rpcmisc.cpp \ - rpcnet.cpp \ - rpcrawtransaction.cpp \ - rpcserver.cpp \ + rpc/blockchain.cpp \ + rpc/mining.cpp \ + rpc/misc.cpp \ + rpc/net.cpp \ + rpc/rawtransaction.cpp \ + rpc/server.cpp \ script/sigcache.cpp \ timedata.cpp \ torcontrol.cpp \ @@ -304,7 +304,7 @@ libbitcoin_util_a_SOURCES = \ compat/glibcxx_sanity.cpp \ compat/strnlen.cpp \ random.cpp \ - rpcprotocol.cpp \ + rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ uint256.cpp \ @@ -322,7 +322,7 @@ endif libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ - rpcclient.cpp \ + rpc/client.cpp \ $(BITCOIN_CORE_H) nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index fb2052108..d1d534b05 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -5,8 +5,8 @@ #include "chainparamsbase.h" #include "clientversion.h" -#include "rpcclient.h" -#include "rpcprotocol.h" +#include "rpc/client.h" +#include "rpc/protocol.h" #include "util.h" #include "utilstrencodings.h" diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 3b6608c95..d1fd56d17 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -5,14 +5,13 @@ #include "chainparams.h" #include "clientversion.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "init.h" #include "noui.h" #include "scheduler.h" #include "util.h" #include "httpserver.h" #include "httprpc.h" -#include "rpcserver.h" #include #include diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 1466dc0cb..e7c28238b 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -3,8 +3,8 @@ #include "base58.h" #include "chainparams.h" #include "httpserver.h" -#include "rpcprotocol.h" -#include "rpcserver.h" +#include "rpc/protocol.h" +#include "rpc/server.h" #include "random.h" #include "sync.h" #include "util.h" diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 91518d7c5..ce1accb04 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -8,7 +8,7 @@ #include "compat.h" #include "util.h" #include "netbase.h" -#include "rpcprotocol.h" // For HTTP status codes +#include "rpc/protocol.h" // For HTTP status codes #include "sync.h" #include "ui_interface.h" diff --git a/src/init.cpp b/src/init.cpp index 282ede55c..fada53536 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -23,7 +23,7 @@ #include "miner.h" #include "net.h" #include "policy/policy.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "script/standard.h" #include "script/sigcache.h" #include "scheduler.h" diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index dcf752cc3..b33df45fb 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -26,7 +26,7 @@ #endif #include "init.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "scheduler.h" #include "ui_interface.h" #include "util.h" diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 7178bc00e..2658e867c 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -12,8 +12,8 @@ #include "bantablemodel.h" #include "chainparams.h" -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "util.h" #include diff --git a/src/rest.cpp b/src/rest.cpp index ad884dac1..ebdccc940 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -9,7 +9,7 @@ #include "primitives/transaction.h" #include "main.h" #include "httpserver.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "streams.h" #include "sync.h" #include "txmempool.h" diff --git a/src/rpcblockchain.cpp b/src/rpc/blockchain.cpp similarity index 99% rename from src/rpcblockchain.cpp rename to src/rpc/blockchain.cpp index 954441d15..de6bda4ea 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -12,7 +12,7 @@ #include "main.h" #include "policy/policy.h" #include "primitives/transaction.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "streams.h" #include "sync.h" #include "txmempool.h" diff --git a/src/rpcclient.cpp b/src/rpc/client.cpp similarity index 98% rename from src/rpcclient.cpp rename to src/rpc/client.cpp index 047158023..b0e9b6f15 100644 --- a/src/rpcclient.cpp +++ b/src/rpc/client.cpp @@ -3,9 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcclient.h" - -#include "rpcprotocol.h" +#include "rpc/client.h" +#include "rpc/protocol.h" #include "util.h" #include diff --git a/src/rpcclient.h b/src/rpc/client.h similarity index 100% rename from src/rpcclient.h rename to src/rpc/client.h diff --git a/src/rpcmining.cpp b/src/rpc/mining.cpp similarity index 99% rename from src/rpcmining.cpp rename to src/rpc/mining.cpp index 958c817d6..996b7f9cb 100644 --- a/src/rpcmining.cpp +++ b/src/rpc/mining.cpp @@ -14,7 +14,7 @@ #include "miner.h" #include "net.h" #include "pow.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "txmempool.h" #include "util.h" #include "utilstrencodings.h" diff --git a/src/rpcmisc.cpp b/src/rpc/misc.cpp similarity index 99% rename from src/rpcmisc.cpp rename to src/rpc/misc.cpp index 9871c3fcc..0aab9c304 100644 --- a/src/rpcmisc.cpp +++ b/src/rpc/misc.cpp @@ -9,7 +9,7 @@ #include "main.h" #include "net.h" #include "netbase.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "timedata.h" #include "util.h" #include "utilstrencodings.h" diff --git a/src/rpcnet.cpp b/src/rpc/net.cpp similarity index 99% rename from src/rpcnet.cpp rename to src/rpc/net.cpp index b61e7c5f1..065214a98 100644 --- a/src/rpcnet.cpp +++ b/src/rpc/net.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" +#include "rpc/server.h" #include "chainparams.h" #include "clientversion.h" diff --git a/src/rpcprotocol.cpp b/src/rpc/protocol.cpp similarity index 99% rename from src/rpcprotocol.cpp rename to src/rpc/protocol.cpp index b7605545d..f5275062a 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpc/protocol.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcprotocol.h" +#include "rpc/protocol.h" #include "random.h" #include "tinyformat.h" diff --git a/src/rpcprotocol.h b/src/rpc/protocol.h similarity index 100% rename from src/rpcprotocol.h rename to src/rpc/protocol.h diff --git a/src/rpcrawtransaction.cpp b/src/rpc/rawtransaction.cpp similarity index 99% rename from src/rpcrawtransaction.cpp rename to src/rpc/rawtransaction.cpp index 64bf569ba..2ec80f468 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -15,7 +15,7 @@ #include "net.h" #include "policy/policy.h" #include "primitives/transaction.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" diff --git a/src/rpcserver.cpp b/src/rpc/server.cpp similarity index 99% rename from src/rpcserver.cpp rename to src/rpc/server.cpp index b638598f7..b2d4559cc 100644 --- a/src/rpcserver.cpp +++ b/src/rpc/server.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" +#include "rpc/server.h" #include "base58.h" #include "init.h" diff --git a/src/rpcserver.h b/src/rpc/server.h similarity index 99% rename from src/rpcserver.h rename to src/rpc/server.h index 219d0422d..38a237d62 100644 --- a/src/rpcserver.h +++ b/src/rpc/server.h @@ -7,7 +7,7 @@ #define BITCOIN_RPCSERVER_H #include "amount.h" -#include "rpcprotocol.h" +#include "rpc/protocol.h" #include "uint256.h" #include diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index cc52e3ea0..d6309ca38 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "base58.h" #include "netbase.h" @@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) adr = find_value(o1, "address"); banned_until = find_value(o1, "banned_until"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); - int64_t now = GetTime(); + int64_t now = GetTime(); BOOST_CHECK(banned_until.get_int64() > now); BOOST_CHECK(banned_until.get_int64()-now <= 200); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 398372af3..3443be209 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "base58.h" #include "main.h" diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b025c3745..9ec28e7b9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -4,7 +4,7 @@ #include "base58.h" #include "chain.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "init.h" #include "main.h" #include "script/script.h" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e54293395..8a2d938ae 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -12,7 +12,7 @@ #include "net.h" #include "netbase.h" #include "policy/rbf.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" @@ -110,7 +110,7 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" @@ -189,7 +189,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" @@ -221,7 +221,7 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "getrawchangeaddress\n" @@ -256,7 +256,7 @@ UniValue setaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" @@ -302,7 +302,7 @@ UniValue getaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" @@ -334,7 +334,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" @@ -402,7 +402,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" @@ -460,7 +460,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp) throw runtime_error( "listaddressgroupings\n" @@ -511,7 +511,7 @@ UniValue signmessage(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 2) throw runtime_error( "signmessage \"bitcoinaddress\" \"message\"\n" @@ -567,7 +567,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" @@ -625,7 +625,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" @@ -714,7 +714,7 @@ UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" @@ -789,7 +789,7 @@ UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 0) throw runtime_error( "getunconfirmedbalance\n" @@ -805,7 +805,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" @@ -878,7 +878,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" @@ -942,7 +942,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" @@ -1056,7 +1056,7 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 3) { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" @@ -1239,7 +1239,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" @@ -1277,7 +1277,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" @@ -1412,7 +1412,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" @@ -1538,7 +1538,7 @@ UniValue listaccounts(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" @@ -1617,7 +1617,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp) throw runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" @@ -1709,7 +1709,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" @@ -1824,7 +1824,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" @@ -1850,7 +1850,7 @@ UniValue keypoolrefill(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" @@ -1894,7 +1894,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" @@ -1954,7 +1954,7 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" @@ -2000,7 +2000,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( "walletlock\n" @@ -2039,7 +2039,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( "encryptwallet \"passphrase\"\n" @@ -2096,7 +2096,7 @@ UniValue lockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" @@ -2180,7 +2180,7 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 0) throw runtime_error( "listlockunspent\n" @@ -2229,7 +2229,7 @@ UniValue settxfee(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( "settxfee amount\n" @@ -2256,7 +2256,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 0) throw runtime_error( "getwalletinfo\n" @@ -2298,7 +2298,7 @@ UniValue resendwallettransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 0) throw runtime_error( "resendwallettransactions\n" @@ -2323,7 +2323,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listunspent ( minconf maxconf [\"address\",...] )\n" From d13f65ebac13ec18b7eb55176c31f1404f185c0c Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 15 Jan 2016 12:55:57 +1100 Subject: [PATCH 0162/1223] rpc: update inline comments to refer to new file paths --- qa/rpc-tests/blockchain.py | 2 +- src/rpc/server.h | 8 ++++---- src/wallet/rpcwallet.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index b0fc7b017..7045ae435 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -5,7 +5,7 @@ # # Test RPC calls related to blockchain state. Tests correspond to code in -# rpcblockchain.cpp. +# rpc/blockchain.cpp. # from decimal import Decimal diff --git a/src/rpc/server.h b/src/rpc/server.h index 38a237d62..99ffad5d4 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -175,7 +175,7 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri extern void EnsureWalletIsUnlocked(); -extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp +extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpc/net.cpp extern UniValue getpeerinfo(const UniValue& params, bool fHelp); extern UniValue ping(const UniValue& params, bool fHelp); extern UniValue addnode(const UniValue& params, bool fHelp); @@ -186,7 +186,7 @@ extern UniValue setban(const UniValue& params, bool fHelp); extern UniValue listbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp); -extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp +extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpc/mining.cpp extern UniValue setgenerate(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp); extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); @@ -207,7 +207,7 @@ extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); extern UniValue setmocktime(const UniValue& params, bool fHelp); -extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp +extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rpc/rawtransaction.cpp extern UniValue listunspent(const UniValue& params, bool fHelp); extern UniValue lockunspent(const UniValue& params, bool fHelp); extern UniValue listlockunspent(const UniValue& params, bool fHelp); @@ -219,7 +219,7 @@ extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); extern UniValue gettxoutproof(const UniValue& params, bool fHelp); extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); -extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp +extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpc/blockchain.cpp extern UniValue getbestblockhash(const UniValue& params, bool fHelp); extern UniValue getdifficulty(const UniValue& params, bool fHelp); extern UniValue settxfee(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8a2d938ae..6576a9c8a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1049,7 +1049,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) return wtx.GetHash().GetHex(); } -// Defined in rpcmisc.cpp +// Defined in rpc/misc.cpp extern CScript _createmultisig_redeemScript(const UniValue& params); UniValue addmultisigaddress(const UniValue& params, bool fHelp) From faa9011d09d7429b97ec7595f9f77abf8ea770d3 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 20 Jan 2016 23:02:24 +0100 Subject: [PATCH 0163/1223] [qt] Peertable: Increase SUBVERSION_COLUMN_WIDTH --- src/qt/rpcconsole.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 8a48179c5..162d61cfd 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -118,7 +118,7 @@ private: enum ColumnWidths { ADDRESS_COLUMN_WIDTH = 200, - SUBVERSION_COLUMN_WIDTH = 100, + SUBVERSION_COLUMN_WIDTH = 150, PING_COLUMN_WIDTH = 80, BANSUBNET_COLUMN_WIDTH = 200, BANTIME_COLUMN_WIDTH = 250 From b768108d9c0b83330572711aef1e569543130d5e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 21 Jan 2016 11:11:01 +0100 Subject: [PATCH 0164/1223] Add option `-permitrbf` to set transaction replacement policy Add a configuration option `-permitrbf` to set transaction replacement policy for the mempool. Enabling it will enable (opt-in) RBF, disabling it will refuse all conflicting transactions. --- src/init.cpp | 2 ++ src/main.cpp | 12 ++++++++---- src/main.h | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 282ede55c..7aecf9351 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -367,6 +367,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); + strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacement (default: %u)"), DEFAULT_PERMIT_REPLACEMENT)); strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); if (showDebug) strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); @@ -1029,6 +1030,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nLocalServices |= NODE_BLOOM; nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + fPermitReplacement = GetBoolArg("-permitrbf", DEFAULT_PERMIT_REPLACEMENT); // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log diff --git a/src/main.cpp b/src/main.cpp index 9870beecc..8522b0d1b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,6 +78,7 @@ bool fAlerts = DEFAULT_ALERTS; /* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; +bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -868,12 +869,15 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // unconfirmed ancestors anyway; doing otherwise is hopelessly // insecure. bool fReplacementOptOut = true; - BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) + if (fPermitReplacement) { - if (txin.nSequence < std::numeric_limits::max()-1) + BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) { - fReplacementOptOut = false; - break; + if (txin.nSequence < std::numeric_limits::max()-1) + { + fReplacementOptOut = false; + break; + } } } if (fReplacementOptOut) diff --git a/src/main.h b/src/main.h index 228877641..98069a225 100644 --- a/src/main.h +++ b/src/main.h @@ -107,6 +107,8 @@ static const bool DEFAULT_TXINDEX = false; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; static const bool DEFAULT_TESTSAFEMODE = false; +/** Default for -permitrbf */ +static const bool DEFAULT_PERMIT_REPLACEMENT = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; @@ -139,6 +141,7 @@ extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; extern bool fAlerts; extern int64_t nMaxTipAge; +extern bool fPermitReplacement; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; From 17b5d3896f2cd189b1a4665956bdfba368d46f0e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 22 Jan 2016 16:37:21 +0100 Subject: [PATCH 0165/1223] devtools: show pull and commit information in github-merge Print the number and title of the pull, as well as the commits to be merged. --- contrib/devtools/github-merge.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 33d33b700..6854ecb07 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -24,6 +24,15 @@ import subprocess GIT = os.getenv('GIT','git') BASH = os.getenv('BASH','bash') +# OS specific configuration for terminal attributes +ATTR_RESET = '' +ATTR_PR = '' +COMMIT_FORMAT = '%h %s (%an)%d' +if os.name == 'posix': # if posix, assume we can use basic terminal escapes + ATTR_RESET = '\033[0m' + ATTR_PR = '\033[1;36m' + COMMIT_FORMAT = '%C(bold blue)%h%Creset %s %C(cyan)(%an)%Creset%C(green)%d%Creset' + def git_config_get(option, default=None): ''' Get named configuration option from git repository. @@ -150,6 +159,9 @@ def main(): print("ERROR: Creating merge failed (already merged?).",file=stderr) exit(4) + print('%s#%s%s %s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title)) + subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) + print() # Run test command if configured. if testcmd: # Go up to the repository's root. From 3a3a9273255f1caa68c96c327489938f7f310806 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 22 Jan 2016 18:00:36 +0100 Subject: [PATCH 0166/1223] [Qt] Add option to increase/decrease font size in the console window --- src/Makefile.qt.include | 2 + src/qt/bitcoin.qrc | 2 + src/qt/forms/debugwindow.ui | 156 ++++++++++++++++++++++++------- src/qt/res/icons/fontbigger.png | Bin 0 -> 1180 bytes src/qt/res/icons/fontsmaller.png | Bin 0 -> 951 bytes src/qt/rpcconsole.cpp | 59 +++++++++--- src/qt/rpcconsole.h | 4 + 7 files changed, 178 insertions(+), 45 deletions(-) create mode 100644 src/qt/res/icons/fontbigger.png create mode 100644 src/qt/res/icons/fontsmaller.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index a390d96a9..82e95abcf 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -245,6 +245,8 @@ RES_ICONS = \ qt/res/icons/eye_minus.png \ qt/res/icons/eye_plus.png \ qt/res/icons/filesave.png \ + qt/res/icons/fontbigger.png \ + qt/res/icons/fontsmaller.png \ qt/res/icons/history.png \ qt/res/icons/info.png \ qt/res/icons/key.png \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index c899e9550..3c9b9d283 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -46,6 +46,8 @@ res/icons/about_qt.png res/icons/verify.png res/icons/warning.png + res/icons/fontbigger.png + res/icons/fontsmaller.png res/movies/spinner-000.png diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 247147036..045eb80d9 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -450,6 +450,125 @@ 3 + + 5 + + + + + 4 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 24 + 24 + + + + Decrease Font Size + + + + + + + :/icons/fontsmaller:/icons/fontsmaller + + + + 24 + 16 + + + + false + + + true + + + + + + + + 24 + 24 + + + + Increase Font Size + + + + + + + :/icons/fontbigger:/icons/fontbigger + + + + 24 + 16 + + + + false + + + true + + + + + + + + 24 + 24 + + + + Clear console + + + Qt::LeftToRight + + + + + + + :/icons/remove:/icons/remove + + + Ctrl+L + + + false + + + true + + + + + @@ -470,43 +589,14 @@ - + 3 - - - > - - - - - - - - - - - 24 - 24 - - - - Clear console - - - - - - - :/icons/remove:/icons/remove - - - Ctrl+L - - - false + + + > diff --git a/src/qt/res/icons/fontbigger.png b/src/qt/res/icons/fontbigger.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca5c563b25ecc2b90a064db3f86e02aa759bb66 GIT binary patch literal 1180 zcmV;N1Y`S&P)qpXJ000DINklA_IpxrUdgwZ&!Liq~JNrkPfg#{Xt6lxPqy2VvWi(9#@%Fmh1OY5AfW-x{xBwOp z5wHcT0W?JKn_gT1^8(Hc;5Gn80yu2IV?)3-fJ6X?2{GvJjqu>iIQICTJbWlb!A?Ex+v0j>nFAHX&7naZk( z1+X2!nSt!7IW@5WwgZ@=ea8l&U0V}7TD1ZIuK^4Jd{91ApBbBPz*Oy~*=NXy6j?4uJ0(b-aiX zaAx_r*&~)$cm%u+;H<5HDcX10$d?kPYma~v0H221V2`op}Ph3E*2B0aHOF z8a;wi?${IH7XXgi2)MKf;ekzTet8_oq@%V0PHl(L2R5)7{+R(k2QY0LVAkY-L6|N* z&18MlsN1<3aYq4|HN9srLZ7RNiEUg{J#LZjs=uE#>h%-An|tRh@-?4;soHndMeEe- z6o!CP0Podv^Oz3p0B{E2+R?Hj9lxH9 zTU-H7z%bLaz(zI(bDC}318@}(+?ihi*mDJ#Wv-YZOpghGhXKN!`Op<$mTV70GUGo@ ztl7qcfB_%40L+%JWeU@|0A3An0iLPJWky}ERZ56n4R9Us4OsZ>mqFI@#%B@2y&JuY zOj_RfaioB23lklcO6Z@ewBU&f|5E^;02~7Ntx=a-0AJL!=2Vq`4B)FO`%GQS?L-Io z_xo~tW;j*3qvntk09z_OxS^5^&y*jokZgFW&Rth!ZK|@j)wSGCRf2!NFSn1FlMPQ) zPu2naGPq;|-0b(|4%3OG3+FdFjU4XX78gdq8=9RUNWeu)08f~g?3~03xNZsH20)Jq z@K%(I?jqK{k4|06ve|ZM-$!%Ovhdwp`_|yMo&n^(Y+W(az9YCXs&pI4=Cgl|t%x@; za|AetWle0jE;^p=qXy}@8t%*_Oba`v4AmZ?B uBTVP=6Yt^zSX=;$3t({pEG~e%=6?Yavtd{5^U?hP0000qpXJ000AiNklI%MsuHY-^0$b<`E^-0Y+qnv)2v{T}kYWpw)XOqgP#Sp& z#%o*ek7gu&1Fu{e>1RFbn;Eg_`yQ<27B2#USp;Sgm_=Y#iogaV0O*Ca(SA6AeSu2_ zZVzBb;Ix4oC2#@z_!4d6RtQD6WA8Gat7WLI4*GO3_Lm$ z6W9*8m;iTlCMK{Qa6J)lN8mWXLHL{Mnu!T)16(R%Pw>pd1hxT|WZy>7+HcOp1l9vf zvu`>4{l+sB6Ic&i3GcxFN9UD^39JW}WZ&B82|OpTFR(QG7DmUZ2;v35Jo&Z;PvitP0M48qiYjHMCa@8(6e4q)G-(KI z3*1^FoQ%EYmxsXPfeY(4dNQ__?VrHofn65|6m7aCunn;5@}6>MW+4GSGd=*g2XOC# zG8}vO9Mu=n8d#cr$8K6Ltupb*b1VRS255sV=87HKbRz(MjEsA% z$C$t_t36IHv1KEHpArFniUsVpUhCARD*}%LuHiE^d2LAdYqf0AnKOeHL zpL{t(+_$H9#-!^f-^>&^7)*3@0Gj41Mn5VmmBH;;5&ey!*QO64cFnL!OfBl$Gb~ns&az&eZ6bP#fHnk?aYA#fQ-QBaf_MbzP;i? z;Pb%sLV))KJ`Wrg0^9@03A~K#`|i{wftQhe-(8a?us-_+_>WwHydkhI`|dE!Xqkz1 zz#R;BQaFx^nOF#{Se^@*Zsg3wa$xBKdyQ#F%S=2HSh17QZv5k(|mO`G1V4On`yI>Z~A)vn#zfV-KsXKkBaOeXfszA@Xg zMVsEP1z4JWTf`rlHoadwurm8rNMmTW73E6@-p;r^TeRtFmFvMQ0<#FrA~1` #include #include +#include #include #include #include @@ -41,9 +42,9 @@ // TODO: receive errors and debug messages through ClientModel const int CONSOLE_HISTORY = 50; -const QSize ICON_SIZE(24, 24); - const int INITIAL_TRAFFIC_GRAPH_MINS = 30; +const QSize FONT_RANGE(4, 40); +const char fontSizeSettingsKey[] = "consoleFontSize"; const struct { const char *url; @@ -245,7 +246,8 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : cachedNodeid(-1), platformStyle(platformStyle), peersTableContextMenu(0), - banTableContextMenu(0) + banTableContextMenu(0), + consoleFontSize(0) { ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); @@ -254,12 +256,16 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); } ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->fontBiggerButton->setIcon(platformStyle->SingleColorIcon(":/icons/fontbigger")); + ui->fontSmallerButton->setIcon(platformStyle->SingleColorIcon(":/icons/fontsmaller")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); ui->messagesWidget->installEventFilter(this); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(ui->fontBiggerButton, SIGNAL(clicked()), this, SLOT(fontBigger())); + connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller())); connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); // set library version labels @@ -288,6 +294,8 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->detailWidget->hide(); ui->peerHeading->setText(tr("Select a peer to view detailed information.")); + QSettings settings; + consoleFontSize = settings.value(fontSizeSettingsKey, QFontInfo(QFont()).pointSize()).toInt(); clear(); } @@ -453,6 +461,39 @@ static QString categoryClass(int category) } } +void RPCConsole::fontBigger() +{ + setFontSize(consoleFontSize+1); +} + +void RPCConsole::fontSmaller() +{ + setFontSize(consoleFontSize-1); +} + +void RPCConsole::setFontSize(int newSize) +{ + QSettings settings; + + //don't allow a insane font size + if (newSize < FONT_RANGE.width() || newSize > FONT_RANGE.height()) + return; + + // temp. store the console content + QString str = ui->messagesWidget->toHtml(); + + // replace font tags size in current content + str.replace(QString("font-size:%1pt").arg(consoleFontSize), QString("font-size:%1pt").arg(newSize)); + + // store the new font size + consoleFontSize = newSize; + settings.setValue(fontSizeSettingsKey, consoleFontSize); + + // clear console (reset icon sizes, default stylesheet) and re-add the content + clear(); + ui->messagesWidget->setHtml(str); +} + void RPCConsole::clear() { ui->messagesWidget->clear(); @@ -468,26 +509,20 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(QSize(consoleFontSize*2, consoleFontSize*2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont()); - // Try to make fixed font adequately large on different OS -#ifdef WIN32 - QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 10 / 8); -#else - QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9); -#endif ui->messagesWidget->document()->setDefaultStyleSheet( QString( "table { }" - "td.time { color: #808080; padding-top: 3px; } " + "td.time { color: #808080; font-size: %2; padding-top: 3px; } " "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } " "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " - ).arg(fixedFontInfo.family(), ptSize) + ).arg(fixedFontInfo.family(), QString("%1pt").arg(consoleFontSize)) ); message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "
" + diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 8a48179c5..83b543e54 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -78,6 +78,9 @@ private Q_SLOTS: public Q_SLOTS: void clear(); + void fontBigger(); + void fontSmaller(); + void setFontSize(int newSize); /** Append the message to the message widget */ void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ @@ -134,6 +137,7 @@ private: RPCTimerInterface *rpcTimerInterface; QMenu *peersTableContextMenu; QMenu *banTableContextMenu; + int consoleFontSize; }; #endif // BITCOIN_QT_RPCCONSOLE_H From 56c9e66a6d7c798394478660f6088b943fe4e96d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 23 Jan 2016 00:05:14 +0100 Subject: [PATCH 0167/1223] [Qt] keep scroll position in GUI console after changing font size --- src/qt/forms/debugwindow.ui | 4 ++-- src/qt/rpcconsole.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 045eb80d9..2f4613099 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -480,7 +480,7 @@ - Decrease Font Size + Decrease font size @@ -512,7 +512,7 @@ - Increase Font Size + Increase font size diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 40c54225f..dca34ed04 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -490,8 +490,10 @@ void RPCConsole::setFontSize(int newSize) settings.setValue(fontSizeSettingsKey, consoleFontSize); // clear console (reset icon sizes, default stylesheet) and re-add the content + float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value(); clear(); ui->messagesWidget->setHtml(str); + ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum()); } void RPCConsole::clear() From e99edc1be0ffad18111f878c0737c0133a6acb77 Mon Sep 17 00:00:00 2001 From: Andrew C Date: Sat, 23 Jan 2016 08:58:17 -0500 Subject: [PATCH 0168/1223] Add achow101's pgp key --- contrib/gitian-downloader/achow101-key.pgp | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 contrib/gitian-downloader/achow101-key.pgp diff --git a/contrib/gitian-downloader/achow101-key.pgp b/contrib/gitian-downloader/achow101-key.pgp new file mode 100644 index 000000000..030fd5cf3 --- /dev/null +++ b/contrib/gitian-downloader/achow101-key.pgp @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +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 +Khvd4+XHE/ecjLOPvLweAg== +=+hz7 +-----END PGP PUBLIC KEY BLOCK----- From fae78fa81802b5387054715c339f286ef436408e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 22 Jan 2016 09:32:29 +0100 Subject: [PATCH 0169/1223] [init] Clarify permitrbf help message --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 7aecf9351..a6d26a02f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -367,7 +367,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); - strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacement (default: %u)"), DEFAULT_PERMIT_REPLACEMENT)); + strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacements in the memory pool (default: %u)"), DEFAULT_PERMIT_REPLACEMENT)); strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); if (showDebug) strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); From 5ed2f16480142f0887cc1a6257ff53e2abc3e5b6 Mon Sep 17 00:00:00 2001 From: Andrew C Date: Sat, 23 Jan 2016 10:35:27 -0500 Subject: [PATCH 0170/1223] [devtools] github-merge get toplevel dir without extra whitespace Fixes a bug in github merge when it runs the tests where the toplevel directory has an extra '\n' appended to the path string. Now it doesn't. --- contrib/devtools/github-merge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 33d33b700..11118fd7d 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -153,7 +153,7 @@ def main(): # Run test command if configured. if testcmd: # Go up to the repository's root. - toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']) + toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() os.chdir(toplevel) if subprocess.call(testcmd,shell=True): print("ERROR: Running %s failed." % testcmd,file=stderr) From 4818dba90074f213efa0fa7faf577ce5fb02eaee Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 25 Jan 2016 16:14:14 +0100 Subject: [PATCH 0171/1223] net: Hardcoded seeds update January 2016 --- contrib/seeds/README.md | 7 +- contrib/seeds/nodes_main.txt | 1436 ++++++++++++++++++---------------- src/chainparamsseeds.h | 1436 ++++++++++++++++++---------------- 3 files changed, 1499 insertions(+), 1380 deletions(-) diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index 63647fa11..c595f83eb 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -3,6 +3,9 @@ Utility to generate the seeds.txt list that is compiled into the client (see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)). -The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this: +The seeds compiled into the release are created from sipa's DNS seed data, like this: + + curl -s http://bitcoin.sipa.be/seeds.txt > seeds_main.txt + python makeseeds.py < seeds_main.txt > nodes_main.txt + python generate-seeds.py . > ../../src/chainparamsseeds.h - curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index 17339d514..f1854b27f 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,879 +1,937 @@ -1.34.168.128:8333 -1.202.128.218:8333 -2.30.0.210:8333 -5.9.96.203:8333 -5.45.71.130:8333 -5.45.98.141:8333 -5.102.145.68:8333 -5.135.160.77:8333 -5.189.134.246:8333 -5.199.164.132:8333 -5.249.135.102:8333 -8.19.44.110:8333 -8.22.230.8:8333 -14.200.200.145:8333 -18.228.0.188:8333 -18.228.0.200:8333 -23.24.168.97:8333 -23.28.35.227:8333 -23.92.76.170:8333 -23.99.64.119:8333 -23.228.166.128:8333 -23.229.45.32:8333 -24.8.105.128:8333 -24.16.69.137:8333 -24.94.98.96:8333 -24.102.118.7:8333 -24.118.166.228:8333 -24.122.133.49:8333 -24.166.97.162:8333 -24.213.235.242:8333 -24.226.107.64:8333 -24.228.192.171:8333 -27.140.133.18:8333 -31.41.40.25:8333 -31.43.101.59:8333 -31.184.195.181:8333 -31.193.139.66:8333 -37.200.70.102:8333 -37.205.10.151:8333 -42.3.106.227:8333 -42.60.133.106:8333 -45.56.85.231:8333 -45.56.102.228:8333 -45.79.130.235:8333 -46.28.204.61:11101 -46.38.235.229:8333 -46.59.2.74:8333 -46.101.132.37:8333 -46.101.168.50:8333 -46.163.76.230:8333 +5.2.145.201:8333 +5.22.142.214:8333 +5.53.172.197:8333 +5.189.161.164:8333 +5.230.140.166:8333 +5.231.3.130:8333 +5.255.80.103:8333 +14.202.230.49:8333 +18.85.11.130:8333 +23.91.97.25:8333 +23.94.100.122:8333 +23.95.99.132:8333 +24.115.8.206:8333 +24.127.128.191:8333 +24.154.178.25:8333 +24.207.103.43:8333 +24.207.104.105:8333 +24.210.230.150:8333 +24.224.18.84:8333 +24.246.168.106:8333 +27.254.64.47:8333 +31.6.71.123:8333 +31.6.71.124:8333 +31.14.134.13:8333 +31.30.36.220:8333 +31.164.6.104:8333 +31.170.106.203:8333 +31.185.134.201:8333 +31.204.128.99:8333 +31.204.128.219:8333 +37.1.219.88:8333 +37.97.132.109:8333 +37.120.160.55:8333 +37.120.169.123:8333 +37.139.32.46:8333 +37.221.163.218:8333 +38.130.192.72:8333 +41.75.96.80:8333 +45.3.0.49:8333 +45.33.72.185:8333 +45.33.96.129:8333 +45.56.4.63:8333 +45.79.0.127:8333 +45.79.80.102:8333 +45.79.97.30:8333 +45.79.132.219:8333 +46.21.97.135:8333 +46.28.205.67:8333 +46.28.206.188:8333 +46.29.20.209:8333 +46.50.234.179:8333 +46.101.160.168:8333 +46.166.161.35:8333 46.166.161.103:8333 46.182.132.100:8333 -46.223.36.94:8333 +46.218.227.92:8333 +46.226.109.20:8333 46.227.66.132:8333 46.227.66.138:8333 +46.229.165.154:8333 +46.229.165.155:8333 +46.229.238.187:8333 +46.234.104.48:8333 46.239.107.74:8333 -46.249.39.100:8333 -46.250.98.108:8333 +46.244.0.138:8333 +46.254.72.195:8333 +50.5.13.44:8333 50.7.37.114:8333 -50.81.53.151:8333 -50.115.43.253:8333 -50.116.20.87:8333 -50.116.33.92:8333 -50.125.167.245:8333 -50.143.9.51:8333 -50.188.192.133:8333 -54.77.162.76:8333 -54.153.97.109:8333 -54.165.192.125:8333 -58.96.105.85:8333 -59.167.196.135:8333 -60.29.227.163:8333 +50.30.37.103:8333 +50.39.105.60:8333 +50.106.40.231:8333 +52.29.0.37:8333 +52.76.192.246:8333 +54.152.192.179:8333 +54.169.64.174:8333 +54.175.160.22:8333 +54.199.128.0:8333 +58.96.171.129:8333 +58.161.238.57:8333 +60.251.195.221:8333 61.35.225.19:8333 62.43.130.178:8333 -62.109.49.26:8333 -62.202.0.97:8333 -62.210.66.227:8333 -62.210.192.169:8333 -64.74.98.205:8333 -64.156.193.100:8333 +62.65.39.12:8333 +62.107.200.30:8333 +62.133.194.2:8333 +62.181.238.186:8333 +62.183.22.50:8333 +62.210.85.120:8333 +62.210.162.89:8333 +62.238.34.125:8333 +64.25.171.73:8333 +64.27.166.30:8333 +64.53.137.101:8333 +64.71.72.44:8333 +64.83.225.146:8333 +64.121.3.163:8333 64.203.102.86:8333 -64.229.142.48:8333 -65.96.193.165:8333 -66.30.3.7:8333 +65.94.131.59:8333 +65.188.136.233:8333 +66.11.162.218:8333 +66.23.228.133:8333 +66.90.137.89:8333 66.114.33.49:8333 -66.118.133.194:8333 -66.135.10.126:8333 +66.150.105.77:8333 66.172.10.4:8333 66.194.38.250:8333 66.194.38.253:8333 -66.215.192.104:8333 -67.60.98.115:8333 -67.164.35.36:8333 -67.191.162.244:8333 -67.207.195.77:8333 -67.219.233.140:8333 +66.194.38.254:8333 +66.231.97.172:8333 +66.240.237.155:8333 +67.159.13.34:8333 +67.205.74.206:8333 67.221.193.55:8333 -67.228.162.228:8333 -68.50.67.199:8333 -68.62.3.203:8333 +67.227.72.17:8333 +68.65.120.53:8333 68.65.205.226:9000 -68.106.42.191:8333 -68.150.181.198:8333 -68.196.196.106:8333 -68.224.194.81:8333 -69.46.5.194:8333 -69.50.171.238:8333 -69.64.43.152:8333 -69.65.41.13:8333 -69.90.132.200:8333 -69.143.1.243:8333 -69.146.98.216:8333 -69.165.246.38:8333 -69.207.6.135:8333 -69.251.208.26:8333 -70.38.1.101:8333 -70.38.9.66:8333 -70.90.2.18:8333 -71.58.228.226:8333 -71.199.11.189:8333 -71.199.193.202:8333 -71.205.232.181:8333 -71.236.200.162:8333 -72.24.73.186:8333 +68.144.4.34:8333 +69.39.49.199:8333 +69.50.171.205:8333 +69.65.41.21:8333 +69.113.98.61:8333 +69.119.97.39:8333 +69.146.70.124:8333 +69.193.71.2:8333 +70.46.10.237:8333 +70.80.200.187:8333 +70.185.97.117:8333 +71.254.160.25:8333 +72.28.203.5:8333 72.52.130.110:8333 -72.53.111.37:8333 +72.83.194.122:8333 +72.128.32.167:8333 +72.179.136.80:8333 72.235.38.70:8333 -73.31.171.149:8333 -73.32.137.72:8333 -73.137.133.238:8333 -73.181.192.103:8333 -73.190.2.60:8333 -73.195.192.137:8333 -73.222.35.117:8333 -74.57.199.180:8333 -74.82.233.205:8333 -74.85.66.82:8333 -74.101.224.127:8333 -74.113.69.16:8333 -74.122.235.68:8333 -74.193.68.141:8333 -74.208.164.219:8333 -75.100.37.122:8333 -75.145.149.169:8333 -75.168.34.20:8333 -76.20.44.240:8333 -76.100.70.17:8333 -76.168.3.239:8333 -76.186.140.103:8333 -77.92.68.221:8333 -77.109.101.142:8333 -77.110.11.86:8333 -77.242.108.18:8333 -78.46.96.150:9020 +74.50.44.193:8333 +74.72.60.83:8333 +74.80.234.116:8333 +74.207.233.193:8333 +75.112.233.128:8333 +75.118.166.197:8333 +75.140.0.241:8333 +75.159.240.66:8333 +75.174.5.26:8333 +76.72.160.252:8333 +76.72.160.254:8333 +76.74.170.112:8333 +76.79.201.54:8333 +76.175.166.164:8333 +76.179.105.27:8333 +77.68.37.200:8333 +77.234.49.196:8333 +77.247.229.93:8333 +78.24.72.78:8333 +78.47.32.147:8333 78.84.100.95:8333 +78.121.69.23:8333 +78.129.167.5:8333 +78.193.96.155:8333 +79.19.37.179:8333 79.132.230.144:8333 79.133.43.63:8333 -79.160.76.153:8333 -79.169.34.24:8333 -79.188.7.78:8333 -80.217.226.25:8333 -80.223.100.179:8333 -80.240.129.221:8333 -81.1.173.243:8333 +79.134.201.66:8333 +79.169.35.235:8333 +80.57.227.14:8333 +80.64.65.87:8333 +80.86.92.70:8333 +80.100.203.151:8333 +80.101.32.121:8333 +80.161.178.73:8333 +80.240.129.170:8333 81.7.11.50:8333 -81.7.16.17:8333 -81.66.111.3:8333 -81.80.9.71:8333 -81.140.43.138:8333 -81.171.34.37:8333 -81.174.247.50:8333 -81.181.155.53:8333 -81.184.5.253:8333 -81.187.69.130:8333 -81.230.3.84:8333 -82.42.128.51:8333 -82.74.226.21:8333 -82.142.75.50:8333 +81.7.11.55:8333 +81.17.17.40:9333 +81.30.39.83:8333 +81.90.36.7:9444 +81.136.224.77:8333 +81.162.231.211:8333 +81.184.0.143:8333 +81.198.128.86:8333 +82.11.33.229:8333 +82.79.128.134:8333 +82.118.233.111:8333 +82.135.139.30:8333 82.199.102.10:8333 -82.200.205.30:8333 +82.221.106.17:8333 82.221.108.21:8333 -82.221.128.35:8333 -82.238.124.41:8333 -82.242.0.245:8333 -83.76.123.110:8333 +82.221.108.27:8333 +83.137.41.3:8333 +83.142.197.168:8333 +83.143.130.19:8333 83.150.9.196:8333 -83.162.196.192:8333 -83.162.234.224:8333 -83.170.104.91:8333 +83.183.17.191:8333 +83.227.173.83:8333 +83.230.5.15:8333 +83.233.105.151:443 +83.246.75.8:8333 +83.250.133.158:8333 83.255.66.118:8334 -84.2.34.104:8333 -84.45.98.91:8333 -84.47.161.150:8333 -84.212.192.131:8333 -84.215.169.101:8333 -84.238.140.176:8333 -84.245.71.31:8333 -85.17.4.212:8333 +84.24.69.59:8333 +84.42.193.6:8333 +84.45.98.87:8333 +84.54.128.11:8333 +84.212.200.24:8333 +84.215.198.109:8333 +84.230.4.177:8333 +85.95.228.83:8333 +85.95.228.123:8333 85.114.128.134:8333 -85.159.237.191:8333 -85.166.130.189:8333 -85.199.4.228:8333 85.214.66.168:8333 -85.214.195.210:8333 -85.229.0.73:8333 -86.21.96.45:8333 -87.48.42.199:8333 -87.81.143.82:8333 -87.81.251.72:8333 -87.104.24.185:8333 -87.104.168.104:8333 -87.117.234.71:8333 -87.118.96.197:8333 -87.145.12.57:8333 -87.159.170.190:8333 -88.150.168.160:8333 -88.208.0.79:8333 -88.208.0.149:8333 +85.214.147.162:8333 +85.243.168.4:8333 +86.1.0.18:8333 +87.79.77.106:8333 +87.91.156.110:8333 +87.236.196.222:8333 +88.85.75.152:8333 +88.87.1.230:8333 +88.87.92.102:8333 +88.89.69.202:8333 +88.97.72.229:8333 +88.164.117.99:8333 +88.198.32.131:8333 +88.202.230.87:8333 +88.214.193.154:8343 88.214.194.226:8343 -89.1.11.32:8333 -89.36.235.108:8333 -89.67.96.2:15321 -89.98.16.41:8333 -89.108.72.195:8333 -89.156.35.157:8333 -89.163.227.28:8333 -89.212.33.237:8333 -89.212.160.165:8333 -89.231.96.83:8333 -89.248.164.64:8333 -90.149.193.199:8333 -91.77.239.245:8333 -91.106.194.97:8333 +89.10.155.88:8333 +89.46.101.44:8333 +89.163.224.212:8333 +89.174.248.20:8333 +89.202.231.198:8333 +89.212.75.6:8333 +90.149.38.172:8333 +90.169.106.139:8333 +91.64.101.150:8333 +91.65.196.179:8333 +91.121.80.17:8333 91.126.77.77:8333 -91.134.38.195:8333 -91.156.97.181:8333 +91.145.76.156:8333 +91.152.150.35:8333 +91.192.137.17:8333 +91.196.170.110:8333 +91.197.44.133:8333 91.207.68.144:8333 -91.209.77.101:8333 +91.210.105.28:8333 +91.211.102.101:8333 +91.211.106.34:8333 91.214.200.205:8333 -91.220.131.242:8333 -91.220.163.18:8333 -91.233.23.35:8333 -92.13.96.93:8333 -92.14.74.114:8333 +91.220.43.146:8333 +91.222.71.89:8333 +91.224.140.242:8333 +91.229.76.14:8333 92.27.7.209:8333 -92.221.228.13:8333 -92.255.207.73:8333 -93.72.167.148:8333 -93.74.163.234:8333 -93.123.174.66:8333 -93.152.166.29:8333 -93.181.45.188:8333 -94.19.12.244:8333 +92.51.167.88:8333 +92.247.229.163:8333 +93.84.114.106:8333 +93.113.36.172:8333 +93.188.224.253:8333 +94.75.239.69:8333 94.190.227.112:8333 -94.198.135.29:8333 +94.214.2.74:8333 94.224.162.65:8333 -94.226.107.86:8333 -94.242.198.161:8333 -95.31.10.209:8333 -95.65.72.244:8333 -95.84.162.95:8333 -95.90.139.46:8333 -95.183.49.27:8005 -95.215.47.133:8333 -96.23.67.85:8333 -96.44.166.190:8333 -97.93.225.74:8333 -98.26.0.34:8333 -98.27.225.102:8333 -98.229.117.229:8333 -98.249.68.125:8333 -98.255.5.155:8333 -99.101.240.114:8333 +94.236.198.253:8333 +94.242.229.158:8333 +95.84.138.99:8333 +95.95.168.87:8333 +95.110.234.93:8333 +95.130.9.200:8333 +95.165.168.168:8333 +95.170.235.254:8333 +95.211.130.154:8333 +96.46.68.104:8333 +96.127.202.148:8333 +97.76.171.35:8333 +98.160.160.67:8333 +99.126.197.187:8333 +99.198.173.1:8333 101.100.174.138:8333 -101.251.203.6:8333 -103.3.60.61:8333 -103.30.42.189:8333 +101.164.201.208:8333 103.224.165.48:8333 -104.36.83.233:8333 -104.37.129.22:8333 -104.54.192.251:8333 +104.128.225.223:8333 104.128.228.252:8333 -104.128.230.185:8334 -104.130.161.47:8333 -104.131.33.60:8333 -104.143.0.156:8333 -104.156.111.72:8333 -104.167.111.84:8333 -104.193.40.248:8333 -104.197.7.174:8333 -104.197.8.250:8333 -104.223.1.133:8333 -104.236.97.140:8333 +104.131.192.94:8333 +104.155.45.201:8334 +104.194.28.195:8663 +104.211.1.27:8333 +104.221.38.177:8333 +104.236.9.79:8333 +104.236.129.178:8333 +104.236.186.249:8333 +104.236.194.15:8333 104.238.128.214:8333 104.238.130.182:8333 106.38.234.84:8333 106.185.36.204:8333 +106.185.38.67:8333 107.6.4.145:8333 107.150.2.6:8333 107.150.40.234:8333 -107.155.108.130:8333 -107.161.182.115:8333 -107.170.66.231:8333 -107.190.128.226:8333 +107.170.13.184:8333 +107.181.250.216:8333 +107.191.101.111:8333 107.191.106.115:8333 -108.16.2.61:8333 -109.70.4.168:8333 -109.162.35.196:8333 -109.163.235.239:8333 -109.190.196.220:8333 -109.191.39.60:8333 +108.59.12.163:8333 +108.161.129.247:8333 +109.193.160.140:8333 +109.197.13.54:8333 +109.230.7.248:8333 109.234.106.191:8333 -109.238.81.82:8333 -114.76.147.27:8333 -115.28.224.127:8333 -115.68.110.82:18333 -118.97.79.218:8333 -118.189.207.197:8333 -119.228.96.233:8333 -120.147.178.81:8333 -121.41.123.5:8333 -121.67.5.230:8333 -122.107.143.110:8333 -123.2.170.98:8333 -123.110.65.94:8333 -123.193.139.19:8333 -125.239.160.41:8333 -128.101.162.193:8333 +109.236.137.80:8333 +109.251.161.121:8333 +112.65.231.226:8333 +115.70.166.57:8333 +115.159.42.80:8333 +117.18.73.34:8333 +118.67.201.40:8333 +118.100.86.246:8333 +118.110.104.152:8333 +119.224.64.141:8333 +120.55.193.136:8333 +122.106.169.178:8333 +123.203.174.15:8333 +123.255.232.94:8333 +124.148.165.165:8333 +124.232.141.31:8333 +128.30.92.69:8333 +128.39.141.182:8333 +128.84.167.20:8333 128.111.73.10:8333 -128.140.229.73:8333 -128.175.195.31:8333 -128.199.107.63:8333 -128.199.192.153:8333 +128.127.38.195:8333 +128.140.224.162:8333 +128.199.101.104:8333 +128.233.224.35:8333 128.253.3.193:20020 -129.123.7.7:8333 -130.89.160.234:8333 -131.72.139.164:8333 -131.191.112.98:8333 -133.1.134.162:8333 -134.19.132.53:8333 -137.226.34.42:8333 -141.41.2.172:8333 -141.255.128.204:8333 -142.217.12.106:8333 -143.215.129.126:8333 +130.180.228.138:8333 +130.185.144.213:8333 +130.255.73.207:8333 +133.218.233.11:8333 +134.249.128.23:8333 +136.159.234.234:8333 +137.116.160.176:8333 +139.162.2.145:8333 +139.162.23.117:8333 +141.134.69.253:8333 +141.255.162.215:8333 +144.122.163.187:8333 +145.131.3.54:8333 +145.255.4.94:8333 146.0.32.101:8337 -147.229.13.199:8333 -149.210.133.244:8333 -149.210.162.187:8333 +147.83.72.91:8333 +148.103.28.68:8333 +149.5.32.102:8333 +149.210.164.195:8333 150.101.163.241:8333 151.236.11.189:8333 -153.121.66.211:8333 -154.20.2.139:8333 -159.253.23.132:8333 +152.3.136.56:8333 +154.20.208.25:8333 +158.181.104.149:8333 +159.253.96.226:8333 +160.36.130.180:8333 +162.209.1.233:8333 +162.209.4.125:8333 162.209.106.123:8333 162.210.198.184:8333 -162.218.65.121:8333 -162.222.161.49:8333 -162.243.132.6:8333 -162.243.132.58:8333 162.248.99.164:53011 162.248.102.117:8333 -163.158.35.110:8333 -164.15.10.189:8333 -164.40.134.171:8333 +162.251.108.53:8333 +163.44.2.48:8333 +163.158.36.17:8333 166.230.71.67:8333 -167.160.161.199:8333 -168.103.195.250:8333 -168.144.27.112:8333 -168.158.129.29:8333 -170.75.162.86:8333 -172.90.99.174:8333 -172.245.5.156:8333 -173.23.166.47:8333 +167.160.36.62:8333 +167.160.169.92:8333 +168.93.129.220:8333 +169.55.99.84:8333 +169.228.66.43:8333 +172.9.169.242:8333 173.32.11.194:8333 -173.34.203.76:8333 -173.171.1.52:8333 -173.175.136.13:8333 -173.230.228.139:8333 -173.247.193.70:8333 -174.49.132.28:8333 -174.52.202.72:8333 -174.53.76.87:8333 -174.109.33.28:8333 -176.28.12.169:8333 -176.35.182.214:8333 -176.36.33.113:8333 -176.36.33.121:8333 -176.58.96.173:8333 -176.121.76.84:8333 +173.230.228.136:8333 +173.246.107.34:8333 +173.254.235.34:8333 +174.0.128.222:8333 +174.25.130.148:8333 +174.50.64.101:8333 +175.140.232.141:8333 +176.36.37.62:8333 +176.46.9.96:8333 +176.124.110.27:8333 +177.39.16.102:8333 +178.17.173.2:8333 +178.62.5.248:8333 178.62.70.16:8333 -178.62.111.26:8333 -178.76.169.59:8333 -178.79.131.32:8333 -178.162.199.216:8333 -178.175.134.35:8333 -178.248.111.4:8333 -178.254.1.170:8333 +178.62.203.185:8333 +178.79.160.118:8333 +178.169.206.244:8333 +178.193.234.62:8333 +178.199.96.108:8333 +178.254.18.96:8333 178.254.34.161:8333 -179.43.143.120:8333 -179.208.156.198:8333 -180.200.128.58:8333 -183.78.169.108:8333 -183.96.96.152:8333 -184.68.2.46:8333 -184.73.160.160:8333 -184.94.227.58:8333 -184.152.68.163:8333 -185.7.35.114:8333 -185.28.76.179:8333 -185.31.160.202:8333 -185.45.192.129:8333 -185.66.140.15:8333 -186.2.167.23:8333 -186.220.101.142:8333 -188.26.5.33:8333 -188.75.136.146:8333 -188.120.194.140:8333 -188.121.5.150:8333 -188.138.0.114:8333 +178.255.41.123:8333 +180.210.34.58:9801 +182.92.226.212:8333 +182.171.246.142:8333 +184.23.8.9:8333 +184.58.162.35:8333 +184.154.9.170:8333 +185.8.238.165:8333 +185.24.97.11:8333 +185.31.137.139:8333 +185.38.44.64:8333 +185.53.128.180:8333 +185.53.129.244:8333 +185.77.129.119:8333 +185.77.129.156:8333 +185.82.203.92:8333 +188.20.97.18:8333 +188.126.8.14:8333 188.138.33.239:8333 -188.166.0.82:8333 +188.155.136.70:8333 +188.166.229.112:8333 188.182.108.129:8333 -188.191.97.208:8333 -188.226.198.102:8001 -190.10.9.217:8333 -190.75.143.144:8333 -190.139.102.146:8333 -191.237.64.28:8333 -192.3.131.61:8333 -192.99.225.3:8333 -192.110.160.122:8333 +188.226.225.174:8010 +188.242.171.8:8333 +188.243.4.139:8333 +190.10.9.234:8333 +190.10.10.147:8333 +190.81.160.184:8333 +190.85.201.37:8333 +192.34.227.230:8333 +192.77.189.200:8333 +192.124.224.7:8333 192.146.137.1:8333 -192.183.198.204:8333 192.203.228.71:8333 +192.206.202.20:8333 193.0.109.3:8333 -193.12.238.204:8333 -193.91.200.85:8333 -193.234.225.156:8333 -194.6.233.38:8333 -194.63.143.136:8333 -194.126.100.246:8333 -195.134.99.195:8333 -195.159.111.98:8333 -195.159.226.139:8333 +193.41.229.130:8333 +193.41.229.156:8333 +193.49.43.219:8333 +193.147.71.120:8333 +193.179.65.233:8333 +193.183.99.46:8333 +193.192.37.135:8333 +193.234.224.195:8333 +194.58.108.213:8333 +194.187.96.2:8333 +194.255.31.59:8333 +195.36.6.101:8333 +195.58.238.243:8333 195.197.175.190:8333 -198.48.199.108:8333 -198.57.208.134:8333 +195.239.1.66:8333 +198.48.196.230:8333 +198.50.192.160:8333 198.57.210.27:8333 -198.62.109.223:8333 +198.84.195.179:8333 198.167.140.8:8333 -198.167.140.18:8333 -199.91.173.234:8333 +198.204.224.106:8333 199.127.226.245:8333 -199.180.134.116:8333 -200.7.96.99:8333 -201.160.106.86:8333 -202.55.87.45:8333 -202.60.68.242:8333 -202.60.69.232:8333 -202.124.109.103:8333 -203.30.197.77:8333 -203.88.160.43:8333 +199.201.110.8:8333 +199.233.234.90:8333 +200.116.98.185:8333 +202.60.70.18:8333 203.151.140.14:8333 -203.219.14.204:8333 -205.147.40.62:8333 -207.235.39.214:8333 -207.244.73.8:8333 -208.12.64.225:8333 +204.112.203.52:8333 +205.200.247.149:8333 +207.226.141.253:8333 +207.255.42.202:8333 +208.53.164.19:8333 +208.66.68.127:8333 +208.66.68.130:8333 +208.71.171.232:8341 208.76.200.200:8333 -209.40.96.121:8333 -209.126.107.176:8333 -209.141.40.149:8333 -209.190.75.59:8333 -209.208.111.142:8333 -210.54.34.164:8333 -211.72.66.229:8333 +208.82.98.189:8333 +208.85.193.31:8333 +208.111.48.41:8333 +208.111.48.45:8333 +209.34.232.72:8333 +209.81.9.223:8333 +209.90.224.2:8333 +209.90.224.4:8333 +209.126.98.174:8333 +209.136.72.69:8333 +209.195.4.74:8333 +209.197.13.62:8333 +211.72.227.8:8333 212.51.144.42:8333 -212.112.33.157:8333 -212.116.72.63:8333 +212.71.233.127:8333 212.126.14.122:8333 +212.159.44.50:8333 +213.5.36.58:8333 +213.57.33.10:8333 213.66.205.194:8333 -213.111.196.21:8333 -213.122.107.102:8333 -213.136.75.175:8333 +213.136.73.125:8333 +213.155.3.216:8333 213.155.7.24:8333 -213.163.64.31:8333 -213.163.64.208:8333 -213.165.86.136:8333 -213.184.8.22:8333 +213.167.17.6:8333 +213.223.138.13:8333 216.15.78.182:8333 -216.55.143.154:8333 -216.115.235.32:8333 -216.126.226.166:8333 -216.145.67.87:8333 +216.38.129.164:8333 +216.48.168.8:8333 216.169.141.169:8333 -216.249.92.230:8333 +216.245.206.181:8333 +216.249.204.161:8333 216.250.138.230:8333 +217.11.225.189:8333 +217.12.34.158:8333 +217.12.202.33:8333 217.20.171.43:8333 -217.23.2.71:8333 -217.23.2.242:8333 -217.25.9.76:8333 -217.40.226.169:8333 -217.123.98.9:8333 -217.155.36.62:8333 +217.23.1.126:8333 +217.23.11.138:8333 +217.111.66.79:8333 +217.155.202.191:8333 +217.158.9.102:8333 217.172.32.18:20993 -218.61.196.202:8333 -218.231.205.41:8333 -220.233.77.200:8333 -223.18.226.85:8333 -223.197.203.82:8333 -223.255.166.142:8333 +220.245.196.37:8333 [2001:1291:2bf:1::100]:8333 -[2001:1418:100:5c2::2]:8333 -[2001:16d8:dd24:0:86c9:681e:f931:256]:8333 -[2001:19f0:1624:e6::579d:9428]:8333 -[2001:19f0:300:1340:225:90ff:fec9:2b6d]:8333 -[2001:19f0:4009:1405::64]:8333 -[2001:1b40:5000:2e::3fb0:6571]:8333 +[2001:1620:f00:282::2]:8333 +[2001:1620:f00:8282::1]:8333 +[2001:19f0:5000:8de8:5400:ff:fe12:55e4]:8333 +[2001:19f0:6c00:9103:5400:ff:fe10:a8d3]:8333 +[2001:1b60:3:172:142b:6dff:fe7a:117]:8333 [2001:410:a000:4050:8463:90b0:fffb:4e58]:8333 -[2001:410:a002:cafe:8463:90b0:fffb:4e58]:8333 -[2001:41d0:1:541e::1]:8333 -[2001:41d0:1:6a34::3]:8333 +[2001:4128:6135:2010:21e:bff:fee8:a3c0]:8333 +[2001:41d0:1008:761::17c]:8333 +[2001:41d0:1:45d8::1]:8333 [2001:41d0:1:6cd3::]:8333 [2001:41d0:1:8b26::1]:8333 -[2001:41d0:1:a33d::1]:8333 -[2001:41d0:1:b855::1]:8333 +[2001:41d0:1:afda::]:8200 +[2001:41d0:1:b26b::1]:8333 [2001:41d0:1:c139::1]:8333 [2001:41d0:1:c8d7::1]:8333 -[2001:41d0:1:dd3f::1]:8333 -[2001:41d0:1:e29d::1]:8333 [2001:41d0:1:f59f::33]:8333 [2001:41d0:1:f7cc::1]:8333 -[2001:41d0:1:ff87::1]:8333 -[2001:41d0:2:2f05::1]:8333 +[2001:41d0:2:1021::1]:8333 [2001:41d0:2:37c3::]:8200 -[2001:41d0:2:3e13::1]:8333 -[2001:41d0:2:8619::]:8333 +[2001:41d0:2:4797:2323:2323:2323:2323]:8333 +[2001:41d0:2:53df::]:8333 [2001:41d0:2:9c94::1]:8333 +[2001:41d0:2:9d3e::1]:8333 [2001:41d0:2:a24f::]:8333 -[2001:41d0:2:adbf::]:8333 -[2001:41d0:2:b721::1]:8333 -[2001:41d0:2:ee52::1]:8333 +[2001:41d0:2:a35a::]:8333 +[2001:41d0:2:b2b8::]:8333 +[2001:41d0:2:c1d9::]:8333 +[2001:41d0:2:c6e::]:8333 +[2001:41d0:2:c9bf::]:8333 [2001:41d0:2:f1a5::]:8333 -[2001:41d0:2:fa54::1]:8333 -[2001:41d0:51:1::2036]:8333 -[2001:41d0:52:a00::1a1]:8333 +[2001:41d0:52:a00::105f]:8333 [2001:41d0:52:cff::6f5]:8333 -[2001:41d0:52:d00::2c0]:8333 -[2001:41d0:52:d00::cf2]:8333 -[2001:41d0:8:1087::1]:8333 -[2001:41d0:8:4a3c::b7c]:8333 +[2001:41d0:52:d00::6e2]:8333 +[2001:41d0:8:3e75::1]:8333 +[2001:41d0:8:62ab::1]:8333 [2001:41d0:8:6728::]:8333 -[2001:41d0:8:b779::1]:8333 -[2001:41d0:8:c30f::1]:8333 -[2001:41d0:8:d2b2::1]:8333 -[2001:41d0:8:d5c3::1]:8333 +[2001:41d0:8:b30a::1]:8333 +[2001:41d0:8:bc26::1]:8333 +[2001:41d0:8:be9a::1]:8333 +[2001:41d0:8:d984::]:8333 [2001:41d0:8:eb8b::]:8333 -[2001:41d0:a:16d0::1]:8333 +[2001:41d0:a:13a2::1]:8333 [2001:41d0:a:2b18::1]:8333 -[2001:41d0:a:3a9c::1]:8333 -[2001:41d0:a:4903::]:8333 -[2001:41d0:a:57b::1]:8333 -[2001:41d0:a:5c7a::]:8333 +[2001:41d0:a:2d14::]:8333 +[2001:41d0:a:4558::1df2:76d3]:8333 +[2001:41d0:a:4aaa::]:8333 +[2001:41d0:a:635b::1]:8333 +[2001:41d0:a:63d8::1]:8333 [2001:41d0:a:6c29::1]:8333 -[2001:41d0:a:f482::1]:8333 -[2001:41d0:b:854:b7c:b7c:b7c:b7c]:8333 -[2001:41d0:d:111c::]:8333 -[2001:44b8:4116:7801:4216:7eff:fe78:3fe4]:8333 -[2001:470:1f08:837::2]:8333 -[2001:470:1f08:c33::2]:8333 -[2001:470:1f09:bca:218:7dff:fe10:be33]:8333 -[2001:470:1f0f:22d::212:26]:8333 +[2001:41d0:a:f9cd::1]:8333 +[2001:41d0:d:20a4::]:8333 +[2001:41d0:e:26b::1]:8333 +[2001:41d0:fc8c:a200:7a24:afff:fe9d:c69b]:8333 +[2001:41f0:61::7]:8333 +[2001:41f0::2]:8333 +[2001:44b8:41bd:6101:148e:4022:4950:e861]:8333 +[2001:470:1:2f9:0:1:107a:a301]:8333 +[2001:470:1f0b:ad6::2]:8333 [2001:470:1f11:12d5::ae1:5611]:8333 -[2001:470:1f14:57a::2]:8333 [2001:470:1f14:7d::2]:8333 -[2001:470:1f15:57c::1]:8333 -[2001:470:1f15:dda:3d9a:3f11:9a56:ed64]:8333 -[2001:470:25:482::2]:8333 -[2001:470:25:e4::2]:8333 -[2001:470:4:26b::2]:8333 +[2001:470:27:ce::2]:8333 +[2001:470:41:6::2]:8333 +[2001:470:507d:0:6ab5:99ff:fe73:ac18]:8333 +[2001:470:583e::2a]:8333 [2001:470:5f:5f::232]:8333 [2001:470:66:119::2]:8333 -[2001:470:67:39d::71]:8333 [2001:470:6c4f::cafe]:8333 -[2001:470:8:2e1::43]:8333 -[2001:470:90a7:96::afe:6021]:8333 +[2001:470:6f:327:913b:7fe:8545:a4f5]:8333 +[2001:470:7dda:1::1]:8333 [2001:470:95c1::2]:8333 [2001:470:b1d0:ffff::1000]:8333 -[2001:470:c1f2:3::201]:8333 [2001:470:d00d:0:3664:a9ff:fe9a:5150]:8333 -[2001:470:e250:0:211:11ff:feb9:924c]:8333 -[2001:4800:7817:101:be76:4eff:fe04:dc52]:8333 -[2001:4800:7819:104:be76:4eff:fe04:7809]:8333 +[2001:470:fab7:1::1]:8333 [2001:4800:7819:104:be76:4eff:fe05:c828]:8333 +[2001:4800:7819:104:be76:4eff:fe05:c9a0]:8333 +[2001:4801:7819:74:b745:b9d5:ff10:a61a]:8333 +[2001:4801:7819:74:b745:b9d5:ff10:aaec]:8333 +[2001:4801:7828:104:be76:4eff:fe10:1325]:8333 +[2001:4802:7800:1:be76:4eff:fe20:f023]:8333 [2001:4802:7800:2:30d7:1775:ff20:1858]:8333 +[2001:4802:7800:2:be76:4eff:fe20:6c26]:8333 [2001:4802:7802:101:be76:4eff:fe20:256]:8333 [2001:4802:7802:103:be76:4eff:fe20:2de8]:8333 [2001:4830:1100:2e8::2]:8333 -[2001:4ba0:fff7:181:dead::1]:8333 +[2001:4b98:dc2:41:216:3eff:fe56:f659]:8333 [2001:4ba0:fffa:5d::93]:8333 -[2001:4ba0:ffff:1be:1:1005:0:1]:8335 -[2001:4c48:110:101:216:3eff:fe24:1162]:8333 -[2001:4dd0:f101::32]:8333 +[2001:4ba0:ffff:1be:1:1005:0:1]:8333 [2001:4dd0:ff00:867f::3]:8333 [2001:4dd0:ff00:9a67::9]:8333 -[2001:4dd0:ff00:9c55:c23f:d5ff:fe6c:7ee9]:8333 [2001:5c0:1400:b::3cc7]:8333 -[2001:5c0:1400:b::3d01]:8333 -[2001:5c0:1400:b::8df]:8333 -[2001:5c0:1501:300::3]:8333 [2001:610:1b19::3]:8333 -[2001:620:500:fff0:f21f:afff:fecf:91cc]:8333 -[2001:67c:1220:80c:ad:8de2:f7e2:c784]:8333 -[2001:67c:21ec:1000::b]:8333 -[2001:6f8:1296:0:76d4:35ff:feba:1d26]:8333 -[2001:840:f000:4250:3e4a:92ff:fe6d:145f]:8333 +[2001:610:600:a41::2]:8333 +[2001:67c:26b4::]:8333 [2001:8d8:840:500::39:1ae]:8333 -[2001:980:efd8:0:21:de4a:2709:912]:8333 -[2001:981:46:1::3]:8333 -[2001:981:9319:2:c0:a8:c8:8]:8333 -[2001:9d8:cafe:3::91]:8333 -[2001:ad0:1:1:26be:5ff:fe25:959d]:8333 +[2001:8d8:965:4a00::10:9343]:8333 +[2001:980:4650:1:2e0:53ff:fe13:2449]:8333 +[2001:981:46:1:ba27:ebff:fe5b:edee]:8333 +[2001:9c8:53e9:369a:226:2dff:fe1b:7472]:8333 +[2001:9d8:cafe:3::87]:8333 +[2001:b10:11:21:3e07:54ff:fe48:7248]:8333 [2001:ba8:1f1:f34c::2]:8333 -[2001:bc8:381c:100::1]:8333 -[2002:175c:4caa::175c:4caa]:8333 -[2002:4404:82f1:0:8d55:8fbb:15fa:f4e0]:8333 -[2002:4475:2233:0:21f:5bff:fe33:9f70]:8333 -[2002:596c:48c3::596c:48c3]:8333 +[2001:bc8:2310:100::1]:8333 +[2001:bc8:3427:101:7a4f:8be:2611:6e79]:8333 +[2001:bc8:3505:200::1]:8333 +[2001:cc0:a004::30:1d]:8333 +[2001:e42:102:1209:153:121:76:171]:8333 +[2002:17ea:14eb::17ea:14eb]:8333 +[2002:2f8:2bc5::2f8:2bc5]:8333 +[2002:4047:482c::4047:482c]:8333 +[2002:45c3:8cca::45c3:8cca]:8333 +[2002:46bb:8a41:0:226:b0ff:feed:5f12]:8888 +[2002:46bb:8c3c:0:8d55:8fbb:15fa:f4e0]:8765 +[2002:4c48:a0fe::4c48:a0fe]:8333 +[2002:4d44:25c8::4d44:25c8]:8333 +[2002:505f:aaa2::505f:aaa2]:8333 +[2002:5bc1:799d::5bc1:799d]:8333 +[2002:6dec:5472::6dec:5472]:8333 [2002:8c6d:6521:9617:12bf:48ff:fed8:1724]:8333 -[2002:a646:5e6a::1:2]:8333 +[2002:ac52:94e2::ac52:94e2]:8333 +[2002:af7e:3eca::af7e:3eca]:8333 [2002:b009:20c5::b009:20c5]:8333 +[2002:c06f:39a0::c06f:39a0]:8333 +[2002:c23a:738a::c23a:738a]:8333 +[2002:c70f:7442::c70f:7442]:8333 +[2002:cec5:be4f::cec5:be4f]:8333 +[2002:d149:9e3a::d149:9e3a]:8333 +[2002:d917:ca5::d917:ca5]:8333 +[2400:8900::f03c:91ff:fe50:153f]:8333 [2400:8900::f03c:91ff:fe6e:823e]:8333 -[2400:8900::f03c:91ff:fe70:d164]:8333 -[2400:8901::f03c:91ff:fe37:9761]:8333 -[2403:4200:403:2::ff]:8333 -[2403:b800:1000:64:40a:e9ff:fe5f:94c1]:8333 -[2403:b800:1000:64:9879:17ff:fe6a:a59f]:8333 +[2400:8900::f03c:91ff:fea8:1934]:8333 +[2400:8901::f03c:91ff:fe26:c4d6]:8333 +[2400:8901::f03c:91ff:fec8:4280]:8333 +[2400:8901::f03c:91ff:fec8:660f]:8333 +[2401:1800:7800:102:be76:4eff:fe1c:559]:8333 +[2401:1800:7800:102:be76:4eff:fe1c:a7d]:8333 +[2405:aa00:2::40]:8333 [2600:3c00::f03c:91ff:fe18:59b2]:8333 -[2600:3c00::f03c:91ff:fe37:a4b1]:8333 -[2600:3c00::f03c:91ff:fe56:2973]:8333 +[2600:3c00::f03c:91ff:fe26:bfb6]:8333 +[2600:3c00::f03c:91ff:fe33:88e3]:8333 [2600:3c00::f03c:91ff:fe6e:7297]:8333 [2600:3c00::f03c:91ff:fe84:8a6e]:8333 [2600:3c01::f03c:91ff:fe18:6adf]:8333 -[2600:3c01::f03c:91ff:fe18:e217]:8333 -[2600:3c01::f03c:91ff:fe33:1b31]:8333 -[2600:3c01::f03c:91ff:fe33:2fe1]:8333 -[2600:3c01::f03c:91ff:fe33:a03f]:8333 +[2600:3c01::f03c:91ff:fe26:c4b8]:8333 +[2600:3c01::f03c:91ff:fe3b:1f76]:8333 [2600:3c01::f03c:91ff:fe50:5e06]:8333 -[2600:3c01::f03c:91ff:fe56:d645]:8333 -[2600:3c01::f03c:91ff:fe6e:a3dc]:8333 -[2600:3c01::f03c:91ff:fe89:a659]:8333 -[2600:3c02::f03c:91ff:fe6e:6f0b]:8333 -[2600:3c03::f03c:91ff:fe33:f6fb]:8333 +[2600:3c01::f03c:91ff:fe61:289b]:8333 +[2600:3c01::f03c:91ff:fe69:89e9]:8333 +[2600:3c01::f03c:91ff:fe84:ac15]:8333 +[2600:3c01::f03c:91ff:fe98:68bb]:8333 +[2600:3c02::f03c:91ff:fe26:713]:8333 +[2600:3c02::f03c:91ff:fe26:c49e]:8333 +[2600:3c02::f03c:91ff:fe84:97d8]:8333 +[2600:3c02::f03c:91ff:fec8:8feb]:8333 +[2600:3c03::f03c:91ff:fe18:da80]:8333 +[2600:3c03::f03c:91ff:fe26:c49b]:8333 [2600:3c03::f03c:91ff:fe50:5fa7]:8333 +[2600:3c03::f03c:91ff:fe67:d2e]:8333 [2600:3c03::f03c:91ff:fe6e:1803]:8333 -[2600:3c03::f03c:91ff:fe6e:4ac0]:8333 -[2601:6:4800:47f:1e4e:1f4d:332c:3bf6]:8333 -[2601:d:5400:fed:8d54:c1e8:7ed7:d45e]:8333 -[2602:100:4b8f:6d2a:20c:29ff:feaf:c4c2]:8333 +[2600:3c03::f03c:91ff:fec8:4bbe]:8333 +[2600:3c03::f03c:91ff:fee4:4e16]:8333 +[2601:18d:8300:58a6::2e4]:8333 +[2601:240:4600:40c0:250:56ff:fea4:6305]:8333 +[2601:581:c200:a719:542c:9cd5:4852:f7d9]:8333 +[2601:647:4900:85f1:ca2a:14ff:fe51:bb35]:8333 +[2601:c2:c002:b300:54a0:15b5:19f7:530d]:8333 +[2602:306:ccff:ad7f:b116:52be:64ba:db3a]:8333 +[2602:ae:1982:9400:846:f78c:fec:4d57]:8333 [2602:ffc5:1f::1f:2d61]:8333 [2602:ffc5:1f::1f:9211]:8333 +[2602:ffc5::75d5:c1c3]:8333 [2602:ffc5::ffc5:b844]:8333 [2602:ffe8:100:2::457:936b]:8333 -[2602:ffea:1001:125::2ad4]:8333 -[2602:ffea:1001:6ff::837d]:8333 +[2602:ffe8:100:2::9d20:2e3c]:8333 [2602:ffea:1001:72b::578b]:8333 -[2602:ffea:1001:77a::9cae]:8333 -[2602:ffea:1:2fe::6bc8]:8333 -[2602:ffea:1:701::7968]:8333 -[2602:ffea:1:70d::82ec]:8333 -[2602:ffea:1:9ff::e957]:8333 -[2602:ffea:1:a5d::4acb]:8333 [2602:ffea:a::24c4:d9fd]:8333 -[2602:ffea:a::c06:ae32]:8333 [2604:0:c1:100:1ec1:deff:fe54:2235]:8333 [2604:180:1:1af::42a9]:8333 -[2604:180::b208:398]:8333 -[2604:2880::6072:aed]:8333 +[2604:180:3:702::c9de]:8333 [2604:4080:1114:0:3285:a9ff:fe93:850c]:8333 -[2604:7c00:17:3d0::5a4d]:8333 -[2604:9a00:2100:a009:2::]:8333 -[2604:a880:1:20::22a:4001]:8333 -[2604:a880:800:10::752:f001]:8333 -[2604:c00:88:32:216:3eff:fee4:fcca]:8333 -[2604:c00:88:32:216:3eff:fef5:bc21]:8333 -[2605:7980:1:2::1761:3d4e]:8333 -[2605:e000:1417:4068:223:32ff:fe96:e2d]:8333 +[2604:6000:ffc0:3c:64a3:94d0:4f1d:1da8]:8333 +[2605:6000:f380:9a01:ba09:8aff:fed4:3511]:8333 +[2605:6001:e00f:7b00:c587:6d91:6eff:eeba]:8333 +[2605:f700:c0:1::25c3:2a3e]:8333 [2606:6000:a441:9903:5054:ff:fe78:66ff]:8333 -[2606:df00:2::ae85:8fc6]:8333 -[2607:5300:100:200::e7f]:8333 +[2607:5300:100:200::1c83]:9334 [2607:5300:10::a1]:8333 -[2607:5300:60:116e::1]:8333 -[2607:5300:60:1535::]:8333 -[2607:5300:60:1b32::1]:8333 -[2607:5300:60:2337::1]:8333 +[2607:5300:60:1c2f::1]:8333 [2607:5300:60:2b90::1]:8333 -[2607:5300:60:2d99::1]:8333 -[2607:5300:60:3cb::1]:8333 +[2607:5300:60:3320::1]:8333 +[2607:5300:60:385::1]:8333 [2607:5300:60:4a85::]:8333 -[2607:5300:60:5112:0:2:4af5:63fe]:8333 -[2607:5300:60:6dd5::]:8333 -[2607:5300:60:a91::1]:8333 -[2607:f1c0:820:1500::7f:3f44]:8333 +[2607:5300:60:65e4::]:8333 +[2607:5300:60:6918::]:8333 +[2607:5300:60:711a:78::a7b5]:8333 +[2607:5300:60:714::1]:8333 +[2607:5300:60:870::1]:8333 +[2607:5300:60:952e:3733::1414]:8333 [2607:f1c0:848:1000::48:943c]:8333 +[2607:f2e0:f:5df::2]:8333 +[2607:f748:1200:f8:21e:67ff:fe99:8f07]:8333 [2607:f948:0:1::7]:8333 -[2607:fcd0:100:2300::4ad:e594]:8333 -[2607:fcd0:100:2300::659e:9cb3]:8333 -[2607:fcd0:100:2300::c74b:a8ae]:8333 -[2607:fcd0:100:2300::d82:d8c2]:8333 -[2607:fcd0:100:4300::8795:2fa8]:8333 -[2607:fcd0:daaa:901::9561:e043]:8333 +[2607:ff68:100:36::131]:8333 +[2803:6900:1::117]:8333 +[2a00:1098:0:80:1000:25:0:1]:8333 +[2a00:1178:2:43:5054:ff:fe84:f86f]:8333 [2a00:1178:2:43:5054:ff:fee7:2eb6]:8333 -[2a00:1328:e100:cc42:230:48ff:fe92:55d]:8333 +[2a00:1178:2:43:8983:cc27:d72:d97a]:8333 +[2a00:1328:e100:cc42:230:48ff:fe92:55c]:8333 [2a00:14f0:e000:80d2:cd1a::1]:8333 -[2a00:16d8:c::5b6a:c261]:8333 -[2a00:61e0:4083:6d01:6852:1376:e972:2091]:8333 -[2a00:c98:2030:a02f:2::2]:8333 +[2a00:1630:2:1802:188:122:91:11]:8333 +[2a00:18e0:0:1800::1]:8333 +[2a00:18e0:0:dcc5:109:234:106:191]:8333 +[2a00:1a28:1157:87::94c7]:8333 +[2a00:1ca8:37::a5fc:40d1]:8333 +[2a00:1ca8:37::ab6d:ce2c]:8333 +[2a00:7143:100:0:216:3eff:fe2e:74a3]:8333 +[2a00:7143:100:0:216:3eff:fed3:5c21]:8333 +[2a00:7c80:0:45::123]:8333 +[2a00:dcc0:eda:98:183:193:c382:6bdb]:8333 +[2a00:dcc0:eda:98:183:193:f72e:d943]:8333 +[2a00:f820:17::4af:1]:8333 +[2a00:f940:2:1:2::101d]:8333 +[2a00:f940:2:1:2::6ac]:8333 [2a01:1b0:7999:402::131]:8333 -[2a01:1e8:e100:811c:700f:65f0:f72a:1084]:8333 -[2a01:238:42da:c500:6546:1293:5422:ab40]:8333 -[2a01:348:6:473::2]:8333 -[2a01:368:e010:2::2]:8333 -[2a01:430:17:1::ffff:549]:8333 -[2a01:430:17:1::ffff:830]:8333 -[2a01:488:66:1000:53a9:d04:0:1]:8333 -[2a01:488:66:1000:57e6:578c:0:1]:8333 +[2a01:238:42dd:f900:7a6c:2bc6:4041:c43]:8333 +[2a01:238:4313:6300:2189:1c97:696b:5ea]:8333 +[2a01:488:66:1000:5c33:91f9:0:1]:8333 [2a01:488:66:1000:b01c:178d:0:1]:8333 -[2a01:488:67:1000:523:fdce:0:1]:8333 -[2a01:488:67:1000:b01c:30ab:0:1]:8333 -[2a01:4f8:100:24aa::2]:8333 +[2a01:4f8:100:34ce::2]:8333 +[2a01:4f8:100:34e4::2]:8333 [2a01:4f8:100:44e7::2]:8333 +[2a01:4f8:100:510e::2]:8333 [2a01:4f8:100:5128::2]:8333 -[2a01:4f8:100:84a7::1:1]:8333 +[2a01:4f8:110:5105::2]:8333 [2a01:4f8:110:516c::2]:8333 -[2a01:4f8:110:536e::2]:8333 +[2a01:4f8:120:43e4::2]:8333 [2a01:4f8:120:62e6::2]:8333 [2a01:4f8:120:702e::2]:8333 -[2a01:4f8:120:8005::2]:8333 [2a01:4f8:120:8203::2]:8333 -[2a01:4f8:120:8422::2]:8333 -[2a01:4f8:121:11eb::2]:8333 +[2a01:4f8:121:234d::2]:8333 [2a01:4f8:121:261::2]:8333 -[2a01:4f8:130:242b::10]:8333 -[2a01:4f8:130:242b::5]:8333 -[2a01:4f8:130:2468::3]:8333 +[2a01:4f8:130:11ea::2]:8333 +[2a01:4f8:130:3332::2]:8333 +[2a01:4f8:130:40ab::2]:8333 [2a01:4f8:130:632c::2]:8333 [2a01:4f8:130:6366::2]:8333 -[2a01:4f8:130:6426::2]:8333 [2a01:4f8:130:934f::2]:8333 -[2a01:4f8:131:2070::2]:8333 -[2a01:4f8:131:54a2::2]:8333 -[2a01:4f8:140:80ad::2]:8333 +[2a01:4f8:131:33ad:fea1::666]:8333 +[2a01:4f8:140:2195::2]:8333 +[2a01:4f8:140:6333::2]:8333 +[2a01:4f8:140:930d::2]:8333 +[2a01:4f8:140:93b0::2]:8333 +[2a01:4f8:141:1167::2]:8333 [2a01:4f8:141:186::2]:8333 -[2a01:4f8:150:210b::2]:8333 -[2a01:4f8:150:2263::5]:8333 -[2a01:4f8:150:2349::2]:8333 -[2a01:4f8:150:61ee::2]:8333 -[2a01:4f8:150:7088:5054:ff:fe45:bff2]:8333 +[2a01:4f8:141:53f0::2]:8333 +[2a01:4f8:150:336a::2]:8333 +[2a01:4f8:150:72ee::4202]:8333 [2a01:4f8:150:8324::2]:9001 -[2a01:4f8:151:1d8::2]:8333 +[2a01:4f8:151:21ca::2]:8333 +[2a01:4f8:151:41c2:0:5404:a67e:f250]:8333 [2a01:4f8:151:5128::2]:8333 +[2a01:4f8:151:52c6::154]:8333 [2a01:4f8:151:6347::2]:9001 -[2a01:4f8:161:526d::2]:8333 -[2a01:4f8:161:9349::2]:8333 -[2a01:4f8:162:23c6::2]:8333 -[2a01:4f8:162:4348::2]:8333 -[2a01:4f8:162:7345::2]:8333 -[2a01:4f8:162:7383::2]:8333 -[2a01:4f8:162:74e3::2]:8333 -[2a01:4f8:190:6065::2]:8333 -[2a01:4f8:190:6349::2]:8333 +[2a01:4f8:160:5136::2]:8333 +[2a01:4f8:160:72c5::2858:e1c5]:8333 +[2a01:4f8:160:72c5::593b:60d5]:8333 +[2a01:4f8:160:814f::2]:8333 +[2a01:4f8:161:13d0::2]:8333 +[2a01:4f8:161:228f::2]:8333 +[2a01:4f8:161:51c4::2]:8333 +[2a01:4f8:161:60a7::2]:8333 +[2a01:4f8:161:7026::2]:8333 +[2a01:4f8:161:9184::2]:8333 +[2a01:4f8:162:2108::2]:8333 +[2a01:4f8:162:218c::2]:8333 +[2a01:4f8:162:4443::2]:8333 +[2a01:4f8:162:51a3::2]:8333 +[2a01:4f8:171:b93::2]:8333 +[2a01:4f8:190:1483::1]:8333 +[2a01:4f8:190:4495::2]:8333 [2a01:4f8:190:64c9::2]:8333 [2a01:4f8:190:91ce::2]:8333 [2a01:4f8:191:2194::83]:8333 -[2a01:4f8:191:40a1::2]:8333 -[2a01:4f8:191:4a7::2]:8333 -[2a01:4f8:191:63b4:5000::1]:8333 -[2a01:4f8:191:7121::2]:8333 +[2a01:4f8:191:40e8::2]:8333 +[2a01:4f8:191:44b4::2]:8333 +[2a01:4f8:191:8242::2]:8333 [2a01:4f8:191:83a2::2]:8333 -[2a01:4f8:191:93c4::2]:8333 -[2a01:4f8:192:60a9:0:1:5:2]:8333 -[2a01:4f8:192:73b2::2]:8333 -[2a01:4f8:192:8098::2]:8333 +[2a01:4f8:192:11b2::2]:8333 +[2a01:4f8:192:216c::2]:8333 +[2a01:4f8:192:22b3::2]:8333 +[2a01:4f8:192:440b::2]:8333 [2a01:4f8:192:db::2]:8333 [2a01:4f8:200:1012::2]:8333 -[2a01:4f8:200:22e3::2]:8333 -[2a01:4f8:200:414e::2]:8333 -[2a01:4f8:200:63af::222]:8333 +[2a01:4f8:200:23d1::dead:beef]:8333 +[2a01:4f8:200:506d::2]:8333 +[2a01:4f8:200:51f0::2]:8333 +[2a01:4f8:200:5389::2]:8333 +[2a01:4f8:200:53e3::2]:8333 +[2a01:4f8:200:6344::2]:8333 +[2a01:4f8:200:6396::2]:8333 +[2a01:4f8:200:63af::119]:8333 [2a01:4f8:200:71e3:78b4:f3ff:fead:e8cf]:8333 -[2a01:4f8:201:5164::2]:8333 +[2a01:4f8:201:214c::2]:8333 +[2a01:4f8:201:233:1::3]:8333 +[2a01:4f8:201:3e3::2]:8333 [2a01:4f8:201:6011::4]:8333 [2a01:4f8:201:60d5::2]:8333 +[2a01:4f8:202:265::2]:8333 +[2a01:4f8:202:3115::2]:8333 +[2a01:4f8:202:31e3::2]:8333 +[2a01:4f8:202:31ef::2]:8333 +[2a01:4f8:202:3392::2]:8333 [2a01:4f8:202:53c3::2]:8333 +[2a01:4f8:202:63f4::2]:8333 +[2a01:4f8:202:7227::2]:8333 +[2a01:4f8:210:2227::2]:8333 [2a01:4f8:210:24aa::2]:8333 -[2a01:4f8:210:502f::2]:8333 [2a01:4f8:211:14cf::2]:8333 -[2a01:4f8:211:1a59::2]:8333 -[2a01:4f8:211:2ac1::2]:8333 -[2a01:4f8:211:cca::2]:8333 -[2a01:4f8:a0:22a5::2]:8333 -[2a01:4f8:a0:5023::2]:8333 +[2a01:4f8:211:181b::2]:8333 +[2a01:4f8:212:289e::2]:8333 +[2a01:4f8:212:33db::2]:18333 +[2a01:4f8:a0:112f::2]:8333 +[2a01:4f8:a0:3174::2]:8333 +[2a01:4f8:a0:328c::2]:8333 [2a01:4f8:a0:5243::2]:8333 -[2a01:4f8:a0:74c8::2]:8333 -[2a01:4f8:a0:8227::2]:8333 -[2a01:4f8:a0:822d::2]:8333 -[2a01:4f8:d13:2183::2]:8333 +[2a01:4f8:c17:19b9::2]:8333 +[2a01:4f8:c17:1a41::2]:8333 +[2a01:4f8:c17:1a92::2]:8333 +[2a01:4f8:c17:273::2]:8333 +[2a01:4f8:c17:435::2]:8333 +[2a01:4f8:c17:755::2]:8333 +[2a01:4f8:c17:b54::2]:8333 +[2a01:4f8:d16:9384::2]:8333 [2a01:608:ffff:a009:8bf5:879d:e51a:f837]:8333 -[2a01:79d:469e:ed94:c23f:d5ff:fe65:20c5]:8333 -[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333 +[2a01:680:10:10:f2de:f1ff:fec9:dc0]:8333 +[2a01:7c8:aaac:1f6:5054:ff:fe30:e585]:8333 +[2a01:7c8:aaac:20b:5054:ff:fe24:435e]:8333 +[2a01:7c8:aaac:43d:5054:ff:fe4e:3dd4]:8333 +[2a01:7c8:aaad:256::1]:8333 +[2a01:7c8:aab6:ea:5054:ff:feff:eac3]:8333 +[2a01:7c8:aab9:5a:5054:ff:fe89:7b26]:8333 +[2a01:7c8:aabc:2c8:5054:ff:fe35:6581]:8333 [2a01:7e00::f03c:91ff:fe18:301e]:8333 -[2a01:7e00::f03c:91ff:fe18:7749]:8333 -[2a01:7e00::f03c:91ff:fe33:2d67]:8333 -[2a01:7e00::f03c:91ff:fe33:347c]:8333 -[2a01:7e00::f03c:91ff:fe33:ae50]:8333 -[2a01:7e00::f03c:91ff:fe56:6b5c]:8333 -[2a01:7e00::f03c:91ff:fe56:bee6]:8333 -[2a01:7e00::f03c:91ff:fe69:4895]:8333 -[2a01:7e00::f03c:91ff:fe69:9912]:8333 -[2a01:7e00::f03c:91ff:fe6e:26ee]:8333 -[2a01:7e00::f03c:91ff:fe73:42f1]:8333 +[2a01:7e00::f03c:91ff:fe18:3942]:8333 +[2a01:7e00::f03c:91ff:fe26:8c87]:8333 +[2a01:7e00::f03c:91ff:fe50:6206]:8333 +[2a01:7e00::f03c:91ff:fe67:559d]:8333 [2a01:7e00::f03c:91ff:fe84:434f]:8333 -[2a01:7e00::f03c:91ff:fe84:b36b]:8333 -[2a01:7e00::f03c:91ff:fe89:1faa]:8333 -[2a01:7e00::f03c:91ff:fe98:816]:8333 +[2a01:7e00::f03c:91ff:fe89:1143]:8333 +[2a01:7e00::f03c:91ff:fe98:2505]:8333 [2a01:7e00::f03c:91ff:fedb:352e]:8333 -[2a01:7e00::f03c:91ff:fedb:4a1d]:8333 -[2a01:e34:edbb:6750:224:1dff:fe89:3897]:8333 -[2a01:e35:2f1d:3fb0:7187:c7ba:bcfc:80ce]:8333 -[2a01:e35:8787:96f0:9032:9297:39ae:496d]:8333 +[2a01:7e01::f03c:91ff:fec8:d7b5]:8333 +[2a01:e34:ee33:1640:c504:f677:b28a:ba42]:8333 +[2a01:e35:2e7e:bc0:e079:f55e:cef3:b5d7]:8333 +[2a01:e35:2ee5:610:21f:d0ff:fe4e:7460]:8333 [2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]:8333 -[2a01:e35:8b66:6a0:4900:9dfd:d841:d025]:8333 -[2a02:168:4a01::39]:8333 -[2a02:168:5404:2:c23f:d5ff:fe6a:512e]:8333 -[2a02:180:1:1::5b8f:538c]:8333 -[2a02:2028:1016::2]:8333 -[2a02:2528:503:2::14]:8333 +[2a01:e35:8aca:6a0:211:aff:fe5e:295e]:8333 +[2a02:180:a:18:81:7:11:50]:8333 +[2a02:1810:1d87:6a00:5604:a6ff:fe60:d87d]:8333 +[2a02:2168:1144:5c01:d63d:7eff:fedd:4f8e]:8333 +[2a02:2498:6d7b:7001:b508:b39d:2cea:5b7a]:8333 [2a02:2528:503:2::15]:8333 -[2a02:2528:ff00:81a6:21e:c5ff:fe8d:f9a5]:8333 -[2a02:2770:5:0:21a:4aff:fee4:c7db]:8333 -[2a02:2770:8:0:21a:4aff:fe7b:3dcd]:8333 -[2a02:348:5e:5a29::1]:8333 -[2a02:7aa0:1619::202f:c06a]:8333 -[2a02:8109:8e40:35fc:ba27:ebff:feae:cf16]:8333 -[2a02:af8:6:1500::1:130]:8333 -[2a02:c200:0:10:1:0:6314:2222]:8333 -[2a02:c200:0:10:2:3:3295:1]:8332 -[2a02:c200:0:10:3:0:5449:1]:8333 -[2a02:c200:1:10:2:3:5899:1]:8333 -[2a02:c200:1:10::2705:1]:8333 -[2a02:ce80:0:20::1]:8333 -[2a02:fe0:c321:27e0:6ef0:49ff:fe11:a61d]:8333 +[2a02:2528:fa:1a56:216:44ff:fe6a:d112]:8333 +[2a02:27f8:2012:0:e9f7:268f:c441:6129]:8333 +[2a02:348:86:3011::1]:8333 +[2a02:4780:1:1::1:8a01]:8333 +[2a02:578:5002:116::2]:8333 +[2a02:6080::1:190b:69e3]:8333 +[2a02:6080::1:e893:d9d6]:8333 +[2a02:770:4000::139]:8333 +[2a02:7aa0:1201::deb3:81a2]:8333 +[2a02:8010:b001::5860:59b5]:8333 +[2a02:810d:21c0:f00:a248:1cff:feb8:5348]:8333 +[2a02:a50::21b:24ff:fe93:4e39]:8333 +[2a02:a80:0:1200::2]:8333 +[2a02:c200:0:10:2:1:5830:1]:8333 +[2a02:c200:0:10:2:5:4692:1]:8333 +[2a02:c200:0:10:3:0:7158:1]:8333 +[2a02:c200:0:10::2244:1]:8333 +[2a02:c200:1:10:2:3:3339:1]:8333 +[2a02:c200:1:10:2:3:7844:1]:8333 +[2a02:c200:1:10:2:5:6288:1]:8333 +[2a02:c200:1:10:3:0:5912:1]:8333 [2a03:4000:2:496::8]:8333 -[2a03:b0c0:0:1010::62:f001]:8333 +[2a03:4000:6:8009::1]:8333 +[2a03:4000:6:8063::bcd0]:8333 +[2a03:4900:fffc:b::2]:8333 +[2a03:b0c0:1:d0::d:5001]:8333 +[2a03:f80:ed15:149:154:155:235:1]:8333 +[2a03:f80:ed15:149:154:155:241:1]:8333 [2a03:f80:ed16:ca7:ea75:b12d:2af:9e2a]:8333 +[2a04:1980:3100:1aab:290:faff:fe70:a3d8]:8333 +[2a04:1980:3100:1aab:e61d:2dff:fe29:f590]:8333 +[2a04:2f80:6:200::89]:8333 +[2a04:ac00:1:4a0b:5054:ff:fe00:5af5]:8333 +[2a04:ad80:0:68::35da]:8333 3ffk7iumtx3cegbi.onion:8333 -3hshaantu6ot4upz.onion:8333 -45c5lc77qgpikafy.onion:8333 +3nmbbakinewlgdln.onion:8333 +4j77gihpokxu2kj4.onion:8333 +546esc6botbjfbxb.onion:8333 +5at7sq5nm76xijkd.onion:8333 77mx2jsxaoyesz2p.onion:8333 7g7j54btiaxhtsiy.onion:8333 -b6fr7dlbu2kpiysf.onion:8333 -bitcoincfqcssig5.onion:8333 +a6obdgzn67l7exu3.onion:8333 +ab64h7olpl7qpxci.onion:8333 +am2a4rahltfuxz6l.onion:8333 +azuxls4ihrr2mep7.onion:8333 +bitcoin7bi4op7wb.onion:8333 bitcoinostk4e4re.onion:8333 +bk7yp6epnmcllq72.onion:8333 bmutjfrj5btseddb.onion:8333 -drp4pvejybx2ejdr.onion:8333 -gixnv56d63buypan.onion:8333 +ceeji4qpfs3ms3zc.onion:8333 +clexmzqio7yhdao4.onion:8333 +gb5ypqt63du3wfhn.onion:8333 h2vlpudzphzqxutd.onion:8333 -hhiv5pnxenvbf4am.onion:8333 -lzxpkn6ptp3ohh63.onion:8333 -msphsgfiqfq5stne.onion:8333 +n42h7r6oumcfsbrs.onion:4176 ncwk3lutemffcpc4.onion:8333 okdzjarwekbshnof.onion:8333 -sjdomi4yb2dwkjbc.onion:8333 -uvwozwxlihntigbb.onion:8333 -v6ylz45dn5ybpk4d.onion:8333 +pjghcivzkoersesd.onion:8333 +rw7ocjltix26mefn.onion:8333 +uws7itep7o3yinxo.onion:8333 vk3qjdehyy4dwcxw.onion:8333 vqpye2k5rcqvj5mq.onion:8333 -xudkoztdfrsuyyou.onion:8333 -z55v4ostefnwfy32.onion:8333 +wpi7rpvhnndl52ee.onion:8333 diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 423362859..1406e8680 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,885 +8,943 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xa8,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x1e,0x00,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x60,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x47,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x62,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x66,0x91,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xa0,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0x86,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xa4,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xf9,0x87,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x13,0x2c,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x16,0xe6,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x18,0xa8,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1c,0x23,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x4c,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x40,0x77}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe4,0xa6,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x08,0x69,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x10,0x45,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x66,0x76,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x76,0xa6,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x7a,0x85,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xa6,0x61,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd5,0xeb,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe2,0x6b,0x40}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe4,0xc0,0xab}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0x8c,0x85,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x29,0x28,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x2b,0x65,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb8,0xc3,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xc1,0x8b,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x46,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x03,0x6a,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x3c,0x85,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x55,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x66,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x82,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x3d}, 11101}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x02,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0x84,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xa8,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x02,0x91,0xc9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x16,0x8e,0xd6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x35,0xac,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0xa1,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe6,0x8c,0xa6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe7,0x03,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xff,0x50,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xca,0xe6,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x55,0x0b,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5b,0x61,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5e,0x64,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5f,0x63,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x73,0x08,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x7f,0x80,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x9a,0xb2,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xcf,0x67,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xcf,0x68,0x69}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd2,0xe6,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe0,0x12,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xf6,0xa8,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0xfe,0x40,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x06,0x47,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x06,0x47,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x0e,0x86,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x1e,0x24,0xdc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xa4,0x06,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xaa,0x6a,0xcb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb9,0x86,0xc9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x80,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x80,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xdb,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x61,0x84,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa0,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa9,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8b,0x20,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xdd,0xa3,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x82,0xc0,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x29,0x4b,0x60,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x03,0x00,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x48,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x60,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x04,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x00,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x50,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x61,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x84,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x15,0x61,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcd,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xce,0xbc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1d,0x14,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x32,0xea,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xa0,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa1,0x23}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa1,0x67}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb6,0x84,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xdf,0x24,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xda,0xe3,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe2,0x6d,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa5,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa5,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xea,0x68,0x30}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xef,0x6b,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf9,0x27,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfa,0x62,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf4,0x00,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfe,0x48,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x05,0x0d,0x2c}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0x25,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x51,0x35,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x73,0x2b,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x14,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x21,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7d,0xa7,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8f,0x09,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xbc,0xc0,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x4d,0xa2,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x99,0x61,0x6d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0xc0,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0x69,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0xa7,0xc4,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0x1d,0xe3,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x1e,0x25,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x27,0x69,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x6a,0x28,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x1d,0x00,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x4c,0xc0,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x98,0xc0,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x40,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xaf,0xa0,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc7,0x80,0x00}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xab,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0xa1,0xee,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0xfb,0xc3,0xdd}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x23,0xe1,0x13}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xca,0x00,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x42,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xc0,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x4a,0x62,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x41,0x27,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6b,0xc8,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x85,0xc2,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb5,0xee,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb7,0x16,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x55,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xa2,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xee,0x22,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x19,0xab,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1b,0xa6,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x35,0x89,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x47,0x48,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x53,0xe1,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x79,0x03,0xa3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xcb,0x66,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe5,0x8e,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x1e,0x03,0x07}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x5e,0x83,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0xbc,0x88,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x0b,0xa2,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x17,0xe4,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x5a,0x89,0x59}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x76,0x85,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x87,0x0a,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x96,0x69,0x4d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xac,0x0a,0x04}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfa}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xd7,0xc0,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x3c,0x62,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa4,0x23,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xbf,0xa2,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0xc3,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xe7,0x61,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf0,0xed,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x9f,0x0d,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcd,0x4a,0xce}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdd,0xc1,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe4,0xa2,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x32,0x43,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x3e,0x03,0xcb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe3,0x48,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x41,0x78,0x35}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x41,0xcd,0xe2}, 9000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x6a,0x2a,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x96,0xb5,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc4,0xc4,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xe0,0xc2,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2e,0x05,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xab,0xee}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2b,0x98}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x41,0x29,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x8f,0x01,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x92,0x62,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xf6,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x06,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfb,0xd0,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x01,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x09,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x02,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xe4,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0x0b,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0xc1,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xcd,0xe8,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xec,0xc8,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x18,0x49,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x90,0x04,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0x31,0xc7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xab,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x41,0x29,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x71,0x62,0x3d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x77,0x61,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x92,0x46,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc1,0x47,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x2e,0x0a,0xed}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x50,0xc8,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0xb9,0x61,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xfe,0xa0,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x1c,0xcb,0x05}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x82,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x35,0x6f,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x53,0xc2,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x80,0x20,0xa7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb3,0x88,0x50}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xeb,0x26,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1f,0xab,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x20,0x89,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x89,0x85,0xee}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xc0,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xbe,0x02,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xc3,0xc0,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xde,0x23,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x52,0xe9,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x55,0x42,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x65,0xe0,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x71,0x45,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x7a,0xeb,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x44,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xd0,0xa4,0xdb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x64,0x25,0x7a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x91,0x95,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xa8,0x22,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x14,0x2c,0xf0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x64,0x46,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xa8,0x03,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xba,0x8c,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x5c,0x44,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6d,0x65,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6e,0x0b,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf2,0x6c,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x60,0x96}, 9020}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x32,0x2c,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x48,0x3c,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x50,0xea,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xe9,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x70,0xe9,0x80}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x76,0xa6,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x8c,0x00,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x9f,0xf0,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xae,0x05,0x1a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x48,0xa0,0xfc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x48,0xa0,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4a,0xaa,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4f,0xc9,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xaf,0xa6,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xb3,0x69,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x44,0x25,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xea,0x31,0xc4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf7,0xe5,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x18,0x48,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2f,0x20,0x93}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x54,0x64,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x79,0x45,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xa7,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc1,0x60,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x13,0x25,0xb3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x85,0x2b,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0x4c,0x99}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa9,0x22,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xbc,0x07,0x4e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd9,0xe2,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdf,0x64,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x81,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x01,0xad,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x86,0xc9,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa9,0x23,0xeb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x39,0xe3,0x0e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x40,0x41,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x56,0x5c,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xcb,0x97}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x65,0x20,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xa1,0xb2,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x81,0xaa}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0b,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x10,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x42,0x6f,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x8c,0x2b,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xae,0xf7,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb8,0x05,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xbb,0x45,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe6,0x03,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x2a,0x80,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x4a,0xe2,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x8e,0x4b,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0b,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x11,0x11,0x28}, 9333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x1e,0x27,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x5a,0x24,0x07}, 9444}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x88,0xe0,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa2,0xe7,0xd3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb8,0x00,0x8f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xc6,0x80,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x0b,0x21,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x4f,0x80,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x76,0xe9,0x6f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x87,0x8b,0x1e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc8,0xcd,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6a,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6c,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xee,0x7c,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xf2,0x00,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x4c,0x7b,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6c,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x29,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8e,0xc5,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x13}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xc4,0xc0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xea,0xe0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xaa,0x68,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xb7,0x11,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe3,0xad,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe6,0x05,0x0f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe9,0x69,0x97}, 443}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfa,0x85,0x9e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xff,0x42,0x76}, 8334}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2d,0x62,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2f,0xa1,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xc0,0x83}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa9,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf5,0x47,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x04,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x18,0x45,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0xc1,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2d,0x62,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x36,0x80,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xc8,0x18}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xc6,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xe6,0x04,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x5f,0xe4,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x5f,0xe4,0x7b}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x72,0x80,0x86}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x9f,0xed,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xa6,0x82,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x42,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xc3,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xe5,0x00,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x60,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0x8f,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0xfb,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x18,0xb9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xea,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x76,0x60,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x91,0x0c,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x9f,0xaa,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xa8,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x4f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x93,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xf3,0xa8,0x04}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x01,0x00,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x4f,0x4d,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x5b,0x9c,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x55,0x4b,0x98}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x57,0x01,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x57,0x5c,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x59,0x45,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x48,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa4,0x75,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x20,0x83}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xca,0xe6,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0xc1,0x9a}, 8343}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0xc2,0xe2}, 8343}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x01,0x0b,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x24,0xeb,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x43,0x60,0x02}, 15321}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x10,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6c,0x48,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x9c,0x23,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x21,0xed}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0xa0,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xf8,0xa4,0x40}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x95,0xc1,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x4d,0xef,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x0a,0x9b,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x2e,0x65,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe0,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xae,0xf8,0x14}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xca,0xe7,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x4b,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x95,0x26,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0xa9,0x6a,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x40,0x65,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x41,0xc4,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x50,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x7e,0x4d,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x26,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x9c,0x61,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x91,0x4c,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0x96,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc0,0x89,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc4,0xaa,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x2c,0x85}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcf,0x44,0x90}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd2,0x69,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd3,0x66,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd3,0x6a,0x22}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0x83,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe9,0x17,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0d,0x60,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0e,0x4a,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0x2b,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xde,0x47,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe0,0x8c,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4c,0x0e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xdd,0xe4,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x48,0xa7,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x7b,0xae,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb5,0x2d,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x33,0xa7,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xf7,0xe5,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x54,0x72,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x71,0x24,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbc,0xe0,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4b,0xef,0x45}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xd6,0x02,0x4a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe0,0xa2,0x41}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xc6,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x41,0x48,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0xa2,0x5f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5a,0x8b,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x31,0x1b}, 8005}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd7,0x2f,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x17,0x43,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2c,0xa6,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x5d,0xe1,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1a,0x00,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1b,0xe1,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xe5,0x75,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xf9,0x44,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x05,0x9b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x65,0xf0,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xec,0xc6,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0x8a,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5f,0xa8,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x6e,0xea,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x82,0x09,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa5,0xa8,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xaa,0xeb,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x82,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2e,0x44,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x7f,0xca,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4c,0xab,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xa0,0xa0,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x7e,0xc5,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xc6,0xad,0x01}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x64,0xae,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0xfb,0xcb,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x03,0x3c,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0xa4,0xc9,0xd0}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x24,0x53,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x25,0x81,0x16}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x36,0xc0,0xfb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe1,0xdf}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe4,0xfc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe6,0xb9}, 8334}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x82,0xa1,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x21,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x9c,0x6f,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xa7,0x6f,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc1,0x28,0xf8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x07,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x08,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdf,0x01,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x61,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0xc0,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x9b,0x2d,0xc9}, 8334}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc2,0x1c,0xc3}, 8663}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xd3,0x01,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdd,0x26,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x09,0x4f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x81,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0xba,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0xc2,0x0f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x80,0xd6}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x82,0xb6}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x26,0xea,0x54}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x24,0xcc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0x43}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x02,0x06}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x28,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x9b,0x6c,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xa1,0xb6,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x42,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbe,0x80,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x0d,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xb5,0xfa,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x65,0x6f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x6a,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x10,0x02,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x46,0x04,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa2,0x23,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbf,0x27,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x0c,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa1,0x81,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc1,0xa0,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc5,0x0d,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0x07,0xf8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x6a,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xee,0x51,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x72,0x4c,0x93,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1c,0xe0,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x44,0x6e,0x52}, 18333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x61,0x4f,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xbd,0xcf,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe4,0x60,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x93,0xb2,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x29,0x7b,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x43,0x05,0xe6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x6b,0x8f,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x02,0xaa,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x6e,0x41,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xc1,0x8b,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0xef,0xa0,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x65,0xa2,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xec,0x89,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xfb,0xa1,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x41,0xe7,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xa6,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x9f,0x2a,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x12,0x49,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x43,0xc9,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x64,0x56,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x6e,0x68,0x98}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe0,0x40,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x37,0xc1,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x6a,0xa9,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xcb,0xae,0x0f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xff,0xe8,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0x94,0xa5,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0xe8,0x8d,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x1e,0x5c,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x27,0x8d,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x54,0xa7,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x6f,0x49,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x8c,0xe5,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0x6b,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xc0,0x99}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x7f,0x26,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x8c,0xe0,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0x65,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xe9,0xe0,0x23}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xfd,0x03,0xc1}, 20020}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x59,0xa0,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x48,0x8b,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xbf,0x70,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0x01,0x86,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x13,0x84,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x29,0x02,0xac}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0x80,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0xd9,0x0c,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb4,0xe4,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x90,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xff,0x49,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xda,0xe9,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xf9,0x80,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x88,0x9f,0xea,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xa0,0xb0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xa2,0x02,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xa2,0x17,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x86,0x45,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa2,0xd7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x7a,0xa3,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x03,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0xff,0x04,0x5e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x00,0x20,0x65}, 8337}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0xe5,0x0d,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0xa2,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x53,0x48,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0x67,0x1c,0x44}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x05,0x20,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0xa4,0xc3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x96,0x65,0xa3,0xf1}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xec,0x0b,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x42,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x98,0x03,0x88,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0xd0,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0xb5,0x68,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x60,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x24,0x82,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x01,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6a,0x7b}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd2,0xc6,0xb8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xda,0x41,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xde,0xa1,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x3a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x63,0xa4}, 53011}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0x23,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x0f,0x0a,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x28,0x86,0xab}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfb,0x6c,0x35}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x2c,0x02,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0x24,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0xe6,0x47,0x43}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0xa1,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x67,0xc3,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x90,0x1b,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x9e,0x81,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaa,0x4b,0xa2,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x5a,0x63,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0xf5,0x05,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x17,0xa6,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0x24,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0xa9,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x5d,0x81,0xdc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0x37,0x63,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0xe4,0x42,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x09,0xa9,0xf2}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x20,0x0b,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x22,0xcb,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xab,0x01,0x34}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xaf,0x88,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xe6,0xe4,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf7,0xc1,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x31,0x84,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x34,0xca,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x35,0x4c,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x0c,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x23,0xb6,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x71}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x3a,0x60,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x79,0x4c,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xe6,0xe4,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf6,0x6b,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xfe,0xeb,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x00,0x80,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x19,0x82,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x32,0x40,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x8c,0xe8,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x25,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x2e,0x09,0x60}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x27,0x10,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x11,0xad,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x05,0xf8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x46,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x6f,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4c,0xa9,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4f,0x83,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc7,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xcb,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4f,0xa0,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa9,0xce,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xc1,0xea,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xc7,0x60,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x12,0x60}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x8f,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0xd0,0x9c,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0xc8,0x80,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x4e,0xa9,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x60,0x60,0x98}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x49,0xa0,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x98,0x44,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x07,0x23,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1c,0x4c,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1f,0xa0,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x42,0x8c,0x0f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0xdc,0x65,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x1a,0x05,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x4b,0x88,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x78,0xc2,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x79,0x05,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x00,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xff,0x29,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0xd2,0x22,0x3a}, 9801}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0x5c,0xe2,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xab,0xf6,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x17,0x08,0x09}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x3a,0xa2,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x9a,0x09,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x08,0xee,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x18,0x61,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1f,0x89,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2c,0x40}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x80,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x81,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x81,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x81,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x52,0xcb,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x14,0x61,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7e,0x08,0x0e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x21,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0x00,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x9b,0x88,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0xe5,0x70}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xb6,0x6c,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xbf,0x61,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xc6,0x66}, 8001}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x09,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x4b,0x8f,0x90}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x8b,0x66,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbf,0xed,0x40,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x83,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0xe1,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x6e,0xa0,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xe1,0xae}, 8010}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf2,0xab,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf3,0x04,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x09,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x0a,0x93}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x51,0xa0,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x55,0xc9,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x22,0xe3,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4d,0xbd,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x7c,0xe0,0x07}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x92,0x89,0x01}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xb7,0xc6,0xcc}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xce,0xca,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x0c,0xee,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5b,0xc8,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xea,0xe1,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x06,0xe9,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3f,0x8f,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x7e,0x64,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x86,0x63,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0xe2,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x29,0xe5,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x29,0xe5,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x31,0x2b,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x93,0x47,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xb3,0x41,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xb7,0x63,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xc0,0x25,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xea,0xe0,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3a,0x6c,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xbb,0x60,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xff,0x1f,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x24,0x06,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x3a,0xee,0xf3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,0xc7,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd0,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xef,0x01,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,0xc4,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0xc0,0xa0}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd2,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3e,0x6d,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x54,0xc3,0xb3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xad,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xcc,0xe0,0x6a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xb4,0x86,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x07,0x60,0x63}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc9,0xa0,0x6a,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x37,0x57,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x7c,0x6d,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x1e,0xc5,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x58,0xa0,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc9,0x6e,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xea,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x74,0x62,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x46,0x12}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x97,0x8c,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0x93,0x28,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xeb,0x27,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x0c,0x40,0xe1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x70,0xcb,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xc8,0xf7,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe2,0x8d,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xff,0x2a,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x35,0xa4,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x44,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x44,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x47,0xab,0xe8}, 8341}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4c,0xc8,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x28,0x60,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x6b,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8d,0x28,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x4b,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xd0,0x6f,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x36,0x22,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x52,0x62,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x55,0xc1,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6f,0x30,0x29}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6f,0x30,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x22,0xe8,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x51,0x09,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x5a,0xe0,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x5a,0xe0,0x04}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x62,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x88,0x48,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc5,0x0d,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0xe3,0x08}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x33,0x90,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x70,0x21,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x74,0x48,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xe9,0x7f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x7e,0x0e,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x9f,0x2c,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x05,0x24,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x39,0x21,0x0a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6f,0xc4,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x7a,0x6b,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x4b,0xaf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x49,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9b,0x03,0xd8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9b,0x07,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x56,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa7,0x11,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xdf,0x8a,0x0d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x0f,0x4e,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x73,0xeb,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x7e,0xe2,0xa6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x91,0x43,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x26,0x81,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x30,0xa8,0x08}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xa9,0x8d,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf9,0x5c,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf5,0xce,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf9,0xcc,0xa1}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0b,0xe1,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0c,0x22,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0c,0xca,0x21}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x14,0xab,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x19,0x09,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x28,0xe2,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x7b,0x62,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9b,0x24,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x01,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x0b,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x6f,0x42,0x4f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9b,0xca,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9e,0x09,0x66}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x20,0x12}, 20993}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x3d,0xc4,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xe7,0xcd,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x4d,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xe2,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xc5,0xcb,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xff,0xa6,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xf5,0xc4,0x25}, 8333}, {{0x20,0x01,0x12,0x91,0x02,0xbf,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00}, 8333}, - {{0x20,0x01,0x14,0x18,0x01,0x00,0x05,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x16,0xd8,0xdd,0x24,0x00,0x00,0x86,0xc9,0x68,0x1e,0xf9,0x31,0x02,0x56}, 8333}, - {{0x20,0x01,0x19,0xf0,0x16,0x24,0x00,0xe6,0x00,0x00,0x00,0x00,0x57,0x9d,0x94,0x28}, 8333}, - {{0x20,0x01,0x19,0xf0,0x03,0x00,0x13,0x40,0x02,0x25,0x90,0xff,0xfe,0xc9,0x2b,0x6d}, 8333}, - {{0x20,0x01,0x19,0xf0,0x40,0x09,0x14,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64}, 8333}, - {{0x20,0x01,0x1b,0x40,0x50,0x00,0x00,0x2e,0x00,0x00,0x00,0x00,0x3f,0xb0,0x65,0x71}, 8333}, + {{0x20,0x01,0x16,0x20,0x0f,0x00,0x02,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x16,0x20,0x0f,0x00,0x82,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x19,0xf0,0x50,0x00,0x8d,0xe8,0x54,0x00,0x00,0xff,0xfe,0x12,0x55,0xe4}, 8333}, + {{0x20,0x01,0x19,0xf0,0x6c,0x00,0x91,0x03,0x54,0x00,0x00,0xff,0xfe,0x10,0xa8,0xd3}, 8333}, + {{0x20,0x01,0x1b,0x60,0x00,0x03,0x01,0x72,0x14,0x2b,0x6d,0xff,0xfe,0x7a,0x01,0x17}, 8333}, {{0x20,0x01,0x04,0x10,0xa0,0x00,0x40,0x50,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333}, - {{0x20,0x01,0x04,0x10,0xa0,0x02,0xca,0xfe,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0x54,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6a,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x20,0x01,0x41,0x28,0x61,0x35,0x20,0x10,0x02,0x1e,0x0b,0xff,0xfe,0xe8,0xa3,0xc0}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x07,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x7c}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0x45,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6c,0xd3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0x8b,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xa3,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xb8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xaf,0xda,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8200}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xb2,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc1,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc8,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xdd,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xe2,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf5,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf7,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xff,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x2f,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x10,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0x37,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8200}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x3e,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x86,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x47,0x97,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x53,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0x9c,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x9d,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0xa2,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xad,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xb7,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xee,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xa3,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xb2,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xc1,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x0c,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xc9,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0xf1,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xfa,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x36}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xa1}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x5f}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0c,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xf5}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc0}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0xf2}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0x10,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0x4a,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x7c}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xe2}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x3e,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x62,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x08,0x67,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xb7,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xc3,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd2,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd5,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xb3,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbe,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd9,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x08,0xeb,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x16,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x13,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x2b,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x3a,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x49,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x05,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x5c,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x2d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x45,0x58,0x00,0x00,0x00,0x00,0x1d,0xf2,0x76,0xd3}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x4a,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x63,0x5b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x63,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x6c,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0xf4,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0b,0x08,0x54,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x11,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x44,0xb8,0x41,0x16,0x78,0x01,0x42,0x16,0x7e,0xff,0xfe,0x78,0x3f,0xe4}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x08,0x08,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x08,0x0c,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x09,0x0b,0xca,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x0f,0x02,0x2d,0x00,0x00,0x00,0x00,0x02,0x12,0x00,0x26}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0xf9,0xcd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x20,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0e,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0xfc,0x8c,0xa2,0x00,0x7a,0x24,0xaf,0xff,0xfe,0x9d,0xc6,0x9b}, 8333}, + {{0x20,0x01,0x41,0xf0,0x00,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, + {{0x20,0x01,0x41,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x44,0xb8,0x41,0xbd,0x61,0x01,0x14,0x8e,0x40,0x22,0x49,0x50,0xe8,0x61}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x01,0x02,0xf9,0x00,0x00,0x00,0x01,0x10,0x7a,0xa3,0x01}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x0b,0x0a,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0x1f,0x11,0x12,0xd5,0x00,0x00,0x00,0x00,0x0a,0xe1,0x56,0x11}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x14,0x05,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0x1f,0x14,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x15,0x05,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x15,0x0d,0xda,0x3d,0x9a,0x3f,0x11,0x9a,0x56,0xed,0x64}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x25,0x04,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x25,0x00,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x04,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x27,0x00,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x41,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x50,0x7d,0x00,0x00,0x6a,0xb5,0x99,0xff,0xfe,0x73,0xac,0x18}, 8333}, + {{0x20,0x01,0x04,0x70,0x58,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a}, 8333}, {{0x20,0x01,0x04,0x70,0x00,0x5f,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x32}, 8333}, {{0x20,0x01,0x04,0x70,0x00,0x66,0x01,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x67,0x03,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71}, 8333}, {{0x20,0x01,0x04,0x70,0x6c,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xfe}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, 8333}, - {{0x20,0x01,0x04,0x70,0x90,0xa7,0x00,0x96,0x00,0x00,0x00,0x00,0x0a,0xfe,0x60,0x21}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x6f,0x03,0x27,0x91,0x3b,0x07,0xfe,0x85,0x45,0xa4,0xf5}, 8333}, + {{0x20,0x01,0x04,0x70,0x7d,0xda,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x04,0x70,0x95,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0xb1,0xd0,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00}, 8333}, - {{0x20,0x01,0x04,0x70,0xc1,0xf2,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01}, 8333}, {{0x20,0x01,0x04,0x70,0xd0,0x0d,0x00,0x00,0x36,0x64,0xa9,0xff,0xfe,0x9a,0x51,0x50}, 8333}, - {{0x20,0x01,0x04,0x70,0xe2,0x50,0x00,0x00,0x02,0x11,0x11,0xff,0xfe,0xb9,0x92,0x4c}, 8333}, - {{0x20,0x01,0x48,0x00,0x78,0x17,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x04,0xdc,0x52}, 8333}, - {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x04,0x78,0x09}, 8333}, + {{0x20,0x01,0x04,0x70,0xfa,0xb7,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc8,0x28}, 8333}, + {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc9,0xa0}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x19,0x00,0x74,0xb7,0x45,0xb9,0xd5,0xff,0x10,0xa6,0x1a}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x19,0x00,0x74,0xb7,0x45,0xb9,0xd5,0xff,0x10,0xaa,0xec}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x28,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x10,0x13,0x25}, 8333}, + {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x20,0xf0,0x23}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0x30,0xd7,0x17,0x75,0xff,0x20,0x18,0x58}, 8333}, + {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x6c,0x26}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x02,0x56}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x03,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x2d,0xe8}, 8333}, {{0x20,0x01,0x48,0x30,0x11,0x00,0x02,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x4b,0xa0,0xff,0xf7,0x01,0x81,0xde,0xad,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x4b,0x98,0x0d,0xc2,0x00,0x41,0x02,0x16,0x3e,0xff,0xfe,0x56,0xf6,0x59}, 8333}, {{0x20,0x01,0x4b,0xa0,0xff,0xfa,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 8333}, - {{0x20,0x01,0x4b,0xa0,0xff,0xff,0x01,0xbe,0x00,0x01,0x10,0x05,0x00,0x00,0x00,0x01}, 8335}, - {{0x20,0x01,0x4c,0x48,0x01,0x10,0x01,0x01,0x02,0x16,0x3e,0xff,0xfe,0x24,0x11,0x62}, 8333}, - {{0x20,0x01,0x4d,0xd0,0xf1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32}, 8333}, + {{0x20,0x01,0x4b,0xa0,0xff,0xff,0x01,0xbe,0x00,0x01,0x10,0x05,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x86,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9a,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 8333}, - {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9c,0x55,0xc2,0x3f,0xd5,0xff,0xfe,0x6c,0x7e,0xe9}, 8333}, {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xc7}, 8333}, - {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x01}, 8333}, - {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xdf}, 8333}, - {{0x20,0x01,0x05,0xc0,0x15,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, {{0x20,0x01,0x06,0x10,0x1b,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, - {{0x20,0x01,0x06,0x20,0x05,0x00,0xff,0xf0,0xf2,0x1f,0xaf,0xff,0xfe,0xcf,0x91,0xcc}, 8333}, - {{0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0x00,0xad,0x8d,0xe2,0xf7,0xe2,0xc7,0x84}, 8333}, - {{0x20,0x01,0x06,0x7c,0x21,0xec,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b}, 8333}, - {{0x20,0x01,0x06,0xf8,0x12,0x96,0x00,0x00,0x76,0xd4,0x35,0xff,0xfe,0xba,0x1d,0x26}, 8333}, - {{0x20,0x01,0x08,0x40,0xf0,0x00,0x42,0x50,0x3e,0x4a,0x92,0xff,0xfe,0x6d,0x14,0x5f}, 8333}, + {{0x20,0x01,0x06,0x10,0x06,0x00,0x0a,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x06,0x7c,0x26,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x08,0xd8,0x08,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x01,0xae}, 8333}, - {{0x20,0x01,0x09,0x80,0xef,0xd8,0x00,0x00,0x00,0x21,0xde,0x4a,0x27,0x09,0x09,0x12}, 8333}, - {{0x20,0x01,0x09,0x81,0x00,0x46,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, - {{0x20,0x01,0x09,0x81,0x93,0x19,0x00,0x02,0x00,0xc0,0x00,0xa8,0x00,0xc8,0x00,0x08}, 8333}, - {{0x20,0x01,0x09,0xd8,0xca,0xfe,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91}, 8333}, - {{0x20,0x01,0x0a,0xd0,0x00,0x01,0x00,0x01,0x26,0xbe,0x05,0xff,0xfe,0x25,0x95,0x9d}, 8333}, + {{0x20,0x01,0x08,0xd8,0x09,0x65,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x93,0x43}, 8333}, + {{0x20,0x01,0x09,0x80,0x46,0x50,0x00,0x01,0x02,0xe0,0x53,0xff,0xfe,0x13,0x24,0x49}, 8333}, + {{0x20,0x01,0x09,0x81,0x00,0x46,0x00,0x01,0xba,0x27,0xeb,0xff,0xfe,0x5b,0xed,0xee}, 8333}, + {{0x20,0x01,0x09,0xc8,0x53,0xe9,0x36,0x9a,0x02,0x26,0x2d,0xff,0xfe,0x1b,0x74,0x72}, 8333}, + {{0x20,0x01,0x09,0xd8,0xca,0xfe,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87}, 8333}, + {{0x20,0x01,0x0b,0x10,0x00,0x11,0x00,0x21,0x3e,0x07,0x54,0xff,0xfe,0x48,0x72,0x48}, 8333}, {{0x20,0x01,0x0b,0xa8,0x01,0xf1,0xf3,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x0b,0xc8,0x38,0x1c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x02,0x17,0x5c,0x4c,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x5c,0x4c,0xaa}, 8333}, - {{0x20,0x02,0x44,0x04,0x82,0xf1,0x00,0x00,0x8d,0x55,0x8f,0xbb,0x15,0xfa,0xf4,0xe0}, 8333}, - {{0x20,0x02,0x44,0x75,0x22,0x33,0x00,0x00,0x02,0x1f,0x5b,0xff,0xfe,0x33,0x9f,0x70}, 8333}, - {{0x20,0x02,0x59,0x6c,0x48,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x6c,0x48,0xc3}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x23,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x34,0x27,0x01,0x01,0x7a,0x4f,0x08,0xbe,0x26,0x11,0x6e,0x79}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x35,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0c,0xc0,0xa0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x1d}, 8333}, + {{0x20,0x01,0x0e,0x42,0x01,0x02,0x12,0x09,0x01,0x53,0x01,0x21,0x00,0x76,0x01,0x71}, 8333}, + {{0x20,0x02,0x17,0xea,0x14,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0xea,0x14,0xeb}, 8333}, + {{0x20,0x02,0x02,0xf8,0x2b,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xf8,0x2b,0xc5}, 8333}, + {{0x20,0x02,0x40,0x47,0x48,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x47,0x48,0x2c}, 8333}, + {{0x20,0x02,0x45,0xc3,0x8c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0xc3,0x8c,0xca}, 8333}, + {{0x20,0x02,0x46,0xbb,0x8a,0x41,0x00,0x00,0x02,0x26,0xb0,0xff,0xfe,0xed,0x5f,0x12}, 8888}, + {{0x20,0x02,0x46,0xbb,0x8c,0x3c,0x00,0x00,0x8d,0x55,0x8f,0xbb,0x15,0xfa,0xf4,0xe0}, 8765}, + {{0x20,0x02,0x4c,0x48,0xa0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x48,0xa0,0xfe}, 8333}, + {{0x20,0x02,0x4d,0x44,0x25,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x44,0x25,0xc8}, 8333}, + {{0x20,0x02,0x50,0x5f,0xaa,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x5f,0xaa,0xa2}, 8333}, + {{0x20,0x02,0x5b,0xc1,0x79,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0xc1,0x79,0x9d}, 8333}, + {{0x20,0x02,0x6d,0xec,0x54,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0xec,0x54,0x72}, 8333}, {{0x20,0x02,0x8c,0x6d,0x65,0x21,0x96,0x17,0x12,0xbf,0x48,0xff,0xfe,0xd8,0x17,0x24}, 8333}, - {{0x20,0x02,0xa6,0x46,0x5e,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02}, 8333}, + {{0x20,0x02,0xac,0x52,0x94,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x52,0x94,0xe2}, 8333}, + {{0x20,0x02,0xaf,0x7e,0x3e,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x7e,0x3e,0xca}, 8333}, {{0x20,0x02,0xb0,0x09,0x20,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x09,0x20,0xc5}, 8333}, + {{0x20,0x02,0xc0,0x6f,0x39,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x6f,0x39,0xa0}, 8333}, + {{0x20,0x02,0xc2,0x3a,0x73,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x3a,0x73,0x8a}, 8333}, + {{0x20,0x02,0xc7,0x0f,0x74,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0x0f,0x74,0x42}, 8333}, + {{0x20,0x02,0xce,0xc5,0xbe,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xc5,0xbe,0x4f}, 8333}, + {{0x20,0x02,0xd1,0x49,0x9e,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x49,0x9e,0x3a}, 8333}, + {{0x20,0x02,0xd9,0x17,0x0c,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x17,0x0c,0xa5}, 8333}, + {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x15,0x3f}, 8333}, {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x82,0x3e}, 8333}, - {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x70,0xd1,0x64}, 8333}, - {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0x97,0x61}, 8333}, - {{0x24,0x03,0x42,0x00,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, 8333}, - {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x04,0x0a,0xe9,0xff,0xfe,0x5f,0x94,0xc1}, 8333}, - {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x98,0x79,0x17,0xff,0xfe,0x6a,0xa5,0x9f}, 8333}, + {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xa8,0x19,0x34}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0xd6}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x42,0x80}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x66,0x0f}, 8333}, + {{0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x05,0x59}, 8333}, + {{0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x0a,0x7d}, 8333}, + {{0x24,0x05,0xaa,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x59,0xb2}, 8333}, - {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0xa4,0xb1}, 8333}, - {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x29,0x73}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xbf,0xb6}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x88,0xe3}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x72,0x97}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x8a,0x6e}, 8333}, {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x6a,0xdf}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0xe2,0x17}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x1b,0x31}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2f,0xe1}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xa0,0x3f}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0xb8}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x3b,0x1f,0x76}, 8333}, {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5e,0x06}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xd6,0x45}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0xa3,0xdc}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0xa6,0x59}, 8333}, - {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x6f,0x0b}, 8333}, - {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xf6,0xfb}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x61,0x28,0x9b}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x89,0xe9}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0xac,0x15}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x68,0xbb}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0x07,0x13}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0x9e}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x97,0xd8}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x8f,0xeb}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0xda,0x80}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0x9b}, 8333}, {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5f,0xa7}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x0d,0x2e}, 8333}, {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x18,0x03}, 8333}, - {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x4a,0xc0}, 8333}, - {{0x26,0x01,0x00,0x06,0x48,0x00,0x04,0x7f,0x1e,0x4e,0x1f,0x4d,0x33,0x2c,0x3b,0xf6}, 8333}, - {{0x26,0x01,0x00,0x0d,0x54,0x00,0x0f,0xed,0x8d,0x54,0xc1,0xe8,0x7e,0xd7,0xd4,0x5e}, 8333}, - {{0x26,0x02,0x01,0x00,0x4b,0x8f,0x6d,0x2a,0x02,0x0c,0x29,0xff,0xfe,0xaf,0xc4,0xc2}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x4b,0xbe}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xe4,0x4e,0x16}, 8333}, + {{0x26,0x01,0x01,0x8d,0x83,0x00,0x58,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xe4}, 8333}, + {{0x26,0x01,0x02,0x40,0x46,0x00,0x40,0xc0,0x02,0x50,0x56,0xff,0xfe,0xa4,0x63,0x05}, 8333}, + {{0x26,0x01,0x05,0x81,0xc2,0x00,0xa7,0x19,0x54,0x2c,0x9c,0xd5,0x48,0x52,0xf7,0xd9}, 8333}, + {{0x26,0x01,0x06,0x47,0x49,0x00,0x85,0xf1,0xca,0x2a,0x14,0xff,0xfe,0x51,0xbb,0x35}, 8333}, + {{0x26,0x01,0x00,0xc2,0xc0,0x02,0xb3,0x00,0x54,0xa0,0x15,0xb5,0x19,0xf7,0x53,0x0d}, 8333}, + {{0x26,0x02,0x03,0x06,0xcc,0xff,0xad,0x7f,0xb1,0x16,0x52,0xbe,0x64,0xba,0xdb,0x3a}, 8333}, + {{0x26,0x02,0x00,0xae,0x19,0x82,0x94,0x00,0x08,0x46,0xf7,0x8c,0x0f,0xec,0x4d,0x57}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x2d,0x61}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x92,0x11}, 8333}, + {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0xd5,0xc1,0xc3}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc5,0xb8,0x44}, 8333}, {{0x26,0x02,0xff,0xe8,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x57,0x93,0x6b}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x01,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0xd4}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x06,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x7d}, 8333}, + {{0x26,0x02,0xff,0xe8,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x9d,0x20,0x2e,0x3c}, 8333}, {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x8b}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xae}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x02,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0xc8}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x68}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xec}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x09,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe9,0x57}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x0a,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0xcb}, 8333}, {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc4,0xd9,0xfd}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x06,0xae,0x32}, 8333}, {{0x26,0x04,0x00,0x00,0x00,0xc1,0x01,0x00,0x1e,0xc1,0xde,0xff,0xfe,0x54,0x22,0x35}, 8333}, {{0x26,0x04,0x01,0x80,0x00,0x01,0x01,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xa9}, 8333}, - {{0x26,0x04,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb2,0x08,0x03,0x98}, 8333}, - {{0x26,0x04,0x28,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x72,0x0a,0xed}, 8333}, + {{0x26,0x04,0x01,0x80,0x00,0x03,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0xde}, 8333}, {{0x26,0x04,0x40,0x80,0x11,0x14,0x00,0x00,0x32,0x85,0xa9,0xff,0xfe,0x93,0x85,0x0c}, 8333}, - {{0x26,0x04,0x7c,0x00,0x00,0x17,0x03,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x4d}, 8333}, - {{0x26,0x04,0x9a,0x00,0x21,0x00,0xa0,0x09,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x2a,0x40,0x01}, 8333}, - {{0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,0x52,0xf0,0x01}, 8333}, - {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xe4,0xfc,0xca}, 8333}, - {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xf5,0xbc,0x21}, 8333}, - {{0x26,0x05,0x79,0x80,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x17,0x61,0x3d,0x4e}, 8333}, - {{0x26,0x05,0xe0,0x00,0x14,0x17,0x40,0x68,0x02,0x23,0x32,0xff,0xfe,0x96,0x0e,0x2d}, 8333}, + {{0x26,0x04,0x60,0x00,0xff,0xc0,0x00,0x3c,0x64,0xa3,0x94,0xd0,0x4f,0x1d,0x1d,0xa8}, 8333}, + {{0x26,0x05,0x60,0x00,0xf3,0x80,0x9a,0x01,0xba,0x09,0x8a,0xff,0xfe,0xd4,0x35,0x11}, 8333}, + {{0x26,0x05,0x60,0x01,0xe0,0x0f,0x7b,0x00,0xc5,0x87,0x6d,0x91,0x6e,0xff,0xee,0xba}, 8333}, + {{0x26,0x05,0xf7,0x00,0x00,0xc0,0x00,0x01,0x00,0x00,0x00,0x00,0x25,0xc3,0x2a,0x3e}, 8333}, {{0x26,0x06,0x60,0x00,0xa4,0x41,0x99,0x03,0x50,0x54,0x00,0xff,0xfe,0x78,0x66,0xff}, 8333}, - {{0x26,0x06,0xdf,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xae,0x85,0x8f,0xc6}, 8333}, - {{0x26,0x07,0x53,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x7f}, 8333}, + {{0x26,0x07,0x53,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x83}, 9334}, {{0x26,0x07,0x53,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x11,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x15,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x1b,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x23,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x1c,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x26,0x07,0x53,0x00,0x00,0x60,0x2b,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x2d,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x03,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x33,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x03,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x26,0x07,0x53,0x00,0x00,0x60,0x4a,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x51,0x12,0x00,0x00,0x00,0x02,0x4a,0xf5,0x63,0xfe}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x6d,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x0a,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0xf1,0xc0,0x08,0x20,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x3f,0x44}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x65,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x69,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x71,0x1a,0x00,0x78,0x00,0x00,0x00,0x00,0xa7,0xb5}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x08,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x95,0x2e,0x37,0x33,0x00,0x00,0x00,0x00,0x14,0x14}, 8333}, {{0x26,0x07,0xf1,0xc0,0x08,0x48,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x94,0x3c}, 8333}, + {{0x26,0x07,0xf2,0xe0,0x00,0x0f,0x05,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x26,0x07,0xf7,0x48,0x12,0x00,0x00,0xf8,0x02,0x1e,0x67,0xff,0xfe,0x99,0x8f,0x07}, 8333}, {{0x26,0x07,0xf9,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x04,0xad,0xe5,0x94}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x65,0x9e,0x9c,0xb3}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0xc7,0x4b,0xa8,0xae}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x0d,0x82,0xd8,0xc2}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x87,0x95,0x2f,0xa8}, 8333}, - {{0x26,0x07,0xfc,0xd0,0xda,0xaa,0x09,0x01,0x00,0x00,0x00,0x00,0x95,0x61,0xe0,0x43}, 8333}, + {{0x26,0x07,0xff,0x68,0x01,0x00,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 8333}, + {{0x28,0x03,0x69,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x17}, 8333}, + {{0x2a,0x00,0x10,0x98,0x00,0x00,0x00,0x80,0x10,0x00,0x00,0x25,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x50,0x54,0x00,0xff,0xfe,0x84,0xf8,0x6f}, 8333}, {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x50,0x54,0x00,0xff,0xfe,0xe7,0x2e,0xb6}, 8333}, - {{0x2a,0x00,0x13,0x28,0xe1,0x00,0xcc,0x42,0x02,0x30,0x48,0xff,0xfe,0x92,0x05,0x5d}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x89,0x83,0xcc,0x27,0x0d,0x72,0xd9,0x7a}, 8333}, + {{0x2a,0x00,0x13,0x28,0xe1,0x00,0xcc,0x42,0x02,0x30,0x48,0xff,0xfe,0x92,0x05,0x5c}, 8333}, {{0x2a,0x00,0x14,0xf0,0xe0,0x00,0x80,0xd2,0xcd,0x1a,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x00,0x16,0xd8,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x6a,0xc2,0x61}, 8333}, - {{0x2a,0x00,0x61,0xe0,0x40,0x83,0x6d,0x01,0x68,0x52,0x13,0x76,0xe9,0x72,0x20,0x91}, 8333}, - {{0x2a,0x00,0x0c,0x98,0x20,0x30,0xa0,0x2f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x00,0x16,0x30,0x00,0x02,0x18,0x02,0x01,0x88,0x01,0x22,0x00,0x91,0x00,0x11}, 8333}, + {{0x2a,0x00,0x18,0xe0,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x00,0x18,0xe0,0x00,0x00,0xdc,0xc5,0x01,0x09,0x02,0x34,0x01,0x06,0x01,0x91}, 8333}, + {{0x2a,0x00,0x1a,0x28,0x11,0x57,0x00,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xc7}, 8333}, + {{0x2a,0x00,0x1c,0xa8,0x00,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0xfc,0x40,0xd1}, 8333}, + {{0x2a,0x00,0x1c,0xa8,0x00,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0x6d,0xce,0x2c}, 8333}, + {{0x2a,0x00,0x71,0x43,0x01,0x00,0x00,0x00,0x02,0x16,0x3e,0xff,0xfe,0x2e,0x74,0xa3}, 8333}, + {{0x2a,0x00,0x71,0x43,0x01,0x00,0x00,0x00,0x02,0x16,0x3e,0xff,0xfe,0xd3,0x5c,0x21}, 8333}, + {{0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x23}, 8333}, + {{0x2a,0x00,0xdc,0xc0,0x0e,0xda,0x00,0x98,0x01,0x83,0x01,0x93,0xc3,0x82,0x6b,0xdb}, 8333}, + {{0x2a,0x00,0xdc,0xc0,0x0e,0xda,0x00,0x98,0x01,0x83,0x01,0x93,0xf7,0x2e,0xd9,0x43}, 8333}, + {{0x2a,0x00,0xf8,0x20,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xaf,0x00,0x01}, 8333}, + {{0x2a,0x00,0xf9,0x40,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x1d}, 8333}, + {{0x2a,0x00,0xf9,0x40,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x06,0xac}, 8333}, {{0x2a,0x01,0x01,0xb0,0x79,0x99,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 8333}, - {{0x2a,0x01,0x01,0xe8,0xe1,0x00,0x81,0x1c,0x70,0x0f,0x65,0xf0,0xf7,0x2a,0x10,0x84}, 8333}, - {{0x2a,0x01,0x02,0x38,0x42,0xda,0xc5,0x00,0x65,0x46,0x12,0x93,0x54,0x22,0xab,0x40}, 8333}, - {{0x2a,0x01,0x03,0x48,0x00,0x06,0x04,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x03,0x68,0xe0,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x49}, 8333}, - {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x30}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x53,0xa9,0x0d,0x04,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x57,0xe6,0x57,0x8c,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x02,0x38,0x42,0xdd,0xf9,0x00,0x7a,0x6c,0x2b,0xc6,0x40,0x41,0x0c,0x43}, 8333}, + {{0x2a,0x01,0x02,0x38,0x43,0x13,0x63,0x00,0x21,0x89,0x1c,0x97,0x69,0x6b,0x05,0xea}, 8333}, + {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x5c,0x33,0x91,0xf9,0x00,0x00,0x00,0x01}, 8333}, {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0xb0,0x1c,0x17,0x8d,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0x05,0x23,0xfd,0xce,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0xb0,0x1c,0x30,0xab,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x34,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x34,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x44,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x51,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x84,0xa7,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x51,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x51,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x53,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x43,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x62,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x70,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x82,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x84,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x11,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x23,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x02,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x11,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x33,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x40,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x64,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x93,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x20,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x54,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x80,0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x33,0xad,0xfe,0xa1,0x00,0x00,0x00,0x00,0x06,0x66}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x63,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x93,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x93,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x11,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x21,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x22,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x61,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x70,0x88,0x50,0x54,0x00,0xff,0xfe,0x45,0xbf,0xf2}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x53,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x33,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x72,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x83,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001}, - {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x01,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x21,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x41,0xc2,0x00,0x00,0x54,0x04,0xa6,0x7e,0xf2,0x50}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x52,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x54}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x63,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001}, - {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x52,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x93,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x23,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x43,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x74,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x60,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x63,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x51,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x72,0xc5,0x00,0x00,0x00,0x00,0x28,0x58,0xe1,0xc5}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x72,0xc5,0x00,0x00,0x00,0x00,0x59,0x3b,0x60,0xd5}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x81,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x13,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x22,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x51,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x60,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x70,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x91,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x21,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x21,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x44,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x51,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x0b,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x14,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x44,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x64,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x91,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x21,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x40,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x04,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x63,0xb4,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x71,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x40,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x44,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x82,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x83,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x93,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x60,0xa9,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x73,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x80,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x11,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x21,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x22,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x44,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x10,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x22,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x41,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x22}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x23,0xd1,0x00,0x00,0x00,0x00,0xde,0xad,0xbe,0xef}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x50,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x51,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x53,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x53,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x19}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x71,0xe3,0x78,0xb4,0xf3,0xff,0xfe,0xad,0xe8,0xcf}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x51,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x21,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x02,0x33,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x03,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x02,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0xef,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x33,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x53,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x63,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x72,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x22,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x50,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x14,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x1a,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x2a,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x0c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x22,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x50,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x18,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x28,0x9e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x33,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 18333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x11,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x31,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x32,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x52,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x74,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x0d,0x13,0x21,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x19,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x1a,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x1a,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x02,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x04,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x07,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x0b,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0d,0x16,0x93,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x06,0x08,0xff,0xff,0xa0,0x09,0x8b,0xf5,0x87,0x9d,0xe5,0x1a,0xf8,0x37}, 8333}, - {{0x2a,0x01,0x07,0x9d,0x46,0x9e,0xed,0x94,0xc2,0x3f,0xd5,0xff,0xfe,0x65,0x20,0xc5}, 8333}, - {{0x2a,0x01,0x07,0xc8,0xaa,0xb5,0x03,0xe6,0x50,0x54,0x00,0xff,0xfe,0xd7,0x4e,0x54}, 8333}, + {{0x2a,0x01,0x06,0x80,0x00,0x10,0x00,0x10,0xf2,0xde,0xf1,0xff,0xfe,0xc9,0x0d,0xc0}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x01,0xf6,0x50,0x54,0x00,0xff,0xfe,0x30,0xe5,0x85}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x02,0x0b,0x50,0x54,0x00,0xff,0xfe,0x24,0x43,0x5e}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x04,0x3d,0x50,0x54,0x00,0xff,0xfe,0x4e,0x3d,0xd4}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xad,0x02,0x56,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xb6,0x00,0xea,0x50,0x54,0x00,0xff,0xfe,0xff,0xea,0xc3}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xb9,0x00,0x5a,0x50,0x54,0x00,0xff,0xfe,0x89,0x7b,0x26}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xbc,0x02,0xc8,0x50,0x54,0x00,0xff,0xfe,0x35,0x65,0x81}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x30,0x1e}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x77,0x49}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2d,0x67}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x34,0x7c}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xae,0x50}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x6b,0x5c}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xbe,0xe6}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x48,0x95}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x99,0x12}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x26,0xee}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x73,0x42,0xf1}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x39,0x42}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0x8c,0x87}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x62,0x06}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x55,0x9d}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x43,0x4f}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0xb3,0x6b}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x1f,0xaa}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x08,0x16}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x11,0x43}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x25,0x05}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x35,0x2e}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x4a,0x1d}, 8333}, - {{0x2a,0x01,0x0e,0x34,0xed,0xbb,0x67,0x50,0x02,0x24,0x1d,0xff,0xfe,0x89,0x38,0x97}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x2f,0x1d,0x3f,0xb0,0x71,0x87,0xc7,0xba,0xbc,0xfc,0x80,0xce}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x87,0x87,0x96,0xf0,0x90,0x32,0x92,0x97,0x39,0xae,0x49,0x6d}, 8333}, + {{0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0xd7,0xb5}, 8333}, + {{0x2a,0x01,0x0e,0x34,0xee,0x33,0x16,0x40,0xc5,0x04,0xf6,0x77,0xb2,0x8a,0xba,0x42}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x2e,0x7e,0x0b,0xc0,0xe0,0x79,0xf5,0x5e,0xce,0xf3,0xb5,0xd7}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x2e,0xe5,0x06,0x10,0x02,0x1f,0xd0,0xff,0xfe,0x4e,0x74,0x60}, 8333}, {{0x2a,0x01,0x0e,0x35,0x8a,0x3f,0x47,0xc0,0xc6,0x17,0xfe,0xff,0xfe,0x3c,0x9f,0xbd}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x8b,0x66,0x06,0xa0,0x49,0x00,0x9d,0xfd,0xd8,0x41,0xd0,0x25}, 8333}, - {{0x2a,0x02,0x01,0x68,0x4a,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39}, 8333}, - {{0x2a,0x02,0x01,0x68,0x54,0x04,0x00,0x02,0xc2,0x3f,0xd5,0xff,0xfe,0x6a,0x51,0x2e}, 8333}, - {{0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x5b,0x8f,0x53,0x8c}, 8333}, - {{0x2a,0x02,0x20,0x28,0x10,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x8a,0xca,0x06,0xa0,0x02,0x11,0x0a,0xff,0xfe,0x5e,0x29,0x5e}, 8333}, + {{0x2a,0x02,0x01,0x80,0x00,0x0a,0x00,0x18,0x00,0x81,0x00,0x07,0x00,0x11,0x00,0x50}, 8333}, + {{0x2a,0x02,0x18,0x10,0x1d,0x87,0x6a,0x00,0x56,0x04,0xa6,0xff,0xfe,0x60,0xd8,0x7d}, 8333}, + {{0x2a,0x02,0x21,0x68,0x11,0x44,0x5c,0x01,0xd6,0x3d,0x7e,0xff,0xfe,0xdd,0x4f,0x8e}, 8333}, + {{0x2a,0x02,0x24,0x98,0x6d,0x7b,0x70,0x01,0xb5,0x08,0xb3,0x9d,0x2c,0xea,0x5b,0x7a}, 8333}, {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15}, 8333}, - {{0x2a,0x02,0x25,0x28,0xff,0x00,0x81,0xa6,0x02,0x1e,0xc5,0xff,0xfe,0x8d,0xf9,0xa5}, 8333}, - {{0x2a,0x02,0x27,0x70,0x00,0x05,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0xe4,0xc7,0xdb}, 8333}, - {{0x2a,0x02,0x27,0x70,0x00,0x08,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0x7b,0x3d,0xcd}, 8333}, - {{0x2a,0x02,0x03,0x48,0x00,0x5e,0x5a,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x2f,0xc0,0x6a}, 8333}, - {{0x2a,0x02,0x81,0x09,0x8e,0x40,0x35,0xfc,0xba,0x27,0xeb,0xff,0xfe,0xae,0xcf,0x16}, 8333}, - {{0x2a,0x02,0x0a,0xf8,0x00,0x06,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x30}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x63,0x14,0x22,0x22}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x03,0x32,0x95,0x00,0x01}, 8332}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x54,0x49,0x00,0x01}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x58,0x99,0x00,0x01}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x05,0x00,0x01}, 8333}, - {{0x2a,0x02,0xce,0x80,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x02,0x0f,0xe0,0xc3,0x21,0x27,0xe0,0x6e,0xf0,0x49,0xff,0xfe,0x11,0xa6,0x1d}, 8333}, + {{0x2a,0x02,0x25,0x28,0x00,0xfa,0x1a,0x56,0x02,0x16,0x44,0xff,0xfe,0x6a,0xd1,0x12}, 8333}, + {{0x2a,0x02,0x27,0xf8,0x20,0x12,0x00,0x00,0xe9,0xf7,0x26,0x8f,0xc4,0x41,0x61,0x29}, 8333}, + {{0x2a,0x02,0x03,0x48,0x00,0x86,0x30,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0x47,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x8a,0x01}, 8333}, + {{0x2a,0x02,0x05,0x78,0x50,0x02,0x01,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x02,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x19,0x0b,0x69,0xe3}, 8333}, + {{0x2a,0x02,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe8,0x93,0xd9,0xd6}, 8333}, + {{0x2a,0x02,0x07,0x70,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x39}, 8333}, + {{0x2a,0x02,0x7a,0xa0,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xde,0xb3,0x81,0xa2}, 8333}, + {{0x2a,0x02,0x80,0x10,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x59,0xb5}, 8333}, + {{0x2a,0x02,0x81,0x0d,0x21,0xc0,0x0f,0x00,0xa2,0x48,0x1c,0xff,0xfe,0xb8,0x53,0x48}, 8333}, + {{0x2a,0x02,0x0a,0x50,0x00,0x00,0x00,0x00,0x02,0x1b,0x24,0xff,0xfe,0x93,0x4e,0x39}, 8333}, + {{0x2a,0x02,0x0a,0x80,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x01,0x58,0x30,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x05,0x46,0x92,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x71,0x58,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x22,0x44,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x33,0x39,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x78,0x44,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x05,0x62,0x88,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x00,0x59,0x12,0x00,0x01}, 8333}, {{0x2a,0x03,0x40,0x00,0x00,0x02,0x04,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333}, - {{0x2a,0x03,0xb0,0xc0,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x62,0xf0,0x01}, 8333}, + {{0x2a,0x03,0x40,0x00,0x00,0x06,0x80,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x03,0x40,0x00,0x00,0x06,0x80,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0xd0}, 8333}, + {{0x2a,0x03,0x49,0x00,0xff,0xfc,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x01,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x0d,0x50,0x01}, 8333}, + {{0x2a,0x03,0x0f,0x80,0xed,0x15,0x01,0x49,0x01,0x54,0x01,0x55,0x02,0x35,0x00,0x01}, 8333}, + {{0x2a,0x03,0x0f,0x80,0xed,0x15,0x01,0x49,0x01,0x54,0x01,0x55,0x02,0x41,0x00,0x01}, 8333}, {{0x2a,0x03,0x0f,0x80,0xed,0x16,0x0c,0xa7,0xea,0x75,0xb1,0x2d,0x02,0xaf,0x9e,0x2a}, 8333}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xab,0x02,0x90,0xfa,0xff,0xfe,0x70,0xa3,0xd8}, 8333}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xab,0xe6,0x1d,0x2d,0xff,0xfe,0x29,0xf5,0x90}, 8333}, + {{0x2a,0x04,0x2f,0x80,0x00,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89}, 8333}, + {{0x2a,0x04,0xac,0x00,0x00,0x01,0x4a,0x0b,0x50,0x54,0x00,0xff,0xfe,0x00,0x5a,0xf5}, 8333}, + {{0x2a,0x04,0xad,0x80,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0xda}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0x4a,0xaf,0xa2,0x8c,0x9d,0xf6,0x22,0x18,0x28}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0xe4,0x70,0x01,0xb3,0xa7,0x9d,0x3e,0x51,0xf9}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0x45,0xd5,0x8b,0xff,0x81,0x9e,0x85,0x00,0xb8}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdb,0x58,0x10,0x81,0x48,0x69,0x2c,0xb3,0x0d,0x6d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe2,0x7f,0xf3,0x20,0xef,0x72,0xaf,0x4d,0x29,0x3c}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xef,0x3c,0x49,0x0b,0xc1,0x74,0xc2,0x92,0x86,0xe1}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0x27,0xf9,0x43,0xad,0x67,0xfd,0x74,0x25,0x43}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xff,0xd9,0x7d,0x26,0x57,0x03,0xb0,0x49,0x67,0x4f}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0xbe,0x9e,0xf0,0x33,0x40,0x2e,0x79,0xc9,0x18}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0f,0x8b,0x1f,0x8d,0x61,0xa6,0x94,0xf4,0x62,0x45}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xa2,0x2c,0x05,0x29,0x20,0xdd}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0x9c,0x11,0x9b,0x2d,0xf7,0xd7,0xf2,0x5e,0x9b}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x00,0x7d,0xc3,0xfd,0xcb,0x7a,0xff,0x07,0xdc,0x48}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x03,0x34,0x0e,0x44,0x07,0x5c,0xcb,0x4b,0xe7,0xcb}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x06,0x69,0x75,0xcb,0x88,0x3c,0x63,0xa6,0x11,0xff}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xbf,0x0a,0x38,0xe7,0xfe,0xc1}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xbf,0x87,0xf8,0x8f,0x6b,0x04,0xb5,0xc3,0xfa}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0b,0x29,0x34,0x96,0x29,0xe8,0x67,0x22,0x0c,0x61}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1c,0x5f,0xc7,0xd4,0x89,0xc0,0x6f,0xa2,0x24,0x71}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x32,0x2e,0xda,0xf7,0xc3,0xf6,0xc3,0x4c,0x3c,0x0d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0x08,0x94,0x72,0x0f,0x2c,0xb6,0xc9,0x6f,0x22}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x12,0xc9,0x76,0x66,0x08,0x77,0xf0,0x71,0x81,0xdc}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x7b,0x87,0xc2,0x7e,0xd8,0xe9,0xbb,0x14,0xed}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0xaa,0xb7,0xd0,0x79,0x79,0xf3,0x0b,0xd2,0x63}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x39,0xd1,0x5e,0xbd,0xb7,0x23,0x6a,0x12,0xf0,0x0c}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0x6e,0xf5,0x37,0xcf,0x9b,0xf6,0xe3,0x9f,0xdb}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x64,0x9e,0x79,0x18,0xa8,0x81,0x61,0xd9,0x4d,0xa4}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0x34,0x7f,0xc7,0xce,0xa3,0x04,0x59,0x06,0x32}, 4176}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x68,0xac,0xad,0xae,0x93,0x23,0x0a,0x51,0x3c,0x5c}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x72,0x87,0x94,0x82,0x36,0x22,0x83,0x23,0xb5,0xc5}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0x46,0xe6,0x23,0x98,0x0e,0x87,0x65,0x24,0x22}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa5,0x6c,0xec,0xda,0xeb,0x41,0xdb,0x34,0x18,0x21}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaf,0xb0,0xbc,0xf3,0xa3,0x6f,0x70,0x17,0xab,0x83}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7a,0x4c,0x71,0x22,0xb9,0x53,0x89,0x19,0x12,0x43}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8d,0xbe,0xe1,0x25,0x73,0x45,0xf5,0xe6,0x10,0xad}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa5,0xa5,0xf4,0x4c,0x8f,0xfb,0xb7,0x84,0x36,0xee}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaa,0xb7,0x04,0x8c,0x87,0xc6,0x38,0x3b,0x0a,0xf6}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x1f,0x82,0x69,0x5d,0x88,0xa1,0x54,0xf5,0x90}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x06,0xa7,0x66,0x63,0x2c,0x65,0x4c,0x61,0xd4}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcf,0x7b,0x5e,0x3a,0x53,0x21,0x5b,0x62,0xe3,0x7a}, 8333} + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb3,0xd1,0xf8,0xbe,0xa7,0x6b,0x46,0xbe,0xe8,0x84}, 8333} }; static SeedSpec6 pnSeed6_test[] = { From 43abb02aa20bd32795478236b20b45d3b4087138 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 23 Jan 2016 10:00:10 +0100 Subject: [PATCH 0172/1223] [Qt] Add a new chevron/arrow icon for the console prompt line --- contrib/debian/copyright | 3 +++ src/Makefile.qt.include | 1 + src/qt/bitcoin.qrc | 1 + src/qt/forms/debugwindow.ui | 41 +++++++++++++++++++++++++++++++---- src/qt/res/icons/chevron.png | Bin 0 -> 1923 bytes 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/qt/res/icons/chevron.png diff --git a/contrib/debian/copyright b/contrib/debian/copyright index bbaa5b163..c039a7bae 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -21,6 +21,7 @@ License: GPL-3+ Files: src/qt/res/icons/add.png src/qt/res/icons/address-book.png + src/qt/res/icons/chevron.png src/qt/res/icons/configure.png src/qt/res/icons/debugwindow.png src/qt/res/icons/edit.png @@ -56,6 +57,8 @@ Comment: Inspired by Stephan Hutchings Typicons Files: src/qt/res/icons/tx_mined.png src/qt/res/src/mine.svg + src/qt/res/icons/fontbigger.png + src/qt/res/icons/fontsmaller.png Copyright: Jonas Schnelli License: Expat Comment: diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 82e95abcf..96b7adcbf 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -225,6 +225,7 @@ RES_ICONS = \ qt/res/icons/about_qt.png \ qt/res/icons/bitcoin.ico \ qt/res/icons/bitcoin.png \ + qt/res/icons/chevron.png \ qt/res/icons/clock1.png \ qt/res/icons/clock2.png \ qt/res/icons/clock3.png \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 3c9b9d283..dcd3b4ae2 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -48,6 +48,7 @@ res/icons/warning.png res/icons/fontbigger.png res/icons/fontsmaller.png + res/icons/chevron.png
res/movies/spinner-000.png diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 2f4613099..763128611 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -479,12 +479,12 @@ 24 - - Decrease font size - + + Decrease font size + :/icons/fontsmaller:/icons/fontsmaller @@ -593,10 +593,43 @@ 3 + + + + false + + + + 16 + 24 + + + + + + + + :/icons/prompticon + :/icons/prompticon:/icons/prompticon + + + + 14 + 14 + + + + false + + + true + + + - > + diff --git a/src/qt/res/icons/chevron.png b/src/qt/res/icons/chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..ac985052c1527a9a687cc1acbb53f940a7df375b GIT binary patch literal 1923 zcmaJ?dr%YS77vlw@M@$)D2*d)C{}Fqf;>pZG$jdv6oLXlP(cmZg`|+|k}PKBC4z+O zwNItfiq)bPMQIUleV|lG=pAe&lwijxVp~?Y1!}p%?WAB4uHC5E`-iEtE1JiOSY&02HtV0t9RUOV5qr0U|M*C*X^DyjOr2E-#kD<8oreEFMq7 z7fEU}D)Rl5^`IO&iTF0tr|#^pzPQy~(C1=69gMGM14i>J830Hd(g z03(1x0j$yJ^hUGSj(!NxXe4U071f#bkXk8a5)^Es5tJxnxO@RWjxQI-iFmvOfmke8 zsZ;`Pypk)I^Mry$tP<9jm>@H{hz0+|3jPx7odpv@WL82J;|>T^Szr_Jux5$zDOzHM z3G!Hhis0kNK3&TrEcg^HkFmnP#BvBR9B*g;r_+lrVtl;YCv!^}PbMES6XR|n<~ls{ zR}XPrX4J}fEjBcHxIZ~Fo_=+FD5I@W7@9EB)5y*BWYkg%gMEX+v^?m%;r6!eEyDAL z%-%N`N@bU0^Pb)I4Pck>lHuq8ZJ&c$e|^pMZ+hvw|NOC{8AJwkf9Y!mU#(=2F>O{vc%kRxQ zih-^zOu}*o`InpVmsrjteie!dM@X18dRddUTLwE`X30ude6i1d3OG*BD#lut4A#PO zT5Wy9J(v5{I+JRm0zd3O|M7)5vn?tr$r*1G*w?4kk8D1G3lZC-9vk`j%Gr~{zEf{i zBpsZ-_v}x;3)@|eZDp0TJ(WS_aU1c9lqn0PJcVDJcyLVByJ<}RL%9BpU9w(x6nR^+ zj`5Nwo zTfaPl(Ve#tJa**m2fz1z{^OScFOV-TL)kaJtwU=)3E(03A?KGacSKE#o@8#WyU10X zp~%kpNb7Tps1*$C-SD}{xeMURxI3{4oR8dv%_mRV@1Fkf+n;`hZT-uf!w8vTN7a24sQ0r!iY zjDNlJQ}7F@Tc_{e+84-B3=DjFawaa}R)66A=%C2s!ia_tf5!3m*5(hk``BDFHBG-w z_mQ{Hc2qB9T|N;$-jM$}X;8X)e`eWd$phC~ipW=ox+7M*t5ZKaa^ud;O*dAPW}-sW z743Jcrm6Goq``5`i)H0#*cR|Uzdz|~ckYrY?&Xl1jOh~9?9ea9=QdGV$D3SvSpm!b zonpO-HGJ=PKo*|#NsiC3)3>80eaBf#=AD^}Ro326&%S>QGCC`{EK!#9d(q?)`|Y+Q zbzwtiYgc!hb=R7CmsST~!y8tNQjI3*FhPzSyMAg~k6Ve`kH}M#*W Date: Mon, 25 Jan 2016 19:39:46 -0500 Subject: [PATCH 0173/1223] Minor improvements to the release process Instruct people to "git fetch" so that if this is their 2nd+ gitian build they will have a fresh bitcoin repo. Instruct people to add all the known pgp keys to their keyring so that gverify will print more useful info. --- doc/release-process.md | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 9a2362cb8..39e3032a6 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -41,6 +41,7 @@ Check out the source code in the following directory hierarchy. pushd ./bitcoin export SIGNER=(your Gitian key, ie bluematt, sipa, etc) export VERSION=(new version, e.g. 0.8.0) + git fetch git checkout v${VERSION} popd @@ -83,25 +84,16 @@ NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from ``` The gbuild invocations below DO NOT DO THIS by default. -###Build (and optionally verify) Bitcoin Core for Linux, Windows, and OS X: +###Build and Sign Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz - mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz - mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ - popd Build output expected: @@ -111,6 +103,27 @@ The gbuild invocations below DO NOT DO THIS by default. 4. OS X unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz) 5. Gitian signatures (in gitian.sigs/${VERSION}-/(your Gitian key)/ +###Verify other gitian builders signatures to your own. (Optional) + + Add other gitian builders keys to your gpg keyring + + gpg --import ../bitcoin/contrib/gitian-downloader/*.pgp + + Verify the signatures + + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + +###Move the outputs to the correct directory + + mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ + mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz + mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ + mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz + mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ + popd + ###Next steps: Commit your signature to gitian.sigs: From cd27bf51e06a8d79790a631696355bd05751b0aa Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Jan 2016 14:50:50 -0500 Subject: [PATCH 0174/1223] release: fix parsing of BIND_NOW with older readelf --- contrib/devtools/security-check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index fe5dc9ad8..0319f739c 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -94,7 +94,7 @@ def check_ELF_RELRO(executable): raise IOError('Error opening file') for line in stdout.split('\n'): tokens = line.split() - if len(tokens)>1 and tokens[1] == '(BIND_NOW)': + if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]): have_bindnow = True return have_gnu_relro and have_bindnow From 475813ba5b208eb9a5d027eb628a717cc123ef4f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Jan 2016 23:03:15 -0500 Subject: [PATCH 0175/1223] release: add _IO_stdin_used to ignored exports For details see: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 --- contrib/devtools/symbol-check.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 93acfcdda..4ad5136f7 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -42,9 +42,12 @@ MAX_VERSIONS = { 'GLIBCXX': (3,4,13), 'GLIBC': (2,11) } +# See here for a description of _IO_stdin_used: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 + # Ignore symbols that are exported as part of every executable IGNORE_EXPORTS = { -'_edata', '_end', '_init', '__bss_start', '_fini' +'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used' } READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') From f3d3eaf78eb51238d799d8f20a585550d1567719 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Jan 2016 14:52:56 -0500 Subject: [PATCH 0176/1223] release: add check-symbols and check-security make targets These are not added to the default checks because some of them depend on release-build configs. --- Makefile.am | 5 ++++- configure.ac | 3 +++ src/Makefile.am | 14 +++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index b2b781172..0a3b00bcc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,9 @@ OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) +BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ + $(top_srcdir)/contrib/devtools/security-check.py + WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ @@ -213,7 +216,7 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) diff --git a/configure.ac b/configure.ac index 3e5303647..9a6d0b3b1 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,8 @@ AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) +AC_PATH_TOOL(READELF, readelf) +AC_PATH_TOOL(CPPFILT, c++filt) dnl pkg-config check. PKG_PROG_PKG_CONFIG @@ -936,6 +938,7 @@ AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno]) AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) +AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) diff --git a/src/Makefile.am b/src/Makefile.am index 948d12424..a104a0148 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,7 +76,7 @@ if BUILD_BITCOIN_UTILS bin_PROGRAMS += bitcoin-cli bitcoin-tx endif -.PHONY: FORCE +.PHONY: FORCE check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ addrman.h \ @@ -459,6 +459,18 @@ clean-local: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< +check-symbols: $(bin_PROGRAMS) +if GLIBC_BACK_COMPAT + @echo "Checking glibc back compat..." + $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS) +endif + +check-security: $(bin_PROGRAMS) +if HARDEN + @echo "Checking binary security..." + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) +endif + %.pb.cc %.pb.h: %.proto @test -f $(PROTOC) $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $( Date: Tue, 26 Jan 2016 22:36:39 -0500 Subject: [PATCH 0177/1223] release: always link librt for glibc back-compat builds glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link in anyway for back-compat. Fixes #7420 --- configure.ac | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 9a6d0b3b1..921b26a94 100644 --- a/configure.ac +++ b/configure.ac @@ -411,6 +411,10 @@ AX_GCC_FUNC_ATTRIBUTE([dllimport]) if test x$use_glibc_compat != xno; then + #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link + #in anyway for back-compat. + AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing)) + #__fdelt_chk's params and return type have changed from long unsigned int to long int. # See which one is present here. AC_MSG_CHECKING(__fdelt_chk type) @@ -424,7 +428,8 @@ if test x$use_glibc_compat != xno; then [ fdelt_type="long int"]) AC_MSG_RESULT($fdelt_type) AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) - +else + AC_SEARCH_LIBS([clock_gettime],[rt]) fi if test x$TARGET_OS != xwindows; then @@ -491,8 +496,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) -AC_SEARCH_LIBS([clock_gettime],[rt]) - AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); From a81c87fafce43e49cc2307947e3951b84be7ca9a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Jan 2016 15:00:30 -0500 Subject: [PATCH 0178/1223] release: add security/symbol checks to gitian --- contrib/gitian-descriptors/gitian-linux.yml | 2 ++ contrib/gitian-descriptors/gitian-win.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 04b9b0177..b4b6ed290 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -96,6 +96,8 @@ script: | ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make ${MAKEOPTS} -C src check-symbols make install-strip cd installed find . -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 361842920..233f5c549 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -126,6 +126,7 @@ script: | ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security make deploy make install-strip cp -f bitcoin-*setup*.exe $OUTDIR/ From c8a6c11d6d4c5910dca14135d466efc5c40f519c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 27 Jan 2016 11:39:58 +0100 Subject: [PATCH 0179/1223] devtools: Fix utf-8 support in messages for github-merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use 'utf-8' instead of the Python 2 default of 'ascii' to encode/decode commit messages. This can be removed when switching to Python 3, as 'utf-8' is the default there. Necessary for merging #7422 due to the ฿ in ฿tcDrak. --- contrib/devtools/github-merge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index f7781cceb..c8dcaae26 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -147,14 +147,14 @@ def main(): else: firstline = 'Merge #%s' % (pull,) message = firstline + '\n\n' - message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]) + message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') try: - subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message,head_branch]) + subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch]) except subprocess.CalledProcessError as e: print("ERROR: Cannot be merged cleanly.",file=stderr) subprocess.check_call([GIT,'merge','--abort']) exit(4) - logmsg = subprocess.check_output([GIT,'log','--pretty=format:%s','-n','1']) + logmsg = subprocess.check_output([GIT,'log','--pretty=format:%s','-n','1']).decode('utf-8') if logmsg.rstrip() != firstline.rstrip(): print("ERROR: Creating merge failed (already merged?).",file=stderr) exit(4) From 40c87b6e6961e61d1cccdd248534e99f7a421564 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Sat, 12 Dec 2015 22:34:08 -0500 Subject: [PATCH 0180/1223] Increase test coverage for addrman and addrinfo Adds several unittests for CAddrMan and CAddrInfo. Increases the accuracy of addrman tests. Removes non-determinism in tests by overriding the random number generator. Extracts testing code from addrman class to test class. --- src/addrman.cpp | 24 ++- src/addrman.h | 13 +- src/test/addrman_tests.cpp | 403 ++++++++++++++++++++++++++++++++++--- 3 files changed, 391 insertions(+), 49 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 078b9e168..2dea0b844 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -220,7 +220,7 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime) return; // find a bucket it is in now - int nRnd = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); + int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT); int nUBucket = -1; for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) { int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT; @@ -277,7 +277,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP int nFactor = 1; for (int n = 0; n < pinfo->nRefCount; n++) nFactor *= 2; - if (nFactor > 1 && (GetRandInt(nFactor) != 0)) + if (nFactor > 1 && (RandomInt(nFactor) != 0)) return false; } else { pinfo = Create(addr, source, &nId); @@ -339,12 +339,12 @@ CAddrInfo CAddrMan::Select_(bool newOnly) // Use a 50% chance for choosing between tried and new table entries. if (!newOnly && - (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0))) { + (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) { // use a tried node double fChanceFactor = 1.0; while (1) { - int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT); - int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT); + int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); while (vvTried[nKBucket][nKBucketPos] == -1) { nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT; nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; @@ -352,7 +352,7 @@ CAddrInfo CAddrMan::Select_(bool newOnly) int nId = vvTried[nKBucket][nKBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; - if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } @@ -360,8 +360,8 @@ CAddrInfo CAddrMan::Select_(bool newOnly) // use a new node double fChanceFactor = 1.0; while (1) { - int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); - int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT); + int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); while (vvNew[nUBucket][nUBucketPos] == -1) { nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT; nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; @@ -369,7 +369,7 @@ CAddrInfo CAddrMan::Select_(bool newOnly) int nId = vvNew[nUBucket][nUBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; - if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } @@ -465,7 +465,7 @@ void CAddrMan::GetAddr_(std::vector& vAddr) if (vAddr.size() >= nNodes) break; - int nRndPos = GetRandInt(vRandom.size() - n) + n; + int nRndPos = RandomInt(vRandom.size() - n) + n; SwapRandom(n, nRndPos); assert(mapInfo.count(vRandom[n]) == 1); @@ -494,3 +494,7 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) if (nTime - info.nTime > nUpdateInterval) info.nTime = nTime; } + +int CAddrMan::RandomInt(int nMax){ + return GetRandInt(nMax); +} \ No newline at end of file diff --git a/src/addrman.h b/src/addrman.h index 1123caabf..26a6dae47 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -175,9 +175,6 @@ private: //! critical section to protect the inner data structures mutable CCriticalSection cs; - //! secret key to randomize bucket select with - uint256 nKey; - //! last used nId int nIdCount; @@ -203,6 +200,8 @@ private: int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; protected: + //! secret key to randomize bucket select with + uint256 nKey; //! Find an entry. CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); @@ -235,6 +234,9 @@ protected: //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. CAddrInfo Select_(bool newOnly); + //! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic. + virtual int RandomInt(int nMax); + #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. int Check_(); @@ -569,11 +571,6 @@ public: Check(); } } - - //! Ensure that bucket placement is always the same for testing purposes. - void MakeDeterministic(){ - nKey.SetNull(); //Do not use outside of tests. - } }; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index a1e6a204f..767b653e4 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -6,11 +6,49 @@ #include #include +#include "hash.h" #include "random.h" using namespace std; -class CAddrManTest : public CAddrMan{}; +class CAddrManTest : public CAddrMan +{ + uint64_t state; + +public: + CAddrManTest() + { + state = 1; + } + + //! Ensure that bucket placement is always the same for testing purposes. + void MakeDeterministic() + { + nKey.SetNull(); + seed_insecure_rand(true); + } + + int RandomInt(int nMax) + { + state = (CHashWriter(SER_GETHASH, 0) << state).GetHash().GetCheapHash(); + return (unsigned int)(state % nMax); + } + + CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL) + { + return CAddrMan::Find(addr, pnId); + } + + CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL) + { + return CAddrMan::Create(addr, addrSource, pnId); + } + + void Delete(int nId) + { + CAddrMan::Delete(nId); + } +}; BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup) @@ -21,7 +59,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); // Test 1: Does Addrman respond correctly when empty. BOOST_CHECK(addrman.size() == 0); @@ -29,26 +67,26 @@ BOOST_AUTO_TEST_CASE(addrman_simple) BOOST_CHECK(addr_null.ToString() == "[::]:0"); // Test 2: Does Addrman::Add work as expected. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); - // Test 3: Does IP address deduplication work correctly. + // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. - CService addr1_dup = CService("250.1.1.1:8333"); + CService addr1_dup = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1_dup), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. - CService addr2 = CService("250.1.1.2:8333"); + CService addr2 = CService("250.1.1.2", 8333); addrman.Add(CAddress(addr2), source); BOOST_CHECK(addrman.size() == 2); - // Test 6: AddrMan::Clear() should empty the new table. + // Test 6: AddrMan::Clear() should empty the new table. addrman.Clear(); BOOST_CHECK(addrman.size() == 0); CAddrInfo addr_null2 = addrman.Select(); @@ -62,16 +100,16 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); // Test 7; Addr with same IP but diff port does not replace existing addr. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); - CService addr1_port = CService("250.1.1.1:8334"); + CService addr1_port = CService("250.1.1.1", 8334); addrman.Add(CAddress(addr1_port), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); @@ -94,10 +132,10 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); // Test 9: Select from new with 1 addr in new. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); @@ -105,7 +143,6 @@ BOOST_AUTO_TEST_CASE(addrman_select) CAddrInfo addr_ret1 = addrman.Select(newOnly); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); - // Test 10: move addr to tried, select from new expected nothing returned. addrman.Good(CAddress(addr1)); BOOST_CHECK(addrman.size() == 1); @@ -114,6 +151,39 @@ BOOST_AUTO_TEST_CASE(addrman_select) CAddrInfo addr_ret3 = addrman.Select(); BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); + + BOOST_CHECK(addrman.size() == 1); + + + // Add three addresses to new table. + CService addr2 = CService("250.3.1.1", 8333); + CService addr3 = CService("250.3.2.2", 9999); + CService addr4 = CService("250.3.3.3", 9999); + + addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333)); + + // Add three addresses to tried table. + CService addr5 = CService("250.4.4.4", 8333); + CService addr6 = CService("250.4.5.5", 7777); + CService addr7 = CService("250.4.6.6", 8333); + + addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5)); + addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6)); + addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7)); + + // Test 11: 6 addrs + 1 addr from last test = 7. + BOOST_CHECK(addrman.size() == 7); + + // Test 12: Select pulls from new and tried regardless of port number. + BOOST_CHECK(addrman.Select().ToString() == "250.4.6.6:8333"); + BOOST_CHECK(addrman.Select().ToString() == "250.3.2.2:9999"); + BOOST_CHECK(addrman.Select().ToString() == "250.3.3.3:9999"); + BOOST_CHECK(addrman.Select().ToString() == "250.4.4.4:8333"); } BOOST_AUTO_TEST_CASE(addrman_new_collisions) @@ -123,26 +193,26 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); - for (unsigned int i = 1; i < 4; i++){ - CService addr = CService("250.1.1."+boost::to_string(i)); + for (unsigned int i = 1; i < 18; i++) { + CService addr = CService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr), source); - //Test 11: No collision in new table yet. + //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); } - //Test 12: new table collision! - CService addr1 = CService("250.1.1.4"); + //Test 14: new table collision! + CService addr1 = CService("250.1.1.18"); addrman.Add(CAddress(addr1), source); - BOOST_CHECK(addrman.size() == 3); + BOOST_CHECK(addrman.size() == 17); - CService addr2 = CService("250.1.1.5"); + CService addr2 = CService("250.1.1.19"); addrman.Add(CAddress(addr2), source); - BOOST_CHECK(addrman.size() == 4); + BOOST_CHECK(addrman.size() == 18); } BOOST_AUTO_TEST_CASE(addrman_tried_collisions) @@ -152,29 +222,300 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); - for (unsigned int i = 1; i < 75; i++){ - CService addr = CService("250.1.1."+boost::to_string(i)); + for (unsigned int i = 1; i < 80; i++) { + CService addr = CService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr), source); addrman.Good(CAddress(addr)); - //Test 13: No collision in tried table yet. + //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); BOOST_CHECK(addrman.size() == i); } - //Test 14: tried table collision! - CService addr1 = CService("250.1.1.76"); + //Test 16: tried table collision! + CService addr1 = CService("250.1.1.80"); addrman.Add(CAddress(addr1), source); - BOOST_CHECK(addrman.size() == 74); + BOOST_CHECK(addrman.size() == 79); - CService addr2 = CService("250.1.1.77"); + CService addr2 = CService("250.1.1.81"); addrman.Add(CAddress(addr2), source); - BOOST_CHECK(addrman.size() == 75); + BOOST_CHECK(addrman.size() == 80); +} + +BOOST_AUTO_TEST_CASE(addrman_find) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333)); + + CNetAddr source1 = CNetAddr("250.1.2.1"); + CNetAddr source2 = CNetAddr("250.1.2.2"); + + addrman.Add(addr1, source1); + addrman.Add(addr2, source2); + addrman.Add(addr3, source1); + + // Test 17: ensure Find returns an IP matching what we searched on. + CAddrInfo* info1 = addrman.Find(addr1); + BOOST_CHECK(info1); + if (info1) + BOOST_CHECK(info1->ToString() == "250.1.2.1:8333"); + + // Test 18; Find does not discriminate by port number. + CAddrInfo* info2 = addrman.Find(addr2); + BOOST_CHECK(info2); + if (info2) + BOOST_CHECK(info2->ToString() == info1->ToString()); + + // Test 19: Find returns another IP matching what we searched on. + CAddrInfo* info3 = addrman.Find(addr3); + BOOST_CHECK(info3); + if (info3) + BOOST_CHECK(info3->ToString() == "251.255.2.1:8333"); +} + +BOOST_AUTO_TEST_CASE(addrman_create) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CNetAddr source1 = CNetAddr("250.1.2.1"); + + int nId; + CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId); + + // Test 20: The result should be the same as the input addr. + BOOST_CHECK(pinfo->ToString() == "250.1.2.1:8333"); + + CAddrInfo* info2 = addrman.Find(addr1); + BOOST_CHECK(info2->ToString() == "250.1.2.1:8333"); } +BOOST_AUTO_TEST_CASE(addrman_delete) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CNetAddr source1 = CNetAddr("250.1.2.1"); + + int nId; + addrman.Create(addr1, source1, &nId); + + // Test 21: Delete should actually delete the addr. + BOOST_CHECK(addrman.size() == 1); + addrman.Delete(nId); + BOOST_CHECK(addrman.size() == 0); + CAddrInfo* info2 = addrman.Find(addr1); + BOOST_CHECK(info2 == NULL); +} + +BOOST_AUTO_TEST_CASE(addrman_getaddr) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + // Test 22: Sanity check, GetAddr should never return anything if addrman + // is empty. + BOOST_CHECK(addrman.size() == 0); + vector vAddr1 = addrman.GetAddr(); + BOOST_CHECK(vAddr1.size() == 0); + + CAddress addr1 = CAddress(CService("250.250.2.1", 8333)); + addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false + CAddress addr2 = CAddress(CService("250.251.2.2", 9999)); + addr2.nTime = GetAdjustedTime(); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333)); + addr3.nTime = GetAdjustedTime(); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333)); + addr4.nTime = GetAdjustedTime(); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333)); + addr5.nTime = GetAdjustedTime(); + CNetAddr source1 = CNetAddr("250.1.2.1"); + CNetAddr source2 = CNetAddr("250.2.3.3"); + + // Test 23: Ensure GetAddr works with new addresses. + addrman.Add(addr1, source1); + addrman.Add(addr2, source2); + addrman.Add(addr3, source1); + addrman.Add(addr4, source2); + addrman.Add(addr5, source1); + + // GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down. + BOOST_CHECK(addrman.GetAddr().size() == 1); + + // Test 24: Ensure GetAddr works with new and tried addresses. + addrman.Good(CAddress(addr1)); + addrman.Good(CAddress(addr2)); + BOOST_CHECK(addrman.GetAddr().size() == 1); + + // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. + for (unsigned int i = 1; i < (8 * 256); i++) { + int octet1 = i % 256; + int octet2 = (i / 256) % 256; + int octet3 = (i / (256 * 2)) % 256; + string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; + CAddress addr = CAddress(CService(strAddr)); + + // Ensure that for all addrs in addrman, isTerrible == false. + addr.nTime = GetAdjustedTime(); + addrman.Add(addr, CNetAddr(strAddr)); + if (i % 8 == 0) + addrman.Good(addr); + } + vector vAddr = addrman.GetAddr(); + + size_t percent23 = (addrman.size() * 23) / 100; + BOOST_CHECK(vAddr.size() == percent23); + BOOST_CHECK(vAddr.size() == 461); + // (Addrman.size() < number of addresses added) due to address collisons. + BOOST_CHECK(addrman.size() == 2007); +} + + +BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CAddress addr1 = CAddress(CService("250.1.1.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999)); + + CNetAddr source1 = CNetAddr("250.1.1.1"); + + + CAddrInfo info1 = CAddrInfo(addr1, source1); + + uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash(); + uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); + + + BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40); + + // Test 26: Make sure key actually randomizes bucket placement. A fail on + // this test could be a security issue. + BOOST_CHECK(info1.GetTriedBucket(nKey1) != info1.GetTriedBucket(nKey2)); + + // Test 27: Two addresses with same IP but different ports can map to + // different buckets because they have different keys. + CAddrInfo info2 = CAddrInfo(addr2, source1); + + BOOST_CHECK(info1.GetKey() != info2.GetKey()); + BOOST_CHECK(info1.GetTriedBucket(nKey1) != info2.GetTriedBucket(nKey1)); + + set buckets; + for (int i = 0; i < 255; i++) { + CAddrInfo infoi = CAddrInfo( + CAddress(CService("250.1.1." + boost::to_string(i))), + CNetAddr("250.1.1." + boost::to_string(i))); + int bucket = infoi.GetTriedBucket(nKey1); + buckets.insert(bucket); + } + // Test 28: IP addresses in the same group (\16 prefix for IPv4) should + // never get more than 8 buckets + BOOST_CHECK(buckets.size() == 8); + + buckets.clear(); + for (int j = 0; j < 255; j++) { + CAddrInfo infoj = CAddrInfo( + CAddress(CService("250." + boost::to_string(j) + ".1.1")), + CNetAddr("250." + boost::to_string(j) + ".1.1")); + int bucket = infoj.GetTriedBucket(nKey1); + buckets.insert(bucket); + } + // Test 29: IP addresses in the different groups should map to more than + // 8 buckets. + BOOST_CHECK(buckets.size() == 160); +} + +BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + + CNetAddr source1 = CNetAddr("250.1.2.1"); + + CAddrInfo info1 = CAddrInfo(addr1, source1); + + uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash(); + uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); + + BOOST_CHECK(info1.GetNewBucket(nKey1) == 786); + + // Test 30: Make sure key actually randomizes bucket placement. A fail on + // this test could be a security issue. + BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2)); + + // Test 31: Ports should not effect bucket placement in the addr + CAddrInfo info2 = CAddrInfo(addr2, source1); + BOOST_CHECK(info1.GetKey() != info2.GetKey()); + BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1)); + + set buckets; + for (int i = 0; i < 255; i++) { + CAddrInfo infoi = CAddrInfo( + CAddress(CService("250.1.1." + boost::to_string(i))), + CNetAddr("250.1.1." + boost::to_string(i))); + int bucket = infoi.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 32: IP addresses in the same group (\16 prefix for IPv4) should + // always map to the same bucket. + BOOST_CHECK(buckets.size() == 1); + + buckets.clear(); + for (int j = 0; j < 4 * 255; j++) { + CAddrInfo infoj = CAddrInfo(CAddress( + CService( + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1")), + CNetAddr("251.4.1.1")); + int bucket = infoj.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 33: IP addresses in the same source groups should map to no more + // than 64 buckets. + BOOST_CHECK(buckets.size() <= 64); + + buckets.clear(); + for (int p = 0; p < 255; p++) { + CAddrInfo infoj = CAddrInfo( + CAddress(CService("250.1.1.1")), + CNetAddr("250." + boost::to_string(p) + ".1.1")); + int bucket = infoj.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 34: IP addresses in the different source groups should map to more + // than 64 buckets. + BOOST_CHECK(buckets.size() > 64); +} BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 78ec83ddfe0e49d18c572b37681e60b9435b2ab4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 27 Jan 2016 20:28:04 +0000 Subject: [PATCH 0181/1223] splashscreen: Resize text to fit exactly --- src/qt/splashscreen.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index facee62ea..4d745088a 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -79,10 +79,9 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) // check font size and drawing with pixPaint.setFont(QFont(font, 33*fontFactor)); QFontMetrics fm = pixPaint.fontMetrics(); - int titleTextWidth = fm.width(titleText); - if(titleTextWidth > 160) { - // strange font rendering, Arial probably not found - fontFactor = 0.75; + int titleTextWidth = fm.width(titleText); + if (titleTextWidth > 176) { + fontFactor = fontFactor * 176 / titleTextWidth; } pixPaint.setFont(QFont(font, 33*fontFactor)); From f9298cc60e093533ce109aedd7d54d59e87865cd Mon Sep 17 00:00:00 2001 From: Jarret Dyrbye Date: Wed, 27 Jan 2016 20:17:02 -0700 Subject: [PATCH 0182/1223] doc: add example for building with constrained resources discussed in github issue #6658 --- doc/build-unix.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 31bbab7f0..943bfadb9 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -50,12 +50,15 @@ Optional dependencies: For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. -System requirements +Memory Requirements -------------------- -C++ compilers are memory-hungry. It is recommended to have at least 1 GB of -memory available when compiling Bitcoin Core. With 512MB of memory or less -compilation will take much longer due to swap thrashing. +C++ compilers are memory-hungry. It is recommended to have at least 1.5 GB of +memory available when compiling Bitcoin Core. On systems with less, gcc can be +tuned to conserve memory with additional CXXFLAGS: + + + ./configure CXXFLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768" Dependency Build Instructions: Ubuntu & Debian ---------------------------------------------- From 29598e41a51ab7c5c98aa8b9af7941e8ceaaf644 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 28 Jan 2016 04:37:34 +0000 Subject: [PATCH 0183/1223] Move PACKAGE_URL to configure.ac --- configure.ac | 2 +- share/setup.nsi.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c90187845..9cd5ff5f3 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ define(_CLIENT_VERSION_IS_RELEASE, false) define(_COPYRIGHT_YEAR, 2015) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[Bitcoin Core]) -AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin]) +AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[http://bitcoin.org/]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 26d382274..e553a5ae8 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -7,7 +7,7 @@ SetCompressor /SOLID lzma !define REGKEY "SOFTWARE\$(^Name)" !define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ !define COMPANY "@PACKAGE_NAME@ project" -!define URL http://www.bitcoin.org/ +!define URL @PACKAGE_URL@ # MUI Symbol Definitions !define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" From cddffaf5e60f638b2acf4d33a4eb43c984825bba Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 28 Jan 2016 04:52:52 +0000 Subject: [PATCH 0184/1223] Bugfix: Include COPYRIGHT_HOLDERS_SUBSTITUTION in Makefile substitutions so it gets passed to extract-strings correctly --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 9cd5ff5f3..1ddb1f4a8 100644 --- a/configure.ac +++ b/configure.ac @@ -925,6 +925,7 @@ AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS") +AC_SUBST(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION") AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL") AC_SUBST(RELDFLAGS) From 77b55a00ed4a3a3a22ec3e299539a1812a0bc605 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 28 Jan 2016 05:09:29 +0000 Subject: [PATCH 0185/1223] Rename permitrbf to replacebyfee "permit" is currently used to configure transaction filtering, whereas replacement is more to do with the memory pool state than the transaction itself. --- src/init.cpp | 4 ++-- src/main.cpp | 4 ++-- src/main.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index a6d26a02f..0032a6d2d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -367,7 +367,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); - strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacements in the memory pool (default: %u)"), DEFAULT_PERMIT_REPLACEMENT)); strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); if (showDebug) strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); @@ -488,6 +487,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); + strUsage += HelpMessageOpt("-replacebyfee", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); @@ -1030,7 +1030,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nLocalServices |= NODE_BLOOM; nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); - fPermitReplacement = GetBoolArg("-permitrbf", DEFAULT_PERMIT_REPLACEMENT); + fEnableReplacement = GetBoolArg("-replacebyfee", DEFAULT_ENABLE_REPLACEMENT); // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log diff --git a/src/main.cpp b/src/main.cpp index c8ea62758..392300d57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,7 +78,7 @@ bool fAlerts = DEFAULT_ALERTS; /* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; -bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT; +bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -869,7 +869,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // unconfirmed ancestors anyway; doing otherwise is hopelessly // insecure. bool fReplacementOptOut = true; - if (fPermitReplacement) + if (fEnableReplacement) { BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) { diff --git a/src/main.h b/src/main.h index 98069a225..ec426003a 100644 --- a/src/main.h +++ b/src/main.h @@ -107,8 +107,8 @@ static const bool DEFAULT_TXINDEX = false; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; static const bool DEFAULT_TESTSAFEMODE = false; -/** Default for -permitrbf */ -static const bool DEFAULT_PERMIT_REPLACEMENT = true; +/** Default for -replacebyfee */ +static const bool DEFAULT_ENABLE_REPLACEMENT = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; @@ -141,7 +141,7 @@ extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; extern bool fAlerts; extern int64_t nMaxTipAge; -extern bool fPermitReplacement; +extern bool fEnableReplacement; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; From 23565157bade9a3dce128c9bb3be9a5508f3421d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 28 Jan 2016 05:31:41 +0000 Subject: [PATCH 0186/1223] Change default configure option --with-system-univalue to "no" --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 9819c2493..24f9f090f 100644 --- a/configure.ac +++ b/configure.ac @@ -149,10 +149,10 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=no]) AC_ARG_WITH([system-univalue], - [AS_HELP_STRING([--without-system-univalue], - [Build with system UniValue (default is auto)])], + [AS_HELP_STRING([--with-system-univalue], + [Build with system UniValue (default is no)])], [system_univalue=$withval], - [system_univalue=auto] + [system_univalue=no] ) AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], From d65dee961e39937e3e671c742ff8db32612ad9af Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 28 Jan 2016 05:27:25 +0000 Subject: [PATCH 0187/1223] Accept replacebyfee=opt-in for turning on opt-in RBF Basic forward-compatibility with more flexible parameters like fss --- src/init.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 0032a6d2d..547e94ad6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -47,8 +47,10 @@ #include #endif +#include #include #include +#include #include #include #include @@ -1030,7 +1032,20 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nLocalServices |= NODE_BLOOM; nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + fEnableReplacement = GetBoolArg("-replacebyfee", DEFAULT_ENABLE_REPLACEMENT); + if ((!fEnableReplacement) && mapArgs.count("-replacebyfee")) { + // Minimal effort at forwards compatibility + std::string strReplacementModeList = GetArg("-replacebyfee", ""); // default is impossible + std::vector vstrReplacementModes; + boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(",")); + BOOST_FOREACH(const std::string& strReplacementMode, vstrReplacementModes) { + if (strReplacementMode == "opt-in") { + fEnableReplacement = true; + break; + } + } + } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log From befeb554184682ac9d98b56ef4e7f20642be01d0 Mon Sep 17 00:00:00 2001 From: Nathaniel Mahieu Date: Thu, 28 Jan 2016 11:10:15 -0600 Subject: [PATCH 0188/1223] Add example for displaying additional configure flags --- doc/build-unix.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index 31bbab7f0..1121a3507 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -236,3 +236,9 @@ In this case there is no dependency on Berkeley DB 4.8. Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC call not `getwork`. + +Additional Configure Flags +-------------------------- +A list of additional configure flags can be displayed with: + + ./configure --help From 8b3d8e3991ff13917dc02d6b2b0237925df396c4 Mon Sep 17 00:00:00 2001 From: Kefkius Date: Thu, 28 Jan 2016 15:26:54 -0500 Subject: [PATCH 0189/1223] GUI: Disable tab navigation for peers tables. Fix a bug in which the Peers tab of the debug window does not allow navigation to other tabs via Ctrl[+Shift]+Tab. --- src/qt/forms/debugwindow.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 763128611..a292924c8 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -905,6 +905,9 @@ Qt::ScrollBarAsNeeded + + false + true @@ -966,6 +969,9 @@ Qt::ScrollBarAsNeeded + + false + true From 325c725fb6205e38142914acb9ed1733d8482d46 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 25 Nov 2015 23:00:23 +0000 Subject: [PATCH 0190/1223] Add whitelistforcerelay to control forced relaying. Also renames whitelistalwaysrelay. Nodes relay all transactions from whitelisted peers, this gets in the way of some useful reasons for whitelisting peers-- for example, bypassing bandwidth limitations. The purpose of this forced relaying is for specialized gateway applications where a node is being used as a P2P connection filter and multiplexer, but where you don't want it getting in the way of (re-)broadcast. This change makes it configurable with whitelistforcerelay. --- src/init.cpp | 13 ++++++++++--- src/main.cpp | 10 +++++----- src/main.h | 6 ++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 3d9b4041c..e67193b32 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -388,7 +388,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); - strUsage += HelpMessageOpt("-whitelistalwaysrelay", strprintf(_("Always relay transactions received from whitelisted peers (default: %d)"), DEFAULT_WHITELISTALWAYSRELAY)); + strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); + strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET @@ -752,13 +753,19 @@ void InitParameterInteraction() // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { - if (SoftSetBoolArg("-whitelistalwaysrelay", false)) - LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistalwaysrelay=0\n", __func__); + if (SoftSetBoolArg("-whitelistrelay", false)) + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__); #ifdef ENABLE_WALLET if (SoftSetBoolArg("-walletbroadcast", false)) LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); #endif } + + // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place. + if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { + if (SoftSetBoolArg("-whitelistrelay", true)) + LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__); + } } static std::string ResolveErrMsg(const char * const optname, const std::string& strBind) diff --git a/src/main.cpp b/src/main.cpp index c8ea62758..235280784 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4495,8 +4495,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); - // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true - if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) + // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true + if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) fBlocksOnly = false; LOCK(cs_main); @@ -4675,8 +4675,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::TX) { // Stop processing the transaction early if - // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))) + // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) { LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id); return true; @@ -4776,7 +4776,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, assert(recentRejects); recentRejects->insert(tx.GetHash()); - if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) { + if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { // Always relay transactions received from whitelisted peers, even // if they were already in the mempool or rejected from it due // to policy, allowing the node to function as a gateway for diff --git a/src/main.h b/src/main.h index 98069a225..c4074cda8 100644 --- a/src/main.h +++ b/src/main.h @@ -42,8 +42,10 @@ struct CNodeStateStats; /** Default for accepting alerts from the P2P network. */ static const bool DEFAULT_ALERTS = true; -/** Default for DEFAULT_WHITELISTALWAYSRELAY. */ -static const bool DEFAULT_WHITELISTALWAYSRELAY = true; +/** Default for DEFAULT_WHITELISTRELAY. */ +static const bool DEFAULT_WHITELISTRELAY = true; +/** Default for DEFAULT_WHITELISTFORCERELAY. */ +static const bool DEFAULT_WHITELISTFORCERELAY = true; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ From 3b66e54457cdfe1f5ffda016d42c23fe848d539c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 29 Jan 2016 01:28:54 +0000 Subject: [PATCH 0191/1223] Simplify check for replacebyfee=opt-in --- src/init.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 547e94ad6..80b014eb9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1039,12 +1039,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string strReplacementModeList = GetArg("-replacebyfee", ""); // default is impossible std::vector vstrReplacementModes; boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(",")); - BOOST_FOREACH(const std::string& strReplacementMode, vstrReplacementModes) { - if (strReplacementMode == "opt-in") { - fEnableReplacement = true; - break; - } - } + fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "opt-in") != vstrReplacementModes.end()); } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log From 93fc58c7426b5f3c68f2657626698846fb512ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 2 Dec 2015 03:13:47 +0100 Subject: [PATCH 0192/1223] Consensus: Remove calls to error() and FormatStateMessage() from some consensus code in main --- src/main.cpp | 83 ++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 51 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 06374cc1b..8e35dc78d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -814,12 +814,13 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, std::vector& vHashTxnToUncache) { + const uint256 hash = tx.GetHash(); AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return false; + return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -837,7 +838,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? - uint256 hash = tx.GetHash(); if (pool.exists(hash)) return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); @@ -1170,7 +1170,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) - return false; + return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause @@ -1964,7 +1964,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Check it again in case a previous version let a bad block in if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) - return false; + return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); @@ -2909,13 +2909,11 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f { // Check proof of work matches claimed amount if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) - return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), - REJECT_INVALID, "high-hash"); + return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); // Check timestamp if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) - return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"), - REJECT_INVALID, "time-too-new"); + return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); return true; } @@ -2937,15 +2935,13 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo bool mutated; uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); if (block.hashMerkleRoot != hashMerkleRoot2) - return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); + return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot", true, "hashMerkleRoot mismatch"); // Check for merkle tree malleability (CVE-2012-2459): repeating sequences // of transactions in a block without affecting the merkle root of a block, // while still invalidating it. if (mutated) - return state.DoS(100, error("CheckBlock(): duplicate transaction"), - REJECT_INVALID, "bad-txns-duplicate", true); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate", true, "duplicate transaction"); } // All potential-corruption validation must be done before we do any @@ -2954,24 +2950,20 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckBlock(): size limits failed"), - REJECT_INVALID, "bad-blk-length"); + return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), - REJECT_INVALID, "bad-cb-missing"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase"); for (unsigned int i = 1; i < block.vtx.size(); i++) if (block.vtx[i].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): more than one coinbase"), - REJECT_INVALID, "bad-cb-multiple"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!CheckTransaction(tx, state)) - return error("CheckBlock(): CheckTransaction of %s failed with %s", - tx.GetHash().ToString(), - FormatStateMessage(state)); + return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), + strprintf("Transaction check failed (tx hash %s) %s", tx.GetHash().ToString(), state.GetDebugMessage())); unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2979,8 +2971,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo nSigOps += GetLegacySigOpCount(tx); } if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops"); + return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount"); if (fCheckPOW && fCheckMerkleRoot) block.fChecked = true; @@ -3007,28 +2998,17 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta const Consensus::Params& consensusParams = Params().GetConsensus(); // Check proof of work if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) - return state.DoS(100, error("%s: incorrect proof of work", __func__), - REJECT_INVALID, "bad-diffbits"); + return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) - return state.Invalid(error("%s: block's timestamp is too early", __func__), - REJECT_INVALID, "time-too-old"); + return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early"); - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s: rejected nVersion=1 block", __func__), - REJECT_OBSOLETE, "bad-version"); - - // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s: rejected nVersion=2 block", __func__), - REJECT_OBSOLETE, "bad-version"); - - // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=3 block", __func__), - REJECT_OBSOLETE, "bad-version"); + // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: + for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades + if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(v%d)", version - 1), + strprintf("rejected nVersion=%d block", version - 1)); return true; } @@ -3045,7 +3025,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn ? pindexPrev->GetMedianTimePast() : block.GetBlockTime(); if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) { - return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction"); } } @@ -3056,7 +3036,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false, "block height mismatch in coinbase"); } } @@ -3083,7 +3063,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state } if (!CheckBlockHeader(block, state)) - return false; + return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index CBlockIndex* pindexPrev = NULL; @@ -3099,7 +3079,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -3146,7 +3126,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); } - return false; + return error("%s: %s", __func__, FormatStateMessage(state)); } int nHeight = pindex->nHeight; @@ -3197,7 +3177,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c bool fRequested = MarkBlockAsReceived(pblock->GetHash()); fRequested |= fForceProcessing; if (!checked) { - return error("%s: CheckBlock FAILED", __func__); + return error("%s: CheckBlock FAILED %s", __func__, FormatStateMessage(state)); } // Store to disk @@ -3231,11 +3211,11 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, // NOTE: CheckBlockHeader is called by CheckBlock if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) - return false; + return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); if (!ContextualCheckBlock(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) return false; assert(state.IsValid()); @@ -3565,7 +3545,8 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) - return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, + pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { CBlockUndo undo; From 666a0f835aa9c3a608810e014d315b90a44c8f62 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 30 Jan 2016 10:10:11 +0800 Subject: [PATCH 0193/1223] Use Debian 8.3 in gitian build guide Add instructions to clone the gitian.sigs repo --- doc/gitian-building.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index e3fb94438..5ca91505e 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - File location and size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Click `Create` -Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.2.0/amd64/iso-cd/debian-8.2.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/debian-8.3.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "d393d17ac6b3113c81186e545c416a00f28ed6e05774284bb5e8f0df39fcbcb9 debian-8.2.0-amd64-netinst.iso" | sha256sum -c + echo "dd25bcdde3c6ea5703cc0f313cde621b13d42ff7d252e2538a11663c93bf8654 debian-8.3.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. @@ -305,6 +305,7 @@ Clone the git repositories for bitcoin and Gitian. ```bash git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin +git clone https://github.com/bitcoin/gitian.sigs.git ``` Setting up the Gitian image From fa331db68bcc68e4c93fb45aaa30f911b0ecfe1a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 23 Nov 2015 20:32:36 +0100 Subject: [PATCH 0194/1223] mempool: Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee --- src/init.cpp | 10 +++++----- src/main.cpp | 8 +++----- src/main.h | 10 ++++++++++ src/wallet/wallet.cpp | 1 - src/wallet/wallet.h | 8 +------- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 3d9b4041c..d72c11313 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -406,8 +406,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); @@ -470,6 +468,8 @@ std::string HelpMessage(HelpMessageMode mode) } strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE))); + strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (showDebug) { @@ -978,7 +978,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); - if (nFeePerK > nHighTransactionFeeWarning) + if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } @@ -987,7 +987,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); - if (nFeePerK > nHighTransactionFeeWarning) + if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) @@ -1001,7 +1001,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); - if (nMaxFee > nHighTransactionMaxFeeWarning) + if (nMaxFee > HIGH_MAX_TX_FEE) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) diff --git a/src/main.cpp b/src/main.cpp index 8beff9769..76ad969c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,13 +75,11 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; -/* If the tip is older than this (in seconds), the node is considered to be in initial block download. - */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT; -/** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); +CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CTxMemPool mempool(::minRelayTxFee); @@ -1004,10 +1002,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C dFreeCount += nSize; } - if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) + if (fRejectAbsurdFee && nFees > maxTxFee) return state.Invalid(false, REJECT_HIGHFEE, "absurdly-high-fee", - strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000)); + strprintf("%d > %d", nFees, maxTxFee)); // Calculate in-mempool ancestors, up to a limit. CTxMemPool::setEntries setAncestors; diff --git a/src/main.h b/src/main.h index 98069a225..6f87d17f9 100644 --- a/src/main.h +++ b/src/main.h @@ -46,6 +46,12 @@ static const bool DEFAULT_ALERTS = true; static const bool DEFAULT_WHITELISTALWAYSRELAY = true; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; +//! -maxtxfee default +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! Discourage users to set fees higher than this amount (in satoshis) per kB +static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; +//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) +static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -limitancestorcount, max number of in-mempool ancestors */ @@ -138,8 +144,12 @@ extern unsigned int nBytesPerSigOp; extern bool fCheckBlockIndex; extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; +/** A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) */ extern CFeeRate minRelayTxFee; +/** Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendrawtransaction) */ +extern CAmount maxTxFee; extern bool fAlerts; +/* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ extern int64_t nMaxTipAge; extern bool fPermitReplacement; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5b8bd5549..dd9d549f6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -37,7 +37,6 @@ using namespace std; * Settings */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); -CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ffc7dcbd2..28d2f8a04 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -32,7 +32,6 @@ * Settings */ extern CFeeRate payTxFee; -extern CAmount maxTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; @@ -40,14 +39,10 @@ extern bool fSendFreeTransactions; static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default static const CAmount DEFAULT_TRANSACTION_FEE = 0; -//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB -static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; //! -fallbackfee default static const CAmount DEFAULT_FALLBACK_FEE = 20000; //! -mintxfee default static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; -//! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; //! minimum change amount static const CAmount MIN_CHANGE = CENT; //! Default for -spendzeroconfchange @@ -56,8 +51,6 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; -//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) -static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; @@ -211,6 +204,7 @@ public: int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; + /** Pass this transaction to the mempool. Fails if absolute fee exceeds maxTxFee. */ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } From 62f7f2ee219416a6abbf35e830d7cbc7057f02c9 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 31 Jan 2016 02:32:00 +0000 Subject: [PATCH 0195/1223] Bugfix: Always include univalue in DIST_SUBDIRS --- src/Makefile.am | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 97593bfe8..8d95b0d23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,10 @@ -DIST_SUBDIRS = secp256k1 +DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(HARDENED_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) if EMBEDDED_UNIVALUE -DIST_SUBDIRS += univalue - LIBUNIVALUE = univalue/libunivalue.la $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) From cdcad9fc5f64a4c1d06fa62e6541cc0bb7646f06 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 31 Jan 2016 02:32:55 +0000 Subject: [PATCH 0196/1223] LDADD dependency order shuffling --- src/Makefile.bench.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 00a80ae81..7062dd62e 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -14,12 +14,12 @@ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bench_bench_bitcoin_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_COMMON) \ - $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ - $(LIBSECP256K1) + $(LIBSECP256K1) \ + $(LIBUNIVALUE) if ENABLE_ZMQ bench_bench_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) From 2f19905324078e07d8c21b991ef010da80403d95 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Sun, 31 Jan 2016 00:40:23 -0500 Subject: [PATCH 0197/1223] Improve block validity/ConnectBlock() comments Previously didn't make clear that the ContextualCheckBlock* functions meant the block headers as context - not the UTXO set itself - and that ConnectBlock() also did UTXO-related validity checks (in the future we may split that functionality into a separate UTXO-specific contextual check block function). Also, reordered to put validity checks first for better readability. --- src/main.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main.h b/src/main.h index 98069a225..4a5131776 100644 --- a/src/main.h +++ b/src/main.h @@ -395,23 +395,27 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus /** Functions for validating blocks and updating the block tree */ +/** Context-independent validity checks */ +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); +bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); + +/** Context-dependent validity checks. + * By "context", we mean only the previous block headers, but not the UTXO + * set; UTXO-related validity checks are done in ConnectBlock(). */ +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); + +/** Apply the effects of this block (with given index) on the UTXO set represented by coins. + * Validity checks that depend on the UTXO set are also done; ConnectBlock() + * can fail if those validity checks fail (among other reasons). */ +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); + /** Undo the effects of this block (with given index) on the UTXO set represented by coins. * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean * will be true if no problems were found. Otherwise, the return value will be false in case * of problems. Note that in any case, coins may be modified. */ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); -/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); - -/** Context-independent validity checks */ -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); -bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); - -/** Context-dependent validity checks */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); -bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); - /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); From 67958519fe22105dff84a3a8118bfc23a8035fb0 Mon Sep 17 00:00:00 2001 From: gladoscc Date: Mon, 1 Feb 2016 19:55:08 +1100 Subject: [PATCH 0198/1223] Add link to whitepaper --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 77d30db69..b568978f0 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. For more information, as well as an immediately useable, binary version of -the Bitcoin Core software, see https://www.bitcoin.org/en/download. +the Bitcoin Core software, see https://www.bitcoin.org/en/download, or read the +[original whitepaper](https://bitcoincore.org/bitcoin.pdf). License ------- From 89d113e02a83617b4e971c160d47551476dacc71 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 31 Jan 2016 11:59:18 +0000 Subject: [PATCH 0199/1223] Blacklist -whitelistalwaysrelay; replaced by -whitelistrelay. --- contrib/devtools/check-doc.py | 2 +- src/init.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 9c589e6e6..8c73cf1e8 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_RO REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay']) def main(): used = check_output(CMD_GREP_ARGS, shell=True) diff --git a/src/init.cpp b/src/init.cpp index e67193b32..173570069 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -751,7 +751,7 @@ void InitParameterInteraction() LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); } - // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode + // disable walletbroadcast and whitelistrelay in blocksonly mode if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { if (SoftSetBoolArg("-whitelistrelay", false)) LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__); @@ -902,6 +902,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-benchmark", false)) InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); + if (GetBoolArg("-whitelistalwaysrelay", false)) + InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); + // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { From 5d743099b5fe77ba423110bea4f5dfd854fef3b2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 21 Jan 2016 13:15:19 +0100 Subject: [PATCH 0200/1223] Get rid of inaccurate ScriptSigArgsExpected (cherry picked from commit 52b29dca7670c3f6d2ab918c0fff1d17c4e494ad) --- src/policy/policy.cpp | 37 ++++++---------------------------- src/script/standard.cpp | 21 ------------------- src/script/standard.h | 1 - src/test/script_P2SH_tests.cpp | 9 --------- src/test/transaction_tests.cpp | 8 -------- 5 files changed, 6 insertions(+), 70 deletions(-) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 019df7227..332abc430 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -132,45 +132,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) const CScript& prevScript = prev.scriptPubKey; if (!Solver(prevScript, whichType, vSolutions)) return false; - int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); - if (nArgsExpected < 0) - return false; - - // Transactions with extra stuff in their scriptSigs are - // non-standard. Note that this EvalScript() call will - // be quick, because if there are any operations - // beside "push data" in the scriptSig - // IsStandardTx() will have already returned false - // and this method isn't called. - std::vector > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) - return false; if (whichType == TX_SCRIPTHASH) { + std::vector > stack; + // convert the scriptSig into a stack, so we can inspect the redeemScript + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0)) + return false; if (stack.empty()) return false; CScript subscript(stack.back().begin(), stack.back().end()); - std::vector > vSolutions2; - txnouttype whichType2; - if (Solver(subscript, whichType2, vSolutions2)) - { - int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); - if (tmpExpected < 0) - return false; - nArgsExpected += tmpExpected; - } - else - { - // Any other Script with less than 15 sigops OK: - unsigned int sigops = subscript.GetSigOpCount(true); - // ... extra data left on the stack after execution is OK, too: - return (sigops <= MAX_P2SH_SIGOPS); + if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) { + return false; } } - - if (stack.size() != (unsigned int)nArgsExpected) - return false; } return true; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 30935768a..67b6af327 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -161,27 +161,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutions) -{ - switch (t) - { - case TX_NONSTANDARD: - case TX_NULL_DATA: - return -1; - case TX_PUBKEY: - return 1; - case TX_PUBKEYHASH: - return 2; - case TX_MULTISIG: - if (vSolutions.size() < 1 || vSolutions[0].size() < 1) - return -1; - return vSolutions[0][0] + 1; - case TX_SCRIPTHASH: - return 1; // doesn't include args needed by the script - } - return -1; -} - bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { vector vSolutions; diff --git a/src/script/standard.h b/src/script/standard.h index 6bac6e409..64bf010ec 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -71,7 +71,6 @@ typedef boost::variant CTxDestination; const char* GetTxnOutputType(txnouttype t); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); -int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 7bd4b8441..28b85e8d2 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -346,15 +346,6 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U); - // Make sure adding crap to the scriptSigs makes them non-standard: - for (int i = 0; i < 3; i++) - { - CScript t = txTo.vin[i].scriptSig; - txTo.vin[i].scriptSig = (CScript() << 11) + t; - BOOST_CHECK(!::AreInputsStandard(txTo, coins)); - txTo.vin[i].scriptSig = t; - } - CMutableTransaction txToNonStd1; txToNonStd1.vout.resize(1); txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID()); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 3dca7ea0f..c27f194b5 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -310,14 +310,6 @@ BOOST_AUTO_TEST_CASE(test_Get) BOOST_CHECK(AreInputsStandard(t1, coins)); BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); - - // Adding extra junk to the scriptSig should make it non-standard: - t1.vin[0].scriptSig << OP_11; - BOOST_CHECK(!AreInputsStandard(t1, coins)); - - // ... as should not having enough: - t1.vin[0].scriptSig = CScript(); - BOOST_CHECK(!AreInputsStandard(t1, coins)); } BOOST_AUTO_TEST_CASE(test_IsStandard) From 1e9613ac090ee82f52e1d02a622358b2a1085249 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Thu, 28 Jan 2016 22:44:14 +0000 Subject: [PATCH 0201/1223] Do not absolutely protect local peers from eviction. With automatic tor HS support in place we should probably not be providing absolute protection for local peers, since HS inbound could be used to attack pretty easily. Instead, this counts on the latency metric inside AttemptToEvictConnection to privilege actually local peers. (cherry picked from commit 46dbcd4833115401fecbb052365b4c7725874414) --- src/net.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 48e9e1015..84c5644cc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -899,8 +899,6 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - if (node->addr.IsLocal()) - continue; vEvictionCandidates.push_back(CNodeRef(node)); } } From 1e05727072a58d3538dc654c5a3de83ed58874b8 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 23 Nov 2015 03:48:54 +0000 Subject: [PATCH 0202/1223] Decide eviction group ties based on time. This corrects a bug the case of tying group size where the code may fail to select the group with the newest member. Since newest time is the final selection criteria, failing to break ties on it on the step before can undermine the final selection. Tied netgroups are very common. (cherry picked from commit 8e09f914f8ec66301257358b250e9a61befadd95) --- src/net.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 84c5644cc..14e22f6cb 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -929,15 +929,20 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { if (vEvictionCandidates.empty()) return false; - // Identify the network group with the most connections + // Identify the network group with the most connections and youngest member. + // (vEvictionCandidates is already sorted by reverse connect time) std::vector naMostConnections; unsigned int nMostConnections = 0; + int64_t nMostConnectionsTime = 0; std::map, std::vector > mapAddrCounts; BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { mapAddrCounts[node->addr.GetGroup()].push_back(node); + int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected; + size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size(); - if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) { - nMostConnections = mapAddrCounts[node->addr.GetGroup()].size(); + if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { + nMostConnections = groupsize; + nMostConnectionsTime = grouptime; naMostConnections = node->addr.GetGroup(); } } @@ -945,14 +950,13 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { // Reduce to the network group with the most connections vEvictionCandidates = mapAddrCounts[naMostConnections]; - // Do not disconnect peers if there is only 1 connection from their network group + // Do not disconnect peers if there is only one unprotected connection from their network group. if (vEvictionCandidates.size() <= 1) // unless we prefer the new connection (for whitelisted peers) if (!fPreferNewConnection) return false; - // Disconnect the most recent connection from the network group with the most connections - std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); + // Disconnect from the network group with the most connections vEvictionCandidates[0]->fDisconnect = true; return true; From fa1b80db889307f5259961ae22128b88b9437b03 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 1 Feb 2016 16:32:51 +0100 Subject: [PATCH 0203/1223] [travis] Only run check-doc.py once --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71cee9925..75c4760b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ env: global: - MAKEJOBS=-j3 - RUN_TESTS=false + - CHECK_DOC=0 - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID - CCACHE_SIZE=100M - CCACHE_TEMPDIR=/tmp/.ccache-temp @@ -29,7 +30,7 @@ matrix: fast_finish: true include: - compiler: ": ARM" - env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" env: HOST=i686-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": 32-bit + dash" @@ -61,10 +62,10 @@ script: - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi + - if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir PACKAGE=bitcoin VERSION=$HOST - - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi - cd bitcoin-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) From 42407ed43ad24ac1016eb457a7b0e720e63188cd Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 1 Feb 2016 18:49:24 +0000 Subject: [PATCH 0204/1223] build-unix: Update UniValue build conditions --- doc/build-unix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 0f7b5a5f7..50c12ebef 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -46,7 +46,7 @@ Optional dependencies: qt | GUI | GUI toolkit (only needed when GUI enabled) protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) - univalue | Utility | JSON parsing and encoding (if missing, bundled version will be used) + univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x) For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. From dbb89dc793b0fc19a0d0ac5c4ef08cc2760b06bf Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 17 Dec 2015 13:45:33 -0500 Subject: [PATCH 0205/1223] Eliminate unnecessary call to CheckBlock ProcessNewBlock would return failure early if CheckBlock failed, before calling AcceptBlock. AcceptBlock also calls CheckBlock, and upon failure would update mapBlockIndex to indicate that a block was failed. By returning early in ProcessNewBlock, we were not marking blocks that fail a check in CheckBlock as permanently failed, and thus would continue to re-request and reprocess them. --- src/main.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bc7b0daaf..01d1024b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3171,16 +3171,10 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp) { - // Preliminary checks - bool checked = CheckBlock(*pblock, state); - { LOCK(cs_main); bool fRequested = MarkBlockAsReceived(pblock->GetHash()); fRequested |= fForceProcessing; - if (!checked) { - return error("%s: CheckBlock FAILED %s", __func__, FormatStateMessage(state)); - } // Store to disk CBlockIndex *pindex = NULL; From b922fbe063b46862aae6efb35074d1e010fe7006 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 1 Feb 2016 19:30:37 +0000 Subject: [PATCH 0206/1223] Rename replacebyfee=opt-in to mempoolreplacement=fee --- src/init.cpp | 10 +++++----- src/main.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 80b014eb9..b5b1cb822 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -489,7 +489,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); - strUsage += HelpMessageOpt("-replacebyfee", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); + strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); @@ -1033,13 +1033,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); - fEnableReplacement = GetBoolArg("-replacebyfee", DEFAULT_ENABLE_REPLACEMENT); - if ((!fEnableReplacement) && mapArgs.count("-replacebyfee")) { + fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); + if ((!fEnableReplacement) && mapArgs.count("-mempoolreplacement")) { // Minimal effort at forwards compatibility - std::string strReplacementModeList = GetArg("-replacebyfee", ""); // default is impossible + std::string strReplacementModeList = GetArg("-mempoolreplacement", ""); // default is impossible std::vector vstrReplacementModes; boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(",")); - fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "opt-in") != vstrReplacementModes.end()); + fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log diff --git a/src/main.h b/src/main.h index ec426003a..0bbec1e8c 100644 --- a/src/main.h +++ b/src/main.h @@ -107,7 +107,7 @@ static const bool DEFAULT_TXINDEX = false; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; static const bool DEFAULT_TESTSAFEMODE = false; -/** Default for -replacebyfee */ +/** Default for -mempoolreplacement */ static const bool DEFAULT_ENABLE_REPLACEMENT = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ From fa1193e25440671300f428670c14dd15110f7714 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 2 Feb 2016 13:40:54 +0100 Subject: [PATCH 0207/1223] [doxygen] Actually display comment --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 6f87d17f9..fccc14b9e 100644 --- a/src/main.h +++ b/src/main.h @@ -149,7 +149,7 @@ extern CFeeRate minRelayTxFee; /** Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendrawtransaction) */ extern CAmount maxTxFee; extern bool fAlerts; -/* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ +/** If the tip is older than this (in seconds), the node is considered to be in initial block download. */ extern int64_t nMaxTipAge; extern bool fPermitReplacement; From fa79db2641182b47b4077345d8261d28c4a87bf0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 20 Nov 2015 16:48:06 +0100 Subject: [PATCH 0208/1223] Move maxTxFee out of mempool Also, remove default values in CMerkleTx::AcceptToMemoryPool() --- src/main.cpp | 10 +++++----- src/main.h | 2 +- src/rpc/rawtransaction.cpp | 8 ++++---- src/test/txvalidationcache_tests.cpp | 2 +- src/wallet/wallet.cpp | 8 ++++---- src/wallet/wallet.h | 5 +++-- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4d16b9f9a..9ed9d0e0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -813,7 +813,7 @@ std::string FormatStateMessage(const CValidationState &state) } bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, + bool* pfMissingInputs, bool fOverrideMempoolLimit, CAmount nAbsurdFee, std::vector& vHashTxnToUncache) { const uint256 hash = tx.GetHash(); @@ -1002,10 +1002,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C dFreeCount += nSize; } - if (fRejectAbsurdFee && nFees > maxTxFee) + if (nAbsurdFee && nFees > nAbsurdFee) return state.Invalid(false, REJECT_HIGHFEE, "absurdly-high-fee", - strprintf("%d > %d", nFees, maxTxFee)); + strprintf("%d > %d", nFees, nAbsurdFee)); // Calculate in-mempool ancestors, up to a limit. CTxMemPool::setEntries setAncestors; @@ -1220,10 +1220,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C } bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) + bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) { std::vector vHashTxToUncache; - bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, vHashTxToUncache); + bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache); if (!res) { BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache) pcoinsTip->Uncache(hashTx); diff --git a/src/main.h b/src/main.h index 793737422..2bea277c0 100644 --- a/src/main.h +++ b/src/main.h @@ -281,7 +281,7 @@ void PruneAndFlush(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit=false, bool fRejectAbsurdFee=false); + bool* pfMissingInputs, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 2ec80f468..de89fdeb0 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -810,9 +810,9 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); uint256 hashTx = tx.GetHash(); - bool fOverrideFees = false; - if (params.size() > 1) - fOverrideFees = params[1].get_bool(); + CAmount nMaxRawTxFee = maxTxFee; + if (params.size() > 1 && params[1].get_bool()) + nMaxRawTxFee = 0; CCoinsViewCache &view = *pcoinsTip; const CCoins* existingCoins = view.AccessCoins(hashTx); @@ -822,7 +822,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) // push to local node and sync with wallets CValidationState state; bool fMissingInputs; - if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, !fOverrideFees)) { + if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, nMaxRawTxFee)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 66be9d3d5..c29e30792 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, false); + return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dd9d549f6..ca7cd0c28 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1251,7 +1251,7 @@ void CWallet::ReacceptWalletTransactions() CWalletTx& wtx = *(item.second); LOCK(mempool.cs); - wtx.AcceptToMemoryPool(false); + wtx.AcceptToMemoryPool(false, maxTxFee); } } @@ -2268,7 +2268,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (fBroadcastTransactions) { // Broadcast - if (!wtxNew.AcceptToMemoryPool(false)) + if (!wtxNew.AcceptToMemoryPool(false, maxTxFee)) { // This must not fail. The transaction has already been signed and recorded. LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); @@ -3025,8 +3025,8 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) +bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 28d2f8a04..c5b277151 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -7,6 +7,7 @@ #define BITCOIN_WALLET_WALLET_H #include "amount.h" +#include "main.h" #include "streams.h" #include "tinyformat.h" #include "ui_interface.h" @@ -204,8 +205,8 @@ public: int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; - /** Pass this transaction to the mempool. Fails if absolute fee exceeds maxTxFee. */ - bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); + /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ + bool AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } From cc2095ecae3f4ff57d3981b5992e032e564ba65d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 3 Feb 2016 05:16:49 +0000 Subject: [PATCH 0209/1223] Rewrite FormatParagraph to handle newlines within input strings correctly --- src/test/util_tests.cpp | 21 ++++++++++++--- src/utilstrencodings.cpp | 56 ++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 997dc3193..1bbd497f7 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -399,12 +399,27 @@ BOOST_AUTO_TEST_CASE(test_FormatParagraph) { BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), ""); BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test"); - BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), "test"); + BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test"); BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test"); BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest"); - BOOST_CHECK_EQUAL(FormatParagraph("testerde test ", 4, 0), "testerde\ntest"); + BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest"); BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test"); - BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string."), "This is a very long test string. This is a second sentence in the very long\ntest string."); + + // Make sure we don't indent a fully-new line following a too-long line ending + BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc"); + + BOOST_CHECK_EQUAL(FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length until it gets here", 79), "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length\nuntil it gets here"); + + // Test wrap length is exact + BOOST_CHECK_EQUAL(FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p"); + BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p"); + // Indent should be included in length of lines + BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h i j k", 79, 4), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\n f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg\n h i j k"); + + BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string.", 79), "This is a very long test string. This is a second sentence in the very long\ntest string."); + BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string."); + BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string."); + BOOST_CHECK_EQUAL(FormatParagraph("Testing that normal newlines do not get indented.\nLike here.", 79), "Testing that normal newlines do not get indented.\nLike here."); } BOOST_AUTO_TEST_CASE(test_FormatSubVersion) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index c5a2b5cdb..a098c3e0a 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -478,34 +478,40 @@ bool ParseDouble(const std::string& str, double *out) std::string FormatParagraph(const std::string& in, size_t width, size_t indent) { std::stringstream out; - size_t col = 0; size_t ptr = 0; - while(ptr < in.size()) + size_t indented = 0; + while (ptr < in.size()) { - // Find beginning of next word - ptr = in.find_first_not_of(' ', ptr); - if (ptr == std::string::npos) - break; - // Find end of next word - size_t endword = in.find_first_of(' ', ptr); - if (endword == std::string::npos) - endword = in.size(); - // Add newline and indentation if this wraps over the allowed width - if (col > 0) - { - if ((col + endword - ptr) > width) - { - out << '\n'; - for(size_t i=0; i Date: Wed, 3 Feb 2016 05:38:27 +0000 Subject: [PATCH 0210/1223] When/if the copyright line does not mention Bitcoin Core developers, add a second line to copyrights in -version, About dialog, and splash screen --- src/bitcoind.cpp | 3 ++- src/init.cpp | 9 ++++----- src/qt/splashscreen.cpp | 11 ++++++++--- src/qt/utilitydialog.cpp | 2 +- src/util.cpp | 14 +++++++++----- src/util.h | 2 +- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 440356aa8..9ad5a4786 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -17,6 +17,7 @@ #include "httpserver.h" #include "httprpc.h" #include "rpcserver.h" +#include "utilstrencodings.h" #include #include @@ -82,7 +83,7 @@ bool AppInit(int argc, char* argv[]) if (mapArgs.count("-version")) { - strUsage += LicenseInfo(); + strUsage += FormatParagraph(LicenseInfo()); } else { diff --git a/src/init.cpp b/src/init.cpp index 8a9cc6d96..5746fb512 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -33,7 +33,6 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" -#include "utilstrencodings.h" #include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/db.h" @@ -513,13 +512,13 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { // todo: remove urls from translations on next change - return FormatParagraph(strprintf(_("Copyright (C) %i-%i %s"), 2009, COPYRIGHT_YEAR, CopyrightHolders())) + "\n" + + return CopyrightHolders(strprintf(_("Copyright (C) %i-%i"), 2009, COPYRIGHT_YEAR) + " ") + "\n" + "\n" + - FormatParagraph(_("This is experimental software.")) + "\n" + + _("This is experimental software.") + "\n" + "\n" + - FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or .")) + "\n" + + _("Distributed under the MIT software license, see the accompanying file COPYING or .") + "\n" + "\n" + - FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) + + _("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.") + "\n"; } diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 4d745088a..21dab957f 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -44,7 +44,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) // define text to place QString titleText = tr(PACKAGE_NAME); QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion())); - QString copyrightText = QChar(0xA9)+QString(" %1-%2 ").arg(2009).arg(COPYRIGHT_YEAR) + QString::fromStdString(CopyrightHolders()); + QString copyrightText = QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR)).c_str()); QString titleAddText = networkStyle->getTitleAddText(); QString font = QApplication::font().toString(); @@ -101,8 +101,13 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); // draw copyright stuff - pixPaint.setFont(QFont(font, 10*fontFactor)); - pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); + { + pixPaint.setFont(QFont(font, 10*fontFactor)); + const int x = pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight; + const int y = paddingTop+titleCopyrightVSpace; + QRect copyrightRect(x, y, pixmap.width() - x - paddingRight, pixmap.height() - y); + pixPaint.drawText(copyrightRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, copyrightText); + } // draw additional text if special network if(!titleAddText.isEmpty()) { diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 3e96f26b3..5fafa5759 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -56,7 +56,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : uri.setMinimal(true); // use non-greedy matching licenseInfoHTML.replace(uri, "\\1"); // Replace newlines with HTML breaks - licenseInfoHTML.replace("\n\n", "

"); + licenseInfoHTML.replace("\n", "
"); ui->aboutMessage->setTextFormat(Qt::RichText); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); diff --git a/src/util.cpp b/src/util.cpp index 0439ead47..1f6b84119 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -834,10 +834,14 @@ int GetNumCores() #endif } -std::string CopyrightHolders() +std::string CopyrightHolders(const std::string& strPrefix) { - std::string strCopyrightHolders = _(COPYRIGHT_HOLDERS); - if (strCopyrightHolders.find("%s") == strCopyrightHolders.npos) - return strCopyrightHolders; - return strprintf(strCopyrightHolders, _(COPYRIGHT_HOLDERS_SUBSTITUTION)); + std::string strCopyrightHolders = strPrefix + _(COPYRIGHT_HOLDERS); + if (strCopyrightHolders.find("%s") != strCopyrightHolders.npos) { + strCopyrightHolders = strprintf(strCopyrightHolders, _(COPYRIGHT_HOLDERS_SUBSTITUTION)); + } + if (strCopyrightHolders.find("Bitcoin Core developers") == strCopyrightHolders.npos) { + strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; + } + return strCopyrightHolders; } diff --git a/src/util.h b/src/util.h index 88e1fe9fb..5a948c6a9 100644 --- a/src/util.h +++ b/src/util.h @@ -242,6 +242,6 @@ template void TraceThread(const char* name, Callable func) } } -std::string CopyrightHolders(); +std::string CopyrightHolders(const std::string& strPrefix); #endif // BITCOIN_UTIL_H From fa762d0f00ba1ad381a749e139f37aef673b70ba Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 3 Feb 2016 12:51:11 +0100 Subject: [PATCH 0211/1223] [wallet.h] Remove main.h include --- src/wallet/wallet.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c5b277151..5072042b8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -7,7 +7,6 @@ #define BITCOIN_WALLET_WALLET_H #include "amount.h" -#include "main.h" #include "streams.h" #include "tinyformat.h" #include "ui_interface.h" From fad6244879be8b9916e85cff4ecdb4377dd62ee2 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 3 Feb 2016 13:14:23 +0100 Subject: [PATCH 0212/1223] ATMP: make nAbsurdFee const --- src/main.cpp | 4 ++-- src/wallet/wallet.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9ed9d0e0b..e4e4bc62b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -812,8 +812,8 @@ std::string FormatStateMessage(const CValidationState &state) state.GetRejectCode()); } -bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, CAmount nAbsurdFee, +bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree, + bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee, std::vector& vHashTxnToUncache) { const uint256 hash = tx.GetHash(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 5072042b8..c02323d6e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -205,7 +205,7 @@ public: bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ - bool AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee); + bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } From c77c6625f3fc88e461a9ec11672edb6a9d4cfd98 Mon Sep 17 00:00:00 2001 From: kirkalx Date: Tue, 2 Feb 2016 22:45:11 +1300 Subject: [PATCH 0213/1223] peers.dat, banlist.dat recreated when missing --- src/net.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 48e9e1015..be00b2d3d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1941,8 +1941,10 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) CAddrDB adb; if (adb.Read(addrman)) LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); - else + else { LogPrintf("Invalid or missing peers.dat; recreating\n"); + DumpAddresses(); + } } uiInterface.InitMessage(_("Loading banlist...")); @@ -1957,8 +1959,11 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); - } else + } else { LogPrintf("Invalid or missing banlist.dat; recreating\n"); + CNode::SetBannedSetDirty(true); // force write + DumpBanlist(); + } fAddressesInitialized = true; From fa616c2fedd19d8e88f042abd5e99ac9595923df Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 25 Dec 2015 13:09:26 +0100 Subject: [PATCH 0214/1223] [doc] Update release-process.md --- doc/release-process.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 39e3032a6..8fb083d0d 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -3,6 +3,7 @@ Release Process * Update translations (ping wumpus, Diapolo or tcatm on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex) * Update [bips.md](bips.md) to account for changes since the last release. +* Update hardcoded [seeds](/contrib/seeds) * * * @@ -19,8 +20,10 @@ Check out the source code in the following directory hierarchy. pushd ./bitcoin contrib/verifysfbinaries/verify.sh + configure.ac doc/README* - share/setup.nsi + doc/Doxyfile + contrib/gitian-descriptors/*.yml src/clientversion.h (change CLIENT_VERSION_IS_RELEASE to true) # tag version in git @@ -84,16 +87,21 @@ NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from ``` The gbuild invocations below DO NOT DO THIS by default. -###Build and Sign Bitcoin Core for Linux, Windows, and OS X: +###Build and sign Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz + mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz + mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ Build output expected: @@ -115,13 +123,6 @@ The gbuild invocations below DO NOT DO THIS by default. ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml -###Move the outputs to the correct directory - - mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ - mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz - mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ - mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz - mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ popd ###Next steps: @@ -137,7 +138,6 @@ Commit your signature to gitian.sigs: popd Wait for Windows/OS X detached signatures: - Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys. Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries. From f3757a039196c804f252a4efba294e8f2b4d301d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 2 Dec 2015 03:15:42 +0100 Subject: [PATCH 0215/1223] Consensus: Decouple pow.cpp from util.h --- src/main.cpp | 5 +++-- src/pow.cpp | 12 ++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4d16b9f9a..8bed2962f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2291,8 +2291,9 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, + LogPrintf("%s: new best=%s height=%d bits=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nBits, + log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); diff --git a/src/pow.cpp b/src/pow.cpp index 40c72f9d7..058404f35 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -9,7 +9,6 @@ #include "chain.h" #include "primitives/block.h" #include "uint256.h" -#include "util.h" unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { @@ -57,7 +56,6 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; - LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan); if (nActualTimespan < params.nPowTargetTimespan/4) nActualTimespan = params.nPowTargetTimespan/4; if (nActualTimespan > params.nPowTargetTimespan*4) @@ -75,12 +73,6 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF if (bnNew > bnPowLimit) bnNew = bnPowLimit; - /// debug print - LogPrintf("GetNextWorkRequired RETARGET\n"); - LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan); - LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString()); - LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); - return bnNew.GetCompact(); } @@ -94,11 +86,11 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) - return error("CheckProofOfWork(): nBits below minimum work"); + return false; // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) - return error("CheckProofOfWork(): hash doesn't match nBits"); + return false; return true; } From 7689041c03278a09c88a2bb78cd00217f6d4b1de Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Thu, 4 Feb 2016 14:36:11 -0500 Subject: [PATCH 0216/1223] [rpc-tests] Change solve() to use rehash --- qa/rpc-tests/test_framework/mininode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index ca65fb6e7..2135570b8 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -536,7 +536,7 @@ class CBlock(CBlockHeader): return True def solve(self): - self.calc_sha256() + self.rehash() target = uint256_from_compact(self.nBits) while self.sha256 > target: self.nNonce += 1 From 0830552673e37142599de897e87510f2f9866e1e Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 4 Feb 2016 17:15:20 -0600 Subject: [PATCH 0217/1223] Fix spelling: misbeha{b,v}ing --- src/net.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.h b/src/net.h index 5f249c445..833c9cf07 100644 --- a/src/net.h +++ b/src/net.h @@ -302,7 +302,7 @@ public: { switch (banReason) { case BanReasonNodeMisbehaving: - return "node misbehabing"; + return "node misbehaving"; case BanReasonManuallyAdded: return "manually added"; default: From 72fd008e7fa5a85dd1d3e69d7c194a6160ec3615 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Sun, 7 Feb 2016 14:06:07 +0100 Subject: [PATCH 0218/1223] Fix quoting of copyright holders in configure.ac. The old configure.ac did not work for a copyright holders string containing commas due to insufficient quoting. The new one allows this. While this is, of course, not of direct consequence to the current code (where the string is "Bitcoin Core"), it should still be fixed now that the string is actually factored out. --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 939dfeaab..bd30b6ab8 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) define(_COPYRIGHT_YEAR, 2016) define(_COPYRIGHT_HOLDERS,[The %s developers]) -define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[Bitcoin Core]) +define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]]) AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[https://bitcoincore.org/]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) @@ -999,10 +999,10 @@ AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision]) AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) -AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release]) +AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Copyright year]) AC_DEFINE(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS", [Copyright holder(s) before %s replacement]) AC_DEFINE(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION", [Replacement for %s in copyright holders string]) -define(_COPYRIGHT_HOLDERS_FINAL, patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])) +define(_COPYRIGHT_HOLDERS_FINAL, [patsubst(_COPYRIGHT_HOLDERS, [%s], [_COPYRIGHT_HOLDERS_SUBSTITUTION])]) AC_DEFINE(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL", [Copyright holder(s)]) AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) From 7c06fbd8f58058d77c3e9da841811201d2e45e92 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 5 Feb 2016 10:45:50 +0100 Subject: [PATCH 0219/1223] rpc: Add WWW-Authenticate header to 401 response A WWW-Authenticate header must be present in the 401 response to make clients know that they can authenticate, and how. WWW-Authenticate: Basic realm="jsonrpc" Fixes #7462. --- src/httprpc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 432a5c079..a447a3eff 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -21,6 +21,9 @@ #include // boost::trim #include //BOOST_FOREACH +/** WWW-Authenticate to present with 401 Unauthorized response */ +static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; + /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. * re-lock the wellet. */ @@ -151,6 +154,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) // Check authorization std::pair authHeader = req->GetHeader("authorization"); if (!authHeader.first) { + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } @@ -163,6 +167,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) shouldn't have their RPC port exposed. */ MilliSleep(250); + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } From 993d089e82fc045d7b0f23e1a5dc934cba0e3306 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Mon, 8 Feb 2016 10:49:27 -0500 Subject: [PATCH 0220/1223] Changed getnetworkhps value to double to avoid overflow. --- src/rpc/mining.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 996b7f9cb..fec0987a4 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -68,7 +68,7 @@ UniValue GetNetworkHashPS(int lookup, int height) { arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; int64_t timeDiff = maxTime - minTime; - return (int64_t)(workDiff.getdouble() / timeDiff); + return workDiff.getdouble() / timeDiff; } UniValue getnetworkhashps(const UniValue& params, bool fHelp) From 301bc7bc7e83f4c268c1722558b07dbb5b55fa92 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 8 Feb 2016 15:32:29 -0500 Subject: [PATCH 0221/1223] Update nQueuedValidatedHeaders after peer disconnection --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 984523408..94071d381 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -332,8 +332,10 @@ void FinalizeNode(NodeId nodeid) { AddressCurrentlyConnected(state->address); } - BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) + BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) { + nQueuedValidatedHeaders -= entry.fValidatedHeaders; mapBlocksInFlight.erase(entry.hash); + } EraseOrphansFor(nodeid); nPreferredDownload -= state->fPreferredDownload; From 1ecbb3b0f717c277f3db1a923fff16f7fc39432c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Feb 2016 03:29:23 +0000 Subject: [PATCH 0222/1223] depends: Use curl for fetching on Linux Currently Travis's wget fails fetching qrencode: Fetching qrencode... ERROR: no certificate subject alternative name matches requested host name `fukuchi.org'. To connect to fukuchi.org insecurely, use `--no-check-certificate'. OpenSSL: error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error Unable to establish SSL connection. make: *** [/home/travis/build/luke-jr/bitcoin/depends/sources/download-stamps/.stamp_fetched-qrencode-qrencode-3.4.4.tar.bz2.hash] Error 4 --- depends/builders/linux.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index 98d0e9de3..75055e77e 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O +build_linux_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o From 5d1148cb79856ac4695a0c7ac1cd28ada04eff34 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Feb 2016 05:53:39 +0000 Subject: [PATCH 0223/1223] Travis: Use curl rather than wget for Mac SDK --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2d43d633..fa44ace5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ install: before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: From 7539f1aae3b41279dc5d49e09f448a78a071e114 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 9 Feb 2016 12:37:05 +0100 Subject: [PATCH 0224/1223] tests: Make proxy_test work on travis servers without IPv6 --- qa/rpc-tests/proxy_test.py | 74 +++++++++++++++----------- qa/rpc-tests/test_framework/netutil.py | 15 ++++++ 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 7f77e664d..b3c65573e 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -7,6 +7,7 @@ import socket from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.netutil import test_ipv6_local ''' Test plan: - Start bitcoind's with different proxy configurations @@ -34,6 +35,7 @@ addnode connect to generic DNS name class ProxyTest(BitcoinTestFramework): def __init__(self): + self.have_ipv6 = test_ipv6_local() # Create two proxies on different ports # ... one unauthenticated self.conf1 = Socks5Configuration() @@ -45,29 +47,36 @@ class ProxyTest(BitcoinTestFramework): self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000)) self.conf2.unauth = True self.conf2.auth = True - # ... one on IPv6 with similar configuration - self.conf3 = Socks5Configuration() - self.conf3.af = socket.AF_INET6 - self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000)) - self.conf3.unauth = True - self.conf3.auth = True + if self.have_ipv6: + # ... one on IPv6 with similar configuration + self.conf3 = Socks5Configuration() + self.conf3.af = socket.AF_INET6 + self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000)) + self.conf3.unauth = True + self.conf3.auth = True + else: + print "Warning: testing without local IPv6 support" self.serv1 = Socks5Server(self.conf1) self.serv1.start() self.serv2 = Socks5Server(self.conf2) self.serv2.start() - self.serv3 = Socks5Server(self.conf3) - self.serv3.start() + if self.have_ipv6: + self.serv3 = Socks5Server(self.conf3) + self.serv3.start() def setup_nodes(self): # Note: proxies are not used to connect to local nodes # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost - return start_nodes(4, self.options.tmpdir, extra_args=[ + args = [ ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'], ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'], ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'], - ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion'] - ]) + [] + ] + if self.have_ipv6: + args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion'] + return start_nodes(4, self.options.tmpdir, extra_args=args) def node_test(self, node, proxies, auth, test_onion=True): rv = [] @@ -84,18 +93,19 @@ class ProxyTest(BitcoinTestFramework): assert_equal(cmd.password, None) rv.append(cmd) - # Test: outgoing IPv6 connection through node - node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry") - cmd = proxies[1].queue.get() - assert(isinstance(cmd, Socks5Command)) - # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 - assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534") - assert_equal(cmd.port, 5443) - if not auth: - assert_equal(cmd.username, None) - assert_equal(cmd.password, None) - rv.append(cmd) + if self.have_ipv6: + # Test: outgoing IPv6 connection through node + node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry") + cmd = proxies[1].queue.get() + assert(isinstance(cmd, Socks5Command)) + # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 + assert_equal(cmd.atyp, AddressType.DOMAINNAME) + assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534") + assert_equal(cmd.port, 5443) + if not auth: + assert_equal(cmd.username, None) + assert_equal(cmd.password, None) + rv.append(cmd) if test_onion: # Test: outgoing onion connection through node @@ -135,10 +145,11 @@ class ProxyTest(BitcoinTestFramework): rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True) # Check that credentials as used for -proxyrandomize connections are unique credentials = set((x.username,x.password) for x in rv) - assert_equal(len(credentials), 4) + assert_equal(len(credentials), len(rv)) - # proxy on IPv6 localhost - self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False) + if self.have_ipv6: + # proxy on IPv6 localhost + self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False) def networks_dict(d): r = {} @@ -167,11 +178,12 @@ class ProxyTest(BitcoinTestFramework): assert_equal(n2[net]['proxy_randomize_credentials'], True) assert_equal(n2['onion']['reachable'], True) - n3 = networks_dict(self.nodes[3].getnetworkinfo()) - for net in ['ipv4','ipv6']: - assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr)) - assert_equal(n3[net]['proxy_randomize_credentials'], False) - assert_equal(n3['onion']['reachable'], False) + if self.have_ipv6: + n3 = networks_dict(self.nodes[3].getnetworkinfo()) + for net in ['ipv4','ipv6']: + assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr)) + assert_equal(n3[net]['proxy_randomize_credentials'], False) + assert_equal(n3['onion']['reachable'], False) if __name__ == '__main__': ProxyTest().main() diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index 50daa8793..bfdef76ad 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -137,3 +137,18 @@ def addr_to_hex(addr): else: raise ValueError('Could not parse address %s' % addr) return binascii.hexlify(bytearray(addr)) + +def test_ipv6_local(): + ''' + Check for (local) IPv6 support. + ''' + import socket + # By using SOCK_DGRAM this will not actually make a connection, but it will + # fail if there is no route to IPv6 localhost. + have_ipv6 = True + try: + s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + s.connect(('::1', 0)) + except socket.error: + have_ipv6 = False + return have_ipv6 From acf598350227a506c7c38d4b7f13b68a182a8233 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 9 Feb 2016 16:17:51 +0100 Subject: [PATCH 0225/1223] tests: Remove May15 test This test is no longer relevant. It was introduced in 8c222dca4f961ad13ec64d690134a40d09b20813 to check the switch to 1MB blocks after the BDB too-many-locks issue back in 2013. The switching code has been long since removed. It also needs a specific data file that is hard to find. I've verified in #6320 that it still passes, however I think there is zero reason to keep it. Closes #6320. --- src/Makefile.test.include | 1 - src/test/checkblock_tests.cpp | 66 ----------------------------------- 2 files changed, 67 deletions(-) delete mode 100644 src/test/checkblock_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 468d3043a..6ef6a69a2 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -44,7 +44,6 @@ BITCOIN_TESTS =\ test/base64_tests.cpp \ test/bip32_tests.cpp \ test/bloom_tests.cpp \ - test/checkblock_tests.cpp \ test/Checkpoints_tests.cpp \ test/coins_tests.cpp \ test/compress_tests.cpp \ diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp deleted file mode 100644 index c945a95ad..000000000 --- a/src/test/checkblock_tests.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "clientversion.h" -#include "consensus/validation.h" -#include "main.h" // For CheckBlock -#include "primitives/block.h" -#include "test/test_bitcoin.h" -#include "utiltime.h" - -#include - -#include -#include -#include - - -BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup) - -bool read_block(const std::string& filename, CBlock& block) -{ - namespace fs = boost::filesystem; - fs::path testFile = fs::current_path() / "data" / filename; -#ifdef TEST_DATA_DIR - if (!fs::exists(testFile)) - { - testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; - } -#endif - FILE* fp = fopen(testFile.string().c_str(), "rb"); - if (!fp) return false; - - fseek(fp, 8, SEEK_SET); // skip msgheader/size - - CAutoFile filein(fp, SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) return false; - - filein >> block; - - return true; -} - -BOOST_AUTO_TEST_CASE(May15) -{ - // Putting a 1MB binary file in the git repository is not a great - // idea, so this test is only run if you manually download - // test/data/Mar12Fork.dat from - // http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/Mar12Fork.dat/download - unsigned int tMay15 = 1368576000; - SetMockTime(tMay15); // Test as if it was right at May 15 - - CBlock forkingBlock; - if (read_block("Mar12Fork.dat", forkingBlock)) - { - CValidationState state; - - // After May 15'th, big blocks are OK: - forkingBlock.nTime = tMay15; // Invalidates PoW - BOOST_CHECK(CheckBlock(forkingBlock, state, false, false)); - } - - SetMockTime(0); -} - -BOOST_AUTO_TEST_SUITE_END() From 40e7b61835cbe5fd471d0b4b71972526bf0e523c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 9 Feb 2016 20:23:09 +0100 Subject: [PATCH 0226/1223] wallet: Ignore MarkConflict if block hash is not known If number of conflict confirms cannot be determined, this means that the block is still unknown or not yet part of the main chain, for example during a reindex. Do nothing in that case, instead of crash with an assertion. Fixes #7234. --- src/wallet/wallet.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ade460d6a..65defc30a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -846,14 +846,19 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) { LOCK2(cs_main, cs_wallet); - CBlockIndex* pindex; - assert(mapBlockIndex.count(hashBlock)); - pindex = mapBlockIndex[hashBlock]; int conflictconfirms = 0; - if (chainActive.Contains(pindex)) { - conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); + if (mapBlockIndex.count(hashBlock)) { + CBlockIndex* pindex = mapBlockIndex[hashBlock]; + if (chainActive.Contains(pindex)) { + conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); + } } - assert(conflictconfirms < 0); + // If number of conflict confirms cannot be determined, this means + // that the block is still unknown or not yet part of the main chain, + // for example when loading the wallet during a reindex. Do nothing in that + // case. + if (conflictconfirms >= 0) + return; // Do not flush the wallet here for performance reasons CWalletDB walletdb(strWalletFile, "r+", false); From c01f08db127883ff985889214eebdbe9513c729a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Feb 2016 22:15:25 +0000 Subject: [PATCH 0227/1223] Bugfix: depends/Travis: Use --location (follow redirects) and --fail [on HTTP error response] with curl --- .travis.yml | 2 +- depends/builders/darwin.mk | 2 +- depends/builders/linux.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index fa44ace5f..1c47e8ed0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ install: before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index b366460e6..cedbddc57 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o #darwin host on darwin builder. overrides darwin host preferences. darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index 75055e77e..d6a304e4b 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o From 149641e8fc9996da01eb76ffe4578828c40d37b5 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Feb 2016 22:17:09 +0000 Subject: [PATCH 0228/1223] Travis: Use Blue Box VMs for IPv6 loopback support --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1c47e8ed0..1a5731f3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,12 @@ # compiler key (which we don't use anyway). This is worked around for now by # replacing the "compilers" with a build name prefixed by the no-op ":" # command. See: https://github.com/travis-ci/travis-ci/issues/4393 +# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback] +# IPv6 support + +sudo: required +dist: precise +group: legacy os: linux language: cpp From 9d95187d5ddee56b6dfb55985008bdf70aed31f2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 10 Feb 2016 14:19:20 +0100 Subject: [PATCH 0229/1223] Correctly report high-S violations --- src/script/interpreter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index a92822326..265131ae0 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -165,7 +165,10 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { return set_error(serror, SCRIPT_ERR_SIG_DER); } std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); - return CPubKey::CheckLowS(vchSigCopy); + if (!CPubKey::CheckLowS(vchSigCopy)) { + return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); + } + return true; } bool static IsDefinedHashtypeSignature(const valtype &vchSig) { From e4eebb604e19f67b0c7a483b1ded1229d75ecdd3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 10 Feb 2016 15:47:06 +0100 Subject: [PATCH 0230/1223] Update the wallet best block marker when pruning --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 20539c1ba..3ad2979b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2262,7 +2262,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { return AbortNode(state, "Failed to write to coin database"); nLastFlush = nNow; } - if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) { + if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { // Update best block in wallet (so we can detect restored wallets). GetMainSignals().SetBestChain(chainActive.GetLocator()); nLastSetChain = nNow; From ae6eca0f49b7598ec08dcf278ffc1994b637bc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Wed, 10 Feb 2016 21:03:51 +0100 Subject: [PATCH 0231/1223] make clean should clean .a files --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index c4f718897..fa7a78f33 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -430,6 +430,7 @@ endif # CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a +CLEANFILES += $(EXTRA_LIBRARIES) CLEANFILES += *.gcda *.gcno CLEANFILES += compat/*.gcda compat/*.gcno CLEANFILES += consensus/*.gcda consensus/*.gcno From c6c2f0fd782ccf607027414012f45c8f48561a30 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Mon, 7 Dec 2015 15:44:16 -0500 Subject: [PATCH 0232/1223] Implement SequenceLocks functions SequenceLocks functions are used to evaluate sequence lock times or heights per BIP 68. The majority of this code is copied from maaku in #6312 Further credit: btcdrak, sipa, NicolasDorier --- src/consensus/consensus.h | 5 +- src/main.cpp | 150 ++++++++++++++++++++++++++++++++- src/main.h | 17 +++- src/policy/policy.h | 5 +- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 38 +++++++-- src/script/interpreter.cpp | 2 +- src/test/miner_tests.cpp | 124 ++++++++++++++++++++------- src/test/script_tests.cpp | 4 +- src/txmempool.cpp | 2 +- 10 files changed, 300 insertions(+), 49 deletions(-) diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 6d6ce7e09..1b28bb320 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -13,8 +13,11 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ static const int COINBASE_MATURITY = 100; -/** Flags for LockTime() */ +/** Flags for nSequence and nLockTime locks */ enum { + /* Interpret sequence numbers as relative lock-time constraints. */ + LOCKTIME_VERIFY_SEQUENCE = (1 << 0), + /* Use GetMedianTimePast() instead of nTime for end point timestamp. */ LOCKTIME_MEDIAN_TIME_PAST = (1 << 1), }; diff --git a/src/main.cpp b/src/main.cpp index a0e996ae7..d9bf3bd75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -667,9 +667,10 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) return true; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - if (!txin.IsFinal()) + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL)) return false; + } return true; } @@ -705,6 +706,128 @@ bool CheckFinalTx(const CTransaction &tx, int flags) return IsFinalTx(tx, nBlockHeight, nBlockTime); } +/** + * Calculates the block height and previous block's median time past at + * which the transaction will be considered final in the context of BIP 68. + * Also removes from the vector of input heights any entries which did not + * correspond to sequence locked inputs as they do not affect the calculation. + */ +static std::pair CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeights, const CBlockIndex& block) +{ + assert(prevHeights->size() == tx.vin.size()); + + // Will be set to the equivalent height- and time-based nLockTime + // values that would be necessary to satisfy all relative lock- + // time constraints given our view of block chain history. + // The semantics of nLockTime are the last invalid height/time, so + // use -1 to have the effect of any height or time being valid. + int nMinHeight = -1; + int64_t nMinTime = -1; + + // tx.nVersion is signed integer so requires cast to unsigned otherwise + // we would be doing a signed comparison and half the range of nVersion + // wouldn't support BIP 68. + bool fEnforceBIP68 = static_cast(tx.nVersion) >= 2 + && flags & LOCKTIME_VERIFY_SEQUENCE; + + // Do not enforce sequence numbers as a relative lock time + // unless we have been instructed to + if (!fEnforceBIP68) { + return std::make_pair(nMinHeight, nMinTime); + } + + for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { + const CTxIn& txin = tx.vin[txinIndex]; + + // Sequence numbers with the most significant bit set are not + // treated as relative lock-times, nor are they given any + // consensus-enforced meaning at this point. + if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { + // The height of this input is not relevant for sequence locks + (*prevHeights)[txinIndex] = 0; + continue; + } + + int nCoinHeight = (*prevHeights)[txinIndex]; + + if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { + int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight-1, 0))->GetMedianTimePast(); + // NOTE: Subtract 1 to maintain nLockTime semantics + // BIP 68 relative lock times have the semantics of calculating + // the first block or time at which the transaction would be + // valid. When calculating the effective block time or height + // for the entire transaction, we switch to using the + // semantics of nLockTime which is the last invalid block + // time or height. Thus we subtract 1 from the calculated + // time or height. + + // Time-based relative lock-times are measured from the + // smallest allowed timestamp of the block containing the + // txout being spent, which is the median time past of the + // block prior. + nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1); + } else { + nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1); + } + } + + return std::make_pair(nMinHeight, nMinTime); +} + +static bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair lockPair) +{ + assert(block.pprev); + int64_t nBlockTime = block.pprev->GetMedianTimePast(); + if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) + return false; + + return true; +} + +bool SequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeights, const CBlockIndex& block) +{ + return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block)); +} + +bool CheckSequenceLocks(const CTransaction &tx, int flags) +{ + AssertLockHeld(cs_main); + AssertLockHeld(mempool.cs); + + CBlockIndex* tip = chainActive.Tip(); + CBlockIndex index; + index.pprev = tip; + // CheckSequenceLocks() uses chainActive.Height()+1 to evaluate + // height based locks because when SequenceLocks() is called within + // CBlock::AcceptBlock(), the height of the block *being* + // evaluated is what is used. Thus if we want to know if a + // transaction can be part of the *next* block, we need to call + // SequenceLocks() with one more than chainActive.Height(). + index.nHeight = tip->nHeight + 1; + + // pcoinsTip contains the UTXO set for chainActive.Tip() + CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); + std::vector prevheights; + prevheights.resize(tx.vin.size()); + for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { + const CTxIn& txin = tx.vin[txinIndex]; + CCoins coins; + if (!viewMemPool.GetCoins(txin.prevout.hash, coins)) { + return error("%s: Missing input", __func__); + } + if (coins.nHeight == MEMPOOL_HEIGHT) { + // Assume all mempool transaction confirm in the next block + prevheights[txinIndex] = tip->nHeight + 1; + } else { + prevheights[txinIndex] = coins.nHeight; + } + } + + std::pair lockPair = CalculateSequenceLocks(tx, flags, &prevheights, index); + return EvaluateSequenceLocks(index, lockPair); +} + + unsigned int GetLegacySigOpCount(const CTransaction& tx) { unsigned int nSigOps = 0; @@ -949,6 +1072,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool view.SetBackend(dummy); + + // Only accept BIP68 sequence locked transactions that can be mined in the next + // block; we don't want our mempool filled up with transactions that can't + // be mined yet. + // Must keep pool.cs for this unless we change CheckSequenceLocks to take a + // CoinsViewCache instead of create its own + if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) + return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final"); } // Check for non-standard pay-to-script-hash in inputs @@ -2075,6 +2206,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); + std::vector prevheights; + int nLockTimeFlags = 0; CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; @@ -2098,6 +2231,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): inputs missing/spent"), REJECT_INVALID, "bad-txns-inputs-missingorspent"); + // Check that transaction is BIP68 final + // BIP68 lock checks (as opposed to nLockTime checks) must + // be in ConnectBlock because they require the UTXO set + prevheights.resize(tx.vin.size()); + for (size_t j = 0; j < tx.vin.size(); j++) { + prevheights[j] = view.AccessCoins(tx.vin[j].prevout.hash)->nHeight; + } + + if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { + return state.DoS(100, error("ConnectBlock(): contains a non-BIP68-final transaction", __func__), + REJECT_INVALID, "bad-txns-nonfinal"); + } + if (fStrictPayToScriptHash) { // Add in sigops done by pay-to-script-hash inputs; diff --git a/src/main.h b/src/main.h index 19623f4d9..66b766316 100644 --- a/src/main.h +++ b/src/main.h @@ -341,7 +341,22 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); */ bool CheckFinalTx(const CTransaction &tx, int flags = -1); -/** +/** + * Check if transaction is final per BIP 68 sequence numbers and can be included in a block. + * Consensus critical. Takes as input a list of heights at which tx's inputs (in order) confirmed. + */ +bool SequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeights, const CBlockIndex& block); + +/** + * Check if transaction will be BIP 68 final in the next block to be created. + * + * Calls SequenceLocks() with data from the tip of the current active chain. + * + * See consensus/consensus.h for flag definitions. + */ +bool CheckSequenceLocks(const CTransaction &tx, int flags); + +/** * Closure representing one script verification * Note that this stores references to the spending transaction */ diff --git a/src/policy/policy.h b/src/policy/policy.h index 31655f2f3..5034b2386 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -45,8 +45,9 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; -/** Used as the flags parameter to CheckFinalTx() in non-consensus code */ -static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_MEDIAN_TIME_PAST; +/** Used as the flags parameter to LockTime() in non-consensus code. */ +static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE | + LOCKTIME_MEDIAN_TIME_PAST; bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); /** diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 46d3cbbe2..7d0b20839 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -37,7 +37,7 @@ std::string CTxIn::ToString() const str += strprintf(", coinbase %s", HexStr(scriptSig)); else str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24)); - if (nSequence != std::numeric_limits::max()) + if (nSequence != SEQUENCE_FINAL) str += strprintf(", nSequence=%u", nSequence); str += ")"; return str; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index c5d8a64a6..1dca378b5 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -61,13 +61,40 @@ public: CScript scriptSig; uint32_t nSequence; + /* Setting nSequence to this value for every input in a transaction + * disables nLockTime. */ + static const uint32_t SEQUENCE_FINAL = 0xffffffff; + + /* Below flags apply in the context of BIP 68*/ + /* If this flag set, CTxIn::nSequence is NOT interpreted as a + * relative lock-time. */ + static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); + + /* If CTxIn::nSequence encodes a relative lock-time and this flag + * is set, the relative lock-time has units of 512 seconds, + * otherwise it specifies blocks with a granularity of 1. */ + static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); + + /* If CTxIn::nSequence encodes a relative lock-time, this mask is + * applied to extract that lock-time from the sequence field. */ + static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; + + /* In order to use the same number of bits to encode roughly the + * same wall-clock duration, and because blocks are naturally + * limited to occur every 600s on average, the minimum granularity + * for time-based relative lock-time is fixed at 512 seconds. + * Converting from CTxIn::nSequence to seconds is performed by + * multiplying by 512 = 2^9, or equivalently shifting up by + * 9 bits. */ + static const int SEQUENCE_LOCKTIME_GRANULARITY = 9; + CTxIn() { - nSequence = std::numeric_limits::max(); + nSequence = SEQUENCE_FINAL; } - explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits::max()); - CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits::max()); + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL); + CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL); ADD_SERIALIZE_METHODS; @@ -78,11 +105,6 @@ public: READWRITE(nSequence); } - bool IsFinal() const - { - return (nSequence == std::numeric_limits::max()); - } - friend bool operator==(const CTxIn& a, const CTxIn& b) { return (a.prevout == b.prevout && diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 57e0edc4b..ac753a9d5 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1147,7 +1147,7 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con // prevent this condition. Alternatively we could test all // inputs, but testing just this input minimizes the data // required to prove correct CHECKLOCKTIMEVERIFY execution. - if (txTo->vin[nIn].IsFinal()) + if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) return false; return true; diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 19ddb5b79..138ba808e 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -57,6 +57,20 @@ struct { {2, 0xbbbeb305}, {2, 0xfe1c810a}, }; +CBlockIndex CreateBlockIndex(int nHeight) +{ + CBlockIndex index; + index.nHeight = nHeight; + index.pprev = chainActive.Tip(); + return index; +} + +bool TestSequenceLocks(const CTransaction &tx, int flags) +{ + LOCK(mempool.cs); + return CheckSequenceLocks(tx, flags); +} + // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { @@ -79,6 +93,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // We can't make transactions until we have inputs // Therefore, load 100 blocks :) + int baseheight = 0; std::vectortxFirst; for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i) { @@ -92,7 +107,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = CTransaction(txCoinbase); - if (txFirst.size() < 2) + if (txFirst.size() == 0) + baseheight = chainActive.Height(); + if (txFirst.size() < 4) txFirst.push_back(new CTransaction(pblock->vtx[0])); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; @@ -240,49 +257,96 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // non-final txs in mempool SetMockTime(chainActive.Tip()->GetMedianTimePast()+1); + int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST; + // height map + std::vector prevheights; - // height locked - tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + // relative height locked + tx.nVersion = 2; + tx.vin.resize(1); + prevheights.resize(1); + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction + tx.vin[0].prevout.n = 0; tx.vin[0].scriptSig = CScript() << OP_1; - tx.vin[0].nSequence = 0; + tx.vin[0].nSequence = chainActive.Tip()->nHeight + 1; // txFirst[0] is the 2nd block + prevheights[0] = baseheight + 1; + tx.vout.resize(1); tx.vout[0].nValue = 4900000000LL; tx.vout[0].scriptPubKey = CScript() << OP_1; - tx.nLockTime = chainActive.Tip()->nHeight+1; + tx.nLockTime = 0; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST)); + BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes + BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail + BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 2))); // Sequence locks pass on 2nd block - // time locked - tx2.vin.resize(1); - tx2.vin[0].prevout.hash = txFirst[1]->GetHash(); - tx2.vin[0].prevout.n = 0; - tx2.vin[0].scriptSig = CScript() << OP_1; - tx2.vin[0].nSequence = 0; - tx2.vout.resize(1); - tx2.vout[0].nValue = 4900000000LL; - tx2.vout[0].scriptPubKey = CScript() << OP_1; - tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; - hash = tx2.GetHash(); - mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx2)); - BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); + // relative time locked + tx.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((chainActive.Tip()->GetMedianTimePast()+1-chainActive[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block + prevheights[0] = baseheight + 2; + hash = tx.GetHash(); + mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes + BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail + + for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) + chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast + BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later + for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) + chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP + + // absolute height locked + tx.vin[0].prevout.hash = txFirst[2]->GetHash(); + tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1; + prevheights[0] = baseheight + 3; + tx.nLockTime = chainActive.Tip()->nHeight + 1; + hash = tx.GetHash(); + mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + BOOST_CHECK(!CheckFinalTx(tx, flags)); // Locktime fails + BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass + BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast())); // Locktime passes on 2nd block + + // absolute time locked + tx.vin[0].prevout.hash = txFirst[3]->GetHash(); + tx.nLockTime = chainActive.Tip()->GetMedianTimePast(); + prevheights.resize(1); + prevheights[0] = baseheight + 4; + hash = tx.GetHash(); + mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + BOOST_CHECK(!CheckFinalTx(tx, flags)); // Locktime fails + BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass + BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 2, chainActive.Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later + + // mempool-dependent transactions (not added) + tx.vin[0].prevout.hash = hash; + prevheights[0] = chainActive.Tip()->nHeight + 1; + tx.nLockTime = 0; + tx.vin[0].nSequence = 0; + BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes + BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass + tx.vin[0].nSequence = 1; + BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail + tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG; + BOOST_CHECK(TestSequenceLocks(tx, flags)); // Sequence locks pass + tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; + BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - // Neither tx should have make it into the template. - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); + // None of the of the absolute height/time locked tx should have made + // it into the template because we still check IsFinalTx in CreateNewBlock, + // but relative locked txs will if inconsistently added to mempool. + // For now these will still generate a valid template until BIP68 soft fork + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); delete pblocktemplate; - - // However if we advance height and time by one, both will. + // However if we advance height by 1 and time by 512, all of them should be mined + for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) + chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast chainActive.Tip()->nHeight++; - SetMockTime(chainActive.Tip()->GetMedianTimePast()+2); - - // FIXME: we should *actually* create a new block so the following test - // works; CheckFinalTx() isn't fooled by monkey-patching nHeight. - //BOOST_CHECK(CheckFinalTx(tx)); - //BOOST_CHECK(CheckFinalTx(tx2)); + SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1); BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 2); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); delete pblocktemplate; chainActive.Tip()->nHeight--; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 0059e4a99..90822c71d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -63,7 +63,7 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) txCredit.vout.resize(1); txCredit.vin[0].prevout.SetNull(); txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0); - txCredit.vin[0].nSequence = std::numeric_limits::max(); + txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; txCredit.vout[0].scriptPubKey = scriptPubKey; txCredit.vout[0].nValue = 0; @@ -80,7 +80,7 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu txSpend.vin[0].prevout.hash = txCredit.GetHash(); txSpend.vin[0].prevout.n = 0; txSpend.vin[0].scriptSig = scriptSig; - txSpend.vin[0].nSequence = std::numeric_limits::max(); + txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; txSpend.vout[0].scriptPubKey = CScript(); txSpend.vout[0].nValue = 0; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index fea5da802..67001cf7d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -504,7 +504,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem list transactionsToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - if (!CheckFinalTx(tx, flags)) { + if (!CheckFinalTx(tx, flags) || !CheckSequenceLocks(tx, flags)) { transactionsToRemove.push_back(tx); } else if (it->GetSpendsCoinbase()) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { From da6ad5f684b91975cae3f37495ccbd041499e86b Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 8 Dec 2015 17:25:28 -0500 Subject: [PATCH 0233/1223] Add RPC test exercising BIP68 (mempool only) --- qa/rpc-tests/bip68-sequence.py | 388 ++++++++++++++++++++++++ qa/rpc-tests/test_framework/mininode.py | 8 + 2 files changed, 396 insertions(+) create mode 100755 qa/rpc-tests/bip68-sequence.py diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py new file mode 100755 index 000000000..45b4f22c0 --- /dev/null +++ b/qa/rpc-tests/bip68-sequence.py @@ -0,0 +1,388 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test BIP68 implementation (mempool only) +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.mininode import * +from test_framework.blocktools import * + +COIN = 100000000 +SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) +SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height) +SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift +SEQUENCE_LOCKTIME_MASK = 0x0000ffff + +# RPC error for non-BIP68 final transactions +NOT_FINAL_ERROR = "64: non-BIP68-final" + +class BIP68Test(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"])) + self.is_network_split = False + self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] + + def run_test(self): + # Generate some coins + self.nodes[0].generate(110) + + print "Running test disable flag" + self.test_disable_flag() + + print "Running test sequence-lock-confirmed-inputs" + self.test_sequence_lock_confirmed_inputs() + + print "Running test sequence-lock-unconfirmed-inputs" + self.test_sequence_lock_unconfirmed_inputs() + + # This test needs to change when BIP68 becomes consensus + print "Running test BIP68 not consensus" + self.test_bip68_not_consensus() + + print "Passed\n" + + # Test that BIP68 is not in effect if tx version is 1, or if + # the first sequence bit is set. + def test_disable_flag(self): + # Create some unconfirmed inputs + new_addr = self.nodes[0].getnewaddress() + self.nodes[0].sendtoaddress(new_addr, 2) # send 2 BTC + + utxos = self.nodes[0].listunspent(0, 0) + assert(len(utxos) > 0) + + utxo = utxos[0] + + tx1 = CTransaction() + value = satoshi_round(utxo["amount"] - self.relayfee)*COIN + + # Check that the disable flag disables relative locktime. + # If sequence locks were used, this would require 1 block for the + # input to mature. + sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1 + tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)] + tx1.vout = [CTxOut(value, CScript([b'a']))] + + tx1_signed = self.nodes[0].signrawtransaction(ToHex(tx1))["hex"] + tx1_id = self.nodes[0].sendrawtransaction(tx1_signed) + tx1_id = int(tx1_id, 16) + + # This transaction will enable sequence-locks, so this transaction should + # fail + tx2 = CTransaction() + tx2.nVersion = 2 + sequence_value = sequence_value & 0x7fffffff + tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)] + tx2.vout = [CTxOut(int(value-self.relayfee*COIN), CScript([b'a']))] + tx2.rehash() + + try: + self.nodes[0].sendrawtransaction(ToHex(tx2)) + except JSONRPCException as exp: + assert_equal(exp.error["message"], NOT_FINAL_ERROR) + else: + assert(False) + + # Setting the version back down to 1 should disable the sequence lock, + # so this should be accepted. + tx2.nVersion = 1 + + self.nodes[0].sendrawtransaction(ToHex(tx2)) + + # Calculate the median time past of a prior block ("confirmations" before + # the current tip). + def get_median_time_past(self, confirmations): + block_hash = self.nodes[0].getblockhash(self.nodes[0].getblockcount()-confirmations) + return self.nodes[0].getblockheader(block_hash)["mediantime"] + + # Test that sequence locks are respected for transactions spending confirmed inputs. + def test_sequence_lock_confirmed_inputs(self): + # Create lots of confirmed utxos, and use them to generate lots of random + # transactions. + max_outputs = 50 + addresses = [] + while len(addresses) < max_outputs: + addresses.append(self.nodes[0].getnewaddress()) + while len(self.nodes[0].listunspent()) < 200: + import random + random.shuffle(addresses) + num_outputs = random.randint(1, max_outputs) + outputs = {} + for i in xrange(num_outputs): + outputs[addresses[i]] = random.randint(1, 20)*0.01 + self.nodes[0].sendmany("", outputs) + self.nodes[0].generate(1) + + utxos = self.nodes[0].listunspent() + + # Try creating a lot of random transactions. + # Each time, choose a random number of inputs, and randomly set + # some of those inputs to be sequence locked (and randomly choose + # between height/time locking). Small random chance of making the locks + # all pass. + for i in xrange(400): + # Randomly choose up to 10 inputs + num_inputs = random.randint(1, 10) + random.shuffle(utxos) + + # Track whether any sequence locks used should fail + should_pass = True + + # Track whether this transaction was built with sequence locks + using_sequence_locks = False + + tx = CTransaction() + tx.nVersion = 2 + value = 0 + for j in xrange(num_inputs): + sequence_value = 0xfffffffe # this disables sequence locks + + # 50% chance we enable sequence locks + if random.randint(0,1): + using_sequence_locks = True + + # 10% of the time, make the input sequence value pass + input_will_pass = (random.randint(1,10) == 1) + sequence_value = utxos[j]["confirmations"] + if not input_will_pass: + sequence_value += 1 + should_pass = False + + # Figure out what the median-time-past was for the confirmed input + # Note that if an input has N confirmations, we're going back N blocks + # from the tip so that we're looking up MTP of the block + # PRIOR to the one the input appears in, as per the BIP68 spec. + orig_time = self.get_median_time_past(utxos[j]["confirmations"]) + cur_time = self.get_median_time_past(0) # MTP of the tip + + # can only timelock this input if it's not too old -- otherwise use height + can_time_lock = True + if ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) >= SEQUENCE_LOCKTIME_MASK: + can_time_lock = False + + # if time-lockable, then 50% chance we make this a time lock + if random.randint(0,1) and can_time_lock: + # Find first time-lock value that fails, or latest one that succeeds + time_delta = sequence_value << SEQUENCE_LOCKTIME_GRANULARITY + if input_will_pass and time_delta > cur_time - orig_time: + sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) + elif (not input_will_pass and time_delta <= cur_time - orig_time): + sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)+1 + sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG + tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value)) + value += utxos[j]["amount"]*COIN + # Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output + tx_size = len(ToHex(tx))/2 + 120*num_inputs + 50 + tx.vout.append(CTxOut(value-self.relayfee*tx_size*COIN/1000, CScript([b'a']))) + rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"] + + try: + self.nodes[0].sendrawtransaction(rawtx) + except JSONRPCException as exp: + assert(not should_pass and using_sequence_locks) + assert_equal(exp.error["message"], NOT_FINAL_ERROR) + else: + assert(should_pass or not using_sequence_locks) + # Recalculate utxos if we successfully sent the transaction + utxos = self.nodes[0].listunspent() + + # Test that sequence locks on unconfirmed inputs must have nSequence + # height or time of 0 to be accepted. + # Then test that BIP68-invalid transactions are removed from the mempool + # after a reorg. + def test_sequence_lock_unconfirmed_inputs(self): + # Store height so we can easily reset the chain at the end of the test + cur_height = self.nodes[0].getblockcount() + + utxos = self.nodes[0].listunspent() + + # Create a mempool tx. + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) + tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) + tx1.rehash() + + # Anyone-can-spend mempool tx. + # Sequence lock of 0 should pass. + tx2 = CTransaction() + tx2.nVersion = 2 + tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] + tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] + tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"] + tx2 = FromHex(tx2, tx2_raw) + tx2.rehash() + + self.nodes[0].sendrawtransaction(tx2_raw) + + # Create a spend of the 0th output of orig_tx with a sequence lock + # of 1, and test what happens when submitting. + # orig_tx.vout[0] must be an anyone-can-spend output + def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock): + sequence_value = 1 + if not use_height_lock: + sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG + + tx = CTransaction() + tx.nVersion = 2 + tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)] + tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee*COIN), CScript([b'a']))] + tx.rehash() + + try: + node.sendrawtransaction(ToHex(tx)) + except JSONRPCException as exp: + assert_equal(exp.error["message"], NOT_FINAL_ERROR) + assert(orig_tx.hash in node.getrawmempool()) + else: + # orig_tx must not be in mempool + assert(orig_tx.hash not in node.getrawmempool()) + return tx + + test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) + test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + + # Now mine some blocks, but make sure tx2 doesn't get mined. + # Use prioritisetransaction to lower the effective feerate to 0 + self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN)) + cur_time = int(time.time()) + for i in xrange(10): + self.nodes[0].setmocktime(cur_time + 600) + self.nodes[0].generate(1) + cur_time += 600 + + assert(tx2.hash in self.nodes[0].getrawmempool()) + + test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) + test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + + # Mine tx2, and then try again + self.nodes[0].prioritisetransaction(tx2.hash, 1e15, int(self.relayfee*COIN)) + + # Advance the time on the node so that we can test timelocks + self.nodes[0].setmocktime(cur_time+600) + self.nodes[0].generate(1) + assert(tx2.hash not in self.nodes[0].getrawmempool()) + + # Now that tx2 is not in the mempool, a sequence locked spend should + # succeed + tx3 = test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False) + assert(tx3.hash in self.nodes[0].getrawmempool()) + + self.nodes[0].generate(1) + assert(tx3.hash not in self.nodes[0].getrawmempool()) + + # One more test, this time using height locks + tx4 = test_nonzero_locks(tx3, self.nodes[0], self.relayfee, use_height_lock=True) + assert(tx4.hash in self.nodes[0].getrawmempool()) + + # Now try combining confirmed and unconfirmed inputs + tx5 = test_nonzero_locks(tx4, self.nodes[0], self.relayfee, use_height_lock=True) + assert(tx5.hash not in self.nodes[0].getrawmempool()) + + tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1)) + tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN) + raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"] + + try: + self.nodes[0].sendrawtransaction(raw_tx5) + except JSONRPCException as exp: + assert_equal(exp.error["message"], NOT_FINAL_ERROR) + else: + assert(False) + + # Test mempool-BIP68 consistency after reorg + # + # State of the transactions in the last blocks: + # ... -> [ tx2 ] -> [ tx3 ] + # tip-1 tip + # And currently tx4 is in the mempool. + # + # If we invalidate the tip, tx3 should get added to the mempool, causing + # tx4 to be removed (fails sequence-lock). + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + assert(tx4.hash not in self.nodes[0].getrawmempool()) + assert(tx3.hash in self.nodes[0].getrawmempool()) + + # Now mine 2 empty blocks to reorg out the current tip (labeled tip-1 in + # diagram above). + # This would cause tx2 to be added back to the mempool, which in turn causes + # tx3 to be removed. + tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16) + height = self.nodes[0].getblockcount() + for i in xrange(2): + block = create_block(tip, create_coinbase(height), cur_time) + block.nVersion = 3 + block.rehash() + block.solve() + tip = block.sha256 + height += 1 + self.nodes[0].submitblock(ToHex(block)) + cur_time += 1 + + mempool = self.nodes[0].getrawmempool() + assert(tx3.hash not in mempool) + assert(tx2.hash in mempool) + + # Reset the chain and get rid of the mocktimed-blocks + self.nodes[0].setmocktime(0) + self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1)) + self.nodes[0].generate(10) + + # Make sure that BIP68 isn't being used to validate blocks. + def test_bip68_not_consensus(self): + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) + + tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) + tx1.rehash() + + # Make an anyone-can-spend transaction + tx2 = CTransaction() + tx2.nVersion = 1 + tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] + tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] + + # sign tx2 + tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"] + tx2 = FromHex(tx2, tx2_raw) + tx2.rehash() + + self.nodes[0].sendrawtransaction(ToHex(tx2)) + + # Now make an invalid spend of tx2 according to BIP68 + sequence_value = 100 # 100 block relative locktime + + tx3 = CTransaction() + tx3.nVersion = 2 + tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)] + tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] + tx3.rehash() + + try: + self.nodes[0].sendrawtransaction(ToHex(tx3)) + except JSONRPCException as exp: + assert_equal(exp.error["message"], NOT_FINAL_ERROR) + else: + assert(False) + + # make a block that violates bip68; ensure that the tip updates + tip = int(self.nodes[0].getbestblockhash(), 16) + block = create_block(tip, create_coinbase(self.nodes[0].getblockcount()+1)) + block.nVersion = 3 + block.vtx.extend([tx1, tx2, tx3]) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + + self.nodes[0].submitblock(ToHex(block)) + assert_equal(self.nodes[0].getbestblockhash(), block.hash) + + +if __name__ == '__main__': + BIP68Test().main() diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 9d0fb713a..259dba71c 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -230,6 +230,14 @@ def ser_int_vector(l): r += struct.pack(" Date: Wed, 10 Feb 2016 16:01:04 -0500 Subject: [PATCH 0234/1223] Bug fix to RPC test --- qa/rpc-tests/bip68-sequence.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 45b4f22c0..bd61282fa 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -202,8 +202,6 @@ class BIP68Test(BitcoinTestFramework): # Store height so we can easily reset the chain at the end of the test cur_height = self.nodes[0].getblockcount() - utxos = self.nodes[0].listunspent() - # Create a mempool tx. txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) @@ -286,6 +284,7 @@ class BIP68Test(BitcoinTestFramework): tx5 = test_nonzero_locks(tx4, self.nodes[0], self.relayfee, use_height_lock=True) assert(tx5.hash not in self.nodes[0].getrawmempool()) + utxos = self.nodes[0].listunspent() tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1)) tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN) raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"] From 8d1de43f0cbc79940d870d0ba09c7d28dd812ef8 Mon Sep 17 00:00:00 2001 From: Leviathn Date: Wed, 10 Feb 2016 18:29:13 -0800 Subject: [PATCH 0235/1223] Remove internal miner This code removes the internal miner which is only useful on Testnet. This leaves the internal miner that is useful on RegTest intact. --- src/init.cpp | 6 -- src/miner.cpp | 203 --------------------------------------------- src/miner.h | 5 -- src/rpc/client.cpp | 3 - src/rpc/mining.cpp | 67 --------------- src/rpc/server.cpp | 2 - src/rpc/server.h | 2 - 7 files changed, 288 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 9ca417b83..05d71b479 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -194,7 +194,6 @@ void Shutdown() if (pwalletMain) pwalletMain->Flush(false); #endif - GenerateBitcoins(false, 0, Params()); StopNode(); StopTorControl(); UnregisterNodeSignals(GetNodeSignals()); @@ -453,8 +452,6 @@ std::string HelpMessage(HelpMessageMode mode) _("If is not supplied or if = 1, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); if (showDebug) strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0"); - strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE)); - strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS)); strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS)); strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS)); @@ -1670,9 +1667,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing); scheduler.scheduleEvery(f, nPowTargetSpacing); - // Generate coins in the background - GenerateBitcoins(GetBoolArg("-gen", DEFAULT_GENERATE), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), chainparams); - // ********************************************************* Step 12: finished SetRPCWarmupFinished(); diff --git a/src/miner.cpp b/src/miner.cpp index c454c0279..41f4f1cdb 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -315,206 +315,3 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned pblock->vtx[0] = txCoinbase; pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); } - -////////////////////////////////////////////////////////////////////////////// -// -// Internal miner -// - -// -// ScanHash scans nonces looking for a hash with at least some zero bits. -// The nonce is usually preserved between calls, but periodically or if the -// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at -// zero. -// -bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) -{ - // Write the first 76 bytes of the block header to a double-SHA256 state. - CHash256 hasher; - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << *pblock; - assert(ss.size() == 80); - hasher.Write((unsigned char*)&ss[0], 76); - - while (true) { - nNonce++; - - // Write the last 4 bytes of the block header (the nonce) to a copy of - // the double-SHA256 state, and compute the result. - CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash); - - // Return the nonce if the hash has at least some zero bits, - // caller will check if it has enough to reach the target - if (((uint16_t*)phash)[15] == 0) - return true; - - // If nothing found after trying for a while, return -1 - if ((nNonce & 0xfff) == 0) - return false; - } -} - -static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams) -{ - LogPrintf("%s\n", pblock->ToString()); - LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); - - // Found a solution - { - LOCK(cs_main); - if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash()) - return error("BitcoinMiner: generated block is stale"); - } - - // Inform about the new block - GetMainSignals().BlockFound(pblock->GetHash()); - - // Process this block the same as if we had received it from another node - CValidationState state; - if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)) - return error("BitcoinMiner: ProcessNewBlock, block not accepted"); - - return true; -} - -void static BitcoinMiner(const CChainParams& chainparams) -{ - LogPrintf("BitcoinMiner started\n"); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - RenameThread("bitcoin-miner"); - - unsigned int nExtraNonce = 0; - - boost::shared_ptr coinbaseScript; - GetMainSignals().ScriptForMining(coinbaseScript); - - try { - // Throw an error if no script was provided. This can happen - // due to some internal error but also if the keypool is empty. - // In the latter case, already the pointer is NULL. - if (!coinbaseScript || coinbaseScript->reserveScript.empty()) - throw std::runtime_error("No coinbase script available (mining requires a wallet)"); - - while (true) { - if (chainparams.MiningRequiresPeers()) { - // Busy-wait for the network to come online so we don't waste time mining - // on an obsolete chain. In regtest mode we expect to fly solo. - do { - bool fvNodesEmpty; - { - LOCK(cs_vNodes); - fvNodesEmpty = vNodes.empty(); - } - if (!fvNodesEmpty && !IsInitialBlockDownload()) - break; - MilliSleep(1000); - } while (true); - } - - // - // Create new block - // - unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev = chainActive.Tip(); - - auto_ptr pblocktemplate(CreateNewBlock(chainparams, coinbaseScript->reserveScript)); - if (!pblocktemplate.get()) - { - LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); - return; - } - CBlock *pblock = &pblocktemplate->block; - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); - - LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(), - ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); - - // - // Search - // - int64_t nStart = GetTime(); - arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - uint256 hash; - uint32_t nNonce = 0; - while (true) { - // Check if something found - if (ScanHash(pblock, nNonce, &hash)) - { - if (UintToArith256(hash) <= hashTarget) - { - // Found a solution - pblock->nNonce = nNonce; - assert(hash == pblock->GetHash()); - - SetThreadPriority(THREAD_PRIORITY_NORMAL); - LogPrintf("BitcoinMiner:\n"); - LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); - ProcessBlockFound(pblock, chainparams); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - coinbaseScript->KeepScript(); - - // In regression test mode, stop mining after a block is found. - if (chainparams.MineBlocksOnDemand()) - throw boost::thread_interrupted(); - - break; - } - } - - // Check for stop or if block needs to be rebuilt - boost::this_thread::interruption_point(); - // Regtest mode doesn't require peers - if (vNodes.empty() && chainparams.MiningRequiresPeers()) - break; - if (nNonce >= 0xffff0000) - break; - if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) - break; - if (pindexPrev != chainActive.Tip()) - break; - - // Update nTime every few seconds - if (UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev) < 0) - break; // Recreate the block if the clock has run backwards, - // so that we can use the correct time. - if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) - { - // Changing pblock->nTime can change work required on testnet: - hashTarget.SetCompact(pblock->nBits); - } - } - } - } - catch (const boost::thread_interrupted&) - { - LogPrintf("BitcoinMiner terminated\n"); - throw; - } - catch (const std::runtime_error &e) - { - LogPrintf("BitcoinMiner runtime error: %s\n", e.what()); - return; - } -} - -void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams) -{ - static boost::thread_group* minerThreads = NULL; - - if (nThreads < 0) - nThreads = GetNumCores(); - - if (minerThreads != NULL) - { - minerThreads->interrupt_all(); - delete minerThreads; - minerThreads = NULL; - } - - if (nThreads == 0 || !fGenerate) - return; - - minerThreads = new boost::thread_group(); - for (int i = 0; i < nThreads; i++) - minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams))); -} diff --git a/src/miner.h b/src/miner.h index 512494198..cd0f13662 100644 --- a/src/miner.h +++ b/src/miner.h @@ -17,9 +17,6 @@ class CScript; class CWallet; namespace Consensus { struct Params; }; -static const bool DEFAULT_GENERATE = false; -static const int DEFAULT_GENERATE_THREADS = 1; - static const bool DEFAULT_PRINTPRIORITY = false; struct CBlockTemplate @@ -29,8 +26,6 @@ struct CBlockTemplate std::vector vTxSigOps; }; -/** Run the miner threads */ -void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams); /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn); /** Modify the extranonce in a block */ diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index b0e9b6f15..b127a3f1a 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -27,8 +27,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "stop", 0 }, { "setmocktime", 0 }, { "getaddednodeinfo", 0 }, - { "setgenerate", 0 }, - { "setgenerate", 1 }, { "generate", 0 }, { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, @@ -160,4 +158,3 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -UniValue getgenerate(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getgenerate\n" - "\nReturn if the server is set to generate coins or not. The default is false.\n" - "It is set with the command line argument -gen (or " + std::string(BITCOIN_CONF_FILENAME) + " setting gen)\n" - "It can also be set with the setgenerate call.\n" - "\nResult\n" - "true|false (boolean) If the server is set to generate coins or not\n" - "\nExamples:\n" - + HelpExampleCli("getgenerate", "") - + HelpExampleRpc("getgenerate", "") - ); - - LOCK(cs_main); - return GetBoolArg("-gen", DEFAULT_GENERATE); -} - UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) @@ -182,50 +163,6 @@ UniValue generate(const UniValue& params, bool fHelp) return blockHashes; } -UniValue setgenerate(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "setgenerate generate ( genproclimit )\n" - "\nSet 'generate' true or false to turn generation on or off.\n" - "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n" - "See the getgenerate call for the current setting.\n" - "\nArguments:\n" - "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n" - "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n" - "\nExamples:\n" - "\nSet the generation on with a limit of one processor\n" - + HelpExampleCli("setgenerate", "true 1") + - "\nCheck the setting\n" - + HelpExampleCli("getgenerate", "") + - "\nTurn off generation\n" - + HelpExampleCli("setgenerate", "false") + - "\nUsing json rpc\n" - + HelpExampleRpc("setgenerate", "true, 1") - ); - - if (Params().MineBlocksOnDemand()) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network"); - - bool fGenerate = true; - if (params.size() > 0) - fGenerate = params[0].get_bool(); - - int nGenProcLimit = GetArg("-genproclimit", DEFAULT_GENERATE_THREADS); - if (params.size() > 1) - { - nGenProcLimit = params[1].get_int(); - if (nGenProcLimit == 0) - fGenerate = false; - } - - mapArgs["-gen"] = (fGenerate ? "1" : "0"); - mapArgs ["-genproclimit"] = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, nGenProcLimit, Params()); - - return NullUniValue; -} - UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -239,8 +176,6 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" - " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n" - " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -259,12 +194,10 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", DEFAULT_GENERATE_THREADS))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("generate", getgenerate(params, false))); return obj; } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index b2d4559cc..77076e029 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -298,8 +298,6 @@ static const CRPCCommand vRPCCommands[] = { "mining", "submitblock", &submitblock, true }, /* Coin generation */ - { "generating", "getgenerate", &getgenerate, true }, - { "generating", "setgenerate", &setgenerate, true }, { "generating", "generate", &generate, true }, /* Raw transactions */ diff --git a/src/rpc/server.h b/src/rpc/server.h index 99ffad5d4..a5e9ea36c 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -186,8 +186,6 @@ extern UniValue setban(const UniValue& params, bool fHelp); extern UniValue listbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp); -extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpc/mining.cpp -extern UniValue setgenerate(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp); extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); extern UniValue getmininginfo(const UniValue& params, bool fHelp); From 1fb91b3496f2f07bbace1f9f8e716f7f62d889e6 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 11 Feb 2016 06:35:25 +0000 Subject: [PATCH 0236/1223] Common argument defaults for NODE_BLOOM stuff and -wallet --- src/init.cpp | 12 +++++++----- src/main.cpp | 2 +- src/main.h | 3 +++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 645c8f94b..4c327db6a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -71,6 +71,8 @@ static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_DISABLE_SAFEMODE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; +static const char * const DEFAULT_WALLET_DAT = "wallet.dat"; + #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; #endif @@ -366,9 +368,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); - strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); + strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), DEFAULT_PEERBLOOMFILTERS)); if (showDebug) - strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); + strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", DEFAULT_ENFORCENODEBLOOM)); strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); @@ -405,7 +407,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); + strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + @@ -979,7 +981,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); - std::string strWalletFile = GetArg("-wallet", "wallet.dat"); + std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); #endif // ENABLE_WALLET fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); @@ -991,7 +993,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Option to startup with mocktime set (used for regression testing): SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op - if (GetBoolArg("-peerbloomfilters", true)) + if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices |= NODE_BLOOM; // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log diff --git a/src/main.cpp b/src/main.cpp index cb3f8f39f..12c349a65 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4276,7 +4276,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pfrom->nVersion >= NO_BLOOM_VERSION) { Misbehaving(pfrom->GetId(), 100); return false; - } else if (GetBoolArg("-enforcenodebloom", false)) { + } else if (GetBoolArg("-enforcenodebloom", DEFAULT_ENFORCENODEBLOOM)) { pfrom->fDisconnect = true; return false; } diff --git a/src/main.h b/src/main.h index 19623f4d9..dff81c006 100644 --- a/src/main.h +++ b/src/main.h @@ -101,6 +101,9 @@ static const bool DEFAULT_TESTSAFEMODE = false; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; +static const bool DEFAULT_PEERBLOOMFILTERS = true; +static const bool DEFAULT_ENFORCENODEBLOOM = false; + struct BlockHasher { size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } From b0ff8572aeb8211ad30f24ca42d20a46debb5e9d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 Feb 2016 16:16:40 +0100 Subject: [PATCH 0237/1223] test: Move non-generated script_invalid test to the correct place This test was introduced in 9fadf1c874f938f87395495776dbae896551873d, but accidentally added in the autogenerated area. --- src/test/data/script_invalid.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 7ce7e0879..54767f46d 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -521,6 +521,12 @@ "STRICTENC", "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." ], +[ + "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", + "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", + "P2SH,STRICTENC", + "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" +], ["Increase DERSIG test coverage"], ["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"], @@ -791,12 +797,6 @@ "SIGPUSHONLY", "P2SH(P2PK) with non-push scriptSig" ], -[ - "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", - "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", - "P2SH,STRICTENC", - "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" -], [ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", From 2317ad7c56c6f5a55984459947f69cc3bfbe340a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 Feb 2016 16:38:02 +0100 Subject: [PATCH 0238/1223] test: Re-introduce JSON pretty printing in test builder --- src/test/script_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 10175ebe8..527bb52f8 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -585,11 +585,11 @@ BOOST_AUTO_TEST_CASE(script_build) for (unsigned int idx = 0; idx < json_good.size(); idx++) { const UniValue& tv = json_good[idx]; - tests_good.insert(tv.get_array().write()); + tests_good.insert(tv.get_array().write(1,4)); } for (unsigned int idx = 0; idx < json_bad.size(); idx++) { const UniValue& tv = json_bad[idx]; - tests_bad.insert(tv.get_array().write()); + tests_bad.insert(tv.get_array().write(1,4)); } } @@ -608,7 +608,7 @@ BOOST_AUTO_TEST_CASE(script_build) } BOOST_FOREACH(TestBuilder& test, bad) { test.Test(false); - std::string str = test.GetJSON().write(); + std::string str = test.GetJSON().write(1,4); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); From 0ecb3401fe157cb0779d3970c6080b463b1b0ed2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 Feb 2016 16:38:16 +0100 Subject: [PATCH 0239/1223] test: Script_error checking in script_invalid tests Check the returned script_error. Add expected script_error for generated as well as custom tests. The specific error is not part of consensus, however it could avoid unclear reporting issues such as #6862 in the future. Fixes #7513. --- src/test/data/script_invalid.json | 963 ++++++++++++++++-------------- src/test/script_tests.cpp | 177 ++++-- 2 files changed, 636 insertions(+), 504 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 54767f46d..9e9113298 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -6,504 +6,519 @@ ["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], ["nSequences are max."], -["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"], -[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."], -[" ", "DEPTH", "P2SH,STRICTENC"], -[" ", "DEPTH", "P2SH,STRICTENC"], +["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation", "EVAL_FALSE"], +[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that.", "EVAL_FALSE"], +[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], +[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["", "", "P2SH,STRICTENC"], -["", "NOP", "P2SH,STRICTENC"], -["", "NOP DEPTH", "P2SH,STRICTENC"], -["NOP", "", "P2SH,STRICTENC"], -["NOP", "DEPTH", "P2SH,STRICTENC"], -["NOP","NOP", "P2SH,STRICTENC"], -["NOP","NOP DEPTH", "P2SH,STRICTENC"], +["", "", "P2SH,STRICTENC","", "EVAL_FALSE"], +["", "NOP", "P2SH,STRICTENC","", "EVAL_FALSE"], +["", "NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP","NOP", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP","NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["DEPTH", "", "P2SH,STRICTENC"], +["DEPTH", "", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes"], -["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes"], -["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes"], +["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes","BAD_OPCODE"], +["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes","BAD_OPCODE"], +["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes","BAD_OPCODE"], -["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved"], -["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack"], -["0","NOP", "P2SH,STRICTENC"], -["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional"], -["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"], -["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"], -["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"], -["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"], +["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved","BAD_OPCODE"], +["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack","EVAL_FALSE"], +["0","NOP", "P2SH,STRICTENC","","EVAL_FALSE"], +["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional", "BAD_OPCODE"], +["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"], +["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"], +["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"], -["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey"], -["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC"], -["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC"], -["0 NOTIF", "123", "P2SH,STRICTENC"], +["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"], +["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["0 NOTIF", "123", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["0", "DUP IF ENDIF", "P2SH,STRICTENC"], -["0", "IF 1 ENDIF", "P2SH,STRICTENC"], -["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC"], -["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC"], -["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC"], +["0", "DUP IF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "IF 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], +["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs"], -["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC"], +["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs", "OP_RETURN"], +["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"], -["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence"], -["1", "ELSE ENDIF", "P2SH,STRICTENC"], -["1", "ENDIF ELSE", "P2SH,STRICTENC"], -["1", "ENDIF ELSE IF", "P2SH,STRICTENC"], -["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC"], -["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC"], -["1", "IF ENDIF ENDIF", "P2SH,STRICTENC"], -["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC"], +["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence", "UNBALANCED_CONDITIONAL"], +["1", "ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "RETURN", "P2SH,STRICTENC"], -["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC"], +["1", "RETURN", "P2SH,STRICTENC", "", "OP_RETURN"], +["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"], -["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format"], -["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], +["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format", "OP_RETURN"], +["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"], -["0", "VERIFY 1", "P2SH,STRICTENC"], -["1", "VERIFY", "P2SH,STRICTENC"], -["1", "VERIFY 0", "P2SH,STRICTENC"], +["0", "VERIFY 1", "P2SH,STRICTENC", "", "VERIFY"], +["1", "VERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["1", "VERIFY 0", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey"], +["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey", "INVALID_ALTSTACK_OPERATION"], -["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"], -["NOP", "NIP", "P2SH,STRICTENC"], -["NOP", "1 NIP", "P2SH,STRICTENC"], -["NOP", "1 0 NIP", "P2SH,STRICTENC"], -["NOP", "OVER 1", "P2SH,STRICTENC"], -["1", "OVER", "P2SH,STRICTENC"], -["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC"], -["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["NOP", "0 PICK", "P2SH,STRICTENC"], -["1", "-1 PICK", "P2SH,STRICTENC"], -["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["NOP", "0 ROLL", "P2SH,STRICTENC"], -["1", "-1 ROLL", "P2SH,STRICTENC"], -["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["NOP", "ROT 1", "P2SH,STRICTENC"], -["NOP", "1 ROT 1", "P2SH,STRICTENC"], -["NOP", "1 2 ROT 1", "P2SH,STRICTENC"], -["NOP", "0 1 2 ROT", "P2SH,STRICTENC"], -["NOP", "SWAP 1", "P2SH,STRICTENC"], -["1", "SWAP 1", "P2SH,STRICTENC"], -["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC"], -["NOP", "TUCK 1", "P2SH,STRICTENC"], -["1", "TUCK 1", "P2SH,STRICTENC"], -["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC"], -["NOP", "2DUP 1", "P2SH,STRICTENC"], -["1", "2DUP 1", "P2SH,STRICTENC"], -["NOP", "3DUP 1", "P2SH,STRICTENC"], -["1", "3DUP 1", "P2SH,STRICTENC"], -["1 2", "3DUP 1", "P2SH,STRICTENC"], -["NOP", "2OVER 1", "P2SH,STRICTENC"], -["1", "2 3 2OVER 1", "P2SH,STRICTENC"], -["NOP", "2SWAP 1", "P2SH,STRICTENC"], -["1", "2 3 2SWAP 1", "P2SH,STRICTENC"], +["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1 NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1 0 NIP", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "0 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "-1 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["NOP", "0 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "-1 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["NOP", "ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "", "EQUALVERIFY"], +["NOP", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 2", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "2 3 2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled"], -["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled"], -["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled"], -["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled"], -["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled"], -["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled"], +["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"], +["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"], +["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"], +["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"], +["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled", "DISABLED_OPCODE"], +["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled", "DISABLED_OPCODE"], -["NOP", "SIZE 1", "P2SH,STRICTENC"], +["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled"], -["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled"], -["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled"], -["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled"], -["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled"], -["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled"], -["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled"], -["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled"], -["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled"], -["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled"], -["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled"], +["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled", "DISABLED_OPCODE"], +["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled", "DISABLED_OPCODE"], +["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled", "DISABLED_OPCODE"], +["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled", "DISABLED_OPCODE"], +["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled", "DISABLED_OPCODE"], +["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled", "DISABLED_OPCODE"], +["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled", "DISABLED_OPCODE"], +["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled", "DISABLED_OPCODE"], +["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled", "DISABLED_OPCODE"], +["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled", "DISABLED_OPCODE"], +["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled", "DISABLED_OPCODE"], -["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items"], -["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items"], -["0 1","EQUAL", "P2SH,STRICTENC"], -["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC"], -["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC"], +["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items", "INVALID_STACK_OPERATION"], +["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items", "INVALID_STACK_OPERATION"], +["0 1","EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "], -["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "], -["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range"], -["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand"], +["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"], +["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"], +["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range", "UNKNOWN_ERROR"], +["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand", "UNKNOWN_ERROR"], -["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"], -["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"], -["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"], -["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"], +["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], -["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], +["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig", "DISCOURAGE_UPGRADABLE_NOPS"], ["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", - "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], + "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript", "DISCOURAGE_UPGRADABLE_NOPS"], -["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], -["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC"], +["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved", "BAD_OPCODE"], +["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed", "BAD_OPCODE"], +["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately"], +["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately", "UNBALANCED_CONDITIONAL"], -["NOP", "RIPEMD160", "P2SH,STRICTENC"], -["NOP", "SHA1", "P2SH,STRICTENC"], -["NOP", "SHA256", "P2SH,STRICTENC"], -["NOP", "HASH160", "P2SH,STRICTENC"], -["NOP", "HASH256", "P2SH,STRICTENC"], +["NOP", "RIPEMD160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SHA1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SHA256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "HASH160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "HASH256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], ["NOP", "'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", "P2SH,STRICTENC", -">520 byte push"], +">520 byte push", +"PUSH_SIZE"], ["0", "IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", "P2SH,STRICTENC", -">520 byte push in non-executed IF branch"], +">520 byte push in non-executed IF branch", +"PUSH_SIZE"], ["1", "0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", -">201 opcodes executed. 0x61 is NOP"], +">201 opcodes executed. 0x61 is NOP", +"OP_COUNT"], ["0", "IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1", "P2SH,STRICTENC", -">201 opcodes including non-executed IF branch. 0x61 is NOP"], +">201 opcodes including non-executed IF branch. 0x61 is NOP", +"OP_COUNT"], ["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "P2SH,STRICTENC", -">1,000 stack size (0x6f is 3DUP)"], +">1,000 stack size (0x6f is 3DUP)", +"STACK_SIZE"], ["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "P2SH,STRICTENC", -">1,000 stack+altstack size"], +">1,000 stack+altstack size", +"STACK_SIZE"], ["NOP", "0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", -"10,001-byte scriptPubKey"], +"10,001-byte scriptPubKey", +"SCRIPT_SIZE"], -["NOP1","NOP10", "P2SH,STRICTENC"], +["NOP1","NOP10", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1","VER", "P2SH,STRICTENC", "OP_VER is reserved"], -["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved"], -["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved"], -["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved"], -["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved"], -["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved"], -["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1"], +["1","VER", "P2SH,STRICTENC", "OP_VER is reserved", "BAD_OPCODE"], +["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved", "BAD_OPCODE"], +["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved", "BAD_OPCODE"], +["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved", "BAD_OPCODE"], +["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved", "BAD_OPCODE"], +["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved", "BAD_OPCODE"], +["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1", "BAD_OPCODE"], -["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"], -["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"], -["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes"], -["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], -["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], +["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"], +["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"], +["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes", "UNKNOWN_ERROR"], +["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"], +["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"], -["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"], -["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers"], +["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)", "UNKNOWN_ERROR"], +["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers", "UNKNOWN_ERROR"], -["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF"], -["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF"], -["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over"], +["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF", "UNBALANCED_CONDITIONAL"], +["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF", "UNBALANCED_CONDITIONAL"], +["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over", "UNBALANCED_CONDITIONAL"], -["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode"], -["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors"], -["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,"], +["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode", "UNBALANCED_CONDITIONAL"], +["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors", "UNBALANCED_CONDITIONAL"], +["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,", "INVALID_STACK_OPERATION"], -["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?"], -["1", "FROMALTSTACK", "P2SH,STRICTENC"], -["1", "2DROP 1", "P2SH,STRICTENC"], -["1", "2DUP", "P2SH,STRICTENC"], -["1 1", "3DUP", "P2SH,STRICTENC"], -["1 1 1", "2OVER", "P2SH,STRICTENC"], -["1 1 1 1 1", "2ROT", "P2SH,STRICTENC"], -["1 1 1", "2SWAP", "P2SH,STRICTENC"], -["NOP", "IFDUP 1", "P2SH,STRICTENC"], -["NOP", "DROP 1", "P2SH,STRICTENC"], -["NOP", "DUP 1", "P2SH,STRICTENC"], -["1", "NIP", "P2SH,STRICTENC"], -["1", "OVER", "P2SH,STRICTENC"], -["1 1 1 3", "PICK", "P2SH,STRICTENC"], -["0", "PICK 1", "P2SH,STRICTENC"], -["1 1 1 3", "ROLL", "P2SH,STRICTENC"], -["0", "ROLL 1", "P2SH,STRICTENC"], -["1 1", "ROT", "P2SH,STRICTENC"], -["1", "SWAP", "P2SH,STRICTENC"], -["1", "TUCK", "P2SH,STRICTENC"], +["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?", "INVALID_STACK_OPERATION"], +["1", "FROMALTSTACK", "P2SH,STRICTENC", "", "INVALID_ALTSTACK_OPERATION"], +["1", "2DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "2DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1", "3DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1 1", "2OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1 1", "2SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "IFDUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1 1 3", "PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["0", "PICK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1 1 3", "ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["0", "ROLL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1", "ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "TUCK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "SIZE 1", "P2SH,STRICTENC"], +["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "EQUAL 1", "P2SH,STRICTENC"], -["1", "EQUALVERIFY 1", "P2SH,STRICTENC"], +["1", "EQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1ADD 1", "P2SH,STRICTENC"], -["NOP", "1SUB 1", "P2SH,STRICTENC"], -["NOP", "NEGATE 1", "P2SH,STRICTENC"], -["NOP", "ABS 1", "P2SH,STRICTENC"], -["NOP", "NOT 1", "P2SH,STRICTENC"], -["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC"], +["NOP", "1ADD 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1SUB 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "NEGATE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "ABS 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "NOT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "ADD", "P2SH,STRICTENC"], -["1", "SUB", "P2SH,STRICTENC"], -["1", "BOOLAND", "P2SH,STRICTENC"], -["1", "BOOLOR", "P2SH,STRICTENC"], -["1", "NUMEQUAL", "P2SH,STRICTENC"], -["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"], -["1", "NUMNOTEQUAL", "P2SH,STRICTENC"], -["1", "LESSTHAN", "P2SH,STRICTENC"], -["1", "GREATERTHAN", "P2SH,STRICTENC"], -["1", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC"], -["1", "MIN", "P2SH,STRICTENC"], -["1", "MAX", "P2SH,STRICTENC"], -["1 1", "WITHIN", "P2SH,STRICTENC"], +["1", "ADD", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "SUB", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "BOOLAND", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "BOOLOR", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "NUMEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "LESSTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "GREATERTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "MIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "MAX", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1 1", "WITHIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "RIPEMD160 1", "P2SH,STRICTENC"], -["NOP", "SHA1 1", "P2SH,STRICTENC"], -["NOP", "SHA256 1", "P2SH,STRICTENC"], -["NOP", "HASH160 1", "P2SH,STRICTENC"], -["NOP", "HASH256 1", "P2SH,STRICTENC"], +["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SHA1 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SHA256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "HASH160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "HASH256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], ["Increase CHECKSIG and CHECKMULTISIG negative test coverage"], -["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items"], -["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items"], -["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items"], -["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative"], -["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"], -["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative"], -["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack"], -["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"], +["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items", "INVALID_STACK_OPERATION"], +["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items", "INVALID_STACK_OPERATION"], +["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items", "INVALID_STACK_OPERATION"], +["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative", "PUBKEY_COUNT"], +["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack", "INVALID_STACK_OPERATION"], +["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative", "SIG_COUNT"], +["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack", "INVALID_STACK_OPERATION"], +["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode","EVAL_FALSE"], ["", "0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG", "P2SH,STRICTENC", -"202 CHECKMULTISIGS, fails due to 201 op limit"], +"202 CHECKMULTISIGS, fails due to 201 op limit", +"OP_COUNT"], ["1", "0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC"], +"P2SH,STRICTENC", +"", +"INVALID_STACK_OPERATION"], ["", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", "P2SH,STRICTENC", -"Fails due to 201 sig op limit"], +"Fails due to 201 sig op limit", +"OP_COUNT"], ["1", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC"], +"P2SH,STRICTENC", +"", +"OP_COUNT"], -["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20"], -["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys"], +["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20", "PUBKEY_COUNT"], +["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys", "SIG_COUNT"], -["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()"], -["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"], +["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()", "SIG_PUSHONLY"], +["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "", "SIG_PUSHONLY"], -["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"], -["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"], +["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail", "BAD_OPCODE"], +["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail", "BAD_OPCODE"], -["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], +["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution", "EVAL_FALSE"], ["MINIMALDATA enforcement for PUSHDATAs"], -["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0"], -["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"], -["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"], -["0x01 0x02", "DROP 1", "MINIMALDATA"], -["0x01 0x03", "DROP 1", "MINIMALDATA"], -["0x01 0x04", "DROP 1", "MINIMALDATA"], -["0x01 0x05", "DROP 1", "MINIMALDATA"], -["0x01 0x06", "DROP 1", "MINIMALDATA"], -["0x01 0x07", "DROP 1", "MINIMALDATA"], -["0x01 0x08", "DROP 1", "MINIMALDATA"], -["0x01 0x09", "DROP 1", "MINIMALDATA"], -["0x01 0x0a", "DROP 1", "MINIMALDATA"], -["0x01 0x0b", "DROP 1", "MINIMALDATA"], -["0x01 0x0c", "DROP 1", "MINIMALDATA"], -["0x01 0x0d", "DROP 1", "MINIMALDATA"], -["0x01 0x0e", "DROP 1", "MINIMALDATA"], -["0x01 0x0f", "DROP 1", "MINIMALDATA"], -["0x01 0x10", "DROP 1", "MINIMALDATA"], +["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0", "MINIMALDATA"], +["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE", "MINIMALDATA"], +["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16", "MINIMALDATA"], +["0x01 0x02", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x03", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x04", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x05", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x06", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x07", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x08", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x09", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0a", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0b", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0c", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0d", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0e", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x0f", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x01 0x10", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], ["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA1 of 72 bytes minimally represented by direct push"], + "PUSHDATA1 of 72 bytes minimally represented by direct push", + "MINIMALDATA"], ["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"], + "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1", + "MINIMALDATA"], ["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"], - + "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2", + "MINIMALDATA"], ["MINIMALDATA enforcement for numeric arguments"], -["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0"], -["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0"], -["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0"], -["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5"], -["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5"], -["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5"], -["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5"], -["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff"], -["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f"], -["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff"], -["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f"], +["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], +["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0", "UNKNOWN_ERROR"], +["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], +["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"], +["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"], +["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"], +["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"], +["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff", "UNKNOWN_ERROR"], +["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f", "UNKNOWN_ERROR"], +["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff", "UNKNOWN_ERROR"], +["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f", "UNKNOWN_ERROR"], ["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"], -["1 0x02 0x0000", "PICK DROP", "MINIMALDATA"], -["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA"], -["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA"], -["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA"], -["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA"], -["0x02 0x0000", "ABS DROP 1", "MINIMALDATA"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA"], -["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA"], +["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA"], -["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA"], -["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA"], -["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA"], -["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA"], -["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA"], -["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA"], -["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA"], +["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA"], -["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA"], -["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA"], -["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"], -["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"], +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], ["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"], @@ -513,301 +528,349 @@ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", "STRICTENC", - "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." + "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded.", + "PUBKEYTYPE" ], [ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", "STRICTENC", - "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid.", + "SIG_DER" ], [ "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", "P2SH,STRICTENC", - "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" + "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs", + "SIG_DER" ], ["Increase DERSIG test coverage"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG", "SIG_DER"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG", "SIG_DER"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG", "SIG_DER"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG", "SIG_DER"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG", "SIG_DER"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG", "SIG_DER"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG", "SIG_DER"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG", "SIG_DER"], ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", - "P2PK, bad sig" + "P2PK, bad sig", + "EVAL_FALSE" ], [ "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", "", - "P2PKH, bad pubkey" + "P2PKH, bad pubkey", + "EQUALVERIFY" ], [ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", - "P2PK anyonecanpay marked with normal hashtype" + "P2PK anyonecanpay marked with normal hashtype", + "EVAL_FALSE" ], [ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", - "P2SH(P2PK), bad redeemscript" + "P2SH(P2PK), bad redeemscript", + "EVAL_FALSE" ], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "P2SH", - "P2SH(P2PKH), bad sig" + "P2SH(P2PKH), bad sig", + "EQUALVERIFY" ], [ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", - "3-of-3, 2 sigs" + "3-of-3, 2 sigs", + "EVAL_FALSE" ], [ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", - "P2SH(2-of-3), 1 sig" + "P2SH(2-of-3), 1 sig", + "EVAL_FALSE" ], [ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too much R padding" + "P2PK with too much R padding", + "SIG_DER" ], [ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too much S padding" + "P2PK with too much S padding", + "SIG_DER" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too little R padding" + "P2PK with too little R padding", + "SIG_DER" ], [ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", - "P2PK NOT with bad sig with too much R padding" + "P2PK NOT with bad sig with too much R padding", + "SIG_DER" ], [ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", - "P2PK NOT with too much R padding but no DERSIG" + "P2PK NOT with too much R padding but no DERSIG", + "EVAL_FALSE" ], [ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", - "P2PK NOT with too much R padding" + "P2PK NOT with too much R padding", + "SIG_DER" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 1, with DERSIG" + "BIP66 example 1, with DERSIG", + "SIG_DER" ], [ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", - "BIP66 example 2, without DERSIG" + "BIP66 example 2, without DERSIG", + "EVAL_FALSE" ], [ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "DERSIG", - "BIP66 example 2, with DERSIG" + "BIP66 example 2, with DERSIG", + "SIG_DER" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 3, without DERSIG" + "BIP66 example 3, without DERSIG", + "EVAL_FALSE" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 3, with DERSIG" + "BIP66 example 3, with DERSIG", + "EVAL_FALSE" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 5, without DERSIG" + "BIP66 example 5, without DERSIG", + "EVAL_FALSE" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 5, with DERSIG" + "BIP66 example 5, with DERSIG", + "SIG_DER" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "DERSIG", - "BIP66 example 6, with DERSIG" + "BIP66 example 6, with DERSIG", + "SIG_DER" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 7, with DERSIG" + "BIP66 example 7, with DERSIG", + "SIG_DER" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", - "BIP66 example 8, without DERSIG" + "BIP66 example 8, without DERSIG", + "EVAL_FALSE" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", - "BIP66 example 8, with DERSIG" + "BIP66 example 8, with DERSIG", + "SIG_DER" ], [ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 9, without DERSIG" + "BIP66 example 9, without DERSIG", + "EVAL_FALSE" ], [ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 9, with DERSIG" + "BIP66 example 9, with DERSIG", + "SIG_DER" ], [ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", - "BIP66 example 10, with DERSIG" + "BIP66 example 10, with DERSIG", + "SIG_DER" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 11, without DERSIG" + "BIP66 example 11, without DERSIG", + "EVAL_FALSE" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 11, with DERSIG" + "BIP66 example 11, with DERSIG", + "EVAL_FALSE" ], [ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "DERSIG", - "P2PK with multi-byte hashtype, with DERSIG" + "P2PK with multi-byte hashtype, with DERSIG", + "SIG_DER" ], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S", - "P2PK with high S" + "P2PK with high S", + "SIG_HIGH_S" ], [ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "STRICTENC", - "P2PK with hybrid pubkey" + "P2PK with hybrid pubkey", + "PUBKEYTYPE" ], [ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", - "P2PK NOT with hybrid pubkey but no STRICTENC" + "P2PK NOT with hybrid pubkey but no STRICTENC", + "EVAL_FALSE" ], [ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", - "P2PK NOT with hybrid pubkey" + "P2PK NOT with hybrid pubkey", + "PUBKEYTYPE" ], [ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", - "P2PK NOT with invalid hybrid pubkey" + "P2PK NOT with invalid hybrid pubkey", + "PUBKEYTYPE" ], [ "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201", "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", "STRICTENC", - "1-of-2 with the first 1 hybrid pubkey" + "1-of-2 with the first 1 hybrid pubkey", + "PUBKEYTYPE" ], [ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "STRICTENC", - "P2PK with undefined hashtype" + "P2PK with undefined hashtype", + "SIG_HASHTYPE" ], [ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", "STRICTENC", - "P2PK NOT with invalid sig and undefined hashtype" + "P2PK NOT with invalid sig and undefined hashtype", + "SIG_HASHTYPE" ], [ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "NULLDUMMY", - "3-of-3 with nonzero dummy" + "3-of-3 with nonzero dummy", + "SIG_NULLDUMMY" ], [ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", "NULLDUMMY", - "3-of-3 NOT with invalid sig with nonzero dummy" + "3-of-3 NOT with invalid sig with nonzero dummy", + "SIG_NULLDUMMY" ], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "SIGPUSHONLY", - "2-of-2 with two identical keys and sigs pushed using OP_DUP" + "2-of-2 with two identical keys and sigs pushed using OP_DUP", + "SIG_PUSHONLY" ], [ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", - "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", + "EVAL_FALSE" ], [ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "SIGPUSHONLY", - "P2SH(P2PK) with non-push scriptSig" + "P2SH(P2PK) with non-push scriptSig", + "EVAL_FALSE" ], [ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "CLEANSTACK,P2SH", - "P2PK with unnecessary input" + "P2PK with unnecessary input", + "CLEANSTACK" ], [ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "CLEANSTACK,P2SH", - "P2SH with unnecessary input" + "P2SH with unnecessary input", + "CLEANSTACK" ], ["The End"] diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 527bb52f8..c0e159bb6 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -52,6 +52,64 @@ read_json(const std::string& jsondata) return v.get_array(); } +struct ScriptErrorDesc +{ + ScriptError_t err; + const char *name; +}; + +static ScriptErrorDesc script_errors[]={ + {SCRIPT_ERR_OK, "OK"}, + {SCRIPT_ERR_UNKNOWN_ERROR, "UNKNOWN_ERROR"}, + {SCRIPT_ERR_EVAL_FALSE, "EVAL_FALSE"}, + {SCRIPT_ERR_OP_RETURN, "OP_RETURN"}, + {SCRIPT_ERR_SCRIPT_SIZE, "SCRIPT_SIZE"}, + {SCRIPT_ERR_PUSH_SIZE, "PUSH_SIZE"}, + {SCRIPT_ERR_OP_COUNT, "OP_COUNT"}, + {SCRIPT_ERR_STACK_SIZE, "STACK_SIZE"}, + {SCRIPT_ERR_SIG_COUNT, "SIG_COUNT"}, + {SCRIPT_ERR_PUBKEY_COUNT, "PUBKEY_COUNT"}, + {SCRIPT_ERR_VERIFY, "VERIFY"}, + {SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"}, + {SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"}, + {SCRIPT_ERR_CHECKSIGVERIFY, "CHECKSIGVERIFY"}, + {SCRIPT_ERR_NUMEQUALVERIFY, "NUMEQUALVERIFY"}, + {SCRIPT_ERR_BAD_OPCODE, "BAD_OPCODE"}, + {SCRIPT_ERR_DISABLED_OPCODE, "DISABLED_OPCODE"}, + {SCRIPT_ERR_INVALID_STACK_OPERATION, "INVALID_STACK_OPERATION"}, + {SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, "INVALID_ALTSTACK_OPERATION"}, + {SCRIPT_ERR_UNBALANCED_CONDITIONAL, "UNBALANCED_CONDITIONAL"}, + {SCRIPT_ERR_NEGATIVE_LOCKTIME, "NEGATIVE_LOCKTIME"}, + {SCRIPT_ERR_UNSATISFIED_LOCKTIME, "UNSATISFIED_LOCKTIME"}, + {SCRIPT_ERR_SIG_HASHTYPE, "SIG_HASHTYPE"}, + {SCRIPT_ERR_SIG_DER, "SIG_DER"}, + {SCRIPT_ERR_MINIMALDATA, "MINIMALDATA"}, + {SCRIPT_ERR_SIG_PUSHONLY, "SIG_PUSHONLY"}, + {SCRIPT_ERR_SIG_HIGH_S, "SIG_HIGH_S"}, + {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"}, + {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"}, + {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"}, + {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"} +}; + +const char *FormatScriptError(ScriptError_t err) +{ + for (unsigned int i=0; i push; std::string comment; int flags; + int scriptError; void DoPush() { @@ -204,7 +263,7 @@ private: } public: - TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_) + TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(-1) { if (P2SH) { creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL); @@ -214,6 +273,12 @@ public: spendTx = BuildSpendingTransaction(CScript(), creditTx); } + TestBuilder& ScriptError(ScriptError_t err) + { + scriptError = err; + return *this; + } + TestBuilder& Add(const CScript& script) { DoPush(); @@ -288,7 +353,7 @@ public: { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment, expect ? SCRIPT_ERR_OK : scriptError); *this = copy; return *this; } @@ -301,6 +366,8 @@ public: array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); array.push_back(comment); + if (scriptError != -1) + array.push_back(FormatScriptError((ScriptError_t)scriptError)); return array; } @@ -328,99 +395,99 @@ BOOST_AUTO_TEST_CASE(script_build) ).PushSig(keys.key0)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2PK, bad sig", 0 - ).PushSig(keys.key0).DamagePush(10)); + ).PushSig(keys.key0).DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, "P2PKH", 0 ).PushSig(keys.key1).Push(keys.pubkey1C)); bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, "P2PKH, bad pubkey", 0 - ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5)); + ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5).ScriptError(SCRIPT_ERR_EQUALVERIFY)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "P2PK anyonecanpay", 0 ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "P2PK anyonecanpay marked with normal hashtype", 0 - ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01")); + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01").ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true ).PushSig(keys.key0).PushRedeem()); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).PushRedeem().DamagePush(10)); + ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true ).PushSig(keys.key0).DamagePush(10).PushRedeem()); bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + ).PushSig(keys.key0).DamagePush(10).PushRedeem().ScriptError(SCRIPT_ERR_EQUALVERIFY)); good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "3-of-3", 0 ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "3-of-3, 2 sigs", 0 - ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0)); + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true - ).Num(0).PushSig(keys.key1).Num(0).PushRedeem()); + ).Num(0).PushSig(keys.key1).Num(0).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too much R padding but no DERSIG", 0 ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too much S padding but no DERSIG", 0 ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too little R padding but no DERSIG", 0 ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, "P2PK NOT with bad sig with too much R padding but no DERSIG", 0 ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10).ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, "P2PK NOT with too much R padding but no DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 1, without DERSIG", 0 ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, "BIP66 example 2, without DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 3, without DERSIG", 0 - ).Num(0)); + ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0)); + ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, "BIP66 example 4, without DERSIG", 0 ).Num(0)); @@ -429,46 +496,46 @@ BOOST_AUTO_TEST_CASE(script_build) ).Num(0)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 5, without DERSIG", 0 - ).Num(1)); + ).Num(1).ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(1)); + ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, "BIP66 example 6, without DERSIG", 0 ).Num(1)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(1)); + ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 7, without DERSIG", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 8, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 9, without DERSIG", 0 - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 10, without DERSIG", 0 ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 11, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, "BIP66 example 12, without DERSIG", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); @@ -480,33 +547,33 @@ BOOST_AUTO_TEST_CASE(script_build) ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); + ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101").ScriptError(SCRIPT_ERR_SIG_DER)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2PK with high S but no LOW_S", 0 ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2PK with high S", SCRIPT_VERIFY_LOW_S - ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33).ScriptError(SCRIPT_ERR_SIG_HIGH_S)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, "P2PK with hybrid pubkey but no STRICTENC", 0 ).PushSig(keys.key0, SIGHASH_ALL)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL)); + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with hybrid pubkey but no STRICTENC", 0 - ).PushSig(keys.key0, SIGHASH_ALL)); + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL)); + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); @@ -515,62 +582,61 @@ BOOST_AUTO_TEST_CASE(script_build) ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + ).Num(0).PushSig(keys.key1, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "P2PK with undefined hashtype but no STRICTENC", 0 ).PushSig(keys.key1, 5)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key1, 5)); + ).PushSig(keys.key1, 5).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0 ).PushSig(keys.key1, 5).DamagePush(10)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key1, 5).DamagePush(10)); + ).PushSig(keys.key1, 5).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "3-of-3 with nonzero dummy but no NULLDUMMY", 0 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0 ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY - ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); + ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0 - ).PushSig(keys.key2).PushRedeem()); + ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, "P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY - ).PushSig(keys.key2).PushRedeem()); + ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH ).Num(11).PushSig(keys.key0)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH - ).Num(11).PushSig(keys.key0)); + ).Num(11).PushSig(keys.key0).ScriptError(SCRIPT_ERR_CLEANSTACK)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true ).Num(11).PushSig(keys.key0).PushRedeem()); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true - ).Num(11).PushSig(keys.key0).PushRedeem()); + ).Num(11).PushSig(keys.key0).PushRedeem().ScriptError(SCRIPT_ERR_CLEANSTACK)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true ).PushSig(keys.key0).PushRedeem()); @@ -598,7 +664,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_FOREACH(TestBuilder& test, good) { test.Test(true); - std::string str = test.GetJSON().write(); + std::string str = test.GetJSON().write(1,4); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); @@ -652,7 +718,7 @@ BOOST_AUTO_TEST_CASE(script_valid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest, SCRIPT_ERR_OK); } } @@ -660,7 +726,6 @@ BOOST_AUTO_TEST_CASE(script_invalid) { // Scripts that should evaluate as invalid UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); @@ -676,8 +741,12 @@ BOOST_AUTO_TEST_CASE(script_invalid) string scriptPubKeyString = test[1].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); + int scriptError = -1; // Expected script error is optional, and follows comment + if (test.size() >= 5 && test[4].get_str() != "") { + scriptError = ParseScriptError(test[4].get_str()); + } - DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest, scriptError); } } From b043c4b746c8199ce948aa5e8b186e0d1a61ad68 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 11 Feb 2016 15:34:04 -0500 Subject: [PATCH 0240/1223] fix sdaftuar's nits again it boggles the mind why these nits can't be delivered on a more timely basis --- src/main.cpp | 10 +++++----- src/main.h | 2 +- src/policy/policy.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d9bf3bd75..7d75e2ea6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -799,10 +799,10 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags) index.pprev = tip; // CheckSequenceLocks() uses chainActive.Height()+1 to evaluate // height based locks because when SequenceLocks() is called within - // CBlock::AcceptBlock(), the height of the block *being* - // evaluated is what is used. Thus if we want to know if a - // transaction can be part of the *next* block, we need to call - // SequenceLocks() with one more than chainActive.Height(). + // ConnectBlock(), the height of the block *being* + // evaluated is what is used. + // Thus if we want to know if a transaction can be part of the + // *next* block, we need to use one more than chainActive.Height() index.nHeight = tip->nHeight + 1; // pcoinsTip contains the UTXO set for chainActive.Tip() @@ -2240,7 +2240,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { - return state.DoS(100, error("ConnectBlock(): contains a non-BIP68-final transaction", __func__), + return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); } diff --git a/src/main.h b/src/main.h index 66b766316..a576078f0 100644 --- a/src/main.h +++ b/src/main.h @@ -350,7 +350,7 @@ bool SequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeig /** * Check if transaction will be BIP 68 final in the next block to be created. * - * Calls SequenceLocks() with data from the tip of the current active chain. + * Simulates calling SequenceLocks() with data from the tip of the current active chain. * * See consensus/consensus.h for flag definitions. */ diff --git a/src/policy/policy.h b/src/policy/policy.h index 5034b2386..f25dbf22d 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -45,7 +45,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; -/** Used as the flags parameter to LockTime() in non-consensus code. */ +/** Used as the flags parameter to sequence and nLocktime checks in non-consensus code. */ static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST; From 5a2b1c0c8b49c5ae79946e71b9f989b33c9fcf5c Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 11 Feb 2016 17:10:41 -0500 Subject: [PATCH 0241/1223] Don't resend wallet txs that aren't in our own mempool --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 65defc30a..ac109b54d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1265,7 +1265,7 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { - if (GetDepthInMainChain() == 0 && !isAbandoned()) { + if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; From 8aa722609d7e736b3a3763e15b552795b94f0e9b Mon Sep 17 00:00:00 2001 From: jmacwhyte Date: Thu, 11 Feb 2016 18:02:46 -0800 Subject: [PATCH 0242/1223] Fix IsInitialBlockDownload to play nice with testnet --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 3ad2979b6..9e478b682 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1384,7 +1384,7 @@ bool IsInitialBlockDownload() if (lockIBDState) return false; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge); + std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge); if (!state) lockIBDState = true; return state; From a0a17b3e441ac82bc64ca183d458258ded26c9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 11 Feb 2016 21:20:12 +0100 Subject: [PATCH 0243/1223] LibreSSL doesn't define OPENSSL_VERSION, use LIBRESSL_VERSION_TEXT instead --- src/init.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 645c8f94b..231fb1801 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1034,8 +1034,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); -#else +#elif defined OPENSSL_VERSION LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); +#elif defined LIBRESSL_VERSION_TEXT + LogPrintf("Using %s\n", LIBRESSL_VERSION_TEXT); #endif #ifdef ENABLE_WALLET From c372572595b6b19a4dd88258401d8a0046ce4469 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 12 Feb 2016 13:55:32 -0500 Subject: [PATCH 0244/1223] Fix and cleanup listreceivedbyX documentation --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 857a3a77e..34ad5a46f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1245,7 +1245,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) "\nList balances by receiving address.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" - "2. includeempty (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n" + "2. includeempty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "\nResult:\n" @@ -1283,7 +1283,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) "\nDEPRECATED. List balances by account.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" - "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n" + "2. includeempty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "\nResult:\n" From 37767fd46f673a06864df6e14d3030622b1cb2c9 Mon Sep 17 00:00:00 2001 From: jloughry Date: Fri, 12 Feb 2016 11:35:32 -0700 Subject: [PATCH 0245/1223] fix spelling of advertise in src and doc --- doc/tor.md | 2 +- src/main.cpp | 8 ++++---- src/net.cpp | 4 ++-- src/net.h | 2 +- src/torcontrol.cpp | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 1d35a658b..be4125544 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -52,7 +52,7 @@ your bitcoind's P2P listen port (8333 by default). this option, and this can be a .onion address. Given the above configuration, you can find your onion address in /var/lib/tor/bitcoin-service/hostname. Onion addresses are given - preference for your node to advertize itself with, for connections + preference for your node to advertise itself with, for connections coming from unroutable addresses (such as 127.0.0.1, where the Tor proxy typically runs). diff --git a/src/main.cpp b/src/main.cpp index 6398fdad9..23429ea2c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -376,7 +376,7 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa mapBlocksInFlight[hash] = std::make_pair(nodeid, it); } -/** Check whether the last unknown block a peer advertized is not yet known. */ +/** Check whether the last unknown block a peer advertised is not yet known. */ void ProcessBlockAvailability(NodeId nodeid) { CNodeState *state = State(nodeid); assert(state != NULL); @@ -4456,11 +4456,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CAddress addr = GetLocalAddress(&pfrom->addr); if (addr.IsRoutable()) { - LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); + LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString()); pfrom->PushAddress(addr); } else if (IsPeerAddrLocalGood(pfrom)) { addr.SetIP(pfrom->addrLocal); - LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); + LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString()); pfrom->PushAddress(addr); } } @@ -5469,7 +5469,7 @@ bool SendMessages(CNode* pto) // Address refresh broadcast int64_t nNow = GetTimeMicros(); if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { - AdvertizeLocal(pto); + AdvertiseLocal(pto); pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); } diff --git a/src/net.cpp b/src/net.cpp index d9c4c1173..e06e5255d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -205,7 +205,7 @@ bool IsPeerAddrLocalGood(CNode *pnode) } // pushes our own address to a peer -void AdvertizeLocal(CNode *pnode) +void AdvertiseLocal(CNode *pnode) { if (fListen && pnode->fSuccessfullyConnected) { @@ -220,7 +220,7 @@ void AdvertizeLocal(CNode *pnode) } if (addrLocal.IsRoutable()) { - LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString()); + LogPrintf("AdvertiseLocal: advertising address %s\n", addrLocal.ToString()); pnode->PushAddress(addrLocal); } } diff --git a/src/net.h b/src/net.h index 833c9cf07..d939ef55a 100644 --- a/src/net.h +++ b/src/net.h @@ -134,7 +134,7 @@ enum }; bool IsPeerAddrLocalGood(CNode *pnode); -void AdvertizeLocal(CNode *pnode); +void AdvertiseLocal(CNode *pnode); void SetLimited(enum Network net, bool fLimited = true); bool IsLimited(enum Network net); bool IsLimited(const CNetAddr& addr); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 2c68526df..10170dbce 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -434,7 +434,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep } service = CService(service_id+".onion", GetListenPort(), false); - LogPrintf("tor: Got service ID %s, advertizing service %s\n", service_id, service.ToString()); + LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString()); if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile()); } else { @@ -615,7 +615,7 @@ void TorController::connected_cb(TorControlConnection& conn) void TorController::disconnected_cb(TorControlConnection& conn) { - // Stop advertizing service when disconnected + // Stop advertising service when disconnected if (service.IsValid()) RemoveLocal(service); service = CService(); From 889426d37e331c9e6c914dae824663a7167effdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20G=2E=20Aragoneses?= Date: Sat, 13 Feb 2016 04:44:42 +0800 Subject: [PATCH 0246/1223] autogen.sh: warn about needing autoconf if autoreconf is not found Changes the error message from: ./autogen.sh: 9: ./autogen.sh: autoreconf: not found To: configuration failed, please install autoconf first --- autogen.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autogen.sh b/autogen.sh index 3e26a1830..46e36ff5b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -6,4 +6,6 @@ if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then LIBTOOLIZE="${GLIBTOOLIZE}" export LIBTOOLIZE fi +which autoreconf >/dev/null || \ + (echo "configuration failed, please install autoconf first" && exit 1) autoreconf --install --force --warnings=all From 6ba8b2a6c4d1bc393dd7c4734090a4c0dfa750c2 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sat, 13 Feb 2016 15:42:24 +0000 Subject: [PATCH 0247/1223] Add bip68-sequence.py to extended rpc tests --- qa/pull-tester/rpc-tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index e7173fda0..7649c1183 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -110,6 +110,7 @@ testScripts = [ testScriptsExt = [ 'bip65-cltv.py', 'bip65-cltv-p2p.py', + 'bip68-sequence.py', 'bipdersig-p2p.py', 'bipdersig.py', 'getblocktemplate_longpoll.py', From 53e53a33c939949665f60d5eeb82abbb21f97128 Mon Sep 17 00:00:00 2001 From: Mark Friedenbach Date: Fri, 25 Sep 2015 16:18:51 -0700 Subject: [PATCH 0248/1223] BIP112: Implement CHECKSEQUENCEVERIFY - Replace NOP3 with CHECKSEQUENCEVERIFY (BIP112) CHECKSEQUENCEVERIFY -> - Fails if txin.nSequence < nSequence, allowing funds of a txout to be locked for a number of blocks or a duration of time after its inclusion in a block. - Pull most of CheckLockTime() out into VerifyLockTime(), a local function that will be reused for CheckSequence() - Add bitwise AND operator to CScriptNum - Enable CHECKSEQUENCEVERIFY as a standard script verify flag - Transactions that fail CSV verification will be rejected from the mempool, making it easy to test the feature. However blocks containing "invalid" CSV-using transactions will still be accepted; this is *not* the soft-fork required to actually enable CSV for production use. --- src/policy/policy.h | 1 + src/script/interpreter.cpp | 89 +++++++++++++++++++++++++++++++--- src/script/interpreter.h | 11 +++++ src/script/script.h | 12 +++++ src/script/script_error.h | 2 +- src/test/data/tx_invalid.json | 54 +++++++++++++++++++++ src/test/data/tx_valid.json | 84 ++++++++++++++++++++++++++++++++ src/test/transaction_tests.cpp | 3 +- 8 files changed, 247 insertions(+), 9 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index aabeebb25..4f9354e36 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -40,6 +40,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | + SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S; /** For convenience, standard but not mandatory verify flags. */ diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 901f901f0..4e87006f5 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -373,7 +373,44 @@ bool EvalScript(vector >& stack, const CScript& script, un break; } - case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_CHECKSEQUENCEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { + // not enabled; treat as a NOP3 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // nSequence, like nLockTime, is a 32-bit unsigned integer + // field. See the comment in CHECKLOCKTIMEVERIFY regarding + // 5-byte numeric operands. + const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKSEQUENCEVERIFY. + if (nSequence < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // To provide for future soft-fork extensibility, if the + // operand has the disabled lock-time flag set, + // CHECKSEQUENCEVERIFY behaves as a NOP. + if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) + break; + + // Compare the specified sequence number with the input. + if (!checker.CheckSequence(nSequence)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + case OP_NOP1: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) @@ -1120,27 +1157,33 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn return true; } -bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +static bool VerifyLockTime(int64_t txToLockTime, int64_t nThreshold, const CScriptNum& nLockTime) { // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether - // nLockTime < LOCKTIME_THRESHOLD. + // nLockTime < nThreshold (either LOCKTIME_THRESHOLD or + // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG). // // We want to compare apples to apples, so fail the script // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) + (txToLockTime < nThreshold && nLockTime < nThreshold) || + (txToLockTime >= nThreshold && nLockTime >= nThreshold) )) return false; // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. - if (nLockTime > (int64_t)txTo->nLockTime) + if (nLockTime > txToLockTime) return false; - // Finally the nLockTime feature can be disabled and thus + return true; +} + +bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // The nLockTime feature can be disabled and thus // CHECKLOCKTIMEVERIFY bypassed if every txin has been // finalized by setting nSequence to maxint. The // transaction would be allowed into the blockchain, making @@ -1153,6 +1196,38 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) return false; + if (!::VerifyLockTime((int64_t)txTo->nLockTime, LOCKTIME_THRESHOLD, nLockTime)) + return false; + + return true; +} + +bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const +{ + // Relative lock times are supported by comparing the passed + // in operand to the sequence number of the input. + const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence; + + // Fail if the transaction's version number is not set high + // enough to trigger BIP 68 rules. + if (static_cast(txTo->nVersion) < 2) + return false; + + // Sequence numbers with their most significant bit set are not + // consensus constrained. Testing that the transaction's sequence + // number do not have this bit set prevents using this property + // to get around a CHECKSEQUENCEVERIFY check. + if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) + return false; + + // Mask off any bits that do not have consensus-enforced meaning + // before doing the integer comparisons of ::VerifyLockTime. + const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG + | CTxIn::SEQUENCE_LOCKTIME_MASK; + + if (!::VerifyLockTime(txToSequence & nLockTimeMask, CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG, nSequence & nLockTimeMask)) + return false; + return true; } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 7b34547ff..e5cb7290f 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -81,6 +81,11 @@ enum // // See BIP65 for details. SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), + + // support CHECKSEQUENCEVERIFY opcode + // + // See BIP112 for details + SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); @@ -100,6 +105,11 @@ public: return false; } + virtual bool CheckSequence(const CScriptNum& nSequence) const + { + return false; + } + virtual ~BaseSignatureChecker() {} }; @@ -116,6 +126,7 @@ public: TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; bool CheckLockTime(const CScriptNum& nLockTime) const; + bool CheckSequence(const CScriptNum& nSequence) const; }; class MutableTransactionSignatureChecker : public TransactionSignatureChecker diff --git a/src/script/script.h b/src/script/script.h index 6551eea30..d2a68a07b 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -165,6 +165,7 @@ enum opcodetype OP_CHECKLOCKTIMEVERIFY = 0xb1, OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_NOP3 = 0xb2, + OP_CHECKSEQUENCEVERIFY = OP_NOP3, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, @@ -259,6 +260,11 @@ public: inline CScriptNum& operator+=( const CScriptNum& rhs) { return operator+=(rhs.m_value); } inline CScriptNum& operator-=( const CScriptNum& rhs) { return operator-=(rhs.m_value); } + inline CScriptNum operator&( const int64_t& rhs) const { return CScriptNum(m_value & rhs);} + inline CScriptNum operator&( const CScriptNum& rhs) const { return operator&(rhs.m_value); } + + inline CScriptNum& operator&=( const CScriptNum& rhs) { return operator&=(rhs.m_value); } + inline CScriptNum operator-() const { assert(m_value != std::numeric_limits::min()); @@ -287,6 +293,12 @@ public: return *this; } + inline CScriptNum& operator&=( const int64_t& rhs) + { + m_value &= rhs; + return *this; + } + int getint() const { if (m_value > std::numeric_limits::max()) diff --git a/src/script/script_error.h b/src/script/script_error.h index bb10b8a29..26df33932 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -35,7 +35,7 @@ typedef enum ScriptError_t SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, SCRIPT_ERR_UNBALANCED_CONDITIONAL, - /* OP_CHECKLOCKTIMEVERIFY */ + /* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */ SCRIPT_ERR_NEGATIVE_LOCKTIME, SCRIPT_ERR_UNSATISFIED_LOCKTIME, diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 902584194..2d7d9b958 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -201,5 +201,59 @@ [[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], "010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH,DERSIG"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument just beyond txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument just beyond txin.nSequence (but within numerical boundries)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument missing"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blockheight txin.nSequence=0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blocktime txin.nSequence=CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument/tx height/time mismatch, both versions"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to insufficient tx.nVersion (<2)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 76d29bcf2..717ad1954 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -233,5 +233,89 @@ [[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], "010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Upper sequence with upper sequence is fine"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^32-1 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 3<<31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["5 byte non-minimally-encoded operandss are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["The argument can be calculated rather than created directly by a PUSHDATA"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194303 1ADD NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 1SUB NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["An ADD producing a 5-byte result that sets CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 65536 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 4259840 ADD NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index c27f194b5..d9195bf34 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -44,7 +44,8 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) - (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY); + (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) + (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY); unsigned int ParseScriptFlags(string strFlags) { From c3c375226ebf98901849593b8ebfe8e8b69895c2 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 12 Feb 2016 20:02:46 +0000 Subject: [PATCH 0249/1223] Separate CheckLockTime() and CheckSequence() logic For the sake of a little repetition, make code more readable. --- src/script/interpreter.cpp | 46 +++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 4e87006f5..d4fe001d7 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1157,33 +1157,27 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn return true; } -static bool VerifyLockTime(int64_t txToLockTime, int64_t nThreshold, const CScriptNum& nLockTime) +bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const { // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether - // nLockTime < nThreshold (either LOCKTIME_THRESHOLD or - // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG). + // nLockTime < LOCKTIME_THRESHOLD. // // We want to compare apples to apples, so fail the script // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (txToLockTime < nThreshold && nLockTime < nThreshold) || - (txToLockTime >= nThreshold && nLockTime >= nThreshold) + (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) )) return false; // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. - if (nLockTime > txToLockTime) + if (nLockTime > (int64_t)txTo->nLockTime) return false; - return true; -} - -bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const -{ - // The nLockTime feature can be disabled and thus + // Finally the nLockTime feature can be disabled and thus // CHECKLOCKTIMEVERIFY bypassed if every txin has been // finalized by setting nSequence to maxint. The // transaction would be allowed into the blockchain, making @@ -1196,9 +1190,6 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) return false; - if (!::VerifyLockTime((int64_t)txTo->nLockTime, LOCKTIME_THRESHOLD, nLockTime)) - return false; - return true; } @@ -1221,17 +1212,32 @@ bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) con return false; // Mask off any bits that do not have consensus-enforced meaning - // before doing the integer comparisons of ::VerifyLockTime. - const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG - | CTxIn::SEQUENCE_LOCKTIME_MASK; + // before doing the integer comparisons + const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK; + const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; + const CScriptNum nSequenceMasked = nSequence & nLockTimeMask; - if (!::VerifyLockTime(txToSequence & nLockTimeMask, CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG, nSequence & nLockTimeMask)) + // There are two kinds of nSequence: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script + // unless the type of nSequenceMasked being tested is the same as + // the nSequenceMasked in the transaction. + if (!( + (txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || + (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) + )) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nSequenceMasked > txToSequenceMasked) return false; return true; } - bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); From ca8fb59ae14b4140e24c4d12c7b87597fd80a932 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Feb 2016 16:09:13 +0100 Subject: [PATCH 0250/1223] wallet: Warn on unexpected EOF while salvaging wallet Check for EOF before every getline, and warn when reading gets to EOF before the end of the data. Stricter error checking could shed more light on issues such as #7463 and #7379. --- src/wallet/db.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 50b0f40a6..0b07cddde 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -165,6 +165,11 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu return (fRecovered ? RECOVER_OK : RECOVER_FAIL); } +/* End of headers, beginning of key/value data */ +static const char *HEADER_END = "HEADER=END"; +/* End of key/value data */ +static const char *DATA_END = "DATA=END"; + bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector& vResult) { LOCK(cs_db); @@ -199,18 +204,29 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector Date: Mon, 15 Feb 2016 15:50:28 +0100 Subject: [PATCH 0251/1223] test: test leading space for ParseHex BerkeleyDB dump files have key and value lines indented. The salvage code passes these to ParseHex as-is. Check this in the tests (should just pass with current code). --- src/test/util_tests.cpp | 4 ++++ src/wallet/db.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 01bc2032d..43e8ae9b3 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -60,6 +60,10 @@ BOOST_AUTO_TEST_CASE(util_ParseHex) result = ParseHex("12 34 56 78"); BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + // Leading space must be supported (used in CDBEnv::Salvage) + result = ParseHex(" 89 34 56 78"); + BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + // Stop parsing at invalid value result = ParseHex("1234 invalid 1234"); BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 50b0f40a6..6af5413a9 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -193,9 +193,9 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector Date: Tue, 16 Feb 2016 09:39:44 +0000 Subject: [PATCH 0252/1223] Code style fix. This if statement is a little obtuse and using braces here improves readability. --- src/script/interpreter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d4fe001d7..149a4f015 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1227,8 +1227,9 @@ bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) con if (!( (txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) - )) + )) { return false; + } // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. From 086da92ea772b70d460993ada0e068d139beddd6 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 16 Feb 2016 12:10:12 -0500 Subject: [PATCH 0253/1223] Add tags to mempool's mapTx indices --- src/miner.cpp | 4 ++-- src/test/mempool_tests.cpp | 22 +++++++++++----------- src/txmempool.cpp | 6 +++--- src/txmempool.h | 8 ++++++++ 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index c454c0279..9281f7285 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -155,10 +155,10 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); } - CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin(); + CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); CTxMemPool::txiter iter; - while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty()) + while (mi != mempool.mapTx.get().end() || !clearedTxs.empty()) { bool priorityTx = false; if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 1347d2365..fa352ace8 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -102,13 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } -template +template void CheckSort(CTxMemPool &pool, std::vector &sortedOrder) { BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); - typename CTxMemPool::indexed_transaction_set::nth_index::type::iterator it = pool.mapTx.get().begin(); + typename CTxMemPool::indexed_transaction_set::index::type::iterator it = pool.mapTx.get().begin(); int count=0; - for (; it != pool.mapTx.get().end(); ++it, ++count) { + for (; it != pool.mapTx.get().end(); ++it, ++count) { BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); } } @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder[2] = tx1.GetHash().ToString(); // 10000 sortedOrder[3] = tx4.GetHash().ToString(); // 15000 sortedOrder[4] = tx2.GetHash().ToString(); // 20000 - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); /* low fee but with high fee child */ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ @@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK_EQUAL(pool.size(), 6); // Check that at this point, tx6 is sorted low sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); CTxMemPool::setEntries setAncestors; setAncestors.insert(pool.mapTx.find(tx6.GetHash())); @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.erase(sortedOrder.begin()); sortedOrder.push_back(tx6.GetHash().ToString()); sortedOrder.push_back(tx7.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx8 = CMutableTransaction(); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now tx8 should be sorted low, but tx6/tx both high sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx9 = CMutableTransaction(); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // tx9 should be sorted low BOOST_CHECK_EQUAL(pool.size(), 9); sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); std::vector snapshotOrder = sortedOrder; @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6 - CheckSort<1>(pool, sortedOrder); + CheckSort(pool, sortedOrder); // there should be 10 transactions in the mempool BOOST_CHECK_EQUAL(pool.size(), 10); @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now try removing tx10 and verify the sort order returns to normal std::list removed; pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); - CheckSort<1>(pool, snapshotOrder); + CheckSort(pool, snapshotOrder); pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true); pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true); @@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.push_back(tx3.GetHash().ToString()); sortedOrder.push_back(tx6.GetHash().ToString()); } - CheckSort<3>(pool, sortedOrder); + CheckSort(pool, sortedOrder); } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0b0f32e40..eee6cbf85 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -859,9 +859,9 @@ void CTxMemPool::RemoveStaged(setEntries &stage) { int CTxMemPool::Expire(int64_t time) { LOCK(cs); - indexed_transaction_set::nth_index<2>::type::iterator it = mapTx.get<2>().begin(); + indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); setEntries toremove; - while (it != mapTx.get<2>().end() && it->GetTime() < time) { + while (it != mapTx.get().end() && it->GetTime() < time) { toremove.insert(mapTx.project<0>(it)); it++; } @@ -957,7 +957,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); while (DynamicMemoryUsage() > sizelimit) { - indexed_transaction_set::nth_index<1>::type::iterator it = mapTx.get<1>().begin(); + indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the // "minimum reasonable fee rate" (ie some value under which we consider txn diff --git a/src/txmempool.h b/src/txmempool.h index 386cb26d2..7a2a1ef43 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -228,6 +228,11 @@ public: } }; +// Multi_index tag names +struct descendant_score {}; +struct entry_time {}; +struct mining_score {}; + class CBlockPolicyEstimator; /** An inpoint - a combination of a transaction and an index n into its vin */ @@ -350,16 +355,19 @@ public: boost::multi_index::ordered_unique, // sorted by fee rate boost::multi_index::ordered_non_unique< + boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByDescendantScore >, // sorted by entry time boost::multi_index::ordered_non_unique< + boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByEntryTime >, // sorted by score (for mining prioritization) boost::multi_index::ordered_unique< + boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByScore > From 110b62f06992d0fb989153afff2dc3aea62a674f Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Wed, 17 Feb 2016 22:44:32 -0800 Subject: [PATCH 0254/1223] Remove vfReachable and modify IsReachable to only use vfLimited. We do not know that a class of Network is reachable, only that it is not. --- src/init.cpp | 7 ++++--- src/net.cpp | 12 +----------- src/net.h | 1 - src/torcontrol.cpp | 2 +- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 048843a4c..fe05bc159 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1199,6 +1199,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = GetArg("-proxy", ""); + SetLimited(NET_TOR); if (proxyArg != "" && proxyArg != "0") { proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize); if (!addrProxy.IsValid()) @@ -1208,7 +1209,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) SetProxy(NET_IPV6, addrProxy); SetProxy(NET_TOR, addrProxy); SetNameProxy(addrProxy); - SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later + SetLimited(NET_TOR, false); // by default, -proxy sets onion as reachable, unless -noonion later } // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses @@ -1217,13 +1218,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string onionArg = GetArg("-onion", ""); if (onionArg != "") { if (onionArg == "0") { // Handle -noonion/-onion=0 - SetReachable(NET_TOR, false); // set onions as unreachable + SetLimited(NET_TOR); // set onions as unreachable } else { proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize); if (!addrOnion.IsValid()) return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg)); SetProxy(NET_TOR, addrOnion); - SetReachable(NET_TOR); + SetLimited(NET_TOR, false); } } diff --git a/src/net.cpp b/src/net.cpp index e06e5255d..b589692d1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -79,7 +79,6 @@ bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; CCriticalSection cs_mapLocalHost; map mapLocalHost; -static bool vfReachable[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; @@ -226,14 +225,6 @@ void AdvertiseLocal(CNode *pnode) } } -void SetReachable(enum Network net, bool fFlag) -{ - LOCK(cs_mapLocalHost); - vfReachable[net] = fFlag; - if (net == NET_IPV6 && fFlag) - vfReachable[NET_IPV4] = true; -} - // learn a new local address bool AddLocal(const CService& addr, int nScore) { @@ -256,7 +247,6 @@ bool AddLocal(const CService& addr, int nScore) info.nScore = nScore + (fAlready ? 1 : 0); info.nPort = addr.GetPort(); } - SetReachable(addr.GetNetwork()); } return true; @@ -319,7 +309,7 @@ bool IsLocal(const CService& addr) bool IsReachable(enum Network net) { LOCK(cs_mapLocalHost); - return vfReachable[net] && !vfLimited[net]; + return !vfLimited[net]; } /** check whether a given address is in a network we can probably connect to */ diff --git a/src/net.h b/src/net.h index d939ef55a..ec296e2ab 100644 --- a/src/net.h +++ b/src/net.h @@ -146,7 +146,6 @@ bool IsLocal(const CService& addr); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); bool IsReachable(enum Network net); bool IsReachable(const CNetAddr &addr); -void SetReachable(enum Network net, bool fFlag = true); CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 10170dbce..6fa8ce9d5 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -459,7 +459,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r if (GetArg("-onion", "") == "") { proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true); SetProxy(NET_TOR, addrOnion); - SetReachable(NET_TOR); + SetLimited(NET_TOR, false); } // Finally - now create the service From 0e3ccbfb26b11ea3d9ed7dfd39886d69097286e1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 18 Feb 2016 18:08:59 +0100 Subject: [PATCH 0255/1223] doc: Add historical release notes for 0.10.4 0.11.2 and 0.12.0 --- doc/release-notes/release-notes-0.10.4.md | 172 +++++ doc/release-notes/release-notes-0.11.2.md | 217 ++++++ doc/release-notes/release-notes-0.12.0.md | 890 ++++++++++++++++++++++ 3 files changed, 1279 insertions(+) create mode 100644 doc/release-notes/release-notes-0.10.4.md create mode 100644 doc/release-notes/release-notes-0.11.2.md create mode 100644 doc/release-notes/release-notes-0.12.0.md diff --git a/doc/release-notes/release-notes-0.10.4.md b/doc/release-notes/release-notes-0.10.4.md new file mode 100644 index 000000000..38a2c1347 --- /dev/null +++ b/doc/release-notes/release-notes-0.10.4.md @@ -0,0 +1,172 @@ +Bitcoin Core version 0.10.4 is now available from: + + + +This is a new minor version release, bringing bug fixes, the BIP65 +(CLTV) consensus change, and relay policy preparation for BIP113. It is +recommended to upgrade to this version as soon as possible. + +Please report bugs using the issue tracker at github: + + + +Upgrading and downgrading +========================= + +How to Upgrade +-------------- + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). + +Downgrade warning +------------------ + +Because release 0.10.0 and later makes use of headers-first synchronization and +parallel block download (see further), the block files and databases are not +backwards-compatible with pre-0.10 versions of Bitcoin Core or other software: + +* Blocks will be stored on disk out of order (in the order they are +received, really), which makes it incompatible with some tools or +other programs. Reindexing using earlier versions will also not work +anymore as a result of this. + +* The block index database will now hold headers for which no block is +stored on disk, which earlier versions won't support. + +If you want to be able to downgrade smoothly, make a backup of your entire data +directory. Without this your node will need start syncing (or importing from +bootstrap.dat) anew afterwards. It is possible that the data from a completely +synchronised 0.10 node may be usable in older versions as-is, but this is not +supported and may break as soon as the older version attempts to reindex. + +This does not affect wallet forward or backward compatibility. There are no +known problems when downgrading from 0.11.x to 0.10.x. + +Notable changes since 0.10.3 +============================ + +BIP65 soft fork to enforce OP_CHECKLOCKTIMEVERIFY opcode +-------------------------------------------------------- + +This release includes several changes related to the [BIP65][] soft fork +which redefines the existing OP_NOP2 opcode as OP_CHECKLOCKTIMEVERIFY +(CLTV) so that a transaction output can be made unspendable until a +specified point in the future. + +1. This release will only relay and mine transactions spending a CLTV + output if they comply with the BIP65 rules as provided in code. + +2. This release will produce version 4 blocks by default. Please see the + *notice to miners* below. + +3. Once 951 out of a sequence of 1,001 blocks on the local node's best block + chain contain version 4 (or higher) blocks, this release will no + longer accept new version 3 blocks and it will only accept version 4 + blocks if they comply with the BIP65 rules for CLTV. + +For more information about the soft-forking change, please see + + +Graphs showing the progress towards block version 4 adoption may be +found at the URLs below: + +- Block versions over the last 50,000 blocks as progress towards BIP65 + consensus enforcement: + +- Block versions over the last 2,000 blocks showing the days to the + earliest possible BIP65 consensus-enforced block: + +**Notice to miners:** Bitcoin Core’s block templates are now for +version 4 blocks only, and any mining software relying on its +getblocktemplate must be updated in parallel to use libblkmaker either +version FIXME or any version from FIXME onward. + +- If you are solo mining, this will affect you the moment you upgrade + Bitcoin Core, which must be done prior to BIP65 achieving its 951/1001 + status. + +- If you are mining with the stratum mining protocol: this does not + affect you. + +- If you are mining with the getblocktemplate protocol to a pool: this + will affect you at the pool operator’s discretion, which must be no + later than BIP65 achieving its 951/1001 status. + +[BIP65]: https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki + +Windows bug fix for corrupted UTXO database on unclean shutdowns +---------------------------------------------------------------- + +Several Windows users reported that they often need to reindex the +entire blockchain after an unclean shutdown of Bitcoin Core on Windows +(or an unclean shutdown of Windows itself). Although unclean shutdowns +remain unsafe, this release no longer relies on memory-mapped files for +the UTXO database, which significantly reduced the frequency of unclean +shutdowns leading to required reindexes during testing. + +For more information, see: + +Other fixes for database corruption on Windows are expected in the +next major release. + +0.10.4 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +- #6953 `8b3311f` alias -h for --help +- #6953 `97546fc` Change URLs to https in debian/control +- #6953 `38671bf` Update debian/changelog and slight tweak to debian/control +- #6953 `256321e` Correct spelling mistakes in doc folder +- #6953 `eae0350` Clarification of unit test build instructions +- #6953 `90897ab` Update bluematt-key, the old one is long-since revoked +- #6953 `a2f2fb6` build: disable -Wself-assign +- #6953 `cf67d8b` Bugfix: Allow mining on top of old tip blocks for testnet (fixes testnet-in-a-box use case) +- #6953 `b3964e3` Drop "with minimal dependencies" from description +- #6953 `43c2789` Split bitcoin-tx into its own package +- #6953 `dfe0d4d` Include bitcoin-tx binary on Debian/Ubuntu +- #6953 `612efe8` [Qt] Raise debug window when requested +- #6953 `3ad96bd` Fix locking in GetTransaction +- #6953 `9c81005` Fix spelling of Qt +- #6946 `94b67e5` Update LevelDB +- #6706 `5dc72f8` CLTV: Add more tests to improve coverage +- #6706 `6a1343b` Add RPC tests for the CHECKLOCKTIMEVERIFY (BIP65) soft-fork +- #6706 `4137248` Add CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic +- #6706 `0e01d0f` Enable CHECKLOCKTIMEVERIFY as a standard script verify flag +- #6706 `6d01325` Replace NOP2 with CHECKLOCKTIMEVERIFY (BIP65) +- #6706 `750d54f` Move LOCKTIME_THRESHOLD to src/script/script.h +- #6706 `6897468` Make CScriptNum() take nMaxNumSize as an argument +- #6867 `5297194` Set TCP_NODELAY on P2P sockets +- #6836 `fb818b6` Bring historical release notes up to date +- #6852 `0b3fd07` build: make sure OpenSSL heeds noexecstack + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Alex Morcos +- Daniel Cousens +- Diego Viola +- Eric Lombrozo +- Esteban Ordano +- Gregory Maxwell +- Luke Dashjr +- MarcoFalke +- Matt Corallo +- Micha +- Mitchell Cash +- Peter Todd +- Pieter Wuille +- Wladimir J. van der Laan +- Zak Wilcox + +And those who contributed additional code review and/or security research. + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.11.2.md b/doc/release-notes/release-notes-0.11.2.md new file mode 100644 index 000000000..2351b8065 --- /dev/null +++ b/doc/release-notes/release-notes-0.11.2.md @@ -0,0 +1,217 @@ +Bitcoin Core version 0.11.2 is now available from: + + + +This is a new minor version release, bringing bug fixes, the BIP65 +(CLTV) consensus change, and relay policy preparation for BIP113. It is +recommended to upgrade to this version as soon as possible. + +Please report bugs using the issue tracker at github: + + + +Upgrading and downgrading +========================= + +How to Upgrade +-------------- + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). + +Downgrade warning +------------------ + +Because release 0.10.0 and later makes use of headers-first synchronization and +parallel block download (see further), the block files and databases are not +backwards-compatible with pre-0.10 versions of Bitcoin Core or other software: + +* Blocks will be stored on disk out of order (in the order they are +received, really), which makes it incompatible with some tools or +other programs. Reindexing using earlier versions will also not work +anymore as a result of this. + +* The block index database will now hold headers for which no block is +stored on disk, which earlier versions won't support. + +If you want to be able to downgrade smoothly, make a backup of your entire data +directory. Without this your node will need start syncing (or importing from +bootstrap.dat) anew afterwards. It is possible that the data from a completely +synchronised 0.10 node may be usable in older versions as-is, but this is not +supported and may break as soon as the older version attempts to reindex. + +This does not affect wallet forward or backward compatibility. There are no +known problems when downgrading from 0.11.x to 0.10.x. + +Notable changes since 0.11.1 +============================ + +BIP65 soft fork to enforce OP_CHECKLOCKTIMEVERIFY opcode +-------------------------------------------------------- + +This release includes several changes related to the [BIP65][] soft fork +which redefines the existing OP_NOP2 opcode as OP_CHECKLOCKTIMEVERIFY +(CLTV) so that a transaction output can be made unspendable until a +specified point in the future. + +1. This release will only relay and mine transactions spending a CLTV + output if they comply with the BIP65 rules as provided in code. + +2. This release will produce version 4 blocks by default. Please see the + *notice to miners* below. + +3. Once 951 out of a sequence of 1,001 blocks on the local node's best block + chain contain version 4 (or higher) blocks, this release will no + longer accept new version 3 blocks and it will only accept version 4 + blocks if they comply with the BIP65 rules for CLTV. + +For more information about the soft-forking change, please see + + +Graphs showing the progress towards block version 4 adoption may be +found at the URLs below: + +- Block versions over the last 50,000 blocks as progress towards BIP65 + consensus enforcement: + +- Block versions over the last 2,000 blocks showing the days to the + earliest possible BIP65 consensus-enforced block: + +**Notice to miners:** Bitcoin Core’s block templates are now for +version 4 blocks only, and any mining software relying on its +getblocktemplate must be updated in parallel to use libblkmaker either +version 0.4.3 or any version from 0.5.2 onward. + +- If you are solo mining, this will affect you the moment you upgrade + Bitcoin Core, which must be done prior to BIP65 achieving its 951/1001 + status. + +- If you are mining with the stratum mining protocol: this does not + affect you. + +- If you are mining with the getblocktemplate protocol to a pool: this + will affect you at the pool operator’s discretion, which must be no + later than BIP65 achieving its 951/1001 status. + +[BIP65]: https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki + +BIP113 mempool-only locktime enforcement using GetMedianTimePast() +---------------------------------------------------------------- + +Bitcoin transactions currently may specify a locktime indicating when +they may be added to a valid block. Current consensus rules require +that blocks have a block header time greater than the locktime specified +in any transaction in that block. + +Miners get to choose what time they use for their header time, with the +consensus rule being that no node will accept a block whose time is more +than two hours in the future. This creates a incentive for miners to +set their header times to future values in order to include locktimed +transactions which weren't supposed to be included for up to two more +hours. + +The consensus rules also specify that valid blocks may have a header +time greater than that of the median of the 11 previous blocks. This +GetMedianTimePast() time has a key feature we generally associate with +time: it can't go backwards. + +[BIP113][] specifies a soft fork (**not enforced in this release**) that +weakens this perverse incentive for individual miners to use a future +time by requiring that valid blocks have a computed GetMedianTimePast() +greater than the locktime specified in any transaction in that block. + +Mempool inclusion rules currently require transactions to be valid for +immediate inclusion in a block in order to be accepted into the mempool. +This release begins applying the BIP113 rule to received transactions, +so transaction whose time is greater than the GetMedianTimePast() will +no longer be accepted into the mempool. + +**Implication for miners:** you will begin rejecting transactions that +would not be valid under BIP113, which will prevent you from producing +invalid blocks if/when BIP113 is enforced on the network. Any +transactions which are valid under the current rules but not yet valid +under the BIP113 rules will either be mined by other miners or delayed +until they are valid under BIP113. Note, however, that time-based +locktime transactions are more or less unseen on the network currently. + +**Implication for users:** GetMedianTimePast() always trails behind the +current time, so a transaction locktime set to the present time will be +rejected by nodes running this release until the median time moves +forward. To compensate, subtract one hour (3,600 seconds) from your +locktimes to allow those transactions to be included in mempools at +approximately the expected time. + +[BIP113]: https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki + +Windows bug fix for corrupted UTXO database on unclean shutdowns +---------------------------------------------------------------- + +Several Windows users reported that they often need to reindex the +entire blockchain after an unclean shutdown of Bitcoin Core on Windows +(or an unclean shutdown of Windows itself). Although unclean shutdowns +remain unsafe, this release no longer relies on memory-mapped files for +the UTXO database, which significantly reduced the frequency of unclean +shutdowns leading to required reindexes during testing. + +For more information, see: + +Other fixes for database corruption on Windows are expected in the +next major release. + +0.11.2 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +- #6124 `684636b` Make CScriptNum() take nMaxNumSize as an argument +- #6124 `4fa7a04` Replace NOP2 with CHECKLOCKTIMEVERIFY (BIP65) +- #6124 `6ea5ca4` Enable CHECKLOCKTIMEVERIFY as a standard script verify flag +- #6351 `5e82e1c` Add CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic +- #6353 `ba1da90` Show softfork status in getblockchaininfo +- #6351 `6af25b0` Add BIP65 to getblockchaininfo softforks list +- #6688 `01878c9` Fix locking in GetTransaction +- #6653 `b3eaa30` [Qt] Raise debug window when requested +- #6600 `1e672ae` Debian/Ubuntu: Include bitcoin-tx binary +- #6600 `2394f4d` Debian/Ubuntu: Split bitcoin-tx into its own package +- #5987 `33d6825` Bugfix: Allow mining on top of old tip blocks for testnet +- #6852 `21e58b8` build: make sure OpenSSL heeds noexecstack +- #6846 `af6edac` alias `-h` for `--help` +- #6867 `95a5039` Set TCP_NODELAY on P2P sockets. +- #6856 `dfe55bd` Do not allow blockfile pruning during reindex. +- #6566 `a1d3c6f` Add rules--presently disabled--for using GetMedianTimePast as end point for lock-time calculations +- #6566 `f720c5f` Enable policy enforcing GetMedianTimePast as the end point of lock-time constraints +- #6917 `0af5b8e` leveldb: Win32WritableFile without memory mapping +- #6948 `4e895b0` Always flush block and undo when switching to new file + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Alex Morcos +- ฿tcDrak +- Chris Kleeschulte +- Daniel Cousens +- Diego Viola +- Eric Lombrozo +- Esteban Ordano +- Gregory Maxwell +- Luke Dashjr +- Marco Falke +- Mark Friedenbach +- Matt Corallo +- Micha +- Mitchell Cash +- Peter Todd +- Pieter Wuille +- Wladimir J. van der Laan +- Zak Wilcox + +And those who contributed additional code review and/or security research. + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md new file mode 100644 index 000000000..332d4cebe --- /dev/null +++ b/doc/release-notes/release-notes-0.12.0.md @@ -0,0 +1,890 @@ +Bitcoin Core version 0.12.0 is now available from: + + + +This is a new major version release, bringing new features and other improvements. + +Please report bugs using the issue tracker at github: + + + +Upgrading and downgrading +========================= + +How to Upgrade +-------------- + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). + +Downgrade warning +----------------- + +### Downgrade to a version < 0.10.0 + +Because release 0.10.0 and later makes use of headers-first synchronization and +parallel block download (see further), the block files and databases are not +backwards-compatible with pre-0.10 versions of Bitcoin Core or other software: + +* Blocks will be stored on disk out of order (in the order they are +received, really), which makes it incompatible with some tools or +other programs. Reindexing using earlier versions will also not work +anymore as a result of this. + +* The block index database will now hold headers for which no block is +stored on disk, which earlier versions won't support. + +If you want to be able to downgrade smoothly, make a backup of your entire data +directory. Without this your node will need start syncing (or importing from +bootstrap.dat) anew afterwards. It is possible that the data from a completely +synchronised 0.10 node may be usable in older versions as-is, but this is not +supported and may break as soon as the older version attempts to reindex. + +This does not affect wallet forward or backward compatibility. + +### Downgrade to a version < 0.12.0 + +Because release 0.12.0 and later will obfuscate the chainstate on every +fresh sync or reindex, the chainstate is not backwards-compatible with +pre-0.12 versions of Bitcoin Core or other software. + +If you want to downgrade after you have done a reindex with 0.12.0 or later, +you will need to reindex when you first start Bitcoin Core version 0.11 or +earlier. + +Notable changes +=============== + +Signature validation using libsecp256k1 +--------------------------------------- + +ECDSA signatures inside Bitcoin transactions now use validation using +[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. + +Depending on the platform, this means a significant speedup for raw signature +validation speed. The advantage is largest on x86_64, where validation is over +five times faster. In practice, this translates to a raw reindexing and new +block validation times that are less than half of what it was before. + +Libsecp256k1 has undergone very extensive testing and validation. + +A side effect of this change is that libconsensus no longer depends on OpenSSL. + +Reduce upload traffic +--------------------- + +A major part of the outbound traffic is caused by serving historic blocks to +other nodes in initial block download state. + +It is now possible to reduce the total upload traffic via the `-maxuploadtarget` +parameter. This is *not* a hard limit but a threshold to minimize the outbound +traffic. When the limit is about to be reached, the uploaded data is cut by not +serving historic blocks (blocks older than one week). +Moreover, any SPV peer is disconnected when they request a filtered block. + +This option can be specified in MiB per day and is turned off by default +(`-maxuploadtarget=0`). +The recommended minimum is 144 * MAX_BLOCK_SIZE (currently 144MB) per day. + +Whitelisted peers will never be disconnected, although their traffic counts for +calculating the target. + +A more detailed documentation about keeping traffic low can be found in +[/doc/reduce-traffic.md](/doc/reduce-traffic.md). + +Direct headers announcement (BIP 130) +------------------------------------- + +Between compatible peers, [BIP 130] +(https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki) +direct headers announcement is used. This means that blocks are advertized by +announcing their headers directly, instead of just announcing the hash. In a +reorganization, all new headers are sent, instead of just the new tip. This +can often prevent an extra roundtrip before the actual block is downloaded. + +With this change, pruning nodes are now able to relay new blocks to compatible +peers. + +Memory pool limiting +-------------------- + +Previous versions of Bitcoin Core had their mempool limited by checking +a transaction's fees against the node's minimum relay fee. There was no +upper bound on the size of the mempool and attackers could send a large +number of transactions paying just slighly more than the default minimum +relay fee to crash nodes with relatively low RAM. A temporary workaround +for previous versions of Bitcoin Core was to raise the default minimum +relay fee. + +Bitcoin Core 0.12 will have a strict maximum size on the mempool. The +default value is 300 MB and can be configured with the `-maxmempool` +parameter. Whenever a transaction would cause the mempool to exceed +its maximum size, the transaction that (along with in-mempool descendants) has +the lowest total feerate (as a package) will be evicted and the node's effective +minimum relay feerate will be increased to match this feerate plus the initial +minimum relay feerate. The initial minimum relay feerate is set to +1000 satoshis per kB. + +Bitcoin Core 0.12 also introduces new default policy limits on the length and +size of unconfirmed transaction chains that are allowed in the mempool +(generally limiting the length of unconfirmed chains to 25 transactions, with a +total size of 101 KB). These limits can be overriden using command line +arguments; see the extended help (`--help -help-debug`) for more information. + +Opt-in Replace-by-fee transactions +---------------------------------- + +It is now possible to replace transactions in the transaction memory pool of +Bitcoin Core 0.12 nodes. Bitcoin Core will only allow replacement of +transactions which have any of their inputs' `nSequence` number set to less +than `0xffffffff - 1`. Moreover, a replacement transaction may only be +accepted when it pays sufficient fee, as described in [BIP 125] +(https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki). + +Transaction replacement can be disabled with a new command line option, +`-mempoolreplacement=0`. Transactions signaling replacement under BIP125 will +still be allowed into the mempool in this configuration, but replacements will +be rejected. This option is intended for miners who want to continue the +transaction selection behavior of previous releases. + +The `-mempoolreplacement` option is *not recommended* for wallet users seeking +to avoid receipt of unconfirmed opt-in transactions, because this option does +not prevent transactions which are replaceable under BIP 125 from being accepted +(only subsequent replacements, which other nodes on the network that implement +BIP 125 are likely to relay and mine). Wallet users wishing to detect whether +a transaction is subject to replacement under BIP 125 should instead use the +updated RPC calls `gettransaction` and `listtransactions`, which now have an +additional field in the output indicating if a transaction is replaceable under +BIP125 ("bip125-replaceable"). + +Note that the wallet in Bitcoin Core 0.12 does not yet have support for +creating transactions that would be replaceable under BIP 125. + + +RPC: Random-cookie RPC authentication +------------------------------------- + +When no `-rpcpassword` is specified, the daemon now uses a special 'cookie' +file for authentication. This file is generated with random content when the +daemon starts, and deleted when it exits. Its contents are used as +authentication token. Read access to this file controls who can access through +RPC. By default it is stored in the data directory but its location can be +overridden with the option `-rpccookiefile`. + +This is similar to Tor's CookieAuthentication: see +https://www.torproject.org/docs/tor-manual.html.en + +This allows running bitcoind without having to do any manual configuration. + +Relay: Any sequence of pushdatas in OP_RETURN outputs now allowed +----------------------------------------------------------------- + +Previously OP_RETURN outputs with a payload were only relayed and mined if they +had a single pushdata. This restriction has been lifted to allow any +combination of data pushes and numeric constant opcodes (OP_1 to OP_16) after +the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire +serialized scriptPubKey, 83 bytes by default. (the previous 80 byte default plus +three bytes overhead) + +Relay and Mining: Priority transactions +--------------------------------------- + +Bitcoin Core has a heuristic 'priority' based on coin value and age. This +calculation is used for relaying of transactions which do not pay the +minimum relay fee, and can be used as an alternative way of sorting +transactions for mined blocks. Bitcoin Core will relay transactions with +insufficient fees depending on the setting of `-limitfreerelay=` (default: +`r=15` kB per minute) and `-blockprioritysize=`. + +In Bitcoin Core 0.12, when mempool limit has been reached a higher minimum +relay fee takes effect to limit memory usage. Transactions which do not meet +this higher effective minimum relay fee will not be relayed or mined even if +they rank highly according to the priority heuristic. + +The mining of transactions based on their priority is also now disabled by +default. To re-enable it, simply set `-blockprioritysize=` where is the size +in bytes of your blocks to reserve for these transactions. The old default was +50k, so to retain approximately the same policy, you would set +`-blockprioritysize=50000`. + +Additionally, as a result of computational simplifications, the priority value +used for transactions received with unconfirmed inputs is lower than in prior +versions due to avoiding recomputing the amounts as input transactions confirm. + +External miner policy set via the `prioritisetransaction` RPC to rank +transactions already in the mempool continues to work as it has previously. +Note, however, that if mining priority transactions is left disabled, the +priority delta will be ignored and only the fee metric will be effective. + +This internal automatic prioritization handling is being considered for removal +entirely in Bitcoin Core 0.13, and it is at this time undecided whether the +more accurate priority calculation for chained unconfirmed transactions will be +restored. Community direction on this topic is particularly requested to help +set project priorities. + +Automatically use Tor hidden services +------------------------------------- + +Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket +API, to create and destroy 'ephemeral' hidden services programmatically. +Bitcoin Core has been updated to make use of this. + +This means that if Tor is running (and proper authorization is available), +Bitcoin Core automatically creates a hidden service to listen on, without +manual configuration. Bitcoin Core will also use Tor automatically to connect +to other .onion nodes if the control socket can be successfully opened. This +will positively affect the number of available .onion nodes and their usage. + +This new feature is enabled by default if Bitcoin Core is listening, and +a connection to Tor can be made. It can be configured with the `-listenonion`, +`-torcontrol` and `-torpassword` settings. To show verbose debugging +information, pass `-debug=tor`. + +Notifications through ZMQ +------------------------- + +Bitcoind can now (optionally) asynchronously notify clients through a +ZMQ-based PUB socket of the arrival of new transactions and blocks. +This feature requires installation of the ZMQ C API library 4.x and +configuring its use through the command line or configuration file. +Please see [docs/zmq.md](/doc/zmq.md) for details of operation. + +Wallet: Transaction fees +------------------------ + +Various improvements have been made to how the wallet calculates +transaction fees. + +Users can decide to pay a predefined fee rate by setting `-paytxfee=` +(or `settxfee ` rpc during runtime). A value of `n=0` signals Bitcoin +Core to use floating fees. By default, Bitcoin Core will use floating +fees. + +Based on past transaction data, floating fees approximate the fees +required to get into the `m`th block from now. This is configurable +with `-txconfirmtarget=` (default: `2`). + +Sometimes, it is not possible to give good estimates, or an estimate +at all. Therefore, a fallback value can be set with `-fallbackfee=` +(default: `0.0002` BTC/kB). + +At all times, Bitcoin Core will cap fees at `-maxtxfee=` (default: +0.10) BTC. +Furthermore, Bitcoin Core will never create transactions smaller than +the current minimum relay fee. +Finally, a user can set the minimum fee rate for all transactions with +`-mintxfee=`, which defaults to 1000 satoshis per kB. + +Wallet: Negative confirmations and conflict detection +----------------------------------------------------- + +The wallet will now report a negative number for confirmations that indicates +how deep in the block chain the conflict is found. For example, if a transaction +A has 5 confirmations and spends the same input as a wallet transaction B, B +will be reported as having -5 confirmations. If another wallet transaction C +spends an output from B, it will also be reported as having -5 confirmations. +To detect conflicts with historical transactions in the chain a one-time +`-rescan` may be needed. + +Unlike earlier versions, unconfirmed but non-conflicting transactions will never +get a negative confirmation count. They are not treated as spendable unless +they're coming from ourself (change) and accepted into our local mempool, +however. The new "trusted" field in the `listtransactions` RPC output +indicates whether outputs of an unconfirmed transaction are considered +spendable. + +Wallet: Merkle branches removed +------------------------------- + +Previously, every wallet transaction stored a Merkle branch to prove its +presence in blocks. This wasn't being used for more than an expensive +sanity check. Since 0.12, these are no longer stored. When loading a +0.12 wallet into an older version, it will automatically rescan to avoid +failed checks. + +Wallet: Pruning +--------------- + +With 0.12 it is possible to use wallet functionality in pruned mode. +This can reduce the disk usage from currently around 60 GB to +around 2 GB. + +However, rescans as well as the RPCs `importwallet`, `importaddress`, +`importprivkey` are disabled. + +To enable block pruning set `prune=` on the command line or in +`bitcoin.conf`, where `N` is the number of MiB to allot for +raw block & undo data. + +A value of 0 disables pruning. The minimal value above 0 is 550. Your +wallet is as secure with high values as it is with low ones. Higher +values merely ensure that your node will not shut down upon blockchain +reorganizations of more than 2 days - which are unlikely to happen in +practice. In future releases, a higher value may also help the network +as a whole: stored blocks could be served to other nodes. + +For further information about pruning, you may also consult the [release +notes of v0.11.0](https://github.com/bitcoin/bitcoin/blob/v0.11.0/doc/release-notes.md#block-file-pruning). + +`NODE_BLOOM` service bit +------------------------ + +Support for the `NODE_BLOOM` service bit, as described in [BIP +111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been +added to the P2P protocol code. + +BIP 111 defines a service bit to allow peers to advertise that they support +bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol +version to allow peers to identify old nodes which allow bloom filtering of the +connection despite lacking the new service bit. + +In this version, it is only enforced for peers that send protocol versions +`>=70011`. For the next major version it is planned that this restriction will be +removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` +service bit for nodes that report versions newer than 70011. + +Option parsing behavior +----------------------- + +Command line options are now parsed strictly in the order in which they are +specified. It used to be the case that `-X -noX` ends up, unintuitively, with X +set, as `-X` had precedence over `-noX`. This is no longer the case. Like for +other software, the last specified value for an option will hold. + +RPC: Low-level API changes +-------------------------- + +- Monetary amounts can be provided as strings. This means that for example the + argument to sendtoaddress can be "0.0001" instead of 0.0001. This can be an + advantage if a JSON library insists on using a lossy floating point type for + numbers, which would be dangerous for monetary amounts. + +* The `asm` property of each scriptSig now contains the decoded signature hash + type for each signature that provides a valid defined hash type. + +* OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) + +The following items contain assembly representations of scriptSig signatures +and are affected by this change: + +- RPC `getrawtransaction` +- RPC `decoderawtransaction` +- RPC `decodescript` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `bitcoin-tx -json` + +For example, the `scriptSig.asm` property of a transaction input that +previously showed an assembly representation of: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 400000 OP_NOP2 + +now shows as: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] 400000 OP_CHECKLOCKTIMEVERIFY + +Note that the output of the RPC `decodescript` did not change because it is +configured specifically to process scriptPubKey and not scriptSig scripts. + +RPC: SSL support dropped +------------------------ + +SSL support for RPC, previously enabled by the option `rpcssl` has been dropped +from both the client and the server. This was done in preparation for removing +the dependency on OpenSSL for the daemon completely. + +Trying to use `rpcssl` will result in an error: + + Error: SSL mode for RPC (-rpcssl) is no longer supported. + +If you are one of the few people that relies on this feature, a flexible +migration path is to use `stunnel`. This is an utility that can tunnel +arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with: + + sudo apt-get install stunnel4 + +Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do: + + stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P '' + +It can also be set up system-wide in inetd style. + +Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution +would allow the use of different authentication, loadbalancing, on-the-fly compression and +caching. A sample config for apache2 could look like: + + Listen 443 + + NameVirtualHost *:443 + + + SSLEngine On + SSLCertificateFile /etc/apache2/ssl/server.crt + SSLCertificateKeyFile /etc/apache2/ssl/server.key + + + ProxyPass http://127.0.0.1:8332/ + ProxyPassReverse http://127.0.0.1:8332/ + # optional enable digest auth + # AuthType Digest + # ... + + # optional bypass bitcoind rpc basic auth + # RequestHeader set Authorization "Basic " + # get the from the shell with: base64 <<< bitcoinrpc: + + + # Or, balance the load: + # ProxyPass / balancer://balancer_cluster_name + + + +Mining Code Changes +------------------- + +The mining code in 0.12 has been optimized to be significantly faster and use less +memory. As part of these changes, consensus critical calculations are cached on a +transaction's acceptance into the mempool and the mining code now relies on the +consistency of the mempool to assemble blocks. However all blocks are still tested +for validity after assembly. + +Other P2P Changes +----------------- + +The list of banned peers is now stored on disk rather than in memory. +Restarting bitcoind will no longer clear out the list of banned peers; instead +a new RPC call (`clearbanned`) can be used to manually clear the list. The new +`setban` RPC call can also be used to manually ban or unban a peer. + +0.12.0 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### RPC and REST + +- #6121 `466f0ea` Convert entire source tree from json_spirit to UniValue (Jonas Schnelli) +- #6234 `d38cd47` fix rpcmining/getblocktemplate univalue transition logic error (Jonas Schnelli) +- #6239 `643114f` Don't go through double in AmountFromValue and ValueFromAmount (Wladimir J. van der Laan) +- #6266 `ebab5d3` Fix univalue handling of \u0000 characters. (Daniel Kraft) +- #6276 `f3d4dbb` Fix getbalance * 0 (Tom Harding) +- #6257 `5ebe7db` Add `paytxfee` and `errors` JSON fields where appropriate (Stephen) +- #6271 `754aae5` New RPC command disconnectnode (Alex van der Peet) +- #6158 `0abfa8a` Add setban/listbanned RPC commands (Jonas Schnelli) +- #6307 `7ecdcd9` rpcban fixes (Jonas Schnelli) +- #6290 `5753988` rpc: make `gettxoutsettinfo` run lock-free (Wladimir J. van der Laan) +- #6262 `247b914` Return all available information via RPC call "validateaddress" (dexX7) +- #6339 `c3f0490` UniValue: don't escape solidus, keep espacing of reverse solidus (Jonas Schnelli) +- #6353 `6bcb0a2` Show softfork status in getblockchaininfo (Wladimir J. van der Laan) +- #6247 `726e286` Add getblockheader RPC call (Peter Todd) +- #6362 `d6db115` Fix null id in RPC response during startup (Forrest Voight) +- #5486 `943b322` [REST] JSON support for /rest/headers (Jonas Schnelli) +- #6379 `c52e8b3` rpc: Accept scientific notation for monetary amounts in JSON (Wladimir J. van der Laan) +- #6388 `fd5dfda` rpc: Implement random-cookie based authentication (Wladimir J. van der Laan) +- #6457 `3c923e8` Include pruned state in chaininfo.json (Simon Males) +- #6456 `bfd807f` rpc: Avoid unnecessary parsing roundtrip in number formatting, fix locale issue (Wladimir J. van der Laan) +- #6380 `240b30e` rpc: Accept strings in AmountFromValue (Wladimir J. van der Laan) +- #6346 `6bb2805` Add OP_RETURN support in createrawtransaction RPC call, add tests. (paveljanik) +- #6013 `6feeec1` [REST] Add memory pool API (paveljanik) +- #6576 `da9beb2` Stop parsing JSON after first finished construct. (Daniel Kraft) +- #5677 `9aa9099` libevent-based http server (Wladimir J. van der Laan) +- #6633 `bbc2b39` Report minimum ping time in getpeerinfo (Matt Corallo) +- #6648 `cd381d7` Simplify logic of REST request suffix parsing. (Daniel Kraft) +- #6695 `5e21388` libevent http fixes (Wladimir J. van der Laan) +- #5264 `48efbdb` show scriptSig signature hash types in transaction decodes. fixes #3166 (mruddy) +- #6719 `1a9f19a` Make HTTP server shutdown more graceful (Wladimir J. van der Laan) +- #6859 `0fbfc51` http: Restrict maximum size of http + headers (Wladimir J. van der Laan) +- #5936 `bf7c195` [RPC] Add optional locktime to createrawtransaction (Tom Harding) +- #6877 `26f5b34` rpc: Add maxmempool and effective min fee to getmempoolinfo (Wladimir J. van der Laan) +- #6970 `92701b3` Fix crash in validateaddress with -disablewallet (Wladimir J. van der Laan) +- #5574 `755b4ba` Expose GUI labels in RPC as comments (Luke-Jr) +- #6990 `dbd2c13` http: speed up shutdown (Wladimir J. van der Laan) +- #7013 `36baa9f` Remove LOCK(cs_main) from decodescript (Peter Todd) +- #6999 `972bf9c` add (max)uploadtarget infos to getnettotals RPC help (Jonas Schnelli) +- #7011 `31de241` Add mediantime to getblockchaininfo (Peter Todd) +- #7065 `f91e29f` http: add Boost 1.49 compatibility (Wladimir J. van der Laan) +- #7087 `be281d8` [Net]Add -enforcenodebloom option (Patrick Strateman) +- #7044 `438ee59` RPC: Added additional config option for multiple RPC users. (Gregory Sanders) +- #7072 `c143c49` [RPC] Add transaction size to JSON output (Nikita Zhavoronkov) +- #7022 `9afbd96` Change default block priority size to 0 (Alex Morcos) +- #7141 `c0c08c7` rpc: Don't translate warning messages (Wladimir J. van der Laan) +- #7312 `fd4bd50` Add RPC call abandontransaction (Alex Morcos) +- #7222 `e25b158` RPC: indicate which transactions are replaceable (Suhas Daftuar) +- #7472 `b2f2b85` rpc: Add WWW-Authenticate header to 401 response (Wladimir J. van der Laan) +- #7469 `9cb31e6` net.h fix spelling: misbeha{b,v}ing (Matt) + +### Configuration and command-line options + +- #6164 `8d05ec7` Allow user to use -debug=1 to enable all debugging (lpescher) +- #5288 `4452205` Added -whiteconnections= option (Josh Lehan) +- #6284 `10ac38e` Fix argument parsing oddity with -noX (Wladimir J. van der Laan) +- #6489 `c9c017a` Give a better error message if system clock is bad (Casey Rodarmor) +- #6462 `c384800` implement uacomment config parameter which can add comments to user agent as per BIP-0014 (Pavol Rusnak) +- #6647 `a3babc8` Sanitize uacomment (MarcoFalke) +- #6742 `3b2d37c` Changed logging to make -logtimestamps to work also for -printtoconsole (arnuschky) +- #6846 `2cd020d` alias -h for -help (Daniel Cousens) +- #6622 `7939164` Introduce -maxuploadtarget (Jonas Schnelli) +- #6881 `2b62551` Debug: Add option for microsecond precision in debug.log (Suhas Daftuar) +- #6776 `e06c14f` Support -checkmempool=N, which runs checks once every N transactions (Pieter Wuille) +- #6896 `d482c0a` Make -checkmempool=1 not fail through int32 overflow (Pieter Wuille) +- #6993 `b632145` Add -blocksonly option (Patrick Strateman) +- #7323 `a344880` 0.12: Backport -bytespersigop option (Luke-Jr) +- #7386 `da83ecd` Add option `-permitrbf` to set transaction replacement policy (Wladimir J. van der Laan) +- #7290 `b16b5bc` Add missing options help (MarcoFalke) +- #7440 `c76bfff` Rename permitrbf to mempoolreplacement and provide minimal string-list forward compatibility (Luke-Jr) + +### Block and transaction handling + +- #6203 `f00b623` Remove P2SH coinbase flag, no longer interesting (Luke-Jr) +- #6222 `9c93ee5` Explicitly set tx.nVersion for the genesis block and mining tests (Mark Friedenbach) +- #5985 `3a1d3e8` Fix removing of orphan transactions (Alex Morcos) +- #6221 `dd8fe82` Prune: Support noncontiguous block files (Adam Weiss) +- #6124 `41076aa` Mempool only CHECKLOCKTIMEVERIFY (BIP65) verification, unparameterized version (Peter Todd) +- #6329 `d0a10c1` acceptnonstdtxn option to skip (most) "non-standard transaction" checks, for testnet/regtest only (Luke-Jr) +- #6410 `7cdefb9` Implement accurate memory accounting for mempool (Pieter Wuille) +- #6444 `24ce77d` Exempt unspendable transaction outputs from dust checks (dexX7) +- #5913 `a0625b8` Add absurdly high fee message to validation state (Shaul Kfir) +- #6177 `2f746c6` Prevent block.nTime from decreasing (Mark Friedenbach) +- #6377 `e545371` Handle no chain tip available in InvalidChainFound() (Ross Nicoll) +- #6551 `39ddaeb` Handle leveldb::DestroyDB() errors on wipe failure (Adam Weiss) +- #6654 `b0ce450` Mempool package tracking (Suhas Daftuar) +- #6715 `82d2aef` Fix mempool packages (Suhas Daftuar) +- #6680 `4f44530` use CBlockIndex instead of uint256 for UpdatedBlockTip signal (Jonas Schnelli) +- #6650 `4fac576` Obfuscate chainstate (James O'Beirne) +- #6777 `9caaf6e` Unobfuscate chainstate data in CCoinsViewDB::GetStats (James O'Beirne) +- #6722 `3b20e23` Limit mempool by throwing away the cheapest txn and setting min relay fee to it (Matt Corallo) +- #6889 `38369dd` fix locking issue with new mempool limiting (Jonas Schnelli) +- #6464 `8f3b3cd` Always clean up manual transaction prioritization (Casey Rodarmor) +- #6865 `d0badb9` Fix chainstate serialized_size computation (Pieter Wuille) +- #6566 `ff057f4` BIP-113: Mempool-only median time-past as endpoint for lock-time calculations (Mark Friedenbach) +- #6934 `3038eb6` Restores mempool only BIP113 enforcement (Gregory Maxwell) +- #6965 `de7d459` Benchmark sanity checks and fork checks in ConnectBlock (Matt Corallo) +- #6918 `eb6172a` Make sigcache faster, more efficient, larger (Pieter Wuille) +- #6771 `38ed190` Policy: Lower default limits for tx chains (Alex Morcos) +- #6932 `73fa5e6` ModifyNewCoins saves database lookups (Alex Morcos) +- #5967 `05d5918` Alter assumptions in CCoinsViewCache::BatchWrite (Alex Morcos) +- #6871 `0e93586` nSequence-based Full-RBF opt-in (Peter Todd) +- #7008 `eb77416` Lower bound priority (Alex Morcos) +- #6915 `2ef5ffa` [Mempool] Improve removal of invalid transactions after reorgs (Suhas Daftuar) +- #6898 `4077ad2` Rewrite CreateNewBlock (Alex Morcos) +- #6872 `bdda4d5` Remove UTXO cache entries when the tx they were added for is removed/does not enter mempool (Matt Corallo) +- #7062 `12c469b` [Mempool] Fix mempool limiting and replace-by-fee for PrioritiseTransaction (Suhas Daftuar) +- #7276 `76de36f` Report non-mandatory script failures correctly (Pieter Wuille) +- #7217 `e08b7cb` Mark blocks with too many sigops as failed (Suhas Daftuar) +- #7387 `f4b2ce8` Get rid of inaccurate ScriptSigArgsExpected (Pieter Wuille) + +### P2P protocol and network code + +- #6172 `88a7ead` Ignore getheaders requests when not synced (Suhas Daftuar) +- #5875 `9d60602` Be stricter in processing unrequested blocks (Suhas Daftuar) +- #6256 `8ccc07c` Use best header chain timestamps to detect partitioning (Gavin Andresen) +- #6283 `a903ad7` make CAddrMan::size() return the correct type of size_t (Diapolo) +- #6272 `40400d5` Improve proxy initialization (continues #4871) (Wladimir J. van der Laan, Diapolo) +- #6310 `66e5465` banlist.dat: store banlist on disk (Jonas Schnelli) +- #6412 `1a2de32` Test whether created sockets are select()able (Pieter Wuille) +- #6498 `219b916` Keep track of recently rejected transactions with a rolling bloom filter (cont'd) (Peter Todd) +- #6556 `70ec975` Fix masking of irrelevant bits in address groups. (Alex Morcos) +- #6530 `ea19c2b` Improve addrman Select() performance when buckets are nearly empty (Pieter Wuille) +- #6583 `af9305a` add support for miniupnpc api version 14 (Pavel Vasin) +- #6374 `69dc5b5` Connection slot exhaustion DoS mitigation (Patrick Strateman) +- #6636 `536207f` net: correctly initialize nMinPingUsecTime (Wladimir J. van der Laan) +- #6579 `0c27795` Add NODE_BLOOM service bit and bump protocol version (Matt Corallo) +- #6148 `999c8be` Relay blocks when pruning (Suhas Daftuar) +- #6588 `cf9bb11` In (strCommand == "tx"), return if AlreadyHave() (Tom Harding) +- #6974 `2f71b07` Always allow getheaders from whitelisted peers (Wladimir J. van der Laan) +- #6639 `bd629d7` net: Automatically create hidden service, listen on Tor (Wladimir J. van der Laan) +- #6984 `9ffc687` don't enforce maxuploadtarget's disconnect for whitelisted peers (Jonas Schnelli) +- #7046 `c322652` Net: Improve blocks only mode. (Patrick Strateman) +- #7090 `d6454f6` Connect to Tor hidden services by default (when listening on Tor) (Peter Todd) +- #7106 `c894fbb` Fix and improve relay from whitelisted peers (Pieter Wuille) +- #7129 `5d5ef3a` Direct headers announcement (rebase of #6494) (Pieter Wuille) +- #7079 `1b5118b` Prevent peer flooding inv request queue (redux) (redux) (Gregory Maxwell) +- #7166 `6ba25d2` Disconnect on mempool requests from peers when over the upload limit. (Gregory Maxwell) +- #7133 `f31955d` Replace setInventoryKnown with a rolling bloom filter (rebase of #7100) (Pieter Wuille) +- #7174 `82aff88` Don't do mempool lookups for "mempool" command without a filter (Matt Corallo) +- #7179 `44fef99` net: Fix sent reject messages for blocks and transactions (Wladimir J. van der Laan) +- #7181 `8fc174a` net: Add and document network messages in protocol.h (Wladimir J. van der Laan) +- #7125 `10b88be` Replace global trickle node with random delays (Pieter Wuille) +- #7415 `cb83beb` net: Hardcoded seeds update January 2016 (Wladimir J. van der Laan) +- #7438 `e2d9a58` Do not absolutely protect local peers; decide group ties based on time (Gregory Maxwell) +- #7439 `86755bc` Add whitelistforcerelay to control forced relaying. [#7099 redux] (Gregory Maxwell) +- #7482 `e16f5b4` Ensure headers count is correct (Suhas Daftuar) + +### Validation + +- #5927 `8d9f0a6` Reduce checkpoints' effect on consensus. (Pieter Wuille) +- #6299 `24f2489` Bugfix: Don't check the genesis block header before accepting it (Jorge Timón) +- #6361 `d7ada03` Use real number of cores for default -par, ignore virtual cores (Wladimir J. van der Laan) +- #6519 `87f37e2` Make logging for validation optional (Wladimir J. van der Laan) +- #6351 `2a1090d` CHECKLOCKTIMEVERIFY (BIP65) IsSuperMajority() soft-fork (Peter Todd) +- #6931 `54e8bfe` Skip BIP 30 verification where not necessary (Alex Morcos) +- #6954 `e54ebbf` Switch to libsecp256k1-based ECDSA validation (Pieter Wuille) +- #6508 `61457c2` Switch to a constant-space Merkle root/branch algorithm. (Pieter Wuille) +- #6914 `327291a` Add pre-allocated vector type and use it for CScript (Pieter Wuille) +- #7500 `889e5b3` Correctly report high-S violations (Pieter Wuille) + + +### Build system + +- #6210 `0e4f2a0` build: disable optional use of gmp in internal secp256k1 build (Wladimir J. van der Laan) +- #6214 `87406aa` [OSX] revert renaming of Bitcoin-Qt.app and use CFBundleDisplayName (partial revert of #6116) (Jonas Schnelli) +- #6218 `9d67b10` build/gitian misc updates (Cory Fields) +- #6269 `d4565b6` gitian: Use the new bitcoin-detached-sigs git repo for OSX signatures (Cory Fields) +- #6418 `d4a910c` Add autogen.sh to source tarball. (randy-waterhouse) +- #6373 `1ae3196` depends: non-qt bumps for 0.12 (Cory Fields) +- #6434 `059b352` Preserve user-passed CXXFLAGS with --enable-debug (Gavin Andresen) +- #6501 `fee6554` Misc build fixes (Cory Fields) +- #6600 `ef4945f` Include bitcoin-tx binary on Debian/Ubuntu (Zak Wilcox) +- #6619 `4862708` depends: bump miniupnpc and ccache (Michael Ford) +- #6801 `ae69a75` [depends] Latest config.guess and config.sub (Michael Ford) +- #6938 `193f7b5` build: If both Qt4 and Qt5 are installed, use Qt5 (Wladimir J. van der Laan) +- #7092 `348b281` build: Set osx permissions in the dmg to make Gatekeeper happy (Cory Fields) +- #6980 `eccd671` [Depends] Bump Boost, miniupnpc, ccache & zeromq (Michael Ford) +- #7424 `aa26ee0` Add security/export checks to gitian and fix current failures (Cory Fields) + +### Wallet + +- #6183 `87550ee` Fix off-by-one error w/ nLockTime in the wallet (Peter Todd) +- #6057 `ac5476e` re-enable wallet in autoprune (Jonas Schnelli) +- #6356 `9e6c33b` Delay initial pruning until after wallet init (Adam Weiss) +- #6088 `91389e5` fundrawtransaction (Matt Corallo) +- #6415 `ddd8d80` Implement watchonly support in fundrawtransaction (Matt Corallo) +- #6567 `0f0f323` Fix crash when mining with empty keypool. (Daniel Kraft) +- #6688 `4939eab` Fix locking in GetTransaction. (Alex Morcos) +- #6645 `4dbd43e` Enable wallet key imports without rescan in pruned mode. (Gregory Maxwell) +- #6550 `5b77244` Do not store Merkle branches in the wallet. (Pieter Wuille) +- #5924 `12a7712` Clean up change computation in CreateTransaction. (Daniel Kraft) +- #6906 `48b5b84` Reject invalid pubkeys when reading ckey items from the wallet. (Gregory Maxwell) +- #7010 `e0a5ef8` Fix fundrawtransaction handling of includeWatching (Peter Todd) +- #6851 `616d61b` Optimisation: Store transaction list order in memory rather than compute it every need (Luke-Jr) +- #6134 `e92377f` Improve usage of fee estimation code (Alex Morcos) +- #7103 `a775182` [wallet, rpc tests] Fix settxfee, paytxfee (MarcoFalke) +- #7105 `30c2d8c` Keep track of explicit wallet conflicts instead of using mempool (Pieter Wuille) +- #7096 `9490bd7` [Wallet] Improve minimum absolute fee GUI options (Jonas Schnelli) +- #6216 `83f06ca` Take the training wheels off anti-fee-sniping (Peter Todd) +- #4906 `96e8d12` Issue#1643: Coinselection prunes extraneous inputs from ApproximateBestSubset (Murch) +- #7200 `06c6a58` Checks for null data transaction before issuing error to debug.log (Andy Craze) +- #7296 `a36d79b` Add sane fallback for fee estimation (Alex Morcos) +- #7293 `ff9b610` Add regression test for vValue sort order (MarcoFalke) +- #7306 `4707797` Make sure conflicted wallet tx's update balances (Alex Morcos) +- #7381 `621bbd8` [walletdb] Fix syntax error in key parser (MarcoFalke) +- #7491 `00ec73e` wallet: Ignore MarkConflict if block hash is not known (Wladimir J. van der Laan) +- #7502 `1329963` Update the wallet best block marker before pruning (Pieter Wuille) + +### GUI + +- #6217 `c57e12a` disconnect peers from peers tab via context menu (Diapolo) +- #6209 `ab0ec67` extend rpc console peers tab (Diapolo) +- #6484 `1369d69` use CHashWriter also in SignVerifyMessageDialog (Pavel Vasin) +- #6487 `9848d42` Introduce PlatformStyle (Wladimir J. van der Laan) +- #6505 `100c9d3` cleanup icons (MarcoFalke) +- #4587 `0c465f5` allow users to set -onion via GUI (Diapolo) +- #6529 `c0f66ce` show client user agent in debug window (Diapolo) +- #6594 `878ea69` Disallow duplicate windows. (Casey Rodarmor) +- #5665 `6f55cdd` add verifySize() function to PaymentServer (Diapolo) +- #6317 `ca5e2a1` minor optimisations in peertablemodel (Diapolo) +- #6315 `e59d2a8` allow banning and unbanning over UI->peers table (Jonas Schnelli) +- #6653 `e04b2fa` Pop debug window in foreground when opened twice (MarcoFalke) +- #6864 `c702521` Use monospace font (MarcoFalke) +- #6887 `3694b74` Update coin control and smartfee labels (MarcoFalke) +- #7000 `814697c` add shortcurts for debug-/console-window (Jonas Schnelli) +- #6951 `03403d8` Use maxTxFee instead of 10000000 (MarcoFalke) +- #7051 `a190777` ui: Add "Copy raw transaction data" to transaction list context menu (Wladimir J. van der Laan) +- #6979 `776848a` simple mempool info in debug window (Jonas Schnelli) +- #7006 `26af1ac` add startup option to reset Qt settings (Jonas Schnelli) +- #6780 `2a94cd6` Call init's parameter interaction before we create the UI options model (Jonas Schnelli) +- #7112 `96b8025` reduce cs_main locks during tip update, more fluently update UI (Jonas Schnelli) +- #7206 `f43c2f9` Add "NODE_BLOOM" to guiutil so that peers don't get UNKNOWN[4] (Matt Corallo) +- #7282 `5cadf3e` fix coincontrol update issue when deleting a send coins entry (Jonas Schnelli) +- #7319 `1320300` Intro: Display required space (Jonas Schnelli) +- #7318 `9265e89` quickfix for RPC timer interface problem (Jonas Schnelli) +- #7327 `b16b5bc` [Wallet] Transaction View: LastMonth calculation fixed (crowning-) +- #7364 `7726c48` [qt] Windows: Make rpcconsole monospace font larger (MarcoFalke) +- #7384 `294f432` [qt] Peertable: Increase SUBVERSION_COLUMN_WIDTH (MarcoFalke) + +### Tests and QA + +- #6305 `9005c91` build: comparison tool swap (Cory Fields) +- #6318 `e307e13` build: comparison tool NPE fix (Cory Fields) +- #6337 `0564c5b` Testing infrastructure: mocktime fixes (Gavin Andresen) +- #6350 `60abba1` add unit tests for the decodescript rpc (mruddy) +- #5881 `3203a08` Fix and improve txn_doublespend.py test (Tom Harding) +- #6390 `6a73d66` tests: Fix bitcoin-tx signing test case (Wladimir J. van der Laan) +- #6368 `7fc25c2` CLTV: Add more tests to improve coverage (Esteban Ordano) +- #6414 `5121c68` Fix intermittent test failure, reduce test time (Tom Harding) +- #6417 `44fa82d` [QA] fix possible reorg issue in (fund)rawtransaction(s).py RPC test (Jonas Schnelli) +- #6398 `3d9362d` rpc: Remove chain-specific RequireRPCPassword (Wladimir J. van der Laan) +- #6428 `bb59e78` tests: Remove old sh-based test framework (Wladimir J. van der Laan) +- #5515 `d946e9a` RFC: Assert on probable deadlocks if the second lock isnt try_lock (Matt Corallo) +- #6287 `d2464df` Clang lock debug (Cory Fields) +- #6465 `410fd74` Don't share objects between TestInstances (Casey Rodarmor) +- #6534 `6c1c7fd` Fix test locking issues and un-revert the probable-deadlines assertions commit (Cory Fields) +- #6509 `bb4faee` Fix race condition on test node shutdown (Casey Rodarmor) +- #6523 `561f8af` Add p2p-fullblocktest.py (Casey Rodarmor) +- #6590 `981fd92` Fix stale socket rebinding and re-enable python tests for Windows (Cory Fields) +- #6730 `cb4d6d0` build: Remove dependency of bitcoin-cli on secp256k1 (Wladimir J. van der Laan) +- #6616 `5ab5dca` Regression Tests: Migrated rpc-tests.sh to all Python rpc-tests.py (Peter Tschipper) +- #6720 `d479311` Creates unittests for addrman, makes addrman more testable. (Ethan Heilman) +- #6853 `c834f56` Added fPowNoRetargeting field to Consensus::Params (Eric Lombrozo) +- #6827 `87e5539` [rpc-tests] Check return code (MarcoFalke) +- #6848 `f2c869a` Add DERSIG transaction test cases (Ross Nicoll) +- #6813 `5242bb3` Support gathering code coverage data for RPC tests with lcov (dexX7) +- #6888 `c8322ff` Clear strMiscWarning before running PartitionAlert (Eric Lombrozo) +- #6894 `2675276` [Tests] Fix BIP65 p2p test (Suhas Daftuar) +- #6863 `725539e` [Test Suite] Fix test for null tx input (Daniel Kraft) +- #6926 `a6d0d62` tests: Initialize networking on windows (Wladimir J. van der Laan) +- #6822 `9fa54a1` [tests] Be more strict checking dust (MarcoFalke) +- #6804 `5fcc14e` [tests] Add basic coverage reporting for RPC tests (James O'Beirne) +- #7045 `72dccfc` Bugfix: Use unique autostart filenames on Linux for testnet/regtest (Luke-Jr) +- #7095 `d8368a0` Replace scriptnum_test's normative ScriptNum implementation (Wladimir J. van der Laan) +- #7063 `6abf6eb` [Tests] Add prioritisetransaction RPC test (Suhas Daftuar) +- #7137 `16f4a6e` Tests: Explicitly set chain limits in replace-by-fee test (Suhas Daftuar) +- #7216 `9572e49` Removed offline testnet DNSSeed 'alexykot.me'. (tnull) +- #7209 `f3ad812` test: don't override BITCOIND and BITCOINCLI if they're set (Wladimir J. van der Laan) +- #7226 `301f16a` Tests: Add more tests to p2p-fullblocktest (Suhas Daftuar) +- #7153 `9ef7c54` [Tests] Add mempool_limit.py test (Jonas Schnelli) +- #7170 `453c567` tests: Disable Tor interaction (Wladimir J. van der Laan) +- #7229 `1ed938b` [qa] wallet: Check if maintenance changes the balance (MarcoFalke) +- #7308 `d513405` [Tests] Eliminate intermittent failures in sendheaders.py (Suhas Daftuar) +- #7468 `947c4ff` [rpc-tests] Change solve() to use rehash (Brad Andrews) + +### Miscellaneous + +- #6213 `e54ff2f` [init] add -blockversion help and extend -upnp help (Diapolo) +- #5975 `1fea667` Consensus: Decouple ContextualCheckBlockHeader from checkpoints (Jorge Timón) +- #6061 `eba2f06` Separate Consensus::CheckTxInputs and GetSpendHeight in CheckInputs (Jorge Timón) +- #5994 `786ed11` detach wallet from miner (Jonas Schnelli) +- #6387 `11576a5` [bitcoin-cli] improve error output (Jonas Schnelli) +- #6401 `6db53b4` Add BITCOIND_SIGTERM_TIMEOUT to OpenRC init scripts (Florian Schmaus) +- #6430 `b01981e` doc: add documentation for shared library libbitcoinconsensus (Braydon Fuller) +- #6372 `dcc495e` Update Linearize tool to support Windows paths; fix variable scope; update README and example configuration (Paul Georgiou) +- #6453 `8fe5cce` Separate core memory usage computation in core_memusage.h (Pieter Wuille) +- #6149 `633fe10` Buffer log messages and explicitly open logs (Adam Weiss) +- #6488 `7cbed7f` Avoid leaking file descriptors in RegisterLoad (Casey Rodarmor) +- #6497 `a2bf40d` Make sure LogPrintf strings are line-terminated (Wladimir J. van der Laan) +- #6504 `b6fee6b` Rationalize currency unit to "BTC" (Ross Nicoll) +- #6507 `9bb4dd8` Removed contrib/bitrpc (Casey Rodarmor) +- #6527 `41d650f` Use unique name for AlertNotify tempfile (Casey Rodarmor) +- #6561 `e08a7d9` limitedmap fixes and tests (Casey Rodarmor) +- #6565 `a6f2aff` Make sure we re-acquire lock if a task throws (Casey Rodarmor) +- #6599 `f4d88c4` Make sure LogPrint strings are line-terminated (Ross Nicoll) +- #6630 `195942d` Replace boost::reverse_lock with our own (Casey Rodarmor) +- #6103 `13b8282` Add ZeroMQ notifications (João Barbosa) +- #6692 `d5d1d2e` devtools: don't push if signing fails in github-merge (Wladimir J. van der Laan) +- #6728 `2b0567b` timedata: Prevent warning overkill (Wladimir J. van der Laan) +- #6713 `f6ce59c` SanitizeString: Allow hypen char (MarcoFalke) +- #5987 `4899a04` Bugfix: Fix testnet-in-a-box use case (Luke-Jr) +- #6733 `b7d78fd` Simple benchmarking framework (Gavin Andresen) +- #6854 `a092970` devtools: Add security-check.py (Wladimir J. van der Laan) +- #6790 `fa1d252` devtools: add clang-format.py (MarcoFalke) +- #7114 `f3d0fdd` util: Don't set strMiscWarning on every exception (Wladimir J. van der Laan) +- #7078 `93e0514` uint256::GetCheapHash bigendian compatibility (arowser) +- #7094 `34e02e0` Assert now > 0 in GetTime GetTimeMillis GetTimeMicros (Patrick Strateman) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- accraze +- Adam Weiss +- Alex Morcos +- Alex van der Peet +- AlSzacrel +- Altoidnerd +- Andriy Voskoboinyk +- antonio-fr +- Arne Brutschy +- Ashley Holman +- Bob McElrath +- Braydon Fuller +- BtcDrak +- Casey Rodarmor +- centaur1 +- Chris Kleeschulte +- Christian Decker +- Cory Fields +- daniel +- Daniel Cousens +- Daniel Kraft +- David Hill +- dexX7 +- Diego Viola +- Elias Rohrer +- Eric Lombrozo +- Erik Mossberg +- Esteban Ordano +- EthanHeilman +- Florian Schmaus +- Forrest Voight +- Gavin Andresen +- Gregory Maxwell +- Gregory Sanders / instagibbs +- Ian T +- Irving Ruan +- Jacob Welsh +- James O'Beirne +- Jeff Garzik +- Johnathan Corgan +- Jonas Schnelli +- Jonathan Cross +- João Barbosa +- Jorge Timón +- Josh Lehan +- J Ross Nicoll +- kazcw +- Kevin Cooper +- lpescher +- Luke Dashjr +- Marco +- MarcoFalke +- Mark Friedenbach +- Matt +- Matt Bogosian +- Matt Corallo +- Matt Quinn +- Micha +- Michael +- Michael Ford / fanquake +- Midnight Magic +- Mitchell Cash +- mrbandrews +- mruddy +- Nick +- Patrick Strateman +- Paul Georgiou +- Paul Rabahy +- Pavel Janík / paveljanik +- Pavel Vasin +- Pavol Rusnak +- Peter Josling +- Peter Todd +- Philip Kaufmann +- Pieter Wuille +- ptschip +- randy-waterhouse +- rion +- Ross Nicoll +- Ryan Havar +- Shaul Kfir +- Simon Males +- Stephen +- Suhas Daftuar +- tailsjoin +- Thomas Kerin +- Tom Harding +- tulip +- unsystemizer +- Veres Lajos +- Wladimir J. van der Laan +- xor-freenet +- Zak Wilcox +- zathras-crypto + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). + From 7eef1d0dad0c48e9faefdc4fe5cfb6182edc79ab Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Tue, 16 Feb 2016 11:42:14 -0800 Subject: [PATCH 0256/1223] Clarify description of blockindex see issues: https://github.com/bitcoin-dot-org/bitcoin.org/issues/1237 https://github.com/bitcoin/bitcoin/issues/7532 --- src/wallet/rpcwallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 34ad5a46f..f54ceb689 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1444,7 +1444,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" - " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n" + " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n" " category of transactions.\n" " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" @@ -1637,7 +1637,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" - " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" + " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n" " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n" @@ -1721,7 +1721,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" - " \"blockindex\" : xx, (numeric) The block index\n" + " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n" " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" " \"txid\" : \"transactionid\", (string) The transaction id.\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" From a08c41dfc23234064da322159652b44684df9375 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 23 Feb 2016 13:30:22 +0100 Subject: [PATCH 0257/1223] doc: include post-mortem fixes to 0.12.0 release notes Parallels https://github.com/bitcoin-dot-org/bitcoin.org/commit/5d490f9d969c58dda90f35c90a393d771337fca9 --- doc/release-notes/release-notes-0.12.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index 332d4cebe..b586d754f 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -61,7 +61,7 @@ Signature validation using libsecp256k1 --------------------------------------- ECDSA signatures inside Bitcoin transactions now use validation using -[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. +[libsecp256k1](https://github.com/bitcoin/secp256k1) instead of OpenSSL. Depending on the platform, this means a significant speedup for raw signature validation speed. The advantage is largest on x86_64, where validation is over @@ -521,7 +521,7 @@ git merge commit are mentioned. ### Configuration and command-line options - #6164 `8d05ec7` Allow user to use -debug=1 to enable all debugging (lpescher) -- #5288 `4452205` Added -whiteconnections= option (Josh Lehan) +- #5288 `4452205` Added `-whiteconnections=` option (Josh Lehan) - #6284 `10ac38e` Fix argument parsing oddity with -noX (Wladimir J. van der Laan) - #6489 `c9c017a` Give a better error message if system clock is bad (Casey Rodarmor) - #6462 `c384800` implement uacomment config parameter which can add comments to user agent as per BIP-0014 (Pavol Rusnak) From 6e4dfa1480e5cdbe07abe90b88f3aab76dbacff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20F=C3=A9lizard?= Date: Tue, 23 Feb 2016 18:49:24 +0000 Subject: [PATCH 0258/1223] [doc] Fix typos --- doc/build-unix.md | 2 +- doc/shared-libraries.md | 2 +- doc/travis-ci.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 96de098c3..1d8395162 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -7,7 +7,7 @@ Some notes on how to build Bitcoin Core in Unix. Note --------------------- Always use absolute paths to configure and compile bitcoin and the dependencies, -for example, when specifying the the path of the dependency: +for example, when specifying the path of the dependency: ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX diff --git a/doc/shared-libraries.md b/doc/shared-libraries.md index f4ff53d6e..ec6f16c8a 100644 --- a/doc/shared-libraries.md +++ b/doc/shared-libraries.md @@ -11,7 +11,7 @@ The interface is defined in the C header `bitcoinconsensus.h` located in `src/s #### Version -`bitcoinconsensus_version` returns an `unsigned int` with the the API version *(currently at an experimental `0`)*. +`bitcoinconsensus_version` returns an `unsigned int` with the API version *(currently at an experimental `0`)*. #### Script Validation diff --git a/doc/travis-ci.txt b/doc/travis-ci.txt index 01f7d02a8..06410405d 100644 --- a/doc/travis-ci.txt +++ b/doc/travis-ci.txt @@ -27,7 +27,7 @@ In order to avoid rebuilding all dependencies for each build, the binaries are cached and re-used when possible. Changes in the dependency-generator will trigger cache-invalidation and rebuilds as necessary. -These caches can be manually removed if necessary. This is one of the the very few +These caches can be manually removed if necessary. This is one of the very few manual operations that is possible with Travis, and it can be done by the Bitcoin Core committer via the Travis web interface. From 92bcca37ab0c52789b13ebee1f4659e30f05e2b6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 17 Feb 2016 15:03:38 +0100 Subject: [PATCH 0259/1223] rpc: Input-from-stdin mode for bitcoin-cli Implements #7442 by adding an option `-stdin` which reads additional arguments from stdin, one per line. For example ```bash echo -e "mysecretcode\n120" | src/bitcoin-cli -stdin walletpassphrase echo -e "walletpassphrase\nmysecretcode\n120" | src/bitcoin-cli -stdin ``` --- src/bitcoin-cli.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 34980d9ca..49935699f 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -43,6 +43,7 @@ std::string HelpMessageCli() strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcclienttimeout=", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT)); + strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)")); return strUsage; } @@ -232,15 +233,17 @@ int CommandLineRPC(int argc, char *argv[]) argc--; argv++; } - - // Method - if (argc < 2) - throw runtime_error("too few parameters"); - string strMethod = argv[1]; - - // Parameters default to strings - std::vector strParams(&argv[2], &argv[argc]); - UniValue params = RPCConvertValues(strMethod, strParams); + std::vector args = std::vector(&argv[1], &argv[argc]); + if (GetBoolArg("-stdin", false)) { + // Read one arg per line from stdin and append + std::string line; + while (std::getline(std::cin,line)) + args.push_back(line); + } + if (args.size() < 1) + throw runtime_error("too few parameters (need at least command)"); + std::string strMethod = args[0]; + UniValue params = RPCConvertValues(strMethod, std::vector(args.begin()+1, args.end())); // Execute and handle connection failures with -rpcwait const bool fWait = GetBoolArg("-rpcwait", false); From f22f14c65bb9fba946e5039132a4c0b01b0c02ce Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 24 Feb 2016 10:22:43 +0100 Subject: [PATCH 0260/1223] doc: mention bitcoin-cli -stdin in release notes --- doc/release-notes.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 801b684e6..707f2357f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -8,6 +8,19 @@ Example item ---------------- +bitcoin-cli: arguments privacy +-------------------------------- + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ echo -e "mysecretcode\n120" | src/bitcoin-cli -stdin walletpassphrase + +It is recommended to use this for sensitive information such as wallet +passphrases, as command-line arguments can usually be read from the process +table by any user on the system. + 0.13.0 Change log ================= From 8c5a5fb85068135c33a8e0513280917e13bb039e Mon Sep 17 00:00:00 2001 From: Jonathan Cross Date: Wed, 24 Feb 2016 15:36:45 +0100 Subject: [PATCH 0261/1223] Improving wording related to Boost library requirements [updated] Fixed formatting as requested on https://github.com/bitcoin/bitcoin/pull/7589 Description: Documentation was unclear in this section and could be interpreted to mean that boost was not a hard requirement for older Ubuntu versions. Related: #7587 --- doc/build-unix.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 1d8395162..5d8644efe 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -67,15 +67,17 @@ Build requirements: sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils -On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the +Options when installing required Boost library files: + +1. On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the individual boost development packages, so the following can be used to only install necessary parts of boost: - sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev + sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev -If that doesn't work, you can install all boost development packages with: +2. If that doesn't work, you can install all boost development packages with: - sudo apt-get install libboost-all-dev + sudo apt-get install libboost-all-dev BerkeleyDB is required for the wallet. db4.8 packages are available [here](https://launchpad.net/~bitcoin/+archive/bitcoin). You can add the repository and install using the following commands: From 8fc81e098362130218f256cd6b60e81227d39db9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 24 Feb 2016 18:34:37 +0100 Subject: [PATCH 0262/1223] mempool: Reduce ERROR logging for mempool rejects Continues "Make logging for validation optional" from #6519. The idea there was to remove all ERROR logging of rejected transaction, and move it to one message in the class 'mempoolrej' which logs the state message (and debug info). The superfluous ERRORs in the log "terrify" users, see for example issue #5794. Unfortunately a lot of new logging was introduced in #6871 (RBF) and #7287 (misc refactoring). This pull updates that new code. --- src/main.cpp | 57 +++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index babdff54e..f3dc3f291 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -947,7 +947,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); + return false; // state filled in by CheckTransaction // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -1160,10 +1160,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); if (setConflicts.count(hashAncestor)) { - return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s", + return state.DoS(10, false, + REJECT_INVALID, "bad-txns-spends-conflicting-tx", false, + strprintf("%s spends conflicting transaction %s", hash.ToString(), - hashAncestor.ToString()), - REJECT_INVALID, "bad-txns-spends-conflicting-tx"); + hashAncestor.ToString())); } } @@ -1200,11 +1201,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // that we don't spend too much time walking descendants. // This should be rare. if (mi->IsDirty()) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants", + return state.DoS(0, false, + REJECT_NONSTANDARD, "too many potential replacements", false, + strprintf("too many potential replacements: rejecting replacement %s; cannot replace tx %s with untracked descendants", hash.ToString(), - mi->GetTx().GetHash().ToString()), - REJECT_NONSTANDARD, "too many potential replacements"); + mi->GetTx().GetHash().ToString())); } // Don't allow the replacement to reduce the feerate of the @@ -1226,12 +1227,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); if (newFeeRate <= oldFeeRate) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s", + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s; new feerate %s <= old feerate %s", hash.ToString(), newFeeRate.ToString(), - oldFeeRate.ToString()), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + oldFeeRate.ToString())); } BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin) @@ -1255,12 +1256,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C nConflictingSize += it->GetTxSize(); } } else { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n", + return state.DoS(0, false, + REJECT_NONSTANDARD, "too many potential replacements", false, + strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n", hash.ToString(), nConflictingCount, - maxDescendantsToVisit), - REJECT_NONSTANDARD, "too many potential replacements"); + maxDescendantsToVisit)); } for (unsigned int j = 0; j < tx.vin.size(); j++) @@ -1275,9 +1276,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // it's cheaper to just check if the new input refers to a // tx that's in the mempool. if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) - return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d", - hash.ToString(), j), - REJECT_NONSTANDARD, "replacement-adds-unconfirmed"); + return state.DoS(0, false, + REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false, + strprintf("replacement %s adds unconfirmed input, idx %d", + hash.ToString(), j)); } } @@ -1286,9 +1288,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // transactions would not be paid for. if (nModifiedFees < nConflictingFees) { - return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", - hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s", + hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees))); } // Finally in addition to paying more fees than the conflicts the @@ -1296,19 +1299,19 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CAmount nDeltaFees = nModifiedFees - nConflictingFees; if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s", + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s", hash.ToString(), FormatMoney(nDeltaFees), - FormatMoney(::minRelayTxFee.GetFee(nSize))), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + FormatMoney(::minRelayTxFee.GetFee(nSize)))); } } // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) - return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); + return false; // state filled in by CheckInputs // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause From 3d19193f14b9400f7c908a61375c330113571a38 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Thu, 25 Feb 2016 19:15:17 -0800 Subject: [PATCH 0263/1223] Remove spurious dollar sign. Fixes #7189. --- build-aux/m4/bitcoin_qt.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 2480267dc..338016c83 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -384,7 +384,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other. if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then - if test x$auto_priority_version = x$qt5; then + if test x$auto_priority_version = xqt5; then PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no]) else PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no]) From 5ecfa36fd01fc27475abbfcd53b4efb9da4a7398 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 26 Feb 2016 09:35:39 +0100 Subject: [PATCH 0264/1223] Remove openssl info from init/log and from Qt debug window --- src/init.cpp | 8 ---- src/qt/forms/debugwindow.ui | 96 ++++++++++++++----------------------- src/qt/rpcconsole.cpp | 7 --- 3 files changed, 35 insertions(+), 76 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 048843a4c..607e9fbc5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1091,14 +1091,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fPrintToDebugLog) OpenDebugLog(); -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); -#elif defined OPENSSL_VERSION - LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); -#elif defined LIBRESSL_VERSION_TEXT - LogPrintf("Using %s\n", LIBRESSL_VERSION_TEXT); -#endif - #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); #endif diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index febbaeda1..a5ac0a7d2 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -7,7 +7,7 @@ 0 0 740 - 450 + 430
@@ -113,32 +113,6 @@ - - - Using OpenSSL version - - - 10 - - - - - - - IBeamCursor - - - N/A - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - Using BerkeleyDB version @@ -148,7 +122,7 @@ - + IBeamCursor @@ -164,14 +138,14 @@ - + Build date - + IBeamCursor @@ -187,14 +161,14 @@ - + Startup time - + IBeamCursor @@ -210,14 +184,27 @@ - + + + + + 75 + true + + + + Network + + + + Name - + IBeamCursor @@ -233,14 +220,14 @@ - + Number of connections - + IBeamCursor @@ -256,7 +243,7 @@ - + @@ -269,14 +256,14 @@ - + Current number of blocks - + IBeamCursor @@ -292,14 +279,14 @@ - + Last block time - + IBeamCursor @@ -315,7 +302,7 @@ - + @@ -328,14 +315,14 @@ - + Current number of transactions - + IBeamCursor @@ -351,27 +338,14 @@ - - - - - 75 - true - - - - Network - - - - + Memory usage - + IBeamCursor @@ -387,7 +361,7 @@ - + 3 @@ -427,7 +401,7 @@ - + Qt::Vertical diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index c18c40525..4e2530ffa 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -275,13 +275,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); // set library version labels - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); -#else - ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); -#endif - #ifdef ENABLE_WALLET ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); #else From fa7a5c54fc836ada12c185c43806c5e4a1044701 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 26 Feb 2016 09:59:39 +0100 Subject: [PATCH 0265/1223] [depends] builders: No need to set -L and --location for curl --- depends/builders/darwin.mk | 2 +- depends/builders/linux.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index cedbddc57..200d6ed22 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o #darwin host on darwin builder. overrides darwin host preferences. darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index d6a304e4b..b03f42401 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o From 146746bbafe5dfea7b2019231c2d37fe57a4c3bb Mon Sep 17 00:00:00 2001 From: Alice Wonder Date: Fri, 26 Feb 2016 09:30:11 -0800 Subject: [PATCH 0266/1223] All files related to my RPM spec file project in one commit --- contrib/rpm/README.md | 185 +++++++++ contrib/rpm/bitcoin-0.12.0-libressl.patch | 24 ++ contrib/rpm/bitcoin.fc | 8 + contrib/rpm/bitcoin.if | 157 ++++++++ contrib/rpm/bitcoin.spec | 444 ++++++++++++++++++++++ contrib/rpm/bitcoin.te | 81 ++++ 6 files changed, 899 insertions(+) create mode 100644 contrib/rpm/README.md create mode 100644 contrib/rpm/bitcoin-0.12.0-libressl.patch create mode 100644 contrib/rpm/bitcoin.fc create mode 100644 contrib/rpm/bitcoin.if create mode 100644 contrib/rpm/bitcoin.spec create mode 100644 contrib/rpm/bitcoin.te diff --git a/contrib/rpm/README.md b/contrib/rpm/README.md new file mode 100644 index 000000000..aecb3ba84 --- /dev/null +++ b/contrib/rpm/README.md @@ -0,0 +1,185 @@ +RPM Spec File Notes +------------------- + +The RPM spec file provided here is for Bitcoin-Core 0.12.0 and builds on CentOS +7 with either the CentOS provided OpenSSL library or with LibreSSL as packaged +at [LibreLAMP.com](https://librelamp.com/). It should hopefully not be too +difficult to port the RPM spec file to most RPM based Linux distributions. + +When porting the spec file to build for a particular distribution, there are +some important notes. + +## Sources + +It is considered good form for all sources to reference a URL where the source +can be downloaded. + +Sources 0-9 should be reserved for source code tarballs. `Source0` should +reference the release tarball available from https://bitcoin.org/bin/ and +`Source1` should reference the BerkeleyDB source. + +Sources 10-99 are for source files that are maintained in the +[Bitcoin git repository](https://github.com/bitcoin/bitcoin) but are not part of +the release tarball. Most of these will reside in the `contrib` sub-directory. + +Sources 10-19 should be reserved for miscellaneous configuration files. +Currently only `Source10` is used, for the example `bitcoin.conf` file. + +Sources 20-29 should be reserved for man pages. Currently only `Source20` +through `Source23` are used. + +Sources 30-39 should be reserved for SELinux related files. Currently only +`Source30` through `Source32` are used. Until those files are in a tagged +release, the full URL specified in the RPM spec file will not work. You can get +them from the git ropository where you retrieved this file. + +Sources 100+ are for files that are not source tarballs and are not maintained +in the bitcoin git repository. At present only an SVG version of the Bitcoin +icon is used. + +## Patches + +In general, patches should be avoided. When a packager feels a patch is +necessary, the packager should bring the problem to the attention of the bitcoin +developers so that an official fix to the issue can make it into the next +release. + +### Patch0 bitcoin-0.12.0-libressl.patch + +This patch is only needed if building against LibreSSL. LibreSSL is not the +standard TLS library on most Linux distributions. The patch will likely not be +needed when 0.12.1 is released, a proper fix is already in the Bitcoin git +master branch. + +## BuildRequires + +The packages specified in the `BuildRequires` are specified according to the +package naming convention currently used in CentOS 7 and EPEL for CentOS 7. You +may need to change some of the package names for other distributions. This is +most likely to be the case with the Qt packages. + +## BerkeleyDB + +The `build-unix.md` file recommends building against BerkeleyDB 4.8.30. Even if +that is the version your Linux distribution ships with, it probably is a good +idea to build Bitcoin Core against a static version of that library compiled +according to the instructions in the `build-unix.md` file so that any changes +the distribution may make in the future will not result in a problem for users. + +The problem that can exist, clients built against different versions of +BerkeleyDB may not be able read each other's `wallet.dat` file which can make it +difficult for a user to recover from backup in the event of a system failure. + +## Graphical User Interface and Qt Version + +The RPM spec file will by default build the GUI client linked against the Qt5 +libraries. If you wish instead to link against the Qt4 libraries you need to +pass the switch `-D '_use_qt4 1'` at build time to the `rpmbuild` or `mock` +command used to build the packages. + +If you would prefer not to build the GUI at all, you can pass the switch +`-D '_no_gui 1'` to the `rpmbuild` or `mock` build command. + +## Desktop and KDE Files + +The desktop and KDE meta files are created in the spec file itself with the +`cat` command. This is done to allow easy distribution specific changes without +needing to use any patches. A specific time stamp is given to the files so that +it does not they do not appear to have been updated every time the package is +built. If you do make changes to them, you probably should update time stamp +assigned to them in the `touch` command that specifies the time stamp. + +## SVG, PNG, and XPM Icons + +The `bitcoin.svg` file is from the source listed as `Source100`. It is used as +the source for the PNG and XPM files. The generated PNG and XPM files are given +the same time stamp as the source SVG file as a means of indicating they are +derived from it. + +## Systemd + +This spec file assumes the target distribution uses systemd. That really only +matters for the `bitcoin-server` package. At this point, most RPM based +distributions that still receive vendor updates do in fact use systemd. + +The files to control the service are created in the RPM spec file itself using +the `cat` command. This is done to make it easy to modify for other +distributions that may implement things differently without needing to patch +source. A specific time stamp is given to the files so that they do not appear +to have been updated every time the package is built. If you do make changes to +them, you probably should update the time stamp assigned to them in the `touch` +command that specifies the time stamp. + +## SELinux + +The `bitcoin-server` package should have SELinux support. How to properly do +that *may* vary by distribution and version of distribution. + +The SELinux stuff in this RPM spec file *should* be correct for CentOS, RHEL, +and Fedora but it would be a good idea to review it before building the package +on other distributions. + +## Tests + +The `%check` section takes a very long time to run. If your build system has a +time limit for package build, you may need to make an exception for this +package. On CentOS 7 the `%check` section completes successfully with both +OpenSSL and LibreSSL, a failure really does mean something is wrong. + +## LibreSSL Build Notes + +To build against LibreSSL you will need to pass the switch +`-D '_use_libressl 1'` to the `rpmbuild` or `mock` command or the spec file will +want the OpenSSL development files. + +### LibreSSL and Boost + +LibreSSL (and some newer builds of OpenSSL) do not have support for SSLv3. This +can cause issues with the Boost package if the Boost package has not been +patched accordingly. On those distributions, you will either need to build +Bitcoin-Core against OpenSSL or use a patched version of Boost in the build +system. + +As SSLv3 is no longer safe, distributions that have not patched Boost to work +with TLS libraries that do not support SSLv3 should have bug reports filed +against the Boost package. This bug report has already been filed for RHEL 7 but +it may need to be filed for other distributions. + +A patch for Boost: https://github.com/boostorg/asio/pull/23/files + +## ZeroMQ + +At this time, this RPM spec file does not support the ZeroMQ build options. A +suitable version of ZeroMQ is not available for the platform this spec file was +developed on (CentOS 7). + +## Legacy Credit + +This RPM spec file is largely based upon the work of Michael Hampton at +[Ringing Liberty](https://www.ringingliberty.com/bitcoin/). He has been +packaging Bitcoin for Fedora at least since 2012. + +Most of the differences between his packaging and this package are stylistic in +nature. The major differences: + +1. He builds from a github tagged release rather than a release tarball. This +should not result in different source code. + +2. He does not build BerkeleyDB but instead uses the BerkeleyDB provided by the +Linux distribution. For the distributions he packages for, they currently all +use the same version of BerkeleyDB so that difference is *probably* just +academic. + +3. As of his 10.11.2 package he did not allow for building against LibreSSL, +specifying a build without the Qt GUI, or specifying which version of the Qt +libraries to use. + +4. I renamed the `bitcoin` package that contains the Qt GUI to `bitcoin-core` as +that appears to be how the general population refers to it, in contrast to +`bitcoin-xt` or `bitcoin-classic`. I wanted to make sure the general population +knows what they are getting when installing the GUI package. + +As far as minor differences, I generally prefer to assign the file permissions +in the `%files` portion of an RPM spec file rather than specifying the +permissions of a file during `%install` and other minor things like that that +are largely just cosmetic. diff --git a/contrib/rpm/bitcoin-0.12.0-libressl.patch b/contrib/rpm/bitcoin-0.12.0-libressl.patch new file mode 100644 index 000000000..555614a06 --- /dev/null +++ b/contrib/rpm/bitcoin-0.12.0-libressl.patch @@ -0,0 +1,24 @@ +diff -ur bitcoin-0.12.0.orig/src/init.cpp bitcoin-0.12.0/src/init.cpp +--- bitcoin-0.12.0.orig/src/init.cpp 2015-12-31 16:00:00.000000000 -0800 ++++ bitcoin-0.12.0/src/init.cpp 2016-02-23 06:03:47.133227757 -0800 +@@ -1075,7 +1075,7 @@ + if (fPrintToDebugLog) + OpenDebugLog(); + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) ++#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) + LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); + #else + LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); +diff -ur bitcoin-0.12.0.orig/src/qt/rpcconsole.cpp bitcoin-0.12.0/src/qt/rpcconsole.cpp +--- bitcoin-0.12.0.orig/src/qt/rpcconsole.cpp 2015-12-31 16:00:00.000000000 -0800 ++++ bitcoin-0.12.0/src/qt/rpcconsole.cpp 2016-02-23 15:09:42.881126841 -0800 +@@ -264,7 +264,7 @@ + + // set library version labels + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) ++#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) + ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); + #else + ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); diff --git a/contrib/rpm/bitcoin.fc b/contrib/rpm/bitcoin.fc new file mode 100644 index 000000000..6f5eef637 --- /dev/null +++ b/contrib/rpm/bitcoin.fc @@ -0,0 +1,8 @@ +/usr/bin/bitcoin-cli -- gen_context(system_u:object_r:bitcoin_exec_t,s0) +/usr/sbin/bitcoind -- gen_context(system_u:object_r:bitcoin_exec_t,s0) +/usr/lib(64)?/bitcoin/bitcoind -- gen_context(system_u:object_r:bitcoin_exec_t,s0) + +/etc/bitcoin(/.*)? gen_context(system_u:object_r:bitcoin_conf_t,s0) +/var/lib/bitcoin(/.*)? gen_context(system_u:object_r:bitcoin_var_lib_t,s0) + +(/var)?/run/bitcoind(/.*)? gen_context(system_u:object_r:bitcoin_var_run_t,s0) diff --git a/contrib/rpm/bitcoin.if b/contrib/rpm/bitcoin.if new file mode 100644 index 000000000..2b096c24d --- /dev/null +++ b/contrib/rpm/bitcoin.if @@ -0,0 +1,157 @@ + +## policy for bitcoin + + +######################################## +## +## Transition to bitcoin. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`bitcoin_domtrans',` + gen_require(` + type bitcoin_t, bitcoin_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, bitcoin_exec_t, bitcoin_t) +') + + +######################################## +## +## Execute bitcoin server in the bitcoin domain. +## +## +## +## Domain allowed access. +## +## +# +interface(`bitcoin_initrc_domtrans',` + gen_require(` + type bitcoin_initrc_exec_t; + ') + + init_labeled_script_domtrans($1, bitcoin_initrc_exec_t) +') + + +######################################## +## +## Search bitcoin lib directories. +## +## +## +## Domain allowed access. +## +## +# +interface(`bitcoin_search_lib',` + gen_require(` + type bitcoin_var_lib_t; + ') + + allow $1 bitcoin_var_lib_t:dir search_dir_perms; + files_search_var_lib($1) +') + +######################################## +## +## Read bitcoin lib files. +## +## +## +## Domain allowed access. +## +## +# +interface(`bitcoin_read_lib_files',` + gen_require(` + type bitcoin_var_lib_t; + ') + + files_search_var_lib($1) + read_files_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) +') + +######################################## +## +## Manage bitcoin lib files. +## +## +## +## Domain allowed access. +## +## +# +interface(`bitcoin_manage_lib_files',` + gen_require(` + type bitcoin_var_lib_t; + ') + + files_search_var_lib($1) + manage_files_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) +') + +######################################## +## +## Manage bitcoin lib directories. +## +## +## +## Domain allowed access. +## +## +# +interface(`bitcoin_manage_lib_dirs',` + gen_require(` + type bitcoin_var_lib_t; + ') + + files_search_var_lib($1) + manage_dirs_pattern($1, bitcoin_var_lib_t, bitcoin_var_lib_t) +') + + +######################################## +## +## All of the rules required to administrate +## an bitcoin environment +## +## +## +## Domain allowed access. +## +## +## +## +## Role allowed access. +## +## +## +# +interface(`bitcoin_admin',` + gen_require(` + type bitcoin_t; + type bitcoin_initrc_exec_t; + type bitcoin_var_lib_t; + ') + + allow $1 bitcoin_t:process { ptrace signal_perms }; + ps_process_pattern($1, bitcoin_t) + + bitcoin_initrc_domtrans($1) + domain_system_change_exemption($1) + role_transition $2 bitcoin_initrc_exec_t system_r; + allow $2 system_r; + + files_search_var_lib($1) + admin_pattern($1, bitcoin_var_lib_t) + +') + diff --git a/contrib/rpm/bitcoin.spec b/contrib/rpm/bitcoin.spec new file mode 100644 index 000000000..38ae03818 --- /dev/null +++ b/contrib/rpm/bitcoin.spec @@ -0,0 +1,444 @@ +%define bdbv 4.8.30 +%global selinux_variants mls strict targeted + +%if 0%{?_no_gui:1} +%define _buildqt 0 +%define buildargs --with-gui=no +%else +%define _buildqt 1 +%if 0%{?_use_qt4} +%define buildargs --with-qrencode --with-gui=qt4 +%else +%define buildargs --with-qrencode --with-gui=qt5 +%endif +%endif + +Name: bitcoin +Version: 0.12.0 +Release: 2%{?dist} +Summary: Peer to Peer Cryptographic Currency + +Group: Applications/System +License: MIT +URL: https://bitcoin.org/ +Source0: https://bitcoin.org/bin/bitcoin-core-%{version}/bitcoin-%{version}.tar.gz +Source1: http://download.oracle.com/berkeley-db/db-%{bdbv}.NC.tar.gz + +Source10: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/examples/bitcoin.conf + +#man pages +Source20: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoind.1 +Source21: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin-cli.1 +Source22: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin-qt.1 +Source23: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/debian/manpages/bitcoin.conf.5 + +#selinux +Source30: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.te +# Source31 - what about bitcoin-tx and bench_bitcoin ??? +Source31: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.fc +Source32: https://raw.githubusercontent.com/bitcoin/bitcoin/v%{version}/contrib/rpm/bitcoin.if + +Source100: https://upload.wikimedia.org/wikipedia/commons/4/46/Bitcoin.svg + +%if 0%{?_use_libressl:1} +BuildRequires: libressl-devel +%else +BuildRequires: openssl-devel +%endif +BuildRequires: boost-devel +BuildRequires: miniupnpc-devel +BuildRequires: autoconf automake libtool +BuildRequires: libevent-devel + + +Patch0: bitcoin-0.12.0-libressl.patch + + +%description +Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to +operate with no central authority or banks; managing transactions and the +issuing of bitcoins is carried out collectively by the network. + +%if %{_buildqt} +%package core +Summary: Peer to Peer Cryptographic Currency +Group: Applications/System +Obsoletes: %{name} < %{version}-%{release} +Provides: %{name} = %{version}-%{release} +%if 0%{?_use_qt4} +BuildRequires: qt-devel +%else +BuildRequires: qt5-qtbase-devel +# for /usr/bin/lrelease-qt5 +BuildRequires: qt5-linguist +%endif +BuildRequires: protobuf-devel +BuildRequires: qrencode-devel +BuildRequires: %{_bindir}/desktop-file-validate +# for icon generation from SVG +BuildRequires: %{_bindir}/inkscape +BuildRequires: %{_bindir}/convert + +%description core +Bitcoin is a digital cryptographic currency that uses peer-to-peer technology to +operate with no central authority or banks; managing transactions and the +issuing of bitcoins is carried out collectively by the network. + +This package contains the Qt based graphical client and node. If you are looking +to run a Bitcoin wallet, this is probably the package you want. +%endif + + +%package libs +Summary: Bitcoin shared libraries +Group: System Environment/Libraries + +%description libs +This package provides the bitcoinconsensus shared libraries. These libraries +may be used by third party software to provide consensus verification +functionality. + +Unless you know need this package, you probably do not. + +%package devel +Summary: Development files for bitcoin +Group: Development/Libraries +Requires: %{name}-libs = %{version}-%{release} + +%description devel +This package contains the header files and static library for the +bitcoinconsensus shared library. If you are developing or compiling software +that wants to link against that library, then you need this package installed. + +Most people do not need this package installed. + +%package server +Summary: The bitcoin daemon +Group: System Environment/Daemons +Requires: bitcoin-utils = %{version}-%{release} +Requires: selinux-policy policycoreutils-python +Requires(pre): shadow-utils +Requires(post): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus +Requires(postun): %{_sbindir}/semodule %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/sestatus +BuildRequires: systemd +BuildRequires: checkpolicy +BuildRequires: %{_datadir}/selinux/devel/Makefile + +%description server +This package provides a stand-alone bitcoin-core daemon. For most users, this +package is only needed if they need a full-node without the graphical client. + +Some third party wallet software will want this package to provide the actual +bitcoin-core node they use to connect to the network. + +If you use the graphical bitcoin-core client then you almost certainly do not +need this package. + +%package utils +Summary: Bitcoin utilities +Group: Applications/System + +%description utils +This package provides several command line utilities for interacting with a +bitcoin-core daemon. + +The bitcoin-cli utility allows you to communicate and control a bitcoin daemon +over RPC, the bitcoin-tx utility allows you to create a custom transaction, and +the bench_bitcoin utility can be used to perform some benchmarks. + +This package contains utilities needed by the bitcoin-server package. + + +%prep +%setup -q +%patch0 -p1 -b .libressl +cp -p %{SOURCE10} ./bitcoin.conf.example +tar -zxf %{SOURCE1} +cp -p db-%{bdbv}.NC/LICENSE ./db-%{bdbv}.NC-LICENSE +mkdir db4 SELinux +cp -p %{SOURCE30} %{SOURCE31} %{SOURCE32} SELinux/ + + +%build +CWD=`pwd` +cd db-%{bdbv}.NC/build_unix/ +../dist/configure --enable-cxx --disable-shared --with-pic --prefix=${CWD}/db4 +make install +cd ../.. + +./autogen.sh +%configure LDFLAGS="-L${CWD}/db4/lib/" CPPFLAGS="-I${CWD}/db4/include/" --with-miniupnpc --enable-glibc-back-compat %{buildargs} +make %{?_smp_mflags} + +pushd SELinux +for selinuxvariant in %{selinux_variants}; do + make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile + mv bitcoin.pp bitcoin.pp.${selinuxvariant} + make NAME=${selinuxvariant} -f %{_datadir}/selinux/devel/Makefile clean +done +popd + + +%install +make install DESTDIR=%{buildroot} + +mkdir -p -m755 %{buildroot}%{_sbindir} +mv %{buildroot}%{_bindir}/bitcoind %{buildroot}%{_sbindir}/bitcoind + +# systemd stuff +mkdir -p %{buildroot}%{_tmpfilesdir} +cat < %{buildroot}%{_tmpfilesdir}/bitcoin.conf +d /run/bitcoind 0750 bitcoin bitcoin - +EOF +touch -a -m -t 201504280000 %{buildroot}%{_tmpfilesdir}/bitcoin.conf + +mkdir -p %{buildroot}%{_sysconfdir}/sysconfig +cat < %{buildroot}%{_sysconfdir}/sysconfig/bitcoin +# Provide options to the bitcoin daemon here, for example +# OPTIONS="-testnet -disable-wallet" + +OPTIONS="" + +# System service defaults. +# Don't change these unless you know what you're doing. +CONFIG_FILE="%{_sysconfdir}/bitcoin/bitcoin.conf" +DATA_DIR="%{_localstatedir}/lib/bitcoin" +PID_FILE="/run/bitcoind/bitcoind.pid" +EOF +touch -a -m -t 201504280000 %{buildroot}%{_sysconfdir}/sysconfig/bitcoin + +mkdir -p %{buildroot}%{_unitdir} +cat < %{buildroot}%{_unitdir}/bitcoin.service +[Unit] +Description=Bitcoin daemon +After=syslog.target network.target + +[Service] +Type=forking +ExecStart=%{_sbindir}/bitcoind -daemon -conf=\${CONFIG_FILE} -datadir=\${DATA_DIR} -pid=\${PID_FILE} \$OPTIONS +EnvironmentFile=%{_sysconfdir}/sysconfig/bitcoin +User=bitcoin +Group=bitcoin + +Restart=on-failure +PrivateTmp=true +TimeoutStopSec=120 +TimeoutStartSec=60 +StartLimitInterval=240 +StartLimitBurst=5 + +[Install] +WantedBy=multi-user.target +EOF +touch -a -m -t 201504280000 %{buildroot}%{_unitdir}/bitcoin.service +#end systemd stuff + +mkdir %{buildroot}%{_sysconfdir}/bitcoin +mkdir -p %{buildroot}%{_localstatedir}/lib/bitcoin + +#SELinux +for selinuxvariant in %{selinux_variants}; do + install -d %{buildroot}%{_datadir}/selinux/${selinuxvariant} + install -p -m 644 SELinux/bitcoin.pp.${selinuxvariant} %{buildroot}%{_datadir}/selinux/${selinuxvariant}/bitcoin.pp +done + +%if %{_buildqt} +# qt icons +install -D -p share/pixmaps/bitcoin.ico %{buildroot}%{_datadir}/pixmaps/bitcoin.ico +install -p share/pixmaps/nsis-header.bmp %{buildroot}%{_datadir}/pixmaps/ +install -p share/pixmaps/nsis-wizard.bmp %{buildroot}%{_datadir}/pixmaps/ +install -p %{SOURCE100} %{buildroot}%{_datadir}/pixmaps/bitcoin.svg +%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin16.png -w16 -h16 +%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin32.png -w32 -h32 +%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin64.png -w64 -h64 +%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin128.png -w128 -h128 +%{_bindir}/inkscape %{SOURCE100} --export-png=%{buildroot}%{_datadir}/pixmaps/bitcoin256.png -w256 -h256 +%{_bindir}/convert -resize 16x16 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin16.xpm +%{_bindir}/convert -resize 32x32 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin32.xpm +%{_bindir}/convert -resize 64x64 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin64.xpm +%{_bindir}/convert -resize 128x128 %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin128.xpm +%{_bindir}/convert %{buildroot}%{_datadir}/pixmaps/bitcoin256.png %{buildroot}%{_datadir}/pixmaps/bitcoin256.xpm +touch %{buildroot}%{_datadir}/pixmaps/*.png -r %{SOURCE100} +touch %{buildroot}%{_datadir}/pixmaps/*.xpm -r %{SOURCE100} + +# Desktop File - change the touch timestamp if modifying +mkdir -p %{buildroot}%{_datadir}/applications +cat < %{buildroot}%{_datadir}/applications/bitcoin-core.desktop +[Desktop Entry] +Encoding=UTF-8 +Name=Bitcoin +Comment=Bitcoin P2P Cryptocurrency +Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair +Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi +Exec=bitcoin-qt %u +Terminal=false +Type=Application +Icon=bitcoin128 +MimeType=x-scheme-handler/bitcoin; +Categories=Office;Finance; +EOF +# change touch date when modifying desktop +touch -a -m -t 201511100546 %{buildroot}%{_datadir}/applications/bitcoin-core.desktop +%{_bindir}/desktop-file-validate %{buildroot}%{_datadir}/applications/bitcoin-core.desktop + +# KDE protocol - change the touch timestamp if modifying +mkdir -p %{buildroot}%{_datadir}/kde4/services +cat < %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol +[Protocol] +exec=bitcoin-qt '%u' +protocol=bitcoin +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +EOF +# change touch date when modifying protocol +touch -a -m -t 201511100546 %{buildroot}%{_datadir}/kde4/services/bitcoin-core.protocol +%endif + +# man pages +install -D -p %{SOURCE20} %{buildroot}%{_mandir}/man1/bitcoind.1 +install -p %{SOURCE21} %{buildroot}%{_mandir}/man1/bitcoin-cli.1 +%if %{_buildqt} +install -p %{SOURCE22} %{buildroot}%{_mandir}/man1/bitcoin-qt.1 +%endif +install -D -p %{SOURCE23} %{buildroot}%{_mandir}/man5/bitcoin.conf.5 + +# nuke these, we do extensive testing of binaries in %%check before packaging +rm -f %{buildroot}%{_bindir}/test_* + +%check +make check +pushd src +srcdir=. test/bitcoin-util-test.py +popd +qa/pull-tester/rpc-tests.py -extended + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%pre server +getent group bitcoin >/dev/null || groupadd -r bitcoin +getent passwd bitcoin >/dev/null || + useradd -r -g bitcoin -d /var/lib/bitcoin -s /sbin/nologin \ + -c "Bitcoin wallet server" bitcoin +exit 0 + +%post server +%systemd_post bitcoin.service +# SELinux +if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then +for selinuxvariant in %{selinux_variants}; do + %{_sbindir}/semodule -s ${selinuxvariant} -i %{_datadir}/selinux/${selinuxvariant}/bitcoin.pp &> /dev/null || : +done +%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8332 +%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8333 +%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18332 +%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18333 +%{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : +%{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin || : +fi + +%posttrans server +%{_bindir}/systemd-tmpfiles --create + +%preun server +%systemd_preun bitcoin.service + +%postun server +%systemd_postun bitcoin.service +# SELinux +if [ $1 -eq 0 ]; then + if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then + %{_sbindir}/semanage port -d -p tcp 8332 + %{_sbindir}/semanage port -d -p tcp 8333 + %{_sbindir}/semanage port -d -p tcp 18332 + %{_sbindir}/semanage port -d -p tcp 18333 + for selinuxvariant in %{selinux_variants}; do + %{_sbindir}/semodule -s ${selinuxvariant} -r bitcoin &> /dev/null || : + done + %{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || : + [ -d %{_localstatedir}/lib/bitcoin ] && \ + %{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin &> /dev/null || : + fi +fi + +%clean +rm -rf %{buildroot} + +%if %{_buildqt} +%files core +%defattr(-,root,root,-) +%license COPYING db-%{bdbv}.NC-LICENSE +%doc COPYING bitcoin.conf.example doc/README.md doc/bips.md doc/files.md doc/multiwallet-qt.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md +%attr(0755,root,root) %{_bindir}/bitcoin-qt +%attr(0644,root,root) %{_datadir}/applications/bitcoin-core.desktop +%attr(0644,root,root) %{_datadir}/kde4/services/bitcoin-core.protocol +%attr(0644,root,root) %{_datadir}/pixmaps/*.ico +%attr(0644,root,root) %{_datadir}/pixmaps/*.bmp +%attr(0644,root,root) %{_datadir}/pixmaps/*.svg +%attr(0644,root,root) %{_datadir}/pixmaps/*.png +%attr(0644,root,root) %{_datadir}/pixmaps/*.xpm +%attr(0644,root,root) %{_mandir}/man1/bitcoin-qt.1* +%endif + +%files libs +%defattr(-,root,root,-) +%license COPYING +%doc COPYING doc/README.md doc/shared-libraries.md +%{_libdir}/lib*.so.* + +%files devel +%defattr(-,root,root,-) +%license COPYING +%doc COPYING doc/README.md doc/developer-notes.md doc/shared-libraries.md +%attr(0644,root,root) %{_includedir}/*.h +%{_libdir}/*.so +%{_libdir}/*.a +%{_libdir}/*.la +%attr(0644,root,root) %{_libdir}/pkgconfig/*.pc + +%files server +%defattr(-,root,root,-) +%license COPYING db-%{bdbv}.NC-LICENSE +%doc COPYING bitcoin.conf.example doc/README.md doc/REST-interface.md doc/bips.md doc/dnsseed-policy.md doc/files.md doc/reduce-traffic.md doc/release-notes.md doc/tor.md +%attr(0755,root,root) %{_sbindir}/bitcoind +%attr(0644,root,root) %{_tmpfilesdir}/bitcoin.conf +%attr(0644,root,root) %{_unitdir}/bitcoin.service +%dir %attr(0750,bitcoin,bitcoin) %{_sysconfdir}/bitcoin +%dir %attr(0750,bitcoin,bitcoin) %{_localstatedir}/lib/bitcoin +%config(noreplace) %attr(0600,root,root) %{_sysconfdir}/sysconfig/bitcoin +%attr(0644,root,root) %{_datadir}/selinux/*/*.pp +%attr(0644,root,root) %{_mandir}/man1/bitcoind.1* +%attr(0644,root,root) %{_mandir}/man5/bitcoin.conf.5* + +%files utils +%defattr(-,root,root,-) +%license COPYING +%doc COPYING bitcoin.conf.example doc/README.md +%attr(0755,root,root) %{_bindir}/bitcoin-cli +%attr(0755,root,root) %{_bindir}/bitcoin-tx +%attr(0755,root,root) %{_bindir}/bench_bitcoin +%attr(0644,root,root) %{_mandir}/man1/bitcoin-cli.1* +%attr(0644,root,root) %{_mandir}/man5/bitcoin.conf.5* + + + +%changelog +* Fri Feb 26 2016 Alice Wonder - 0.12.0-2 +- Rename Qt package from bitcoin to bitcoin-core +- Make building of the Qt package optional +- When building the Qt package, default to Qt5 but allow building +- against Qt4 +- Only run SELinux stuff in post scripts if it is not set to disabled + +* Wed Feb 24 2016 Alice Wonder - 0.12.0-1 +- Initial spec file for 0.12.0 release + +# This spec file is written from scratch but a lot of the packaging decisions are directly +# based upon the 0.11.2 package spec file from https://www.ringingliberty.com/bitcoin/ diff --git a/contrib/rpm/bitcoin.te b/contrib/rpm/bitcoin.te new file mode 100644 index 000000000..d6231c591 --- /dev/null +++ b/contrib/rpm/bitcoin.te @@ -0,0 +1,81 @@ +policy_module(bitcoin, 1.100.1) + +######################################## +# +# Declarations +# + +type bitcoin_t; +type bitcoin_exec_t; +init_daemon_domain(bitcoin_t, bitcoin_exec_t) + +permissive bitcoin_t; + +type bitcoin_initrc_exec_t; +init_script_file(bitcoin_initrc_exec_t) + +type bitcoin_conf_t; +files_type(bitcoin_conf_t) + +type bitcoin_var_lib_t; +files_type(bitcoin_var_lib_t) + +type bitcoin_var_run_t; +files_type(bitcoin_var_run_t) + +type bitcoin_port_t; +corenet_port(bitcoin_port_t) + +######################################## +# +# bitcoin local policy +# +allow bitcoin_t self:process { fork }; + +allow bitcoin_t self:fifo_file rw_fifo_file_perms; +allow bitcoin_t self:unix_stream_socket create_stream_socket_perms; + +manage_dirs_pattern(bitcoin_t, bitcoin_conf_t, bitcoin_conf_t) +manage_files_pattern(bitcoin_t, bitcoin_conf_t, bitcoin_conf_t) + +manage_dirs_pattern(bitcoin_t, bitcoin_var_lib_t, bitcoin_var_lib_t) +manage_files_pattern(bitcoin_t, bitcoin_var_lib_t, bitcoin_var_lib_t) +files_var_lib_filetrans(bitcoin_t, bitcoin_var_lib_t, { dir file }) + +manage_dirs_pattern(bitcoin_t, bitcoin_var_run_t, bitcoin_var_run_t) +manage_files_pattern(bitcoin_t, bitcoin_var_run_t, bitcoin_var_run_t) + +sysnet_dns_name_resolve(bitcoin_t) +corenet_all_recvfrom_unlabeled(bitcoin_t) + +allow bitcoin_t self:tcp_socket create_stream_socket_perms; +corenet_tcp_sendrecv_generic_if(bitcoin_t) +corenet_tcp_sendrecv_generic_node(bitcoin_t) +corenet_tcp_sendrecv_all_ports(bitcoin_t) +corenet_tcp_bind_generic_node(bitcoin_t) + +gen_require(` + type bitcoin_port_t; +') +allow bitcoin_t bitcoin_port_t:tcp_socket name_bind; + +gen_require(` + type bitcoin_port_t; +') +allow bitcoin_t bitcoin_port_t:tcp_socket name_connect; + +domain_use_interactive_fds(bitcoin_t) + +files_read_etc_files(bitcoin_t) + +miscfiles_read_localization(bitcoin_t) + +sysnet_dns_name_resolve(bitcoin_t) + +allow bitcoin_t bitcoin_exec_t:file execute_no_trans; +allow bitcoin_t self:process setsched; +corecmd_exec_ls(bitcoin_t) +corenet_tcp_connect_http_port(bitcoin_t) +dev_read_urand(bitcoin_t) +fs_getattr_xattr_fs(bitcoin_t) +kernel_read_system_state(bitcoin_t) From 0e4b50a48c72061f4bafe7f99f0b261a148b457b Mon Sep 17 00:00:00 2001 From: Alice Wonder Date: Fri, 26 Feb 2016 10:09:03 -0800 Subject: [PATCH 0267/1223] Description of RPM directory --- contrib/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/README.md b/contrib/README.md index b6e572102..fe7747603 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -42,6 +42,9 @@ Various PGP files of core developers. ### [MacDeploy](/contrib/macdeploy) ### Scripts and notes for Mac builds. +### [RPM](/contrib/rpm) ### +RPM spec file for building bitcoin-core on RPM based distributions + Test and Verify Tools --------------------- From ff2be40685fe2cef689b4617015cee9f28e2f2c3 Mon Sep 17 00:00:00 2001 From: Alfie John Date: Sat, 27 Feb 2016 03:02:34 +0000 Subject: [PATCH 0268/1223] [doc] Typo fix Small typo in Unix install notes --- doc/build-unix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 1d8395162..17ac517ab 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -11,7 +11,7 @@ for example, when specifying the path of the dependency: ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX -Here BDB_PREFIX must absolute path - it is defined using $(pwd) which ensures +Here BDB_PREFIX must be an absolute path - it is defined using $(pwd) which ensures the usage of the absolute path. To Build From 5c70a6d6d15cc301b76558f708948c375fe63ccb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 27 Feb 2016 06:09:18 +0000 Subject: [PATCH 0269/1223] Bugfix: gitian: Add curl to packages (now needed for depends) --- contrib/gitian-descriptors/gitian-linux.yml | 1 + contrib/gitian-descriptors/gitian-osx.yml | 1 + contrib/gitian-descriptors/gitian-win.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 0c3c439dd..037e552f9 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -6,6 +6,7 @@ suites: architectures: - "amd64" packages: +- "curl" - "g++-multilib" - "git-core" - "pkg-config" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 9ac774c8a..8deec36ce 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -6,6 +6,7 @@ suites: architectures: - "amd64" packages: +- "curl" - "g++" - "git-core" - "pkg-config" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 6bb482d45..9a56e5939 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -6,6 +6,7 @@ suites: architectures: - "amd64" packages: +- "curl" - "g++" - "git-core" - "pkg-config" From fa06ce09498707d5e82633f1e1b034675e552628 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 19 Dec 2015 14:27:15 +0100 Subject: [PATCH 0270/1223] Fix doxygen comment for payTxFee --- src/wallet/wallet.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 65defc30a..16653b9fd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -33,9 +33,7 @@ using namespace std; -/** - * Settings - */ +/** Transaction fee set by the user */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; From f41927e2c033ab5044b203bda8ddfbc747e61526 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sat, 27 Feb 2016 21:06:21 +0000 Subject: [PATCH 0271/1223] Add missing sudo entry in gitian VM setup. [ci skip] --- doc/gitian-building.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 5ca91505e..77882a1b9 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -262,6 +262,7 @@ Then set up LXC and the rest with the following, which is a complex jumble of se # the version of lxc-start in Debian needs to run as root, so make sure # that the build script can execute it without providing a password echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc +echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-execute" >> /etc/sudoers.d/gitian-lxc # make /etc/rc.local script that sets up bridge between guest and host echo '#!/bin/sh -e' > /etc/rc.local echo 'brctl addbr br0' >> /etc/rc.local From 0040118959305c4f2b0e7e9c42cf3e865607a04a Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Mon, 29 Feb 2016 13:34:09 -0500 Subject: [PATCH 0272/1223] Fixes ZMQ startup with bad arguments. --- src/zmq/zmqnotificationinterface.cpp | 1 - src/zmq/zmqpublishnotifier.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index c8adcf846..870553242 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -100,7 +100,6 @@ bool CZMQNotificationInterface::Initialize() if (i!=notifiers.end()) { - Shutdown(); return false; } diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index ddc8fe93e..f5839620f 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -69,6 +69,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) if (rc!=0) { zmqError("Failed to bind address"); + zmq_close(psocket); return false; } From fafe446d0e5d51b7f17628d397e3d3d9fac8b9d8 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 27 Feb 2016 15:11:50 +0100 Subject: [PATCH 0273/1223] [depends] Delete unused patches Superseded by 4bdad99f5000539dcf03ddc92c142fa6deb44c01 --- .../patches/boost/darwin_boost_atomic-1.patch | 35 ------------ .../patches/boost/darwin_boost_atomic-2.patch | 55 ------------------- depends/patches/boost/gcc_5_no_cxx11.patch | 37 ------------- 3 files changed, 127 deletions(-) delete mode 100644 depends/patches/boost/darwin_boost_atomic-1.patch delete mode 100644 depends/patches/boost/darwin_boost_atomic-2.patch delete mode 100644 depends/patches/boost/gcc_5_no_cxx11.patch diff --git a/depends/patches/boost/darwin_boost_atomic-1.patch b/depends/patches/boost/darwin_boost_atomic-1.patch deleted file mode 100644 index 97f59cb7e..000000000 --- a/depends/patches/boost/darwin_boost_atomic-1.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/include/boost/atomic/detail/cas128strong.hpp b/include/boost/atomic/detail/cas128strong.hpp -index 906c13e..dcb4d7d 100644 ---- a/include/boost/atomic/detail/cas128strong.hpp -+++ b/include/boost/atomic/detail/cas128strong.hpp -@@ -196,15 +196,17 @@ class base_atomic - - public: - BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) -- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) -+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT - { -+ memset(&v_, 0, sizeof(v_)); - memcpy(&v_, &v, sizeof(value_type)); - } - - void - store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { -- storage_type value_s = 0; -+ storage_type value_s; -+ memset(&value_s, 0, sizeof(value_s)); - memcpy(&value_s, &value, sizeof(value_type)); - platform_fence_before_store(order); - platform_store128(value_s, &v_); -@@ -247,7 +249,9 @@ class base_atomic - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { -- storage_type expected_s = 0, desired_s = 0; -+ storage_type expected_s, desired_s; -+ memset(&expected_s, 0, sizeof(expected_s)); -+ memset(&desired_s, 0, sizeof(desired_s)); - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - diff --git a/depends/patches/boost/darwin_boost_atomic-2.patch b/depends/patches/boost/darwin_boost_atomic-2.patch deleted file mode 100644 index ca5076520..000000000 --- a/depends/patches/boost/darwin_boost_atomic-2.patch +++ /dev/null @@ -1,55 +0,0 @@ -diff --git a/include/boost/atomic/detail/gcc-atomic.hpp b/include/boost/atomic/detail/gcc-atomic.hpp -index a130590..4af99a1 100644 ---- a/include/boost/atomic/detail/gcc-atomic.hpp -+++ b/include/boost/atomic/detail/gcc-atomic.hpp -@@ -958,14 +958,16 @@ class base_atomic - - public: - BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) -- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) -+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT - { -+ memset(&v_, 0, sizeof(v_)); - memcpy(&v_, &v, sizeof(value_type)); - } - - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { -- storage_type tmp = 0; -+ storage_type tmp; -+ memset(&tmp, 0, sizeof(tmp)); - memcpy(&tmp, &v, sizeof(value_type)); - __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); - } -@@ -980,7 +982,8 @@ class base_atomic - - value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { -- storage_type tmp = 0; -+ storage_type tmp; -+ memset(&tmp, 0, sizeof(tmp)); - memcpy(&tmp, &v, sizeof(value_type)); - tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); - value_type res; -@@ -994,7 +997,9 @@ class base_atomic - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { -- storage_type expected_s = 0, desired_s = 0; -+ storage_type expected_s, desired_s; -+ memset(&expected_s, 0, sizeof(expected_s)); -+ memset(&desired_s, 0, sizeof(desired_s)); - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, -@@ -1010,7 +1015,9 @@ class base_atomic - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { -- storage_type expected_s = 0, desired_s = 0; -+ storage_type expected_s, desired_s; -+ memset(&expected_s, 0, sizeof(expected_s)); -+ memset(&desired_s, 0, sizeof(desired_s)); - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, diff --git a/depends/patches/boost/gcc_5_no_cxx11.patch b/depends/patches/boost/gcc_5_no_cxx11.patch deleted file mode 100644 index 04514c593..000000000 --- a/depends/patches/boost/gcc_5_no_cxx11.patch +++ /dev/null @@ -1,37 +0,0 @@ -From eec808554936ae068b23df07ab54d4dc6302a695 Mon Sep 17 00:00:00 2001 -From: jzmaddock -Date: Sat, 23 Aug 2014 09:38:02 +0100 -Subject: [PATCH] Fix BOOST_NO_CXX11_VARIADIC_TEMPLATES definition - the - feature was introduced in GCC 4.4. - ---- - include/boost/config/compiler/gcc.hpp | 9 +-------- - 1 file changed, 1 insertion(+), 8 deletions(-) - -diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp -index f37159d..97d8a18 100644 ---- a/include/boost/config/compiler/gcc.hpp -+++ b/include/boost/config/compiler/gcc.hpp -@@ -154,14 +154,6 @@ - # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS - # define BOOST_NO_CXX11_RVALUE_REFERENCES - # define BOOST_NO_CXX11_STATIC_ASSERT -- --// Variadic templates compiler: --// http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html --# if defined(__VARIADIC_TEMPLATES) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4) && defined(__GXX_EXPERIMENTAL_CXX0X__)) --# define BOOST_HAS_VARIADIC_TMPL --# else --# define BOOST_NO_CXX11_VARIADIC_TEMPLATES --# endif - #endif - - // C++0x features in 4.4.n and later -@@ -176,6 +168,7 @@ - # define BOOST_NO_CXX11_DELETED_FUNCTIONS - # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES - # define BOOST_NO_CXX11_INLINE_NAMESPACES -+# define BOOST_NO_CXX11_VARIADIC_TEMPLATES - #endif - - #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) From f5ecd0737130eed8daf9d76c5232dce7e40b7150 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 1 Mar 2016 13:45:21 +0100 Subject: [PATCH 0274/1223] doc: Add missing credit to 0.12.0 release notes Closes #7624 --- doc/release-notes/release-notes-0.12.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index b586d754f..80a0fa9da 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -809,6 +809,7 @@ Thanks to everyone who directly contributed to this release: - Chris Kleeschulte - Christian Decker - Cory Fields +- crowning- - daniel - Daniel Cousens - Daniel Kraft From fa97f95c15a7aee15feea500571a10a90f22ea8b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 27 Feb 2016 15:15:38 +0100 Subject: [PATCH 0275/1223] [doc] Fix markdown --- README.md | 2 +- contrib/verifysfbinaries/README.md | 4 ++-- doc/README.md | 2 +- doc/release-notes/release-notes-0.12.0.md | 7 +++---- doc/release-process.md | 2 +- qa/rpc-tests/multi_rpc.py | 2 +- share/rpcuser/README.md | 3 +-- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b568978f0..d5b742534 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. For more information, as well as an immediately useable, binary version of -the Bitcoin Core software, see https://www.bitcoin.org/en/download, or read the +the Bitcoin Core software, see https://bitcoin.org/en/download, or read the [original whitepaper](https://bitcoincore.org/bitcoin.pdf). License diff --git a/contrib/verifysfbinaries/README.md b/contrib/verifysfbinaries/README.md index 8c038865b..1db3fe52f 100644 --- a/contrib/verifysfbinaries/README.md +++ b/contrib/verifysfbinaries/README.md @@ -1,6 +1,6 @@ -### Verify SF Binaries ### +### Verify Binaries ### This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org. It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file. -The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2. \ No newline at end of file +The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2. diff --git a/doc/README.md b/doc/README.md index c0f9ee522..cf475ef18 100644 --- a/doc/README.md +++ b/doc/README.md @@ -49,7 +49,7 @@ The following are developer notes on how to build Bitcoin on your native platfor Development --------------------- -The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing. +The Bitcoin repo's [root README](/README.md) contains relevant information on the development process and automated testing. - [Developer Notes](developer-notes.md) - [Multiwallet Qt Development](multiwallet-qt.md) diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index b586d754f..3ada9107e 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -99,7 +99,7 @@ Direct headers announcement (BIP 130) Between compatible peers, [BIP 130] (https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki) -direct headers announcement is used. This means that blocks are advertized by +direct headers announcement is used. This means that blocks are advertised by announcing their headers directly, instead of just announcing the hash. In a reorganization, all new headers are sent, instead of just the new tip. This can often prevent an extra roundtrip before the actual block is downloaded. @@ -272,7 +272,7 @@ at all. Therefore, a fallback value can be set with `-fallbackfee=` At all times, Bitcoin Core will cap fees at `-maxtxfee=` (default: 0.10) BTC. -Furthermore, Bitcoin Core will never create transactions smaller than +Furthermore, Bitcoin Core will never create transactions paying less than the current minimum relay fee. Finally, a user can set the minimum fee rate for all transactions with `-mintxfee=`, which defaults to 1000 satoshis per kB. @@ -701,7 +701,7 @@ git merge commit are mentioned. - #7112 `96b8025` reduce cs_main locks during tip update, more fluently update UI (Jonas Schnelli) - #7206 `f43c2f9` Add "NODE_BLOOM" to guiutil so that peers don't get UNKNOWN[4] (Matt Corallo) - #7282 `5cadf3e` fix coincontrol update issue when deleting a send coins entry (Jonas Schnelli) -- #7319 `1320300` Intro: Display required space (Jonas Schnelli) +- #7319 `1320300` Intro: Display required space (MarcoFalke) - #7318 `9265e89` quickfix for RPC timer interface problem (Jonas Schnelli) - #7327 `b16b5bc` [Wallet] Transaction View: LastMonth calculation fixed (crowning-) - #7364 `7726c48` [qt] Windows: Make rpcconsole monospace font larger (MarcoFalke) @@ -841,7 +841,6 @@ Thanks to everyone who directly contributed to this release: - Kevin Cooper - lpescher - Luke Dashjr -- Marco - MarcoFalke - Mark Friedenbach - Matt diff --git a/doc/release-process.md b/doc/release-process.md index 8fb083d0d..2c83896c2 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -210,7 +210,7 @@ Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spur - Optionally reddit /r/Bitcoin, ... but this will usually sort out itself -- Notify BlueMatt so that he can start building [https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin](the PPAs) +- Notify BlueMatt so that he can start building [the PPAs](https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin) - Add release notes for the new version to the directory `doc/release-notes` in git master diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 62071d426..2452b7731 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -44,7 +44,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Old authpair authpair = url.username + ':' + url.password - #New authpair generated via contrib/rpcuser tool + #New authpair generated via share/rpcuser tool rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM=" diff --git a/share/rpcuser/README.md b/share/rpcuser/README.md index 7c2c909a4..12a8e6fb0 100644 --- a/share/rpcuser/README.md +++ b/share/rpcuser/README.md @@ -7,5 +7,4 @@ Create an RPC user login credential. Usage: -./rpcuser.py - + ./rpcuser.py From fa266524592cc18c789cc587d738fb0e548fd23a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 28 Feb 2016 22:42:26 +0100 Subject: [PATCH 0276/1223] Make sure LogPrintf strings are line-terminated --- src/httprpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index a447a3eff..04d3386e9 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -219,7 +219,7 @@ static bool InitRPCAuthentication() return false; } } else { - LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation."); + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n"); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; From fa58c76b9ff01abfc7f037fee85e70f342981d42 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 25 Dec 2015 13:14:26 +0100 Subject: [PATCH 0277/1223] [gitian] Default reference_datetime to commit author date --- contrib/gitian-descriptors/gitian-linux.yml | 3 +-- contrib/gitian-descriptors/gitian-osx-signer.yml | 1 - contrib/gitian-descriptors/gitian-osx.yml | 3 +-- contrib/gitian-descriptors/gitian-win-signer.yml | 1 - contrib/gitian-descriptors/gitian-win.yml | 3 +-- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 1f2c4f999..8b2ab4ebf 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -5,7 +5,7 @@ suites: - "trusty" architectures: - "amd64" -packages: +packages: - "curl" - "g++-multilib" - "git-core" @@ -18,7 +18,6 @@ packages: - "binutils-gold" - "ca-certificates" - "python" -reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index c4165470a..ea67e1b7e 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -6,7 +6,6 @@ architectures: - "amd64" packages: - "faketime" -reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 6f68ae08c..74fc2e93a 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -5,7 +5,7 @@ suites: - "trusty" architectures: - "amd64" -packages: +packages: - "ca-certificates" - "curl" - "g++" @@ -27,7 +27,6 @@ packages: - "python-dev" - "python-setuptools" - "fonts-tuffy" -reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 27c4f01eb..6b53b89b6 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -7,7 +7,6 @@ architectures: packages: - "libssl-dev" - "autoconf" -reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index f0fbff3e1..719ca9c23 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -5,7 +5,7 @@ suites: - "trusty" architectures: - "amd64" -packages: +packages: - "curl" - "g++" - "git-core" @@ -21,7 +21,6 @@ packages: - "zip" - "ca-certificates" - "python" -reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" From 2e23066b733576e683fa154717e8693640ced0f3 Mon Sep 17 00:00:00 2001 From: lewuathe Date: Wed, 2 Mar 2016 22:59:31 +0900 Subject: [PATCH 0278/1223] Delete outdated test-patches reference --- contrib/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contrib/README.md b/contrib/README.md index b6e572102..5155ff0cb 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -48,9 +48,5 @@ Test and Verify Tools ### [TestGen](/contrib/testgen) ### Utilities to generate test vectors for the data-driven Bitcoin tests. -### [Test Patches](/contrib/test-patches) ### -These patches are applied when the automated pull-tester -tests each pull and when master is tested using jenkins. - ### [Verify SF Binaries](/contrib/verifysfbinaries) ### This script attempts to download and verify the signature file SHA256SUMS.asc from SourceForge. From fa5f19319a3f00ca6586daba955d296295c82a1f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 1 Feb 2016 17:57:45 +0100 Subject: [PATCH 0279/1223] [travis] Exit early when check-doc.py fails --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3305906e4..31b3d6d96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,6 +58,7 @@ install: - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: - unset CC; unset CXX + - if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi - mkdir -p depends/SDKs depends/sdk-sources - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi @@ -68,7 +69,6 @@ script: - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi - - if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir PACKAGE=bitcoin VERSION=$HOST From e2195037116f47b11b66452351dba4fe606423a2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 3 Mar 2016 13:28:07 +0100 Subject: [PATCH 0280/1223] Fix memleak in TorController [rework] It looks like, TorController::disconnected_cb(TorControlConnection& conn) gets called multiple times which results in multiple event_new(). Avoid this by creating the event only once in the constructore, and deleting it only once in the destructor (thanks to Cory Fields for the idea). Replaces the fix by Jonas Schnelli in #7610, see discussion there. --- src/torcontrol.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 10170dbce..a04b5c302 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -398,6 +398,9 @@ TorController::TorController(struct event_base* base, const std::string& target) target(target), conn(base), reconnect(true), reconnect_ev(0), reconnect_timeout(RECONNECT_TIMEOUT_START) { + reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); + if (!reconnect_ev) + LogPrintf("tor: Failed to create event for reconnection: out of memory?\n"); // Start connection attempts immediately if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), boost::bind(&TorController::disconnected_cb, this, _1) )) { @@ -413,8 +416,10 @@ TorController::TorController(struct event_base* base, const std::string& target) TorController::~TorController() { - if (reconnect_ev) - event_del(reconnect_ev); + if (reconnect_ev) { + event_free(reconnect_ev); + reconnect_ev = 0; + } if (service.IsValid()) { RemoveLocal(service); } @@ -626,8 +631,8 @@ void TorController::disconnected_cb(TorControlConnection& conn) // Single-shot timer for reconnect. Use exponential backoff. struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); - reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); - event_add(reconnect_ev, &time); + if (reconnect_ev) + event_add(reconnect_ev, &time); reconnect_timeout *= RECONNECT_TIMEOUT_EXP; } From 72c265158127ff1084cdb034439ddbe1783b0791 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 22 Feb 2016 10:48:44 +0100 Subject: [PATCH 0281/1223] [Wallet] move wallet help string creation to CWallet --- src/init.cpp | 31 +------------------------------ src/wallet/wallet.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 5 +++++ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 048843a4c..ac1cfc551 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -72,7 +72,6 @@ static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_DISABLE_SAFEMODE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; -static const char * const DEFAULT_WALLET_DAT = "wallet.dat"; #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; @@ -395,26 +394,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET - strUsage += HelpMessageGroup(_("Wallet options:")); - strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); - strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); - strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), - CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); - strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); - strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); - strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); - strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + - " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + strUsage += CWallet::GetWalletHelpString(showDebug); #endif #if ENABLE_ZMQ @@ -432,16 +412,10 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); -#endif strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE)); strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE)); strUsage += HelpMessageOpt("-dropmessagestest=", "Randomly drop 1 of every network messages"); strUsage += HelpMessageOpt("-fuzzmessagestest=", "Randomly fuzz 1 of every network messages"); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); -#endif strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT)); strUsage += HelpMessageOpt("-limitancestorcount=", strprintf("Do not accept transactions if number of in-mempool ancestors is or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); strUsage += HelpMessageOpt("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); @@ -477,9 +451,6 @@ std::string HelpMessage(HelpMessageMode mode) if (showDebug) { strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); -#endif } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 65defc30a..04b4df519 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -41,6 +41,8 @@ unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; +const char * DEFAULT_WALLET_DAT = "wallet.dat"; + /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee @@ -2956,6 +2958,41 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st return false; } +std::string CWallet::GetWalletHelpString(bool showDebug) +{ + std::string strUsage = HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); + strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); + strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); + strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + + if (showDebug) + { + strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); + + strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + } + + return strUsage; +} + CKeyPool::CKeyPool() { nTime = GetTime(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 990b27c7c..6312735c9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -55,6 +55,8 @@ static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; +extern const char * DEFAULT_WALLET_DAT; + class CBlockIndex; class CCoinControl; class COutput; @@ -869,6 +871,9 @@ public: /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ bool AbandonTransaction(const uint256& hashTx); + + /* Returns the wallets help message */ + static std::string GetWalletHelpString(bool showDebug); }; /** A key allocated from the key pool. */ From b51ed4036e157a116414f53ac8da78c6b35bf041 Mon Sep 17 00:00:00 2001 From: Eric Shaw Date: Tue, 1 Mar 2016 14:16:32 -0500 Subject: [PATCH 0282/1223] QT: Add 'copy full transaction details' option Adds feature from issue #7484 modifies the ctrl-c binding to copy full transaction details in transaction view. Added translation --- src/qt/transactiontablemodel.cpp | 28 ++++++++++++++++++++++++++++ src/qt/transactiontablemodel.h | 2 ++ src/qt/transactionview.cpp | 16 ++++++++++------ src/qt/transactionview.h | 1 + 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 1647b2a6f..d2a52b302 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -609,6 +609,34 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return QString::fromStdString(rec->hash.ToString()); case TxHexRole: return priv->getTxHex(rec); + case TxPlainTextRole: + { + QString details; + QDateTime date = QDateTime::fromTime_t(static_cast(rec->time)); + QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + + details.append(date.toString("M/d/yy HH:mm")); + details.append(" "); + details.append(formatTxStatus(rec)); + details.append(". "); + if(!formatTxType(rec).isEmpty()) { + details.append(formatTxType(rec)); + details.append(" "); + } + if(!rec->address.empty()) { + if(txLabel.isEmpty()) + details.append(tr("(no label)") + " "); + else { + details.append("("); + details.append(txLabel); + details.append(") "); + } + details.append(QString::fromStdString(rec->address)); + details.append(" "); + } + details.append(formatTxAmount(rec, false, BitcoinUnits::separatorNever)); + return details; + } case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index fe59a15f6..6932646e1 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -62,6 +62,8 @@ public: TxHashRole, /** Transaction data, hex-encoded */ TxHexRole, + /** Whole transaction as plain text */ + TxPlainTextRole, /** Is transaction confirmed? */ ConfirmedRole, /** Formatted amount, without brackets when unconfirmed */ diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 4a9a19821..a4d4c7a35 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -142,6 +142,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *copyAmountAction = new QAction(tr("Copy amount"), this); QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this); QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this); + QAction *copyTxPlainText = new QAction(tr("Copy full transaction details"), this); QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); @@ -151,6 +152,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyAmountAction); contextMenu->addAction(copyTxIDAction); contextMenu->addAction(copyTxHexAction); + contextMenu->addAction(copyTxPlainText); contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); @@ -173,6 +175,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID())); connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex())); + connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText())); connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); } @@ -388,6 +391,11 @@ void TransactionView::copyTxHex() GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHexRole); } +void TransactionView::copyTxPlainText() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole); +} + void TransactionView::editLabel() { if(!transactionView->selectionModel() ||!model) @@ -526,12 +534,8 @@ bool TransactionView::eventFilter(QObject *obj, QEvent *event) QKeyEvent *ke = static_cast(event); if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier)) { - QModelIndex i = this->transactionView->currentIndex(); - if (i.isValid() && i.column() == TransactionTableModel::Amount) - { - GUIUtil::setClipboard(i.data(TransactionTableModel::FormattedAmountRole).toString()); - return true; - } + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole); + return true; } } return QWidget::eventFilter(obj, event); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index cf2b8fbcd..2cfbd471b 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -94,6 +94,7 @@ private Q_SLOTS: void copyAmount(); void copyTxID(); void copyTxHex(); + void copyTxPlainText(); void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); From 9988554fc76250b1f695c616341c8dd3278c928b Mon Sep 17 00:00:00 2001 From: R E Broadley Date: Fri, 26 Jun 2015 22:38:07 +0300 Subject: [PATCH 0283/1223] No "Unknown command" for getaddr command. --- src/main.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index babdff54e..378c454cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5064,13 +5064,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - // This asymmetric behavior for inbound and outbound connections was introduced - // to prevent a fingerprinting attack: an attacker can send specific fake addresses - // to users' AddrMan and later request them by sending getaddr messages. - // Making nodes which are behind NAT and can only make outgoing connections ignore - // the getaddr message mitigates the attack. - else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) + else if (strCommand == NetMsgType::GETADDR) { + // This asymmetric behavior for inbound and outbound connections was introduced + // to prevent a fingerprinting attack: an attacker can send specific fake addresses + // to users' AddrMan and later request them by sending getaddr messages. + // Making nodes which are behind NAT and can only make outgoing connections ignore + // the getaddr message mitigates the attack. + if (!pfrom->fInbound) { + LogPrint("net", "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->id); + return true; + } + pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); BOOST_FOREACH(const CAddress &addr, vAddr) From d6cc6a1830bb7e03701488ca30c46457434dec6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Thu, 11 Feb 2016 01:07:22 +0000 Subject: [PATCH 0284/1223] Use CCoinControl selection in CWallet::FundTransaction --- src/coincontrol.h | 5 ++--- src/qt/coincontroldialog.cpp | 2 +- src/wallet/wallet.cpp | 13 ++----------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/coincontrol.h b/src/coincontrol.h index 9626ad2c5..12fe9ce21 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -38,10 +38,9 @@ public: return (setSelected.size() > 0); } - bool IsSelected(const uint256& hash, unsigned int n) const + bool IsSelected(const COutPoint& output) const { - COutPoint outpt(hash, n); - return (setSelected.count(outpt) > 0); + return (setSelected.count(output) > 0); } void Select(const COutPoint& output) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 7393c83c7..f90949995 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -796,7 +796,7 @@ void CoinControlDialog::updateView() } // set checkbox - if (coinControl->IsSelected(txhash, out.i)) + if (coinControl->IsSelected(COutPoint(txhash, out.i))) itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8ea957ee3..6c7173ede 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1669,7 +1669,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const isminetype mine = IsMine(pcoin->vout[i]); if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) && - (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i))) + (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected(COutPoint((*it).first, i)))) vCoins.push_back(COutput(pcoin, i, nDepth, ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO))); @@ -1927,16 +1927,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC // Add new txins (keeping original txin scriptSig/order) BOOST_FOREACH(const CTxIn& txin, wtx.vin) { - bool found = false; - BOOST_FOREACH(const CTxIn& origTxIn, tx.vin) - { - if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n) - { - found = true; - break; - } - } - if (!found) + if (!coinControl.IsSelected(txin.prevout)) tx.vin.push_back(txin); } From ce41cf082c861cc8d333b811b3101d52d06f50ec Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Wed, 9 Mar 2016 09:20:16 +0000 Subject: [PATCH 0285/1223] Add curl to Gitian setup instrustions curl is required to fetch dependencies [ci skip] --- doc/gitian-building.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 77882a1b9..54993d13a 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -252,7 +252,7 @@ First we need to log in as `root` to set up dependencies and make sure that our user can use the sudo command. Type/paste the following in the terminal: ```bash -apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring +apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring curl adduser debian sudo ``` From 3252208cb10be645bae415c90fb2ed8217838490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 9 Mar 2016 00:19:16 +0000 Subject: [PATCH 0286/1223] Improve EncodeBase58 performance --- src/base58.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/base58.cpp b/src/base58.cpp index 5e26cf8d4..d81c26092 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -68,26 +68,31 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { // Skip & count leading zeroes. int zeroes = 0; + int length = 0; while (pbegin != pend && *pbegin == 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. - std::vector b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up. + int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. + std::vector b58(size); // Process the bytes. while (pbegin != pend) { int carry = *pbegin; + int i = 0; // Apply "b58 = b58 * 256 + ch". - for (std::vector::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) { + for (std::vector::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } + assert(carry == 0); + length = i; pbegin++; } // Skip leading zeroes in base58 result. - std::vector::iterator it = b58.begin(); + std::vector::iterator it = b58.begin() + (size - length); while (it != b58.end() && *it == 0) it++; // Translate the result into a string. From 7d2f84c72fbb0b19275885badafb3738d44f2e10 Mon Sep 17 00:00:00 2001 From: Pavel Vasin Date: Wed, 9 Mar 2016 19:29:23 +0300 Subject: [PATCH 0287/1223] remove unused NOBLKS_VERSION_{START,END} constants --- src/version.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/version.h b/src/version.h index f7cf18d0b..af2eb8eab 100644 --- a/src/version.h +++ b/src/version.h @@ -24,10 +24,6 @@ static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION; //! if possible, avoid requesting addresses nodes older than this static const int CADDR_TIME_VERSION = 31402; -//! only request blocks from nodes outside this range of versions -static const int NOBLKS_VERSION_START = 32000; -static const int NOBLKS_VERSION_END = 32400; - //! BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; From 8a253b342c5272496926ed391b078742bbe937ae Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 9 Mar 2016 22:30:15 +0100 Subject: [PATCH 0288/1223] Make the generate RPC call function for non-regtest --- src/rpc/client.cpp | 1 + src/rpc/mining.cpp | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index b0e9b6f15..6fe16c0cd 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -30,6 +30,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "setgenerate", 0 }, { "setgenerate", 1 }, { "generate", 0 }, + { "generate", 1 }, { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, { "sendtoaddress", 1 }, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index fec0987a4..a21243443 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -114,13 +114,13 @@ UniValue getgenerate(const UniValue& params, bool fHelp) UniValue generate(const UniValue& params, bool fHelp) { - if (fHelp || params.size() < 1 || params.size() > 1) + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "generate numblocks\n" - "\nMine blocks immediately (before the RPC call returns)\n" - "\nNote: this function can only be used on the regtest network\n" + "generate numblocks ( maxtries )\n" + "\nMine up to numblocks blocks immediately (before the RPC call returns)\n" "\nArguments:\n" "1. numblocks (numeric, required) How many blocks are generated immediately.\n" + "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" "\nResult\n" "[ blockhashes ] (array) hashes of blocks generated\n" "\nExamples:\n" @@ -128,13 +128,15 @@ UniValue generate(const UniValue& params, bool fHelp) + HelpExampleCli("generate", "11") ); - if (!Params().MineBlocksOnDemand()) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); - + static const int nInnerLoopCount = 0x10000; int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); + uint64_t nMaxTries = 1000000; + if (params.size() > 1) { + nMaxTries = params[1].get_int(); + } boost::shared_ptr coinbaseScript; GetMainSignals().ScriptForMining(coinbaseScript); @@ -165,10 +167,15 @@ UniValue generate(const UniValue& params, bool fHelp) LOCK(cs_main); IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { - // Yes, there is a chance every nonce could fail to satisfy the -regtest - // target -- 1 in 2^(2^32). That ain't gonna happen. + while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { ++pblock->nNonce; + --nMaxTries; + } + if (nMaxTries == 0) { + break; + } + if (pblock->nNonce == nInnerLoopCount) { + continue; } CValidationState state; if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) From 2ab835ae6c02de14264896d571c0bba230a1e9f0 Mon Sep 17 00:00:00 2001 From: Elliot Olds Date: Thu, 10 Mar 2016 03:12:40 -0800 Subject: [PATCH 0289/1223] Check if zmq is installed in tests, update docs If ZMQ is enabled, check whether it's installed before running ZMQ tests. If it isn't, disable ZMQ and print a warning. Also add dependency info to test docs, so users know ZMQ is required before running tests, and so they know how to install it. When following the build instructions before this change then trying to run the RPC tests, a unix user would get an error when python tried to import zmq. There may be other dependencies that should be added to the docs, particularly ones for non-unix systems. This is the only unlisted dependency I encountered using linux. --- README.md | 4 ++-- qa/README.md | 11 +++++++++++ qa/pull-tester/rpc-tests.py | 9 +++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5b742534..85b198556 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,10 @@ submit new unit tests for old code. Unit tests can be compiled and run There are also [regression and integration tests](/qa) of the RPC interface, written in Python, that are run automatically on the build server. -These tests can be run with: `qa/pull-tester/rpc-tests.py` +These tests can be run (if the [test dependencies](/qa) are installed) with: `qa/pull-tester/rpc-tests.py` The Travis CI system makes sure that every pull request is built for Windows -and Linux, OSX, and that unit and sanity tests are automatically run. +and Linux, OS X, and that unit and sanity tests are automatically run. ### Manual Quality Assurance (QA) Testing diff --git a/qa/README.md b/qa/README.md index 758d1f47e..2b476c4d8 100644 --- a/qa/README.md +++ b/qa/README.md @@ -5,6 +5,17 @@ Every pull request to the bitcoin repository is built and run through the regression test suite. You can also run all or only individual tests locally. +Test dependencies +================= +Before running the tests, the following must be installed. + +Unix +---- +The python-zmq library is required. On Ubuntu or Debian it can be installed via: +``` +sudo apt-get install python-zmq +``` + Running tests ============= diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 7649c1183..485888e9b 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -40,6 +40,15 @@ if not vars().has_key('ENABLE_UTILS'): ENABLE_UTILS=0 if not vars().has_key('ENABLE_ZMQ'): ENABLE_ZMQ=0 + +# python-zmq may not be installed. Handle this gracefully and with some helpful info +if ENABLE_ZMQ: + try: + import zmq + except ImportError: + print("WARNING: \"import zmq\" failed. Setting ENABLE_ZMQ=0. " \ + "To run zmq tests, see dependency info in /qa/README.md.") + ENABLE_ZMQ=0 ENABLE_COVERAGE=0 From 393b22eacb8aff58aaa4da48085f3ea37424ba59 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 11 Mar 2016 12:03:45 +0000 Subject: [PATCH 0290/1223] Add a source file for unit test utils. --- src/test/testutil.cpp | 3 +++ src/test/testutil.h | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/test/testutil.cpp create mode 100644 src/test/testutil.h diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp new file mode 100644 index 000000000..de01228f0 --- /dev/null +++ b/src/test/testutil.cpp @@ -0,0 +1,3 @@ +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/testutil.h b/src/test/testutil.h new file mode 100644 index 000000000..2e83115e5 --- /dev/null +++ b/src/test/testutil.h @@ -0,0 +1,11 @@ +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/** + * Utility functions shared by unit tests + */ +#ifndef BITCOIN_TEST_TESTUTIL_H +#define BITCOIN_TEST_TESTUTIL_H + +#endif // BITCOIN_TEST_TESTUTIL_H From fc7c60d6998a330966ffe99274c93b5278ed2ee1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 22 Feb 2016 12:07:55 +0100 Subject: [PATCH 0291/1223] [Wallet] move "load wallet phase" to CWallet --- src/init.cpp | 153 +++--------------------------------------- src/wallet/wallet.cpp | 150 +++++++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 3 + 3 files changed, 163 insertions(+), 143 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 6973574cf..0fd8de08c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1424,149 +1424,16 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pwalletMain = NULL; LogPrintf("Wallet disabled!\n"); } else { - - // needed to restore wallet transaction meta data after -zapwallettxes - std::vector vWtx; - - if (GetBoolArg("-zapwallettxes", false)) { - uiInterface.InitMessage(_("Zapping all transactions from wallet...")); - - pwalletMain = new CWallet(strWalletFile); - DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx); - if (nZapWalletRet != DB_LOAD_OK) { - uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); - return false; - } - - delete pwalletMain; - pwalletMain = NULL; - } - - uiInterface.InitMessage(_("Loading wallet...")); - - nStart = GetTimeMillis(); - bool fFirstRun = true; - pwalletMain = new CWallet(strWalletFile); - DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); - if (nLoadWalletRet != DB_LOAD_OK) - { - if (nLoadWalletRet == DB_CORRUPT) - strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; - else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) - { - InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data" - " or address book entries might be missing or incorrect.")); - } - else if (nLoadWalletRet == DB_TOO_NEW) - strErrors << strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) << "\n"; - else if (nLoadWalletRet == DB_NEED_REWRITE) - { - strErrors << strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) << "\n"; - LogPrintf("%s", strErrors.str()); - return InitError(strErrors.str()); - } - else - strErrors << _("Error loading wallet.dat") << "\n"; - } - - if (GetBoolArg("-upgradewallet", fFirstRun)) - { - int nMaxVersion = GetArg("-upgradewallet", 0); - if (nMaxVersion == 0) // the -upgradewallet without argument case - { - LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); - nMaxVersion = CLIENT_VERSION; - pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately - } - else - LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); - if (nMaxVersion < pwalletMain->GetVersion()) - strErrors << _("Cannot downgrade wallet") << "\n"; - pwalletMain->SetMaxVersion(nMaxVersion); - } - - if (fFirstRun) - { - // Create new keyUser and set as default key - RandAddSeedPerfmon(); - - CPubKey newDefaultKey; - if (pwalletMain->GetKeyFromPool(newDefaultKey)) { - pwalletMain->SetDefaultKey(newDefaultKey); - if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive")) - strErrors << _("Cannot write default address") << "\n"; - } - - pwalletMain->SetBestChain(chainActive.GetLocator()); - } - - LogPrintf("%s", strErrors.str()); - LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); - - RegisterValidationInterface(pwalletMain); - - CBlockIndex *pindexRescan = chainActive.Tip(); - if (GetBoolArg("-rescan", false)) - pindexRescan = chainActive.Genesis(); - else - { - CWalletDB walletdb(strWalletFile); - CBlockLocator locator; - if (walletdb.ReadBestBlock(locator)) - pindexRescan = FindForkInGlobalIndex(chainActive, locator); - else - pindexRescan = chainActive.Genesis(); - } - if (chainActive.Tip() && chainActive.Tip() != pindexRescan) - { - //We can't rescan beyond non-pruned blocks, stop and throw an error - //this might happen if a user uses a old wallet within a pruned node - // or if he ran -disablewallet for a longer time, then decided to re-enable - if (fPruneMode) - { - CBlockIndex *block = chainActive.Tip(); - while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block) - block = block->pprev; - - if (pindexRescan != block) - return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); - } - - uiInterface.InitMessage(_("Rescanning...")); - LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight); - nStart = GetTimeMillis(); - pwalletMain->ScanForWalletTransactions(pindexRescan, true); - LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); - pwalletMain->SetBestChain(chainActive.GetLocator()); - nWalletDBUpdated++; - - // Restore wallet transaction metadata after -zapwallettxes=1 - if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") - { - CWalletDB walletdb(strWalletFile); - - BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) - { - uint256 hash = wtxOld.GetHash(); - std::map::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi != pwalletMain->mapWallet.end()) - { - const CWalletTx* copyFrom = &wtxOld; - CWalletTx* copyTo = &mi->second; - copyTo->mapValue = copyFrom->mapValue; - copyTo->vOrderForm = copyFrom->vOrderForm; - copyTo->nTimeReceived = copyFrom->nTimeReceived; - copyTo->nTimeSmart = copyFrom->nTimeSmart; - copyTo->fFromMe = copyFrom->fFromMe; - copyTo->strFromAccount = copyFrom->strFromAccount; - copyTo->nOrderPos = copyFrom->nOrderPos; - copyTo->WriteToDisk(&walletdb); - } - } - } - } - pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); - } // (!fDisableWallet) + std::string warningString; + std::string errorString; + pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString); + if (!pwalletMain) + return false; + if (!warningString.empty()) + InitWarning(warningString); + if (!errorString.empty()) + return InitError(errorString); + } #else // ENABLE_WALLET LogPrintf("No wallet support compiled in!\n"); #endif // !ENABLE_WALLET diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6ce7fcbb2..56287d4f4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2991,6 +2991,156 @@ std::string CWallet::GetWalletHelpString(bool showDebug) return strUsage; } +CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString) +{ + // needed to restore wallet transaction meta data after -zapwallettxes + std::vector vWtx; + + if (GetBoolArg("-zapwallettxes", false)) { + uiInterface.InitMessage(_("Zapping all transactions from wallet...")); + + CWallet *tempWallet = new CWallet(strWalletFile); + DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); + if (nZapWalletRet != DB_LOAD_OK) { + uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); + return NULL; + } + + delete tempWallet; + tempWallet = NULL; + } + + uiInterface.InitMessage(_("Loading wallet...")); + + int64_t nStart = GetTimeMillis(); + bool fFirstRun = true; + CWallet *walletInstance = new CWallet(strWalletFile); + DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) + { + if (nLoadWalletRet == DB_CORRUPT) + errorString += _("Error loading wallet.dat: Wallet corrupted") + "\n"; + else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) + { + warningString += _("Error reading wallet.dat! All keys read correctly, but transaction data" + " or address book entries might be missing or incorrect."); + } + else if (nLoadWalletRet == DB_TOO_NEW) + errorString += strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) + "\n"; + else if (nLoadWalletRet == DB_NEED_REWRITE) + { + errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n"; + LogPrintf("%s", errorString); + return walletInstance; + } + else + errorString += _("Error loading wallet.dat") + "\n"; + } + + if (GetBoolArg("-upgradewallet", fFirstRun)) + { + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = CLIENT_VERSION; + walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } + else + LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < walletInstance->GetVersion()) + errorString += _("Cannot downgrade wallet") + "\n"; + walletInstance->SetMaxVersion(nMaxVersion); + } + + if (fFirstRun) + { + // Create new keyUser and set as default key + RandAddSeedPerfmon(); + + CPubKey newDefaultKey; + if (walletInstance->GetKeyFromPool(newDefaultKey)) { + walletInstance->SetDefaultKey(newDefaultKey); + if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) + errorString += _("Cannot write default address") += "\n"; + } + + walletInstance->SetBestChain(chainActive.GetLocator()); + } + + LogPrintf("%s", errorString); + LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); + + RegisterValidationInterface(walletInstance); + + CBlockIndex *pindexRescan = chainActive.Tip(); + if (GetBoolArg("-rescan", false)) + pindexRescan = chainActive.Genesis(); + else + { + CWalletDB walletdb(strWalletFile); + CBlockLocator locator; + if (walletdb.ReadBestBlock(locator)) + pindexRescan = FindForkInGlobalIndex(chainActive, locator); + else + pindexRescan = chainActive.Genesis(); + } + if (chainActive.Tip() && chainActive.Tip() != pindexRescan) + { + //We can't rescan beyond non-pruned blocks, stop and throw an error + //this might happen if a user uses a old wallet within a pruned node + // or if he ran -disablewallet for a longer time, then decided to re-enable + if (fPruneMode) + { + CBlockIndex *block = chainActive.Tip(); + while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block) + block = block->pprev; + + if (pindexRescan != block) + { + errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"); + return walletInstance; + } + } + + uiInterface.InitMessage(_("Rescanning...")); + LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight); + nStart = GetTimeMillis(); + walletInstance->ScanForWalletTransactions(pindexRescan, true); + LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); + walletInstance->SetBestChain(chainActive.GetLocator()); + nWalletDBUpdated++; + + // Restore wallet transaction metadata after -zapwallettxes=1 + if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") + { + CWalletDB walletdb(strWalletFile); + + BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) + { + uint256 hash = wtxOld.GetHash(); + std::map::iterator mi = walletInstance->mapWallet.find(hash); + if (mi != walletInstance->mapWallet.end()) + { + const CWalletTx* copyFrom = &wtxOld; + CWalletTx* copyTo = &mi->second; + copyTo->mapValue = copyFrom->mapValue; + copyTo->vOrderForm = copyFrom->vOrderForm; + copyTo->nTimeReceived = copyFrom->nTimeReceived; + copyTo->nTimeSmart = copyFrom->nTimeSmart; + copyTo->fFromMe = copyFrom->fFromMe; + copyTo->strFromAccount = copyFrom->strFromAccount; + copyTo->nOrderPos = copyFrom->nOrderPos; + copyTo->WriteToDisk(&walletdb); + } + } + } + } + walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); + + return walletInstance; +} + CKeyPool::CKeyPool() { nTime = GetTime(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6312735c9..d009211a9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -874,6 +874,9 @@ public: /* Returns the wallets help message */ static std::string GetWalletHelpString(bool showDebug); + + /* initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ + static CWallet* InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString); }; /** A key allocated from the key pool. */ From 2fdaa255295402d24bb16a72b07cc72c9a5df8e4 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 11 Mar 2016 15:04:05 +0000 Subject: [PATCH 0292/1223] Move GetTempPath() to testutil. --- src/Makefile.test.include | 2 ++ src/test/alert_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 3 ++- src/test/testutil.cpp | 30 ++++++++++++++++++++++++++++++ src/test/testutil.h | 4 ++++ src/util.cpp | 22 ---------------------- src/util.h | 1 - 7 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 6ef6a69a2..0c4e47a14 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -78,6 +78,8 @@ BITCOIN_TESTS =\ test/streams_tests.cpp \ test/test_bitcoin.cpp \ test/test_bitcoin.h \ + test/testutil.cpp \ + test/testutil.h \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ test/txvalidationcache_tests.cpp \ diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 0895ef332..87d35be41 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -12,9 +12,9 @@ #include "main.h" // For PartitionCheck #include "serialize.h" #include "streams.h" -#include "util.h" #include "utilstrencodings.h" +#include "test/testutil.h" #include "test/test_bitcoin.h" #include diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 0416d0c92..39586d7bb 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -17,12 +17,13 @@ #include "txdb.h" #include "txmempool.h" #include "ui_interface.h" -#include "util.h" #ifdef ENABLE_WALLET #include "wallet/db.h" #include "wallet/wallet.h" #endif +#include "test/testutil.h" + #include #include #include diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp index de01228f0..304cffb79 100644 --- a/src/test/testutil.cpp +++ b/src/test/testutil.cpp @@ -1,3 +1,33 @@ // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "testutil.h" + +#ifdef WIN32 +#include +#endif + +#include + +boost::filesystem::path GetTempPath() { +#if BOOST_FILESYSTEM_VERSION == 3 + return boost::filesystem::temp_directory_path(); +#else + // TODO: remove when we don't support filesystem v2 anymore + boost::filesystem::path path; +#ifdef WIN32 + char pszPath[MAX_PATH] = ""; + + if (GetTempPathA(MAX_PATH, pszPath)) + path = boost::filesystem::path(pszPath); +#else + path = boost::filesystem::path("/tmp"); +#endif + if (path.empty() || !boost::filesystem::is_directory(path)) { + LogPrintf("GetTempPath(): failed to find temp path\n"); + return boost::filesystem::path(""); + } + return path; +#endif +} diff --git a/src/test/testutil.h b/src/test/testutil.h index 2e83115e5..5875dc50e 100644 --- a/src/test/testutil.h +++ b/src/test/testutil.h @@ -8,4 +8,8 @@ #ifndef BITCOIN_TEST_TESTUTIL_H #define BITCOIN_TEST_TESTUTIL_H +#include + +boost::filesystem::path GetTempPath(); + #endif // BITCOIN_TEST_TESTUTIL_H diff --git a/src/util.cpp b/src/util.cpp index 492697e12..59f58f2c5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -738,28 +738,6 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif -boost::filesystem::path GetTempPath() { -#if BOOST_FILESYSTEM_VERSION == 3 - return boost::filesystem::temp_directory_path(); -#else - // TODO: remove when we don't support filesystem v2 anymore - boost::filesystem::path path; -#ifdef WIN32 - char pszPath[MAX_PATH] = ""; - - if (GetTempPathA(MAX_PATH, pszPath)) - path = boost::filesystem::path(pszPath); -#else - path = boost::filesystem::path("/tmp"); -#endif - if (path.empty() || !boost::filesystem::is_directory(path)) { - LogPrintf("GetTempPath(): failed to find temp path\n"); - return boost::filesystem::path(""); - } - return path; -#endif -} - void runCommand(const std::string& strCommand) { int nErr = ::system(strCommand.c_str()); diff --git a/src/util.h b/src/util.h index 9da8fdf87..ac099f118 100644 --- a/src/util.h +++ b/src/util.h @@ -133,7 +133,6 @@ void ReadConfigFile(std::map& mapSettingsRet, std::map #ifdef WIN32 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif -boost::filesystem::path GetTempPath(); void OpenDebugLog(); void ShrinkDebugFile(); void runCommand(const std::string& strCommand); From 21e45a097e154be6be4a503f2181896c5f761385 Mon Sep 17 00:00:00 2001 From: Andrew C Date: Fri, 11 Mar 2016 11:57:10 -0500 Subject: [PATCH 0293/1223] Fix history deletion bug after font change The history is no longer cleared after the font size is changed --- src/qt/rpcconsole.cpp | 11 +++++++---- src/qt/rpcconsole.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 4e2530ffa..90c555ccc 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -490,16 +490,19 @@ void RPCConsole::setFontSize(int newSize) // clear console (reset icon sizes, default stylesheet) and re-add the content float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value(); - clear(); + clear(false); ui->messagesWidget->setHtml(str); ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum()); } -void RPCConsole::clear() +void RPCConsole::clear(bool clearHistory) { ui->messagesWidget->clear(); - history.clear(); - historyPtr = 0; + if(clearHistory) + { + history.clear(); + historyPtr = 0; + } ui->lineEdit->clear(); ui->lineEdit->setFocus(); diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 648e32638..b7a786822 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -77,7 +77,7 @@ private Q_SLOTS: void clearSelectedNode(); public Q_SLOTS: - void clear(); + void clear(bool clearHistory = true); void fontBigger(); void fontSmaller(); void setFontSize(int newSize); From ce7413fcb7d28bd72e5ade7dc9756504de766fc2 Mon Sep 17 00:00:00 2001 From: Luv Khemani Date: Sat, 27 Feb 2016 11:57:12 +0800 Subject: [PATCH 0294/1223] Add autocomplete to bitcoin-qt's console window. Removed externs Added listCommands() to CRPCTable Move autocomplete init to RPCConsole::setClientModel() --- src/qt/rpcconsole.cpp | 15 ++++++++++++++- src/qt/rpcconsole.h | 2 ++ src/rpc/server.cpp | 11 +++++++++++ src/rpc/server.h | 6 ++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 4e2530ffa..e40d14464 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #if QT_VERSION < 0x050000 #include @@ -446,7 +447,19 @@ void RPCConsole::setClientModel(ClientModel *model) ui->buildDate->setText(model->formatBuildDate()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); - } + + //Setup autocomplete and attach it + QStringList wordList; + std::vector commandList = tableRPC.listCommands(); + for (size_t i = 0; i < commandList.size(); ++i) + { + wordList << commandList[i].c_str(); + } + + autoCompleter = new QCompleter(wordList, this); + ui->lineEdit->setCompleter(autoCompleter); + + } } static QString categoryClass(int category) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 648e32638..ad10ec12a 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -11,6 +11,7 @@ #include "net.h" #include +#include class ClientModel; class PlatformStyle; @@ -138,6 +139,7 @@ private: QMenu *peersTableContextMenu; QMenu *banTableContextMenu; int consoleFontSize; + QCompleter *autoCompleter; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index b2d4559cc..e6fae263b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -499,6 +499,17 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms g_rpcSignals.PostCommand(*pcmd); } +std::vector CRPCTable::listCommands() const +{ + std::vector commandList; + typedef std::map commandMap; + + std::transform( mapCommands.begin(), mapCommands.end(), + std::back_inserter(commandList), + boost::bind(&commandMap::value_type::first,_1) ); + return commandList; +} + std::string HelpExampleCli(const std::string& methodname, const std::string& args) { return "> bitcoin-cli " + methodname + " " + args + "\n"; diff --git a/src/rpc/server.h b/src/rpc/server.h index 99ffad5d4..3f46841c4 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -145,6 +145,12 @@ public: */ UniValue execute(const std::string &method, const UniValue ¶ms) const; + /** + * Returns a list of registered commands + * @returns List of registered commands. + */ + std::vector listCommands() const; + /** * Appends a CRPCCommand to the dispatch table. From a6ee0caa4e5a6459f49995ac2dfd40e2444f7c04 Mon Sep 17 00:00:00 2001 From: Pavel Vasin Date: Sat, 12 Mar 2016 17:11:59 +0300 Subject: [PATCH 0295/1223] use cached block hash in blockToJSON() --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index de6bda4ea..da57973da 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -89,7 +89,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) From 15e6e13624e3bd322db67861ec27bd5f9d18b6e8 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 5 Mar 2016 16:08:10 -0500 Subject: [PATCH 0296/1223] [Wallet] optimize return value of InitLoadWallet() --- src/init.cpp | 7 +++++-- src/wallet/wallet.cpp | 14 +++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 0fd8de08c..ba9860014 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1427,12 +1427,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string warningString; std::string errorString; pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString); - if (!pwalletMain) - return false; if (!warningString.empty()) InitWarning(warningString); if (!errorString.empty()) + { + LogPrintf("%s", errorString); return InitError(errorString); + } + if (!pwalletMain) + return false; } #else // ENABLE_WALLET LogPrintf("No wallet support compiled in!\n"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 56287d4f4..d409d7480 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3002,6 +3002,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall CWallet *tempWallet = new CWallet(strWalletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { + errorString = _("Error loading wallet.dat: Wallet corrupted"); uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); return NULL; } @@ -3031,10 +3032,12 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall { errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n"; LogPrintf("%s", errorString); - return walletInstance; } else errorString += _("Error loading wallet.dat") + "\n"; + + if (!errorString.empty()) + return NULL; } if (GetBoolArg("-upgradewallet", fFirstRun)) @@ -3049,7 +3052,10 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall else LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); if (nMaxVersion < walletInstance->GetVersion()) + { errorString += _("Cannot downgrade wallet") + "\n"; + return NULL; + } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3062,13 +3068,15 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) + { errorString += _("Cannot write default address") += "\n"; + return NULL; + } } walletInstance->SetBestChain(chainActive.GetLocator()); } - LogPrintf("%s", errorString); LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); RegisterValidationInterface(walletInstance); @@ -3099,7 +3107,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall if (pindexRescan != block) { errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"); - return walletInstance; + return NULL; } } From 322a7a2fe031b66988d09fbac00c260ab78e7144 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 14 Mar 2016 12:46:59 +0100 Subject: [PATCH 0297/1223] qt: Remove reflection from `about` icon While trying to find a black/white version of the Bitcoin logo for the organization I noticed the about.png is not entirely black - it has some reflection. Remove this to make it the same as other icons. Also ran the icons through `contrib/devtools/optimize-pngs.py`, so `chevron.png` was optimized too. --- src/qt/res/icons/about.png | Bin 4726 -> 3717 bytes src/qt/res/icons/chevron.png | Bin 1923 -> 803 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png index 83eb3c07ee560450b04816fe3713a4203e3b6213..4143be8baca0d49d143959bf010273383603bba8 100644 GIT binary patch delta 3717 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 literal 4726 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 LMFvhpu0mjf!{l_- literal 1923 zcmaJ?dr%YS77vlw@M@$)D2*d)C{}Fqf;>pZG$jdv6oLXlP(cmZg`|+|k}PKBC4z+O zwNItfiq)bPMQIUleV|lG=pAe&lwijxVp~?Y1!}p%?WAB4uHC5E`-iEtE1JiOSY&02HtV0t9RUOV5qr0U|M*C*X^DyjOr2E-#kD<8oreEFMq7 z7fEU}D)Rl5^`IO&iTF0tr|#^pzPQy~(C1=69gMGM14i>J830Hd(g z03(1x0j$yJ^hUGSj(!NxXe4U071f#bkXk8a5)^Es5tJxnxO@RWjxQI-iFmvOfmke8 zsZ;`Pypk)I^Mry$tP<9jm>@H{hz0+|3jPx7odpv@WL82J;|>T^Szr_Jux5$zDOzHM z3G!Hhis0kNK3&TrEcg^HkFmnP#BvBR9B*g;r_+lrVtl;YCv!^}PbMES6XR|n<~ls{ zR}XPrX4J}fEjBcHxIZ~Fo_=+FD5I@W7@9EB)5y*BWYkg%gMEX+v^?m%;r6!eEyDAL z%-%N`N@bU0^Pb)I4Pck>lHuq8ZJ&c$e|^pMZ+hvw|NOC{8AJwkf9Y!mU#(=2F>O{vc%kRxQ zih-^zOu}*o`InpVmsrjteie!dM@X18dRddUTLwE`X30ude6i1d3OG*BD#lut4A#PO zT5Wy9J(v5{I+JRm0zd3O|M7)5vn?tr$r*1G*w?4kk8D1G3lZC-9vk`j%Gr~{zEf{i zBpsZ-_v}x;3)@|eZDp0TJ(WS_aU1c9lqn0PJcVDJcyLVByJ<}RL%9BpU9w(x6nR^+ zj`5Nwo zTfaPl(Ve#tJa**m2fz1z{^OScFOV-TL)kaJtwU=)3E(03A?KGacSKE#o@8#WyU10X zp~%kpNb7Tps1*$C-SD}{xeMURxI3{4oR8dv%_mRV@1Fkf+n;`hZT-uf!w8vTN7a24sQ0r!iY zjDNlJQ}7F@Tc_{e+84-B3=DjFawaa}R)66A=%C2s!ia_tf5!3m*5(hk``BDFHBG-w z_mQ{Hc2qB9T|N;$-jM$}X;8X)e`eWd$phC~ipW=ox+7M*t5ZKaa^ud;O*dAPW}-sW z743Jcrm6Goq``5`i)H0#*cR|Uzdz|~ckYrY?&Xl1jOh~9?9ea9=QdGV$D3SvSpm!b zonpO-HGJ=PKo*|#NsiC3)3>80eaBf#=AD^}Ro326&%S>QGCC`{EK!#9d(q?)`|Y+Q zbzwtiYgc!hb=R7CmsST~!y8tNQjI3*FhPzSyMAg~k6Ve`kH}M#*W Date: Fri, 26 Feb 2016 12:48:53 +0100 Subject: [PATCH 0298/1223] [wallet] Move hardcoded file name out of log messages --- src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.cpp | 30 +++++++++++++++++------------- src/wallet/walletdb.cpp | 18 +++++++++--------- src/wallet/walletdb.h | 2 +- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f54ceb689..759f894cc 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -394,7 +394,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, strError); } if (!pwalletMain->CommitTransaction(wtxNew, reservekey)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of the wallet and coins were spent in the copy but not marked as spent here."); } UniValue sendtoaddress(const UniValue& params, bool fHelp) @@ -1827,7 +1827,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" - "\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n" + "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n" "\nArguments:\n" "1. \"destination\" (string) The destination directory or file\n" "\nExamples:\n" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d409d7480..bcfefa27f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -399,13 +399,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { - warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!" - " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" - " your balance or transactions are incorrect you should" - " restore from a backup."), GetDataDir()); + warningString += strprintf(_("Warning: Wallet file corrupt, data salvaged!" + " Original %s saved as %s in %s; if" + " your balance or transactions are incorrect you should" + " restore from a backup."), + walletFile, "wallet.{timestamp}.bak", GetDataDir()); } if (r == CDBEnv::RECOVER_FAIL) - errorString += _("wallet.dat corrupt, salvage failed"); + errorString += strprintf(_("%s corrupt, salvage failed"), walletFile); } return true; @@ -2968,7 +2969,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); @@ -3002,8 +3003,8 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall CWallet *tempWallet = new CWallet(strWalletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { - errorString = _("Error loading wallet.dat: Wallet corrupted"); - uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); + errorString = strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile); + uiInterface.InitMessage(strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile)); return NULL; } @@ -3020,21 +3021,24 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) - errorString += _("Error loading wallet.dat: Wallet corrupted") + "\n"; + errorString += strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile) + "\n"; else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - warningString += _("Error reading wallet.dat! All keys read correctly, but transaction data" - " or address book entries might be missing or incorrect."); + warningString += strprintf(_("Error reading %s! All keys read correctly, but transaction data" + " or address book entries might be missing or incorrect."), + strWalletFile); } else if (nLoadWalletRet == DB_TOO_NEW) - errorString += strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) + "\n"; + errorString += strprintf(_("Error loading %s: Wallet requires newer version of %s"), + strWalletFile, _(PACKAGE_NAME)) + + "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) { errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n"; LogPrintf("%s", errorString); } else - errorString += _("Error loading wallet.dat") + "\n"; + errorString += strprintf(_("Error loading %s"), strWalletFile) + "\n"; if (!errorString.empty()) return NULL; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 67511976d..0a4a1dae2 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -847,16 +847,16 @@ void ThreadFlushWalletDB(const string& strFile) map::iterator mi = bitdb.mapFileUseCount.find(strFile); if (mi != bitdb.mapFileUseCount.end()) { - LogPrint("db", "Flushing wallet.dat\n"); + LogPrint("db", "Flushing %s\n", strFile); nLastFlushed = nWalletDBUpdated; int64_t nStart = GetTimeMillis(); - // Flush wallet.dat so it's self contained + // Flush wallet file so it's self contained bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); bitdb.mapFileUseCount.erase(mi++); - LogPrint("db", "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart); + LogPrint("db", "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart); } } } @@ -879,7 +879,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) bitdb.CheckpointLSN(wallet.strWalletFile); bitdb.mapFileUseCount.erase(wallet.strWalletFile); - // Copy wallet.dat + // Copy wallet file boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; boost::filesystem::path pathDest(strDest); if (boost::filesystem::is_directory(pathDest)) @@ -891,10 +891,10 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) #else boost::filesystem::copy_file(pathSrc, pathDest); #endif - LogPrintf("copied wallet.dat to %s\n", pathDest.string()); + LogPrintf("copied %s to %s\n", wallet.strWalletFile, pathDest.string()); return true; } catch (const boost::filesystem::filesystem_error& e) { - LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); + LogPrintf("error copying %s to %s - %s\n", wallet.strWalletFile, pathDest.string(), e.what()); return false; } } @@ -905,15 +905,15 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) } // -// Try to (very carefully!) recover wallet.dat if there is a problem. +// Try to (very carefully!) recover wallet file if there is a problem. // bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys) { // Recovery procedure: - // move wallet.dat to wallet.timestamp.bak + // move wallet file to wallet.timestamp.bak // Call Salvage with fAggressive=true to // get as much data as possible. - // Rewrite salvaged data to wallet.dat + // Rewrite salvaged data to fresh wallet file // Set -rescan so any missing transactions will be // found. int64_t now = GetTime(); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 8da33dead..7e8cc4084 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -73,7 +73,7 @@ public: } }; -/** Access to the wallet database (wallet.dat) */ +/** Access to the wallet database */ class CWalletDB : public CDB { public: From fa3a81af18347a1d3fed41aa89ee643cbf0e7abc Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 19 Jan 2016 17:47:55 +0100 Subject: [PATCH 0299/1223] [tests] Extend util_ParseMoney test case --- src/test/util_tests.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 43e8ae9b3..b99f952a0 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -200,6 +200,8 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney) BOOST_CHECK_EQUAL(ret, COIN*10); BOOST_CHECK(ParseMoney("1.00", ret)); BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney("1", ret)); + BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK(ParseMoney("0.1", ret)); BOOST_CHECK_EQUAL(ret, COIN/10); BOOST_CHECK(ParseMoney("0.01", ret)); @@ -219,6 +221,9 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney) // Attempted 63 bit overflow should fail BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); + + // Parsing negative amounts must fail + BOOST_CHECK(!ParseMoney("-1", ret)); } BOOST_AUTO_TEST_CASE(util_IsHex) From 3d7e97376aad055de0af7dc09abf3ee80e734740 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 14 Mar 2016 16:07:42 +0100 Subject: [PATCH 0300/1223] Fix torcontrol.cpp unused private field warning --- src/torcontrol.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index f755992a3..1c7bc2dbe 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -393,8 +393,8 @@ private: static void reconnect_cb(evutil_socket_t fd, short what, void *arg); }; -TorController::TorController(struct event_base* base, const std::string& target): - base(base), +TorController::TorController(struct event_base* baseIn, const std::string& target): + base(baseIn), target(target), conn(base), reconnect(true), reconnect_ev(0), reconnect_timeout(RECONNECT_TIMEOUT_START) { From fad7dc8a6c0ca9c067a249cf8896dd2e64703e48 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 16 Jan 2016 23:14:49 +0100 Subject: [PATCH 0301/1223] [qa] wallet: speed up tests --- qa/rpc-tests/wallet.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 6cd879e4a..3cd495deb 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -267,10 +267,6 @@ class WalletTest (BitcoinTestFramework): stop_nodes(self.nodes) wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - self.sync_all() assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) From fa8cd46f39778925eaf2caf812cccd9fb8503368 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 4 Jan 2016 13:54:23 +0100 Subject: [PATCH 0302/1223] [qa] Move create_tx() to util.py --- qa/rpc-tests/mempool_reorg.py | 18 +++++------------- qa/rpc-tests/mempool_resurrect_test.py | 12 ++---------- qa/rpc-tests/mempool_spendcoinbase.py | 10 +--------- qa/rpc-tests/test_framework/util.py | 8 ++++++++ 4 files changed, 16 insertions(+), 32 deletions(-) diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index 40684e7fb..5e9856e5d 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -25,14 +25,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.is_network_split = False self.sync_all() - def create_tx(self, from_txid, to_address, amount): - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - signresult = self.nodes[0].signrawtransaction(rawtx) - assert_equal(signresult["complete"], True) - return signresult["hex"] - def run_test(self): start_count = self.nodes[0].getblockcount() @@ -52,9 +44,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # and make sure the mempool code behaves correctly. b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 49.99) - spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 49.99) - spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 49.99) + spend_101_raw = create_tx(self.nodes[0], coinbase_txids[1], node1_address, 49.99) + spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 49.99) + spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 49.99) # Create a block-height-locked transaction which will be invalid after reorg timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99}) @@ -71,8 +63,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework): assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: - spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 49.98) - spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 49.98) + spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 49.98) + spend_103_1_raw = create_tx(self.nodes[0], spend_103_id, node1_address, 49.98) # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 9fcc88a2a..0ba46e6f5 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -21,14 +21,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.nodes.append(start_node(0, self.options.tmpdir, args)) self.is_network_split = False - def create_tx(self, from_txid, to_address, amount): - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - signresult = self.nodes[0].signrawtransaction(rawtx) - assert_equal(signresult["complete"], True) - return signresult["hex"] - def run_test(self): node0_address = self.nodes[0].getnewaddress() # Spend block 1/2/3's coinbase transactions @@ -43,13 +35,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework): b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends1_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] + spends1_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.99) for txid in coinbase_txids ] spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] blocks = [] blocks.extend(self.nodes[0].generate(1)) - spends2_raw = [ self.create_tx(txid, node0_address, 49.98) for txid in spends1_id ] + spends2_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.98) for txid in spends1_id ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] blocks.extend(self.nodes[0].generate(1)) diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 16f512db3..507b5ff41 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -26,14 +26,6 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): self.nodes.append(start_node(0, self.options.tmpdir, args)) self.is_network_split = False - def create_tx(self, from_txid, to_address, amount): - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = self.nodes[0].createrawtransaction(inputs, outputs) - signresult = self.nodes[0].signrawtransaction(rawtx) - assert_equal(signresult["complete"], True) - return signresult["hex"] - def run_test(self): chain_height = self.nodes[0].getblockcount() assert_equal(chain_height, 200) @@ -44,7 +36,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): # is too immature to spend. b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] + spends_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.99) for txid in coinbase_txids ] spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 8c472a518..ce3102988 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -493,6 +493,14 @@ def gen_return_txouts(): txouts = txouts + script_pubkey return txouts +def create_tx(node, coinbase, to_address, amount): + inputs = [{ "txid" : coinbase, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + assert_equal(signresult["complete"], True) + return signresult["hex"] + def create_lots_of_big_transactions(node, txouts, utxos, fee): addr = node.getnewaddress() txids = [] From fad8cfb893ac0ba83c6fc2367ade55bfe4fa75f6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 22 Dec 2015 10:43:46 +0100 Subject: [PATCH 0303/1223] [qa] mininode: Add and use CONSTs --- qa/rpc-tests/bip68-sequence.py | 1 - qa/rpc-tests/invalidblockrequest.py | 6 +++--- qa/rpc-tests/invalidtxrequest.py | 2 +- qa/rpc-tests/listtransactions.py | 4 ++-- qa/rpc-tests/maxuploadtarget.py | 2 +- qa/rpc-tests/mempool_packages.py | 7 +++---- qa/rpc-tests/prioritise_transaction.py | 2 +- qa/rpc-tests/replace-by-fee.py | 1 - qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/mininode.py | 6 ++++-- 10 files changed, 16 insertions(+), 17 deletions(-) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index bd61282fa..84f941da3 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -13,7 +13,6 @@ from test_framework.script import * from test_framework.mininode import * from test_framework.blocktools import * -COIN = 100000000 SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height) SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index f91a8da01..daad312d3 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -78,8 +78,8 @@ class InvalidBlockRequestTest(ComparisonTestFramework): self.block_time += 1 # chr(81) is OP_TRUE - tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000) - tx2 = create_transaction(tx1, 0, chr(81), 50*100000000) + tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50 * COIN) + tx2 = create_transaction(tx1, 0, chr(81), 50 * COIN) block2.vtx.extend([tx1, tx2]) block2.hashMerkleRoot = block2.calc_merkle_root() @@ -103,7 +103,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): ''' block3 = create_block(self.tip, create_coinbase(height), self.block_time) self.block_time += 1 - block3.vtx[0].vout[0].nValue = 100*100000000 # Too high! + block3.vtx[0].vout[0].nValue = 100 * COIN # Too high! block3.vtx[0].sha256=None block3.vtx[0].calc_sha256() block3.hashMerkleRoot = block3.calc_merkle_root() diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index c2fe4f1df..8fe471ccd 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -63,7 +63,7 @@ class InvalidTxRequestTest(ComparisonTestFramework): # chr(100) is OP_NOTIF # Transaction will be rejected with code 16 (REJECT_INVALID) - tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000 - 12000) + tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50 * COIN - 12000) yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) # TODO: test further transactions... diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 45ede8f04..da1e98dc3 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -7,7 +7,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import CTransaction +from test_framework.mininode import CTransaction, COIN import cStringIO import binascii @@ -192,7 +192,7 @@ class ListTransactionsTest(BitcoinTestFramework): # Replace tx3, and check that tx4 becomes unknown tx3_b = tx3_modified - tx3_b.vout[0].nValue -= 0.004*100000000 # bump the fee + tx3_b.vout[0].nValue -= 0.004 * COIN # bump the fee tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 4d6b343f7..2517bed47 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -176,7 +176,7 @@ class MaxUploadTest(BitcoinTestFramework): getdata_request.inv.append(CInv(2, big_old_block)) max_bytes_per_day = 200*1024*1024 - daily_buffer = 144 * 1000000 + daily_buffer = 144 * MAX_BLOCK_SIZE max_bytes_available = max_bytes_per_day - daily_buffer success_count = max_bytes_available / old_block_size diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 47c1028b9..6109cb026 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -59,13 +59,12 @@ class MempoolPackagesTest(BitcoinTestFramework): descendant_count = 1 descendant_fees = 0 descendant_size = 0 - SATOSHIS = 100000000 for x in reversed(chain): assert_equal(mempool[x]['descendantcount'], descendant_count) descendant_fees += mempool[x]['fee'] assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) - assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees) + assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN) descendant_size += mempool[x]['size'] assert_equal(mempool[x]['descendantsize'], descendant_size) descendant_count += 1 @@ -78,7 +77,7 @@ class MempoolPackagesTest(BitcoinTestFramework): descendant_fees = 0 for x in reversed(chain): descendant_fees += mempool[x]['fee'] - assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+1000) + assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 1000) # Adding one more transaction on to the chain should fail. try: @@ -106,7 +105,7 @@ class MempoolPackagesTest(BitcoinTestFramework): descendant_fees += mempool[x]['fee'] if (x == chain[-1]): assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002)) - assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+2000) + assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 2000) # TODO: check that node1's mempool is as expected diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 4a79d38da..506466705 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -9,8 +9,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import COIN -COIN = 100000000 class PrioritiseTransactionTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index ba1956853..eded24f40 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -13,7 +13,6 @@ from test_framework.script import * from test_framework.mininode import * import binascii -COIN = 100000000 MAX_REPLACEMENT_LIMIT = 100 def satoshi_round(amount): diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 7eea41b75..b075f69c4 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -45,7 +45,7 @@ def create_coinbase(height, pubkey = None): coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), ser_string(serialize_script_num(height)), 0xffffffff)) coinbaseoutput = CTxOut() - coinbaseoutput.nValue = 50*100000000 + coinbaseoutput.nValue = 50 * COIN halvings = int(height/150) # regtest coinbaseoutput.nValue >>= halvings if (pubkey != None): diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 81bb439ce..934d0c7a7 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -38,6 +38,8 @@ MY_SUBVERSION = "/python-mininode-tester:0.0.1/" MAX_INV_SZ = 50000 MAX_BLOCK_SIZE = 1000000 +COIN = 100000000L # 1 btc in satoshis + # Keep our own socket map for asyncore, so that we can track disconnects # ourselves (to workaround an issue with closing an asyncore socket when # using select) @@ -377,7 +379,7 @@ class CTxOut(object): def __repr__(self): return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ - % (self.nValue // 100000000, self.nValue % 100000000, + % (self.nValue // COIN, self.nValue % COIN, binascii.hexlify(self.scriptPubKey)) @@ -426,7 +428,7 @@ class CTransaction(object): def is_valid(self): self.calc_sha256() for tout in self.vout: - if tout.nValue < 0 or tout.nValue > 21000000L * 100000000L: + if tout.nValue < 0 or tout.nValue > 21000000 * COIN: return False return True From 7659438a63ef162b4a4f942f86683ae6785f8162 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 19 Oct 2015 12:42:42 -0400 Subject: [PATCH 0304/1223] CTxMemPool::removeForBlock now uses RemoveStaged --- src/txmempool.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index eee6cbf85..01f6c97ae 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -564,8 +564,12 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigned i } BOOST_FOREACH(const CTransaction& tx, vtx) { - std::list dummy; - remove(tx, dummy, false); + txiter it = mapTx.find(tx.GetHash()); + if (it != mapTx.end()) { + setEntries stage; + stage.insert(it); + RemoveStaged(stage); + } removeConflicts(tx, conflicts); ClearPrioritisation(tx.GetHash()); } From 5de2baa138cda501038a4558bc169b2cfe5b7d6b Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 19 Oct 2015 12:43:38 -0400 Subject: [PATCH 0305/1223] Rename CTxMemPool::remove -> removeRecursive remove is no longer called non-recursively, so simplify the logic and eliminate an unnecessary parameter --- src/main.cpp | 2 +- src/test/mempool_tests.cpp | 20 ++++++++++---------- src/txmempool.cpp | 18 +++++++----------- src/txmempool.h | 2 +- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 027a36394..d5254806a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2502,7 +2502,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons list removed; CValidationState stateDummy; if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { - mempool.remove(tx, removed, true); + mempool.removeRecursive(tx, removed); } else if (mempool.exists(tx.GetHash())) { vHashUpdate.push_back(tx.GetHash()); } diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index fa352ace8..ebdf7dbaa 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -57,12 +57,12 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) std::list removed; // Nothing in pool, remove should do nothing: - testPool.remove(txParent, removed, true); + testPool.removeRecursive(txParent, removed); BOOST_CHECK_EQUAL(removed.size(), 0); // Just the parent: testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); - testPool.remove(txParent, removed, true); + testPool.removeRecursive(txParent, removed); BOOST_CHECK_EQUAL(removed.size(), 1); removed.clear(); @@ -74,16 +74,16 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Remove Child[0], GrandChild[0] should be removed: - testPool.remove(txChild[0], removed, true); + testPool.removeRecursive(txChild[0], removed); BOOST_CHECK_EQUAL(removed.size(), 2); removed.clear(); // ... make sure grandchild and child are gone: - testPool.remove(txGrandChild[0], removed, true); + testPool.removeRecursive(txGrandChild[0], removed); BOOST_CHECK_EQUAL(removed.size(), 0); - testPool.remove(txChild[0], removed, true); + testPool.removeRecursive(txChild[0], removed); BOOST_CHECK_EQUAL(removed.size(), 0); // Remove parent, all children/grandchildren should go: - testPool.remove(txParent, removed, true); + testPool.removeRecursive(txParent, removed); BOOST_CHECK_EQUAL(removed.size(), 5); BOOST_CHECK_EQUAL(testPool.size(), 0); removed.clear(); @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) } // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be // put into the mempool (maybe because it is non-standard): - testPool.remove(txParent, removed, true); + testPool.removeRecursive(txParent, removed); BOOST_CHECK_EQUAL(removed.size(), 6); BOOST_CHECK_EQUAL(testPool.size(), 0); removed.clear(); @@ -281,11 +281,11 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now try removing tx10 and verify the sort order returns to normal std::list removed; - pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); + pool.removeRecursive(pool.mapTx.find(tx10.GetHash())->GetTx(), removed); CheckSort(pool, snapshotOrder); - pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true); - pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true); + pool.removeRecursive(pool.mapTx.find(tx9.GetHash())->GetTx(), removed); + pool.removeRecursive(pool.mapTx.find(tx8.GetHash())->GetTx(), removed); /* Now check the sort on the mining score index. * Final order should be: * diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 01f6c97ae..2d1b78bea 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -461,7 +461,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants } } -void CTxMemPool::remove(const CTransaction &origTx, std::list& removed, bool fRecursive) +void CTxMemPool::removeRecursive(const CTransaction &origTx, std::list& removed) { // Remove transaction from memory pool { @@ -470,8 +470,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem txiter origit = mapTx.find(origTx.GetHash()); if (origit != mapTx.end()) { txToRemove.insert(origit); - } else if (fRecursive) { - // If recursively removing but origTx isn't in the mempool + } else { + // When recursively removing but origTx isn't in the mempool // be sure to remove any children that are in the pool. This can // happen during chain re-orgs if origTx isn't re-accepted into // the mempool for any reason. @@ -485,12 +485,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem } } setEntries setAllRemoves; - if (fRecursive) { - BOOST_FOREACH(txiter it, txToRemove) { - CalculateDescendants(it, setAllRemoves); - } - } else { - setAllRemoves.swap(txToRemove); + BOOST_FOREACH(txiter it, txToRemove) { + CalculateDescendants(it, setAllRemoves); } BOOST_FOREACH(txiter it, setAllRemoves) { removed.push_back(it->GetTx()); @@ -524,7 +520,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem } BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { list removed; - remove(tx, removed, true); + removeRecursive(tx, removed); } } @@ -539,7 +535,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list const CTransaction &txConflict = *it->second.ptx; if (txConflict != tx) { - remove(txConflict, removed, true); + removeRecursive(txConflict, removed); ClearPrioritisation(txConflict.GetHash()); } } diff --git a/src/txmempool.h b/src/txmempool.h index 7a2a1ef43..da5a97649 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -428,7 +428,7 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); - void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); + void removeRecursive(const CTransaction &tx, std::list& removed); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); void removeForBlock(const std::vector& vtx, unsigned int nBlockHeight, From 76a76321d2f36992178ddaaf4d023c5e33c14fbf Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 21 Oct 2015 10:18:24 -0400 Subject: [PATCH 0306/1223] Remove work limit in UpdateForDescendants() The work limit served to prevent the descendant walking algorithm from doing too much work by marking the parent transaction as dirty. However to implement ancestor tracking, it's not possible to similarly mark those descendant transactions as dirty without having to calculate them to begin with. This commit removes the work limit altogether. With appropriate chain limits (-limitdescendantcount) the concern about doing too much work inside this function should be mitigated. --- src/main.cpp | 14 ----------- src/txmempool.cpp | 59 +++++++++-------------------------------------- src/txmempool.h | 19 +-------------- 3 files changed, 12 insertions(+), 80 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d5254806a..7a69d9666 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1194,20 +1194,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // Save these to avoid repeated lookups setIterConflicting.insert(mi); - // If this entry is "dirty", then we don't have descendant - // state for this transaction, which means we probably have - // lots of in-mempool descendants. - // Don't allow replacements of dirty transactions, to ensure - // that we don't spend too much time walking descendants. - // This should be rare. - if (mi->IsDirty()) { - return state.DoS(0, false, - REJECT_NONSTANDARD, "too many potential replacements", false, - strprintf("too many potential replacements: rejecting replacement %s; cannot replace tx %s with untracked descendants", - hash.ToString(), - mi->GetTx().GetHash().ToString())); - } - // Don't allow the replacement to reduce the feerate of the // mempool. // diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 2d1b78bea..693d42667 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -64,21 +64,13 @@ void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) // Update the given tx for any in-mempool descendants. // Assumes that setMemPoolChildren is correct for the given tx and all // descendants. -bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit, cacheMap &cachedDescendants, const std::set &setExclude) +void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set &setExclude) { - // Track the number of entries (outside setExclude) that we'd need to visit - // (will bail out if it exceeds maxDescendantsToVisit) - int nChildrenToVisit = 0; - setEntries stageEntries, setAllDescendants; stageEntries = GetMemPoolChildren(updateIt); while (!stageEntries.empty()) { const txiter cit = *stageEntries.begin(); - if (cit->IsDirty()) { - // Don't consider any more children if any descendant is dirty - return false; - } setAllDescendants.insert(cit); stageEntries.erase(cit); const setEntries &setChildren = GetMemPoolChildren(cit); @@ -88,22 +80,11 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit // We've already calculated this one, just add the entries for this set // but don't traverse again. BOOST_FOREACH(const txiter cacheEntry, cacheIt->second) { - // update visit count only for new child transactions - // (outside of setExclude and stageEntries) - if (setAllDescendants.insert(cacheEntry).second && - !setExclude.count(cacheEntry->GetTx().GetHash()) && - !stageEntries.count(cacheEntry)) { - nChildrenToVisit++; - } + setAllDescendants.insert(cacheEntry); } } else if (!setAllDescendants.count(childEntry)) { - // Schedule for later processing and update our visit count - if (stageEntries.insert(childEntry).second && !setExclude.count(childEntry->GetTx().GetHash())) { - nChildrenToVisit++; - } - } - if (nChildrenToVisit > maxDescendantsToVisit) { - return false; + // Schedule for later processing + stageEntries.insert(childEntry); } } } @@ -121,7 +102,6 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit } } mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); - return true; } // vHashesToUpdate is the set of transaction hashes from a disconnected block @@ -167,10 +147,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes UpdateParent(childIter, it, true); } } - if (!UpdateForDescendants(it, 100, mapMemPoolDescendantsToUpdate, setAlreadyIncluded)) { - // Mark as dirty if we can't do the calculation. - mapTx.modify(it, set_dirty()); - } + UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded); } } @@ -301,22 +278,13 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) } } -void CTxMemPoolEntry::SetDirty() -{ - nCountWithDescendants = 0; - nSizeWithDescendants = nTxSize; - nModFeesWithDescendants = GetModifiedFee(); -} - void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) { - if (!IsDirty()) { - nSizeWithDescendants += modifySize; - assert(int64_t(nSizeWithDescendants) > 0); - nModFeesWithDescendants += modifyFee; - nCountWithDescendants += modifyCount; - assert(int64_t(nCountWithDescendants) > 0); - } + nSizeWithDescendants += modifySize; + assert(int64_t(nSizeWithDescendants) > 0); + nModFeesWithDescendants += modifyFee; + nCountWithDescendants += modifyCount; + assert(int64_t(nCountWithDescendants) > 0); } CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) : @@ -658,12 +626,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(setChildrenCheck == GetMemPoolChildren(it)); // Also check to make sure size is greater than sum with immediate children. // just a sanity check, not definitive that this calc is correct... - if (!it->IsDirty()) { - assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); - } else { - assert(it->GetSizeWithDescendants() == it->GetTxSize()); - assert(it->GetModFeesWithDescendants() == it->GetModifiedFee()); - } + assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); if (fDependsWait) waitingOnDependants.push_back(&(*it)); diff --git a/src/txmempool.h b/src/txmempool.h index da5a97649..b1b6645a0 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -108,13 +108,6 @@ public: // modified fees with descendants. void UpdateFeeDelta(int64_t feeDelta); - /** We can set the entry to be dirty if doing the full calculation of in- - * mempool descendants will be too expensive, which can potentially happen - * when re-adding transactions from a block back to the mempool. - */ - void SetDirty(); - bool IsDirty() const { return nCountWithDescendants == 0; } - uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } @@ -138,12 +131,6 @@ struct update_descendant_state int64_t modifyCount; }; -struct set_dirty -{ - void operator() (CTxMemPoolEntry &e) - { e.SetDirty(); } -}; - struct update_fee_delta { update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } @@ -555,15 +542,11 @@ private: * updated and hence their state is already reflected in the parent * state). * - * If updating an entry requires looking at more than maxDescendantsToVisit - * transactions, outside of the ones in setExclude, then give up. - * * cachedDescendants will be updated with the descendants of the transaction * being updated, so that future invocations don't need to walk the * same transaction again, if encountered in another transaction chain. */ - bool UpdateForDescendants(txiter updateIt, - int maxDescendantsToVisit, + void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set &setExclude); /** Update ancestors of hash to add/remove it as a descendant transaction. */ From 72abd2ce3c5ad8157d3a993693df1919a6ad79c3 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 19 Oct 2015 10:54:28 -0400 Subject: [PATCH 0307/1223] Add ancestor tracking to mempool This implements caching of ancestor state to each mempool entry, similar to descendant tracking, but also including caching sigops-with-ancestors (as that metric will be helpful to future code that implements better transaction selection in CreatenewBlock). --- src/main.cpp | 2 +- src/txmempool.cpp | 88 +++++++++++++++++++++++++++++++++++++++-------- src/txmempool.h | 49 ++++++++++++++++++++++---- 3 files changed, 117 insertions(+), 22 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7a69d9666..2ae560e01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1323,7 +1323,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C FormatMoney(nModifiedFees - nConflictingFees), (int)nSize - (int)nConflictingSize); } - pool.RemoveStaged(allConflicting); + pool.RemoveStaged(allConflicting, false); // Store transaction in memory pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 693d42667..f7961a6b8 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -38,6 +38,11 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, assert(inChainInputValue <= nValueIn); feeDelta = 0; + + nCountWithAncestors = 1; + nSizeWithAncestors = nTxSize; + nModFeesWithAncestors = nFee; + nSigOpCountWithAncestors = sigOpCount; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -58,6 +63,7 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) { nModFeesWithDescendants += newFeeDelta - feeDelta; + nModFeesWithAncestors += newFeeDelta - feeDelta; feeDelta = newFeeDelta; } @@ -99,6 +105,8 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan modifyFee += cit->GetModifiedFee(); modifyCount++; cachedDescendants[updateIt].insert(cit); + // Update ancestor state for each descendant + mapTx.modify(cit, update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCount())); } } mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); @@ -108,6 +116,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan // which has been re-added to the mempool. // for each entry, look for descendants that are outside hashesToUpdate, and // add fee/size information for such descendants to the parent. +// for each such descendant, also update the ancestor state to include the parent. void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashesToUpdate) { LOCK(cs); @@ -228,6 +237,20 @@ void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors } } +void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncestors) +{ + int64_t updateCount = setAncestors.size(); + int64_t updateSize = 0; + CAmount updateFee = 0; + int updateSigOps = 0; + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + updateSize += ancestorIt->GetTxSize(); + updateFee += ancestorIt->GetModifiedFee(); + updateSigOps += ancestorIt->GetSigOpCount(); + } + mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOps)); +} + void CTxMemPool::UpdateChildrenForRemoval(txiter it) { const setEntries &setMemPoolChildren = GetMemPoolChildren(it); @@ -236,11 +259,30 @@ void CTxMemPool::UpdateChildrenForRemoval(txiter it) } } -void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) +void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants) { // For each entry, walk back all ancestors and decrement size associated with this // transaction const uint64_t nNoLimit = std::numeric_limits::max(); + if (updateDescendants) { + // updateDescendants should be true whenever we're not recursively + // removing a tx and all its descendants, eg when a transaction is + // confirmed in a block. + // Here we only update statistics and not data in mapLinks (which + // we need to preserve until we're finished with all operations that + // need to traverse the mempool). + BOOST_FOREACH(txiter removeIt, entriesToRemove) { + setEntries setDescendants; + CalculateDescendants(removeIt, setDescendants); + setDescendants.erase(removeIt); // don't update state for self + int64_t modifySize = -((int64_t)removeIt->GetTxSize()); + CAmount modifyFee = -removeIt->GetModifiedFee(); + int modifySigOps = -removeIt->GetSigOpCount(); + BOOST_FOREACH(txiter dit, setDescendants) { + mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps)); + } + } + } BOOST_FOREACH(txiter removeIt, entriesToRemove) { setEntries setAncestors; const CTxMemPoolEntry &entry = *removeIt; @@ -264,10 +306,7 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) // transactions as the set of things to update for removal. CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); // Note that UpdateAncestorsOf severs the child links that point to - // removeIt in the entries for the parents of removeIt. This is - // fine since we don't need to use the mempool children of any entries - // to walk back over our ancestors (but we do need the mempool - // parents!) + // removeIt in the entries for the parents of removeIt. UpdateAncestorsOf(false, removeIt, setAncestors); } // After updating all the ancestor sizes, we can now sever the link between each @@ -278,7 +317,7 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) } } -void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) +void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) { nSizeWithDescendants += modifySize; assert(int64_t(nSizeWithDescendants) > 0); @@ -287,6 +326,17 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t assert(int64_t(nCountWithDescendants) > 0); } +void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int modifySigOps) +{ + nSizeWithAncestors += modifySize; + assert(int64_t(nSizeWithAncestors) > 0); + nModFeesWithAncestors += modifyFee; + nCountWithAncestors += modifyCount; + assert(int64_t(nCountWithAncestors) > 0); + nSigOpCountWithAncestors += modifySigOps; + assert(int(nSigOpCountWithAncestors) >= 0); +} + CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) : nTransactionsUpdated(0) { @@ -377,6 +427,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, } } UpdateAncestorsOf(true, newit, setAncestors); + UpdateEntryForAncestors(newit, setAncestors); nTransactionsUpdated++; totalTxSize += entry.GetTxSize(); @@ -459,7 +510,7 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, std::listGetTx()); } - RemoveStaged(setAllRemoves); + RemoveStaged(setAllRemoves, false); } } @@ -532,7 +583,7 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigned i if (it != mapTx.end()) { setEntries stage; stage.insert(it); - RemoveStaged(stage); + RemoveStaged(stage, true); } removeConflicts(tx, conflicts); ClearPrioritisation(tx.GetHash()); @@ -590,6 +641,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children); bool fDependsWait = false; setEntries setParentCheck; + int64_t parentSizes = 0; + unsigned int parentSigOpCount = 0; BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); @@ -597,7 +650,10 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; - setParentCheck.insert(it2); + if (setParentCheck.insert(it2).second) { + parentSizes += it2->GetTxSize(); + parentSigOpCount += it2->GetSigOpCount(); + } } else { const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); assert(coins && coins->IsAvailable(txin.prevout.n)); @@ -610,17 +666,19 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const i++; } assert(setParentCheck == GetMemPoolParents(it)); + // Also check to make sure ancestor size/sigops are >= sum with immediate + // parents. + assert(it->GetSizeWithAncestors() >= parentSizes + it->GetTxSize()); + assert(it->GetSigOpCountWithAncestors() >= parentSigOpCount + it->GetSigOpCount()); // Check children against mapNextTx CTxMemPool::setEntries setChildrenCheck; std::map::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; - CAmount childModFee = 0; for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { txiter childit = mapTx.find(iter->second.ptx->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); - childModFee += childit->GetModifiedFee(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); @@ -812,9 +870,9 @@ size_t CTxMemPool::DynamicMemoryUsage() const { return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; } -void CTxMemPool::RemoveStaged(setEntries &stage) { +void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants) { AssertLockHeld(cs); - UpdateForRemoveFromMempool(stage); + UpdateForRemoveFromMempool(stage, updateDescendants); BOOST_FOREACH(const txiter& it, stage) { removeUnchecked(it); } @@ -832,7 +890,7 @@ int CTxMemPool::Expire(int64_t time) { BOOST_FOREACH(txiter removeit, toremove) { CalculateDescendants(removeit, stage); } - RemoveStaged(stage); + RemoveStaged(stage, false); return stage.size(); } @@ -941,7 +999,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe BOOST_FOREACH(txiter it, stage) txn.push_back(it->GetTx()); } - RemoveStaged(stage); + RemoveStaged(stage, false); if (pvNoSpendsRemaining) { BOOST_FOREACH(const CTransaction& tx, txn) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { diff --git a/src/txmempool.h b/src/txmempool.h index b1b6645a0..0db3d5bd2 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -80,6 +80,12 @@ private: uint64_t nSizeWithDescendants; //! ... and size CAmount nModFeesWithDescendants; //! ... and total fees (all including us) + // Analogous statistics for ancestor transactions + uint64_t nCountWithAncestors; + uint64_t nSizeWithAncestors; + CAmount nModFeesWithAncestors; + unsigned int nSigOpCountWithAncestors; + public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, @@ -103,7 +109,9 @@ public: size_t DynamicMemoryUsage() const { return nUsageSize; } // Adjusts the descendant state, if this entry is not dirty. - void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + // Adjusts the ancestor state + void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int modifySigOps); // Updates the fee delta used for mining priority score, and the // modified fees with descendants. void UpdateFeeDelta(int64_t feeDelta); @@ -113,6 +121,11 @@ public: CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } bool GetSpendsCoinbase() const { return spendsCoinbase; } + + uint64_t GetCountWithAncestors() const { return nCountWithAncestors; } + uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } + CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } + unsigned int GetSigOpCountWithAncestors() const { return nSigOpCountWithAncestors; } }; // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. @@ -123,7 +136,7 @@ struct update_descendant_state {} void operator() (CTxMemPoolEntry &e) - { e.UpdateState(modifySize, modifyFee, modifyCount); } + { e.UpdateDescendantState(modifySize, modifyFee, modifyCount); } private: int64_t modifySize; @@ -131,6 +144,22 @@ struct update_descendant_state int64_t modifyCount; }; +struct update_ancestor_state +{ + update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int _modifySigOps) : + modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOps(_modifySigOps) + {} + + void operator() (CTxMemPoolEntry &e) + { e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOps); } + + private: + int64_t modifySize; + CAmount modifyFee; + int64_t modifyCount; + int modifySigOps; +}; + struct update_fee_delta { update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } @@ -440,8 +469,12 @@ public: public: /** Remove a set of transactions from the mempool. * If a transaction is in this set, then all in-mempool descendants must - * also be in the set.*/ - void RemoveStaged(setEntries &stage); + * also be in the set, unless this transaction is being removed for being + * in a block. + * Set updateDescendants to true when removing a tx that was in a block, so + * that any in-mempool descendants have their ancestor state updated. + */ + void RemoveStaged(setEntries &stage, bool updateDescendants); /** When adding transactions from a disconnected block back to the mempool, * new mempool entries may have children in the mempool (which is generally @@ -551,8 +584,12 @@ private: const std::set &setExclude); /** Update ancestors of hash to add/remove it as a descendant transaction. */ void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors); - /** For each transaction being removed, update ancestors and any direct children. */ - void UpdateForRemoveFromMempool(const setEntries &entriesToRemove); + /** Set ancestor state for an entry */ + void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors); + /** For each transaction being removed, update ancestors and any direct children. + * If updateDescendants is true, then also update in-mempool descendants' + * ancestor state. */ + void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants); /** Sever link between specified transaction and direct children. */ void UpdateChildrenForRemoval(txiter entry); From e2eeb5dda790cf301aa669704a25fb35f67400e7 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 19 Oct 2015 15:15:12 -0400 Subject: [PATCH 0308/1223] Add ancestor feerate index to mempool --- src/test/mempool_tests.cpp | 104 +++++++++++++++++++++++++++++++++++++ src/txmempool.cpp | 4 +- src/txmempool.h | 32 +++++++++++- 3 files changed, 137 insertions(+), 3 deletions(-) diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index ebdf7dbaa..c8b43df26 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -317,6 +317,110 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) CheckSort(pool, sortedOrder); } +BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) +{ + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + entry.hadNoDependencies = true; + + /* 3rd highest fee */ + CMutableTransaction tx1 = CMutableTransaction(); + tx1.vout.resize(1); + tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx1.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); + + /* highest fee */ + CMutableTransaction tx2 = CMutableTransaction(); + tx2.vout.resize(1); + tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx2.vout[0].nValue = 2 * COIN; + pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); + uint64_t tx2Size = ::GetSerializeSize(tx2, SER_NETWORK, PROTOCOL_VERSION); + + /* lowest fee */ + CMutableTransaction tx3 = CMutableTransaction(); + tx3.vout.resize(1); + tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx3.vout[0].nValue = 5 * COIN; + pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); + + /* 2nd highest fee */ + CMutableTransaction tx4 = CMutableTransaction(); + tx4.vout.resize(1); + tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx4.vout[0].nValue = 6 * COIN; + pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); + + /* equal fee rate to tx1, but newer */ + CMutableTransaction tx5 = CMutableTransaction(); + tx5.vout.resize(1); + tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx5.vout[0].nValue = 11 * COIN; + pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); + BOOST_CHECK_EQUAL(pool.size(), 5); + + std::vector sortedOrder; + sortedOrder.resize(5); + sortedOrder[0] = tx2.GetHash().ToString(); // 20000 + sortedOrder[1] = tx4.GetHash().ToString(); // 15000 + // tx1 and tx5 are both 10000 + // Ties are broken by hash, not timestamp, so determine which + // hash comes first. + if (tx1.GetHash() < tx5.GetHash()) { + sortedOrder[2] = tx1.GetHash().ToString(); + sortedOrder[3] = tx5.GetHash().ToString(); + } else { + sortedOrder[2] = tx5.GetHash().ToString(); + sortedOrder[3] = tx1.GetHash().ToString(); + } + sortedOrder[4] = tx3.GetHash().ToString(); // 0 + + CheckSort(pool, sortedOrder); + + /* low fee parent with high fee child */ + /* tx6 (0) -> tx7 (high) */ + CMutableTransaction tx6 = CMutableTransaction(); + tx6.vout.resize(1); + tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx6.vout[0].nValue = 20 * COIN; + uint64_t tx6Size = ::GetSerializeSize(tx6, SER_NETWORK, PROTOCOL_VERSION); + + pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); + BOOST_CHECK_EQUAL(pool.size(), 6); + sortedOrder.push_back(tx6.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + CMutableTransaction tx7 = CMutableTransaction(); + tx7.vin.resize(1); + tx7.vin[0].prevout = COutPoint(tx6.GetHash(), 0); + tx7.vin[0].scriptSig = CScript() << OP_11; + tx7.vout.resize(1); + tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx7.vout[0].nValue = 10 * COIN; + uint64_t tx7Size = ::GetSerializeSize(tx7, SER_NETWORK, PROTOCOL_VERSION); + + /* set the fee to just below tx2's feerate when including ancestor */ + CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1; + + //CTxMemPoolEntry entry7(tx7, fee, 2, 10.0, 1, true); + pool.addUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7)); + BOOST_CHECK_EQUAL(pool.size(), 7); + sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + /* after tx6 is mined, tx7 should move up in the sort */ + std::vector vtx; + vtx.push_back(tx6); + std::list dummy; + pool.removeForBlock(vtx, 1, dummy, false); + + sortedOrder.erase(sortedOrder.begin()+1); + sortedOrder.pop_back(); + sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString()); + CheckSort(pool, sortedOrder); +} + BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index f7961a6b8..48fbe5602 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -866,8 +866,8 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); - // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. - return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; + // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; } void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants) { diff --git a/src/txmempool.h b/src/txmempool.h index 0db3d5bd2..3f80a6ec2 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -244,10 +244,34 @@ public: } }; +class CompareTxMemPoolEntryByAncestorFee +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + double aFees = a.GetModFeesWithAncestors(); + double aSize = a.GetSizeWithAncestors(); + + double bFees = b.GetModFeesWithAncestors(); + double bSize = b.GetSizeWithAncestors(); + + // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). + double f1 = aFees * bSize; + double f2 = aSize * bFees; + + if (f1 == f2) { + return a.GetTx().GetHash() < b.GetTx().GetHash(); + } + + return f1 > f2; + } +}; + // Multi_index tag names struct descendant_score {}; struct entry_time {}; struct mining_score {}; +struct ancestor_score {}; class CBlockPolicyEstimator; @@ -380,12 +404,18 @@ public: boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByEntryTime - >, + >, // sorted by score (for mining prioritization) boost::multi_index::ordered_unique< boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByScore + >, + // sorted by fee rate with ancestors + boost::multi_index::ordered_non_unique< + boost::multi_index::tag, + boost::multi_index::identity, + CompareTxMemPoolEntryByAncestorFee > > > indexed_transaction_set; From ce019bf90fe89c1256a89c489795987ef0b8a18f Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 8 Mar 2016 15:49:26 -0500 Subject: [PATCH 0309/1223] Check all ancestor state in CTxMemPool::check() --- src/txmempool.cpp | 27 ++++++++++++++++++++++----- src/txmempool.h | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 48fbe5602..ae851621c 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -160,7 +160,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes } } -bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) +bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const { setEntries parentHashes; const CTransaction &tx = entry.GetTx(); @@ -666,10 +666,27 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const i++; } assert(setParentCheck == GetMemPoolParents(it)); - // Also check to make sure ancestor size/sigops are >= sum with immediate - // parents. - assert(it->GetSizeWithAncestors() >= parentSizes + it->GetTxSize()); - assert(it->GetSigOpCountWithAncestors() >= parentSigOpCount + it->GetSigOpCount()); + // Verify ancestor state is correct. + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy); + uint64_t nCountCheck = setAncestors.size() + 1; + uint64_t nSizeCheck = it->GetTxSize(); + CAmount nFeesCheck = it->GetModifiedFee(); + unsigned int nSigOpCheck = it->GetSigOpCount(); + + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + nSizeCheck += ancestorIt->GetTxSize(); + nFeesCheck += ancestorIt->GetModifiedFee(); + nSigOpCheck += ancestorIt->GetSigOpCount(); + } + + assert(it->GetCountWithAncestors() == nCountCheck); + assert(it->GetSizeWithAncestors() == nSizeCheck); + assert(it->GetSigOpCountWithAncestors() == nSigOpCheck); + assert(it->GetModFeesWithAncestors() == nFeesCheck); + // Check children against mapNextTx CTxMemPool::setEntries setChildrenCheck; std::map::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); diff --git a/src/txmempool.h b/src/txmempool.h index 3f80a6ec2..a82d17c2f 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -527,7 +527,7 @@ public: * fSearchForParents = whether to search a tx's vin for in-mempool parents, or * look up parents from mapLinks. Must be true for entries not in the mempool */ - bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true); + bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true) const; /** Populate setDescendants with all in-mempool descendants of hash. * Assumes that setDescendants includes all in-mempool descendants of anything From fa48bb31484e28a0750d622040616ed04d53053a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 14 Mar 2016 18:08:07 +0100 Subject: [PATCH 0310/1223] [qt] Remove 0-fee from send dialog --- src/qt/forms/sendcoinsdialog.ui | 55 +-------------------------------- src/qt/sendcoinsdialog.cpp | 6 ---- src/wallet/wallet.cpp | 3 +- 3 files changed, 3 insertions(+), 61 deletions(-) diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 8911b41cb..12d6a62c0 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -617,7 +617,7 @@ 0 0 830 - 68 + 104 @@ -1167,59 +1167,6 @@ - - - - 8 - - - 4 - - - - - Send as zero-fee transaction if possible - - - - - - - (confirmation may take longer) - - - 5 - - - - - - - Qt::Horizontal - - - - 1 - 1 - - - - - - - - - - Qt::Vertical - - - - 1 - 1 - - - - diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 5fc7b57a4..e11ffd1b7 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -115,7 +115,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa ui->sliderSmartFee->setValue(settings.value("nSmartFeeSliderPosition").toInt()); ui->customFee->setValue(settings.value("nTransactionFee").toLongLong()); ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool()); - ui->checkBoxFreeTx->setChecked(settings.value("fSendFreeTransactions").toBool()); minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool()); } @@ -170,8 +169,6 @@ void SendCoinsDialog::setModel(WalletModel *model) connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls())); connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables())); connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); - connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables())); - connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); ui->customFee->setSingleStep(CWallet::GetRequiredFee(1000)); updateFeeSectionControls(); updateMinFeeLabel(); @@ -189,7 +186,6 @@ SendCoinsDialog::~SendCoinsDialog() settings.setValue("nSmartFeeSliderPosition", ui->sliderSmartFee->value()); settings.setValue("nTransactionFee", (qint64)ui->customFee->value()); settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked()); - settings.setValue("fSendFreeTransactions", ui->checkBoxFreeTx->isChecked()); delete ui; } @@ -605,8 +601,6 @@ void SendCoinsDialog::updateGlobalFeeVariables() // set nMinimumTotalFee to 0 in case of user has selected that the fee is per KB CoinControlDialog::coinControl->nMinimumTotalFee = ui->radioCustomAtLeast->isChecked() ? ui->customFee->value() : 0; } - - fSendFreeTransactions = ui->checkBoxFreeTx->isChecked(); } void SendCoinsDialog::updateFeeMinimizedLabel() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bcfefa27f..1ef055e55 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2970,7 +2970,8 @@ std::string CWallet::GetWalletHelpString(bool showDebug) CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + if (showDebug) + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); From c3932b32700a210b5fbf36e32bddac604dec9288 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 14 Mar 2016 19:22:11 +0100 Subject: [PATCH 0311/1223] List solvability in listunspent output and improve help --- src/qt/walletmodel.cpp | 6 +++--- src/wallet/rpcwallet.cpp | 6 +++++- src/wallet/test/wallet_tests.cpp | 2 +- src/wallet/wallet.cpp | 3 ++- src/wallet/wallet.h | 5 +++-- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index cf38c64eb..a5b43270f 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -572,7 +572,7 @@ void WalletModel::getOutputs(const std::vector& vOutpoints, std::vect if (!wallet->mapWallet.count(outpoint.hash)) continue; int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true, true); vOutputs.push_back(out); } } @@ -599,7 +599,7 @@ void WalletModel::listCoins(std::map >& mapCoins) if (!wallet->mapWallet.count(outpoint.hash)) continue; int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true, true); if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == ISMINE_SPENDABLE) vCoins.push_back(out); } @@ -611,7 +611,7 @@ void WalletModel::listCoins(std::map >& mapCoins) while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0])) { if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break; - cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true); + cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true, true); } CTxDestination address; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 759f894cc..077b35254 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2348,7 +2348,9 @@ UniValue listunspent(const UniValue& params, bool fHelp) " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" - " \"confirmations\" : n (numeric) The number of confirmations\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" " }\n" " ,...\n" "]\n" @@ -2425,6 +2427,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) entry.push_back(Pair("amount",ValueFromAmount(nValue))); entry.push_back(Pair("confirmations",out.nDepth)); entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); results.push_back(entry); } @@ -2446,6 +2449,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "Note that all existing inputs must have their previous output transaction be in the wallet.\n" "Note that all inputs selected must be of standard form and P2SH scripts must be" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" + "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index e84d58802..06c9c903e 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -48,7 +48,7 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa wtx->fDebitCached = true; wtx->nDebitCached = 1; } - COutput output(wtx, nInput, nAge, true); + COutput output(wtx, nInput, nAge, true, true); vCoins.push_back(output); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bcfefa27f..590082824 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1675,7 +1675,8 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i))) vCoins.push_back(COutput(pcoin, i, nDepth, ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || - (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO))); + (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO), + (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO)); } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d009211a9..37a84153b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -412,10 +412,11 @@ public: int i; int nDepth; bool fSpendable; + bool fSolvable; - COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) + COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn) { - tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; } std::string ToString() const; From 6851107b3a52ec869e5e3a2cb4eb02d6c743b8e5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 15 Feb 2016 05:13:27 +0100 Subject: [PATCH 0312/1223] BIP9 Implementation Inspired by former implementations by Eric Lombrozo and Rusty Russell, and based on code by Jorge Timon. --- src/Makefile.am | 2 + src/chain.h | 2 - src/chainparams.cpp | 6 ++ src/consensus/params.h | 28 +++++++++ src/init.cpp | 2 +- src/main.cpp | 80 +++++++++++++++++++++-- src/main.h | 5 ++ src/miner.cpp | 11 ++-- src/primitives/block.h | 3 +- src/test/miner_tests.cpp | 33 +++++++++- src/versionbits.cpp | 133 +++++++++++++++++++++++++++++++++++++++ src/versionbits.h | 59 +++++++++++++++++ 12 files changed, 345 insertions(+), 19 deletions(-) create mode 100644 src/versionbits.cpp create mode 100644 src/versionbits.h diff --git a/src/Makefile.am b/src/Makefile.am index fa7a78f33..7765ea43e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -152,6 +152,7 @@ BITCOIN_CORE_H = \ utilmoneystr.h \ utiltime.h \ validationinterface.h \ + versionbits.h \ wallet/crypter.h \ wallet/db.h \ wallet/rpcwallet.h \ @@ -204,6 +205,7 @@ libbitcoin_server_a_SOURCES = \ txdb.cpp \ txmempool.cpp \ validationinterface.cpp \ + versionbits.cpp \ $(BITCOIN_CORE_H) if ENABLE_ZMQ diff --git a/src/chain.h b/src/chain.h index 919998356..5b9605a80 100644 --- a/src/chain.h +++ b/src/chain.h @@ -14,8 +14,6 @@ #include -#include - struct CDiskBlockPos { int nFile; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b962f6ac0..6501af78b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -81,6 +81,8 @@ public: consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowNoRetargeting = false; + consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 + consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -162,6 +164,8 @@ public: consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = false; + consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains + consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -225,6 +229,8 @@ public: consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = true; + consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains + consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; diff --git a/src/consensus/params.h b/src/consensus/params.h index 335750fe8..d5039211a 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -7,8 +7,28 @@ #define BITCOIN_CONSENSUS_PARAMS_H #include "uint256.h" +#include +#include namespace Consensus { + +enum DeploymentPos +{ + MAX_VERSION_BITS_DEPLOYMENTS = 0, +}; + +/** + * Struct for each individual consensus rule change using BIP9. + */ +struct BIP9Deployment { + /** Bit position to select the particular bit in nVersion. */ + int bit; + /** Start MedianTime for version bits miner confirmation. Can be a date in the past */ + int64_t nStartTime; + /** Timeout/expiry MedianTime for the deployment attempt. */ + int64_t nTimeout; +}; + /** * Parameters that influence chain consensus. */ @@ -22,6 +42,14 @@ struct Params { /** Block height and hash at which BIP34 becomes active */ int BIP34Height; uint256 BIP34Hash; + /** + * Minimum blocks including miner confirmation of the total of 2016 blocks in a retargetting period, + * (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. + * Examples: 1916 for 95%, 1512 for testchains. + */ + uint32_t nRuleChangeActivationThreshold; + uint32_t nMinerConfirmationWindow; + BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]; /** Proof of work parameters */ uint256 powLimit; bool fPowAllowMinDifficultyBlocks; diff --git a/src/init.cpp b/src/init.cpp index 637b69ab0..a39256c6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -466,7 +466,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) - strUsage += HelpMessageOpt("-blockversion=", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION)); + strUsage += HelpMessageOpt("-blockversion=", "Override block version to test forking scenarios"); strUsage += HelpMessageGroup(_("RPC server options:")); strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); diff --git a/src/main.cpp b/src/main.cpp index 027a36394..45e588189 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ #include "utilmoneystr.h" #include "utilstrencodings.h" #include "validationinterface.h" +#include "versionbits.h" #include @@ -2083,6 +2084,51 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const } } +// Protected by cs_main +static VersionBitsCache versionbitscache; + +int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) +{ + LOCK(cs_main); + int32_t nVersion = VERSIONBITS_TOP_BITS; + + for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { + ThresholdState state = VersionBitsState(pindexPrev, params, (Consensus::DeploymentPos)i, versionbitscache); + if (state == THRESHOLD_LOCKED_IN || state == THRESHOLD_STARTED) { + nVersion |= VersionBitsMask(params, (Consensus::DeploymentPos)i); + } + } + + return nVersion; +} + +/** + * Threshold condition checker that triggers when unknown versionbits are seen on the network. + */ +class WarningBitsConditionChecker : public AbstractThresholdConditionChecker +{ +private: + int bit; + +public: + WarningBitsConditionChecker(int bitIn) : bit(bitIn) {} + + int64_t BeginTime(const Consensus::Params& params) const { return 0; } + int64_t EndTime(const Consensus::Params& params) const { return std::numeric_limits::max(); } + int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; } + int Threshold(const Consensus::Params& params) const { return params.nRuleChangeActivationThreshold; } + + bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const + { + return ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && + ((pindex->nVersion >> bit) & 1) != 0 && + ((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0; + } +}; + +// Protected by cs_main +static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS]; + static int64_t nTimeCheck = 0; static int64_t nTimeForks = 0; static int64_t nTimeVerify = 0; @@ -2452,24 +2498,42 @@ void static UpdateTip(CBlockIndex *pindexNew) { // Check the version of the last 100 blocks to see if we need to upgrade: static bool fWarned = false; - if (!IsInitialBlockDownload() && !fWarned) + if (!IsInitialBlockDownload()) { int nUpgraded = 0; const CBlockIndex* pindex = chainActive.Tip(); + for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { + WarningBitsConditionChecker checker(bit); + ThresholdState state = checker.GetStateFor(pindex, chainParams.GetConsensus(), warningcache[bit]); + if (state == THRESHOLD_ACTIVE || state == THRESHOLD_LOCKED_IN) { + if (state == THRESHOLD_ACTIVE) { + strMiscWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit); + if (!fWarned) { + CAlert::Notify(strMiscWarning, true); + fWarned = true; + } + } else { + LogPrintf("%s: unknown new rules are about to activate (versionbit %i)\n", __func__, bit); + } + } + } for (int i = 0; i < 100 && pindex != NULL; i++) { - if (pindex->nVersion > CBlock::CURRENT_VERSION) + int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus()); + if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0) ++nUpgraded; pindex = pindex->pprev; } if (nUpgraded > 0) - LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION); + LogPrintf("%s: %d of last 100 blocks have unexpected version\n", __func__, nUpgraded); if (nUpgraded > 100/2) { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: This version is obsolete; upgrade required!"); - CAlert::Notify(strMiscWarning, true); - fWarned = true; + strMiscWarning = _("Warning: Unknown block versions being mined! It's possible unknown rules are in effect"); + if (!fWarned) { + CAlert::Notify(strMiscWarning, true); + fWarned = true; + } } } } @@ -3763,6 +3827,10 @@ void UnloadBlockIndex() setDirtyFileInfo.clear(); mapNodeState.clear(); recentRejects.reset(NULL); + versionbitscache.Clear(); + for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) { + warningcache[b].clear(); + } BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) { delete entry.second; diff --git a/src/main.h b/src/main.h index 5ba2be251..7670bb74d 100644 --- a/src/main.h +++ b/src/main.h @@ -537,6 +537,11 @@ extern CBlockTreeDB *pblocktree; */ int GetSpendHeight(const CCoinsViewCache& inputs); +/** + * Determine what nVersion a new block should use. + */ +int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params); + /** Reject codes greater or equal to this can be returned by AcceptToMemPool * for transactions, to signal internal conditions. They cannot and should not * be sent over the P2P network. diff --git a/src/miner.cpp b/src/miner.cpp index ec87e84ca..ef8fd4db4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -79,11 +79,6 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s return NULL; CBlock *pblock = &pblocktemplate->block; // pointer for convenience - // -regtest only: allow overriding block.nVersion with - // -blockversion=N to test forking scenarios - if (chainparams.MineBlocksOnDemand()) - pblock->nVersion = GetArg("-blockversion", pblock->nVersion); - // Create coinbase tx CMutableTransaction txNew; txNew.vin.resize(1); @@ -137,6 +132,12 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); + // -regtest only: allow overriding block.nVersion with + // -blockversion=N to test forking scenarios + if (chainparams.MineBlocksOnDemand()) + pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime(); diff --git a/src/primitives/block.h b/src/primitives/block.h index 0e93399c0..42276b2bc 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -21,7 +21,6 @@ class CBlockHeader { public: // header - static const int32_t CURRENT_VERSION=4; int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -49,7 +48,7 @@ public: void SetNull() { - nVersion = CBlockHeader::CURRENT_VERSION; + nVersion = 0; hashPrevBlock.SetNull(); hashMerkleRoot.SetNull(); nTime = 0; diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index f3297e074..ab6485081 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -247,13 +247,40 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // subsidy changing int nHeight = chainActive.Height(); - chainActive.Tip()->nHeight = 209999; + // Create an actual 209999-long block chain (without valid blocks). + while (chainActive.Tip()->nHeight < 209999) { + CBlockIndex* prev = chainActive.Tip(); + CBlockIndex* next = new CBlockIndex(); + next->phashBlock = new uint256(GetRandHash()); + pcoinsTip->SetBestBlock(next->GetBlockHash()); + next->pprev = prev; + next->nHeight = prev->nHeight + 1; + next->BuildSkip(); + chainActive.SetTip(next); + } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; - chainActive.Tip()->nHeight = 210000; + // Extend to a 210000-long block chain. + while (chainActive.Tip()->nHeight < 210000) { + CBlockIndex* prev = chainActive.Tip(); + CBlockIndex* next = new CBlockIndex(); + next->phashBlock = new uint256(GetRandHash()); + pcoinsTip->SetBestBlock(next->GetBlockHash()); + next->pprev = prev; + next->nHeight = prev->nHeight + 1; + next->BuildSkip(); + chainActive.SetTip(next); + } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; - chainActive.Tip()->nHeight = nHeight; + // Delete the dummy blocks again. + while (chainActive.Tip()->nHeight > nHeight) { + CBlockIndex* del = chainActive.Tip(); + chainActive.SetTip(del->pprev); + pcoinsTip->SetBestBlock(del->pprev->GetBlockHash()); + delete del->phashBlock; + delete del; + } // non-final txs in mempool SetMockTime(chainActive.Tip()->GetMedianTimePast()+1); diff --git a/src/versionbits.cpp b/src/versionbits.cpp new file mode 100644 index 000000000..fbb60c0fc --- /dev/null +++ b/src/versionbits.cpp @@ -0,0 +1,133 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "versionbits.h" + +ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const +{ + int nPeriod = Period(params); + int nThreshold = Threshold(params); + int64_t nTimeStart = BeginTime(params); + int64_t nTimeTimeout = EndTime(params); + + // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1. + if (pindexPrev != NULL) { + pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)); + } + + // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known + std::vector vToCompute; + while (cache.count(pindexPrev) == 0) { + if (pindexPrev == NULL) { + // The genesis block is by definition defined. + cache[pindexPrev] = THRESHOLD_DEFINED; + break; + } + if (pindexPrev->GetMedianTimePast() < nTimeStart) { + // Optimizaton: don't recompute down further, as we know every earlier block will be before the start time + cache[pindexPrev] = THRESHOLD_DEFINED; + break; + } + vToCompute.push_back(pindexPrev); + pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod); + } + + // At this point, cache[pindexPrev] is known + assert(cache.count(pindexPrev)); + ThresholdState state = cache[pindexPrev]; + + // Now walk forward and compute the state of descendants of pindexPrev + while (!vToCompute.empty()) { + ThresholdState stateNext = state; + pindexPrev = vToCompute.back(); + vToCompute.pop_back(); + + switch (state) { + case THRESHOLD_DEFINED: { + if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) { + stateNext = THRESHOLD_FAILED; + } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) { + stateNext = THRESHOLD_STARTED; + } + break; + } + case THRESHOLD_STARTED: { + if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) { + stateNext = THRESHOLD_FAILED; + break; + } + // We need to count + const CBlockIndex* pindexCount = pindexPrev; + int count = 0; + for (int i = 0; i < nPeriod; i++) { + if (Condition(pindexCount, params)) { + count++; + } + pindexCount = pindexCount->pprev; + } + if (count >= nThreshold) { + stateNext = THRESHOLD_LOCKED_IN; + } + break; + } + case THRESHOLD_LOCKED_IN: { + // Always progresses into ACTIVE. + stateNext = THRESHOLD_ACTIVE; + break; + } + case THRESHOLD_FAILED: + case THRESHOLD_ACTIVE: { + // Nothing happens, these are terminal states. + break; + } + } + cache[pindexPrev] = state = stateNext; + } + + return state; +} + +namespace +{ +/** + * Class to implement versionbits logic. + */ +class VersionBitsConditionChecker : public AbstractThresholdConditionChecker { +private: + const Consensus::DeploymentPos id; + +protected: + int64_t BeginTime(const Consensus::Params& params) const { return params.vDeployments[id].nStartTime; } + int64_t EndTime(const Consensus::Params& params) const { return params.vDeployments[id].nTimeout; } + int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; } + int Threshold(const Consensus::Params& params) const { return params.nRuleChangeActivationThreshold; } + + bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const + { + return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0); + } + +public: + VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {} + uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; } +}; + +} + +ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) +{ + return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]); +} + +uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos) +{ + return VersionBitsConditionChecker(pos).Mask(params); +} + +void VersionBitsCache::Clear() +{ + for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) { + caches[d].clear(); + } +} diff --git a/src/versionbits.h b/src/versionbits.h new file mode 100644 index 000000000..04f473827 --- /dev/null +++ b/src/versionbits.h @@ -0,0 +1,59 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_VERSIONBITS +#define BITCOIN_CONSENSUS_VERSIONBITS + +#include "chain.h" +#include + +/** What block version to use for new blocks (pre versionbits) */ +static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4; +/** What bits to set in version for versionbits blocks */ +static const int32_t VERSIONBITS_TOP_BITS = 0x20000000UL; +/** What bitmask determines whether versionbits is in use */ +static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL; +/** Total bits available for versionbits */ +static const int32_t VERSIONBITS_NUM_BITS = 29; + +enum ThresholdState { + THRESHOLD_DEFINED, + THRESHOLD_STARTED, + THRESHOLD_LOCKED_IN, + THRESHOLD_ACTIVE, + THRESHOLD_FAILED, +}; + +// A map that gives the state for blocks whose height is a multiple of Period(). +// The map is indexed by the block's parent, however, so all keys in the map +// will either be NULL or a block with (height + 1) % Period() == 0. +typedef std::map ThresholdConditionCache; + +/** + * Abstract class that implements BIP9-style threshold logic, and caches results. + */ +class AbstractThresholdConditionChecker { +protected: + virtual bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const =0; + virtual int64_t BeginTime(const Consensus::Params& params) const =0; + virtual int64_t EndTime(const Consensus::Params& params) const =0; + virtual int Period(const Consensus::Params& params) const =0; + virtual int Threshold(const Consensus::Params& params) const =0; + +public: + // Note that the function below takes a pindexPrev as input: they compute information for block B based on its parent. + ThresholdState GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const; +}; + +struct VersionBitsCache +{ + ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]; + + void Clear(); +}; + +ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache); +uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos); + +#endif From 732e774c0655a3a6bcb3f2f02c88b37ea1bd3e68 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 20 Feb 2016 02:57:36 +0100 Subject: [PATCH 0313/1223] Versionbits tests --- src/Makefile.test.include | 1 + src/test/versionbits_tests.cpp | 185 +++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/test/versionbits_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 0c4e47a14..57f9ac50e 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -83,6 +83,7 @@ BITCOIN_TESTS =\ test/timedata_tests.cpp \ test/transaction_tests.cpp \ test/txvalidationcache_tests.cpp \ + test/versionbits_tests.cpp \ test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp new file mode 100644 index 000000000..9de8461d8 --- /dev/null +++ b/src/test/versionbits_tests.cpp @@ -0,0 +1,185 @@ +// Copyright (c) 2014-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "chain.h" +#include "random.h" +#include "versionbits.h" +#include "test/test_bitcoin.h" + +#include + +/* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */ +int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; } + +static const Consensus::Params paramsDummy = Consensus::Params(); + +class TestConditionChecker : public AbstractThresholdConditionChecker +{ +private: + mutable ThresholdConditionCache cache; + +public: + int64_t BeginTime(const Consensus::Params& params) const { return TestTime(10000); } + int64_t EndTime(const Consensus::Params& params) const { return TestTime(20000); } + int Period(const Consensus::Params& params) const { return 1000; } + int Threshold(const Consensus::Params& params) const { return 900; } + bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const { return (pindex->nVersion & 0x100); } + + ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); } +}; + +#define CHECKERS 6 + +class VersionBitsTester +{ + // A fake blockchain + std::vector vpblock; + + // 6 independent checkers for the same bit. + // The first one performs all checks, the second only 50%, the third only 25%, etc... + // This is to test whether lack of cached information leads to the same results. + TestConditionChecker checker[CHECKERS]; + + // Test counter (to identify failures) + int num; + +public: + VersionBitsTester() : num(0) {} + + VersionBitsTester& Reset() { + for (unsigned int i = 0; i < vpblock.size(); i++) { + delete vpblock[i]; + } + for (unsigned int i = 0; i < CHECKERS; i++) { + checker[i] = TestConditionChecker(); + } + vpblock.clear(); + return *this; + } + + ~VersionBitsTester() { + Reset(); + } + + VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) { + while (vpblock.size() < height) { + CBlockIndex* pindex = new CBlockIndex(); + pindex->nHeight = vpblock.size(); + pindex->pprev = vpblock.size() > 0 ? vpblock.back() : NULL; + pindex->nTime = nTime; + pindex->nVersion = nVersion; + pindex->BuildSkip(); + vpblock.push_back(pindex); + } + return *this; + } + + VersionBitsTester& TestDefined() { + for (int i = 0; i < CHECKERS; i++) { + if ((insecure_rand() & ((1 << i) - 1)) == 0) { + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num)); + } + } + num++; + return *this; + } + + VersionBitsTester& TestStarted() { + for (int i = 0; i < CHECKERS; i++) { + if ((insecure_rand() & ((1 << i) - 1)) == 0) { + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num)); + } + } + num++; + return *this; + } + + VersionBitsTester& TestLockedIn() { + for (int i = 0; i < CHECKERS; i++) { + if ((insecure_rand() & ((1 << i) - 1)) == 0) { + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); + } + } + num++; + return *this; + } + + VersionBitsTester& TestActive() { + for (int i = 0; i < CHECKERS; i++) { + if ((insecure_rand() & ((1 << i) - 1)) == 0) { + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num)); + } + } + num++; + return *this; + } + + VersionBitsTester& TestFailed() { + for (int i = 0; i < CHECKERS; i++) { + if ((insecure_rand() & ((1 << i) - 1)) == 0) { + BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num)); + } + } + num++; + return *this; + } +}; + +BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup) + +BOOST_AUTO_TEST_CASE(versionbits_test) +{ + for (int i = 0; i < 64; i++) { + // DEFINED -> FAILED + VersionBitsTester().TestDefined() + .Mine(1, TestTime(1), 0x100).TestDefined() + .Mine(11, TestTime(11), 0x100).TestDefined() + .Mine(989, TestTime(989), 0x100).TestDefined() + .Mine(999, TestTime(20000), 0x100).TestDefined() + .Mine(1000, TestTime(20000), 0x100).TestFailed() + .Mine(1999, TestTime(30001), 0x100).TestFailed() + .Mine(2000, TestTime(30002), 0x100).TestFailed() + .Mine(2001, TestTime(30003), 0x100).TestFailed() + .Mine(2999, TestTime(30004), 0x100).TestFailed() + .Mine(3000, TestTime(30005), 0x100).TestFailed() + + // DEFINED -> STARTED -> FAILED + .Reset().TestDefined() + .Mine(1, TestTime(1), 0).TestDefined() + .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined() // One second more and it would be defined + .Mine(2000, TestTime(10000), 0x100).TestStarted() // So that's what happens the next period + .Mine(2051, TestTime(10010), 0).TestStarted() // 51 old blocks + .Mine(2950, TestTime(10020), 0x100).TestStarted() // 899 new blocks + .Mine(3000, TestTime(20000), 0).TestFailed() // 50 old blocks (so 899 out of the past 1000) + .Mine(4000, TestTime(20010), 0x100).TestFailed() + + // DEFINED -> STARTED -> FAILED while threshold reached + .Reset().TestDefined() + .Mine(1, TestTime(1), 0).TestDefined() + .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined() // One second more and it would be defined + .Mine(2000, TestTime(10000), 0x101).TestStarted() // So that's what happens the next period + .Mine(2999, TestTime(30000), 0x100).TestStarted() // 999 new blocks + .Mine(3000, TestTime(30000), 0x100).TestFailed() // 1 new block (so 1000 out of the past 1000 are new) + .Mine(3999, TestTime(30001), 0).TestFailed() + .Mine(4000, TestTime(30002), 0).TestFailed() + .Mine(14333, TestTime(30003), 0).TestFailed() + .Mine(24000, TestTime(40000), 0).TestFailed() + + // DEFINED -> STARTED -> LOCKEDIN at the last minute -> ACTIVE + .Reset().TestDefined() + .Mine(1, TestTime(1), 0).TestDefined() + .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined() // One second more and it would be defined + .Mine(2000, TestTime(10000), 0x101).TestStarted() // So that's what happens the next period + .Mine(2050, TestTime(10010), 0x200).TestStarted() // 50 old blocks + .Mine(2950, TestTime(10020), 0x100).TestStarted() // 900 new blocks + .Mine(2999, TestTime(19999), 0x200).TestStarted() // 49 old blocks + .Mine(3000, TestTime(29999), 0x200).TestLockedIn() // 1 old block (so 900 out of the past 1000) + .Mine(3999, TestTime(30001), 0).TestLockedIn() + .Mine(4000, TestTime(30002), 0).TestActive() + .Mine(14333, TestTime(30003), 0).TestActive() + .Mine(24000, TestTime(40000), 0).TestActive(); + } +} + +BOOST_AUTO_TEST_SUITE_END() From d23f6c6a0d2dc8a3f5f159faf7a40157259a8f8f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 3 Mar 2016 21:00:03 +0100 Subject: [PATCH 0314/1223] Softfork status report in RPC --- src/main.cpp | 6 +++++- src/main.h | 4 ++++ src/rpc/blockchain.cpp | 22 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 45e588189..e4567a897 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5859,7 +5859,11 @@ bool SendMessages(CNode* pto) return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } - +ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos) +{ + LOCK(cs_main); + return VersionBitsState(chainActive.Tip(), params, pos, versionbitscache); +} class CMainCleanup { diff --git a/src/main.h b/src/main.h index 7670bb74d..b66ad53c8 100644 --- a/src/main.h +++ b/src/main.h @@ -16,6 +16,7 @@ #include "net.h" #include "script/script_error.h" #include "sync.h" +#include "versionbits.h" #include #include @@ -289,6 +290,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state); +/** Get the BIP9 state for a given deployment at the current tip. */ +ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos); + struct CNodeStateStats { int nMisbehavior; int nSyncHeight; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index da57973da..a110dff0d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -604,6 +604,20 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } +static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + switch (VersionBitsTipState(consensusParams, id)) { + case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; + case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; + case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; + case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; + case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; + } + return rv; +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -634,6 +648,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " },\n" " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" + " ],\n" + " \"bip9_softforks\": [ (array) status of BIP9 softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of the softfork\n" + " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " }\n" " ]\n" "}\n" "\nExamples:\n" @@ -657,10 +677,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); + UniValue bip9_softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); + obj.push_back(Pair("bip9_softforks", bip9_softforks)); if (fPruneMode) { From 532cbb22b57f25c89df30588185b0db659871c86 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 9 Mar 2016 16:00:53 -0500 Subject: [PATCH 0315/1223] Add testing of ComputeBlockVersion --- src/chainparams.cpp | 9 +++ src/consensus/params.h | 3 +- src/test/versionbits_tests.cpp | 109 +++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 6501af78b..35e090a0b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -83,6 +83,9 @@ public: consensus.fPowNoRetargeting = false; consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -166,6 +169,9 @@ public: consensus.fPowNoRetargeting = false; consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -231,6 +237,9 @@ public: consensus.fPowNoRetargeting = true; consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; diff --git a/src/consensus/params.h b/src/consensus/params.h index d5039211a..7c3a8e84c 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -14,7 +14,8 @@ namespace Consensus { enum DeploymentPos { - MAX_VERSION_BITS_DEPLOYMENTS = 0, + DEPLOYMENT_TESTDUMMY, + MAX_VERSION_BITS_DEPLOYMENTS }; /** diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 9de8461d8..63dc4726b 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -6,6 +6,9 @@ #include "random.h" #include "versionbits.h" #include "test/test_bitcoin.h" +#include "chainparams.h" +#include "main.h" +#include "consensus/params.h" #include @@ -124,6 +127,8 @@ public: num++; return *this; } + + CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : NULL; } }; BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup) @@ -182,4 +187,108 @@ BOOST_AUTO_TEST_CASE(versionbits_test) } } +BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) +{ + // Check that ComputeBlockVersion will set the appropriate bit correctly + // on mainnet. + const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + + // Use the TESTDUMMY deployment for testing purposes. + int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit; + int64_t nStartTime = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime; + int64_t nTimeout = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout; + + assert(nStartTime < nTimeout); + + // In the first chain, test that the bit is set by CBV until it has failed. + // In the second chain, test the bit is set by CBV while STARTED and + // LOCKED-IN, and then no longer set while ACTIVE. + VersionBitsTester firstChain, secondChain; + + // Start generating blocks before nStartTime + int64_t nTime = nStartTime - 1; + + // Before MedianTimePast of the chain has crossed nStartTime, the bit + // should not be set. + CBlockIndex *lastBlock = NULL; + lastBlock = firstChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1< 0) { + lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1< Date: Wed, 9 Mar 2016 09:48:20 -0500 Subject: [PATCH 0316/1223] Test versionbits deployments --- src/test/versionbits_tests.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 63dc4726b..1f86a06a3 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -185,6 +185,28 @@ BOOST_AUTO_TEST_CASE(versionbits_test) .Mine(14333, TestTime(30003), 0).TestActive() .Mine(24000, TestTime(40000), 0).TestActive(); } + + // Sanity checks of version bit deployments + const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { + uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i); + // Make sure that no deployment tries to set an invalid bit. + BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask); + + // Verify that the deployment windows of different deployment using the + // same bit are disjoint. + // This test may need modification at such time as a new deployment + // is proposed that reuses the bit of an activated soft fork, before the + // end time of that soft fork. (Alternatively, the end time of that + // activated soft fork could be later changed to be earlier to avoid + // overlap.) + for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) { + if (VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)j) == bitmask) { + BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout || + mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout); + } + } + } } BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) From 8c74cedef53ab791ed333f25794f8b9d2e9f51aa Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 15 Mar 2016 12:09:16 -0400 Subject: [PATCH 0317/1223] RPC test for BIP9 warning logic --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/p2p-versionbits-warning.py | 160 ++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100755 qa/rpc-tests/p2p-versionbits-warning.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 485888e9b..f15eaacbd 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -115,6 +115,7 @@ testScripts = [ 'invalidblockrequest.py', 'invalidtxrequest.py', 'abandonconflict.py', + 'p2p-versionbits-warning.py', ] testScriptsExt = [ 'bip65-cltv.py', diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py new file mode 100755 index 000000000..061dcbf0e --- /dev/null +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python2 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time +from test_framework.blocktools import create_block, create_coinbase + +''' +Test version bits' warning system. + +Generate chains with block versions that appear to be signalling unknown +soft-forks, and test that warning alerts are generated. +''' + +VB_PERIOD = 144 # versionbits period length for regtest +VB_THRESHOLD = 108 # versionbits activation threshold for regtest +VB_TOP_BITS = 0x20000000 +VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment + +# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending +# p2p messages to a node, generating the messages in the main testing logic. +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + + def add_connection(self, conn): + self.connection = conn + + def on_inv(self, conn, message): + pass + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_pong(self, conn, message): + self.last_pong = message + + # Sync up with the node after delivery of a block + def sync_with_ping(self, timeout=30): + self.connection.send_message(msg_ping(nonce=self.ping_counter)) + received_pong = False + sleep_time = 0.05 + while not received_pong and timeout > 0: + time.sleep(sleep_time) + timeout -= sleep_time + with mininode_lock: + if self.last_pong.nonce == self.ping_counter: + received_pong = True + self.ping_counter += 1 + return received_pong + + +class VersionBitsWarningTest(BitcoinTestFramework): + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = [] + self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") + # Open and close to create zero-length file + with open(self.alert_filename, 'w') as f: + pass + self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""] + self.nodes.append(start_node(0, self.options.tmpdir, self.node_options)) + + import re + self.vb_pattern = re.compile("^Warning.*versionbit") + + # Send numblocks blocks via peer with nVersionToUse set. + def send_blocks_with_version(self, peer, numblocks, nVersionToUse): + tip = self.nodes[0].getbestblockhash() + height = self.nodes[0].getblockcount() + block_time = self.nodes[0].getblockheader(tip)["time"]+1 + tip = int(tip, 16) + + for i in xrange(numblocks): + block = create_block(tip, create_coinbase(height+1), block_time) + block.nVersion = nVersionToUse + block.solve() + peer.send_message(msg_block(block)) + block_time += 1 + height += 1 + tip = block.sha256 + peer.sync_with_ping() + + def test_versionbits_in_alert_file(self): + with open(self.alert_filename, 'r') as f: + alert_text = f.read() + assert(self.vb_pattern.match(alert_text)) + + def run_test(self): + # Setup the p2p connection and start up the network thread. + test_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)) + test_node.add_connection(connections[0]) + + NetworkThread().start() # Start up network handling in another thread + + # Test logic begins here + test_node.wait_for_verack() + + # 1. Have the node mine one period worth of blocks + self.nodes[0].generate(VB_PERIOD) + + # 2. Now build one period of blocks on the tip, with < VB_THRESHOLD + # blocks signaling some unknown bit. + nVersion = VB_TOP_BITS | (1<= VB_THRESHOLD blocks signaling + # some unknown bit + self.send_blocks_with_version(test_node, VB_THRESHOLD, nVersion) + self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD) + # Might not get a versionbits-related alert yet, as we should + # have gotten a different alert due to more than 51/100 blocks + # being of unexpected version. + # Check that getinfo() shows some kind of error. + assert(len(self.nodes[0].getinfo()["errors"]) != 0) + + # Mine a period worth of expected blocks so the generic block-version warning + # is cleared, and restart the node. This should move the versionbit state + # to ACTIVE. + self.nodes[0].generate(VB_PERIOD) + stop_node(self.nodes[0], 0) + wait_bitcoinds() + # Empty out the alert file + with open(self.alert_filename, 'w') as f: + pass + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) + + # Connecting one block should be enough to generate an error. + self.nodes[0].generate(1) + assert(len(self.nodes[0].getinfo()["errors"]) != 0) + stop_node(self.nodes[0], 0) + wait_bitcoinds() + self.test_versionbits_in_alert_file() + + # Test framework expects the node to still be running... + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) + + +if __name__ == '__main__': + VersionBitsWarningTest().main() From ec143391ef791c15c0d4520befb8863b61bfc2ea Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 1 Mar 2016 09:28:16 -0500 Subject: [PATCH 0318/1223] Tests: make prioritise_transaction.py more robust --- qa/rpc-tests/prioritise_transaction.py | 33 +++++++++++++++++++------- qa/rpc-tests/test_framework/util.py | 6 +++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 506466705..f8d9063b4 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -9,8 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import COIN - +from test_framework.mininode import COIN, MAX_BLOCK_SIZE class PrioritiseTransactionTest(BitcoinTestFramework): @@ -29,14 +28,29 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] def run_test(self): - utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) + utxo_count = 90 + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], utxo_count) base_fee = self.relayfee*100 # our transactions are smaller than 100kb txids = [] # Create 3 batches of transactions at 3 different fee rate levels + range_size = utxo_count // 3 for i in xrange(3): txids.append([]) - txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) + start_range = i * range_size + end_range = start_range + range_size + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], (i+1)*base_fee) + + # Make sure that the size of each group of transactions exceeds + # MAX_BLOCK_SIZE -- otherwise the test needs to be revised to create + # more transactions. + mempool = self.nodes[0].getrawmempool(True) + sizes = [0, 0, 0] + for i in xrange(3): + for j in txids[i]: + assert(j in mempool) + sizes[i] += mempool[j]['size'] + assert(sizes[i] > MAX_BLOCK_SIZE) # Fail => raise utxo_count # add a fee delta to something in the cheapest bucket and make sure it gets mined # also check that a different entry in the cheapest bucket is NOT mined (lower @@ -47,7 +61,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.nodes[0].generate(1) mempool = self.nodes[0].getrawmempool() - print "Assert that prioritised transasction was mined" + print "Assert that prioritised transaction was mined" assert(txids[0][0] not in mempool) assert(txids[0][1] in mempool) @@ -60,7 +74,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): assert(high_fee_tx != None) # Add a prioritisation before a tx is in the mempool (de-prioritising a - # high-fee transaction). + # high-fee transaction so that it's now low fee). self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN)) # Add everything back to mempool @@ -70,8 +84,11 @@ class PrioritiseTransactionTest(BitcoinTestFramework): mempool = self.nodes[0].getrawmempool() assert(high_fee_tx in mempool) - # Now verify the high feerate transaction isn't mined. - self.nodes[0].generate(5) + # Now verify the modified-high feerate transaction isn't mined before + # the other high fee transactions. Keep mining until our mempool has + # decreased by all the high fee size that we calculated above. + while (self.nodes[0].getmempoolinfo()['bytes'] > sizes[0] + sizes[1]): + self.nodes[0].generate(1) # High fee transaction should not have been mined, but other high fee rate # transactions should have been. diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index ce3102988..8d4bd52b9 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -448,6 +448,8 @@ def assert_is_hash_string(string, length=64): def satoshi_round(amount): return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) +# Helper to create at least "count" utxos +# Pass in a fee that is sufficient for relay and mining new transactions. def create_confirmed_utxos(fee, node, count): node.generate(int(0.5*count)+101) utxos = node.listunspent() @@ -475,6 +477,8 @@ def create_confirmed_utxos(fee, node, count): assert(len(utxos) >= count) return utxos +# Create large OP_RETURN txouts that can be appended to a transaction +# to make it large (helper for constructing large transactions). def gen_return_txouts(): # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create # So we have big transactions (and therefore can't fit very many into each block) @@ -501,6 +505,8 @@ def create_tx(node, coinbase, to_address, amount): assert_equal(signresult["complete"], True) return signresult["hex"] +# Create a spend of each passed-in utxo, splicing in "txouts" to each raw +# transaction to make it large. See gen_return_txouts() above. def create_lots_of_big_transactions(node, txouts, utxos, fee): addr = node.getnewaddress() txids = [] From 982670c333aff6d5660c18ed00931df764733529 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 4 Dec 2015 15:01:22 -0500 Subject: [PATCH 0319/1223] Add LockPoints Obtain LockPoints to store in CTxMemPoolEntry and during a reorg, evaluate whether they are still valid and if not, recalculate them. --- src/main.cpp | 89 ++++++++++++++++++++++++++++++--------- src/main.h | 12 +++++- src/test/test_bitcoin.cpp | 2 +- src/test/test_bitcoin.h | 4 +- src/txmempool.cpp | 18 ++++++-- src/txmempool.h | 32 +++++++++++++- 6 files changed, 131 insertions(+), 26 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index babdff54e..525d9902b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -794,7 +794,25 @@ bool SequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeig return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block)); } -bool CheckSequenceLocks(const CTransaction &tx, int flags) +bool TestLockPointValidity(const LockPoints* lp) +{ + AssertLockHeld(cs_main); + assert(lp); + // If there are relative lock times then the maxInputBlock will be set + // If there are no relative lock times, the LockPoints don't depend on the chain + if (lp->maxInputBlock) { + // Check whether chainActive is an extension of the block at which the LockPoints + // calculation was valid. If not LockPoints are no longer valid + if (!chainActive.Contains(lp->maxInputBlock)) { + return false; + } + } + + // LockPoints still valid + return true; +} + +bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool useExistingLockPoints) { AssertLockHeld(cs_main); AssertLockHeld(mempool.cs); @@ -810,25 +828,57 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags) // *next* block, we need to use one more than chainActive.Height() index.nHeight = tip->nHeight + 1; - // pcoinsTip contains the UTXO set for chainActive.Tip() - CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); - std::vector prevheights; - prevheights.resize(tx.vin.size()); - for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { - const CTxIn& txin = tx.vin[txinIndex]; - CCoins coins; - if (!viewMemPool.GetCoins(txin.prevout.hash, coins)) { - return error("%s: Missing input", __func__); + std::pair lockPair; + if (useExistingLockPoints) { + assert(lp); + lockPair.first = lp->height; + lockPair.second = lp->time; + } + else { + // pcoinsTip contains the UTXO set for chainActive.Tip() + CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); + std::vector prevheights; + prevheights.resize(tx.vin.size()); + for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { + const CTxIn& txin = tx.vin[txinIndex]; + CCoins coins; + if (!viewMemPool.GetCoins(txin.prevout.hash, coins)) { + return error("%s: Missing input", __func__); + } + if (coins.nHeight == MEMPOOL_HEIGHT) { + // Assume all mempool transaction confirm in the next block + prevheights[txinIndex] = tip->nHeight + 1; + } else { + prevheights[txinIndex] = coins.nHeight; + } } - if (coins.nHeight == MEMPOOL_HEIGHT) { - // Assume all mempool transaction confirm in the next block - prevheights[txinIndex] = tip->nHeight + 1; - } else { - prevheights[txinIndex] = coins.nHeight; + lockPair = CalculateSequenceLocks(tx, flags, &prevheights, index); + if (lp) { + lp->height = lockPair.first; + lp->time = lockPair.second; + // Also store the hash of the block with the highest height of + // all the blocks which have sequence locked prevouts. + // This hash needs to still be on the chain + // for these LockPoint calculations to be valid + // Note: It is impossible to correctly calculate a maxInputBlock + // if any of the sequence locked inputs depend on unconfirmed txs, + // except in the special case where the relative lock time/height + // is 0, which is equivalent to no sequence lock. Since we assume + // input height of tip+1 for mempool txs and test the resulting + // lockPair from CalculateSequenceLocks against tip+1. We know + // EvaluateSequenceLocks will fail if there was a non-zero sequence + // lock on a mempool input, so we can use the return value of + // CheckSequenceLocks to indicate the LockPoints validity + int maxInputHeight = 0; + BOOST_FOREACH(int height, prevheights) { + // Can ignore mempool inputs since we'll fail if they had non-zero locks + if (height != tip->nHeight+1) { + maxInputHeight = std::max(maxInputHeight, height); + } + } + lp->maxInputBlock = tip->GetAncestor(maxInputHeight); } } - - std::pair lockPair = CalculateSequenceLocks(tx, flags, &prevheights, index); return EvaluateSequenceLocks(index, lockPair); } @@ -1017,6 +1067,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CCoinsViewCache view(&dummy); CAmount nValueIn = 0; + LockPoints lp; { LOCK(pool.cs); CCoinsViewMemPool viewMemPool(pcoinsTip, pool); @@ -1060,7 +1111,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // be mined yet. // Must keep pool.cs for this unless we change CheckSequenceLocks to take a // CoinsViewCache instead of create its own - if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) + if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final"); } @@ -1092,7 +1143,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } } - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps); + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps, lp); unsigned int nSize = entry.GetTxSize(); // Check that the transaction doesn't have an excessive number of diff --git a/src/main.h b/src/main.h index 5ba2be251..85ec60ac6 100644 --- a/src/main.h +++ b/src/main.h @@ -39,6 +39,7 @@ class CValidationInterface; class CValidationState; struct CNodeStateStats; +struct LockPoints; /** Default for accepting alerts from the P2P network. */ static const bool DEFAULT_ALERTS = true; @@ -368,6 +369,11 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); */ bool CheckFinalTx(const CTransaction &tx, int flags = -1); +/** + * Test whether the LockPoints height and time are still valid on the current chain + */ +bool TestLockPointValidity(const LockPoints* lp); + /** * Check if transaction is final per BIP 68 sequence numbers and can be included in a block. * Consensus critical. Takes as input a list of heights at which tx's inputs (in order) confirmed. @@ -378,10 +384,14 @@ bool SequenceLocks(const CTransaction &tx, int flags, std::vector* prevHeig * Check if transaction will be BIP 68 final in the next block to be created. * * Simulates calling SequenceLocks() with data from the tip of the current active chain. + * Optionally stores in LockPoints the resulting height and time calculated and the hash + * of the block needed for calculation or skips the calculation and uses the LockPoints + * passed in for evaluation. + * The LockPoints should not be considered valid if CheckSequenceLocks returns false. * * See consensus/consensus.h for flag definitions. */ -bool CheckSequenceLocks(const CTransaction &tx, int flags); +bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp = NULL, bool useExistingLockPoints = false); /** * Closure representing one script verification diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 0416d0c92..a272018cf 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -151,7 +151,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPo CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, - hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount); + hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount, lp); } void Shutdown(void* parg) diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index c62392088..769ae5a13 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -9,6 +9,7 @@ #include "key.h" #include "pubkey.h" #include "txdb.h" +#include "txmempool.h" #include #include @@ -71,7 +72,8 @@ struct TestMemPoolEntryHelper bool hadNoDependencies; bool spendsCoinbase; unsigned int sigOpCount; - + LockPoints lp; + TestMemPoolEntryHelper() : nFee(0), nTime(0), dPriority(0.0), nHeight(1), hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0b0f32e40..5f814749b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -22,10 +22,10 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, - bool _spendsCoinbase, unsigned int _sigOps): + bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp): tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), - spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps) + spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp) { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); @@ -61,6 +61,11 @@ void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) feeDelta = newFeeDelta; } +void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp) +{ + lockPoints = lp; +} + // Update the given tx for any in-mempool descendants. // Assumes that setMemPoolChildren is correct for the given tx and all // descendants. @@ -506,7 +511,11 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem list transactionsToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - if (!CheckFinalTx(tx, flags) || !CheckSequenceLocks(tx, flags)) { + LockPoints lp = it->GetLockPoints(); + bool validLP = TestLockPointValidity(&lp); + if (!CheckFinalTx(tx, flags) || !CheckSequenceLocks(tx, flags, &lp, validLP)) { + // Note if CheckSequenceLocks fails the LockPoints may still be invalid + // So it's critical that we remove the tx and not depend on the LockPoints. transactionsToRemove.push_back(tx); } else if (it->GetSpendsCoinbase()) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -521,6 +530,9 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem } } } + if (!validLP) { + mapTx.modify(it, update_lock_points(lp)); + } } BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { list removed; diff --git a/src/txmempool.h b/src/txmempool.h index 386cb26d2..5997346b0 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -19,6 +19,7 @@ #include "boost/multi_index/ordered_index.hpp" class CAutoFile; +class CBlockIndex; inline double AllowFreeThreshold() { @@ -35,6 +36,21 @@ inline bool AllowFree(double dPriority) /** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */ static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF; +struct LockPoints +{ + // Will be set to the blockchain height and median time past + // values that would be necessary to satisfy all relative locktime + // constraints (BIP68) of this tx given our view of block chain history + int height; + int64_t time; + // As long as the current chain descends from the highest height block + // containing one of the inputs used in the calculation, then the cached + // values are still valid even after a reorg. + CBlockIndex* maxInputBlock; + + LockPoints() : height(0), time(0), maxInputBlock(NULL) { } +}; + class CTxMemPool; /** \class CTxMemPoolEntry @@ -70,6 +86,7 @@ private: bool spendsCoinbase; //! keep track of transactions that spend a coinbase unsigned int sigOpCount; //! Legacy sig ops plus P2SH sig op count int64_t feeDelta; //! Used for determining the priority of the transaction for mining in a block + LockPoints lockPoints; //! Track the height and time at which tx was final // Information about descendants of this transaction that are in the // mempool; if we remove this transaction we must remove all of these @@ -84,7 +101,7 @@ public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase, - unsigned int nSigOps); + unsigned int nSigOps, LockPoints lp); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } @@ -101,12 +118,15 @@ public: unsigned int GetSigOpCount() const { return sigOpCount; } int64_t GetModifiedFee() const { return nFee + feeDelta; } size_t DynamicMemoryUsage() const { return nUsageSize; } + const LockPoints& GetLockPoints() const { return lockPoints; } // Adjusts the descendant state, if this entry is not dirty. void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); // Updates the fee delta used for mining priority score, and the // modified fees with descendants. void UpdateFeeDelta(int64_t feeDelta); + // Update the LockPoints after a reorg + void UpdateLockPoints(const LockPoints& lp); /** We can set the entry to be dirty if doing the full calculation of in- * mempool descendants will be too expensive, which can potentially happen @@ -154,6 +174,16 @@ private: int64_t feeDelta; }; +struct update_lock_points +{ + update_lock_points(const LockPoints& _lp) : lp(_lp) { } + + void operator() (CTxMemPoolEntry &e) { e.UpdateLockPoints(lp); } + +private: + const LockPoints& lp; +}; + // extracts a TxMemPoolEntry's transaction hash struct mempoolentry_txid { From fa4a52254178655f50e73b50153730a60ffafd32 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 6 Mar 2016 18:30:51 +0100 Subject: [PATCH 0320/1223] [qa] Add tests verifychain, lockunspent, getbalance, listsinceblock --- qa/rpc-tests/blockchain.py | 2 ++ qa/rpc-tests/mempool_limit.py | 1 - qa/rpc-tests/mempool_packages.py | 1 + qa/rpc-tests/wallet.py | 21 ++++++++++++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 7045ae435..272a5dc15 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -28,6 +28,7 @@ class BlockchainTest(BitcoinTestFramework): Test blockchain-related RPC calls: - gettxoutsetinfo + - verifychain """ @@ -44,6 +45,7 @@ class BlockchainTest(BitcoinTestFramework): def run_test(self): self._test_gettxoutsetinfo() self._test_getblockheader() + self.nodes[0].verifychain(4, 0) def _test_gettxoutsetinfo(self): node = self.nodes[0] diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index 7914ceea2..c19a63c69 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -38,7 +38,6 @@ class MempoolLimitTest(BitcoinTestFramework): self.nodes[0].settxfee(0) # return to automatic fee selection txFS = self.nodes[0].signrawtransaction(txF['hex']) txid = self.nodes[0].sendrawtransaction(txFS['hex']) - self.nodes[0].lockunspent(True, [us0]) relayfee = self.nodes[0].getnetworkinfo()['relayfee'] base_fee = relayfee*100 diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 6109cb026..bc3f9e051 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -7,6 +7,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import COIN MAX_ANCESTORS = 25 MAX_DESCENDANTS = 25 diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 3cd495deb..e52d4e766 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -59,6 +59,15 @@ class WalletTest (BitcoinTestFramework): self.nodes[0].generate(1) self.sync_all() + # Exercise locking of unspent outputs + unspent_0 = self.nodes[2].listunspent()[0] + unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} + self.nodes[2].lockunspent(False, [unspent_0]) + assert_raises(JSONRPCException, self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) + assert_equal([unspent_0], self.nodes[2].listlockunspent()) + self.nodes[2].lockunspent(True, [unspent_0]) + assert_equal(len(self.nodes[2].listlockunspent()), 0) + # Have node1 generate 100 blocks (so node0 can recover the fee) self.nodes[1].generate(100) self.sync_all() @@ -148,6 +157,10 @@ class WalletTest (BitcoinTestFramework): assert(txid1 in self.nodes[3].getrawmempool()) + # Exercise balance rpcs + assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1) + assert_equal(self.nodes[0].getunconfirmedbalance(), 1) + #check if we can list zero value tx as available coins #1. create rawtx #2. hex-changed one output to 0.0 @@ -251,7 +264,7 @@ class WalletTest (BitcoinTestFramework): #check if wallet or blochchain maintenance changes the balance self.sync_all() - self.nodes[0].generate(1) + blocks = self.nodes[0].generate(2) self.sync_all() balance_nodes = [self.nodes[i].getbalance() for i in range(3)] @@ -269,6 +282,12 @@ class WalletTest (BitcoinTestFramework): self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) + # Exercise listsinceblock with the last two blocks + coinbase_tx_1 = self.nodes[0].listsinceblock(blocks[0]) + assert_equal(coinbase_tx_1["lastblock"], blocks[1]) + assert_equal(len(coinbase_tx_1["transactions"]), 1) + assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1]) + assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) if __name__ == '__main__': WalletTest ().main () From fae8467d416c193e3b2892bceafde478a23a36c5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 17 Mar 2016 14:52:55 +0100 Subject: [PATCH 0321/1223] [qt] Remove unneeded "fSendFreeTransactions" check --- src/qt/sendcoinsdialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index e11ffd1b7..780a6c970 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -104,8 +104,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE); if (!settings.contains("fPayOnlyMinFee")) settings.setValue("fPayOnlyMinFee", false); - if (!settings.contains("fSendFreeTransactions")) - settings.setValue("fSendFreeTransactions", false); ui->groupFee->setId(ui->radioSmartFee, 0); ui->groupFee->setId(ui->radioCustomFee, 1); ui->groupFee->button((int)std::max(0, std::min(1, settings.value("nFeeRadio").toInt())))->setChecked(true); From fab688049402a111b32df6ca0765d3bcbb2d6ab5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 17 Mar 2016 16:47:15 +0100 Subject: [PATCH 0322/1223] [qa] Add amount tests --- src/Makefile.test.include | 1 + src/test/amount_tests.cpp | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/test/amount_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 0c4e47a14..000d2af61 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -38,6 +38,7 @@ BITCOIN_TESTS =\ test/scriptnum10.h \ test/addrman_tests.cpp \ test/alert_tests.cpp \ + test/amount_tests.cpp \ test/allocator_tests.cpp \ test/base32_tests.cpp \ test/base58_tests.cpp \ diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp new file mode 100644 index 000000000..59dab2063 --- /dev/null +++ b/src/test/amount_tests.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amount.h" +#include "test/test_bitcoin.h" + +#include + +BOOST_FIXTURE_TEST_SUITE(amount_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(GetFeeTest) +{ + CFeeRate feeRate; + + feeRate = CFeeRate(0); + // Must always return 0 + BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); + BOOST_CHECK_EQUAL(feeRate.GetFee(1e5), 0); + + feeRate = CFeeRate(1000); + // Must always just return the arg + BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); + BOOST_CHECK_EQUAL(feeRate.GetFee(1), 1); + BOOST_CHECK_EQUAL(feeRate.GetFee(121), 121); + BOOST_CHECK_EQUAL(feeRate.GetFee(999), 999); + BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 1e3); + BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 9e3); + + feeRate = CFeeRate(123); + // Truncates the result, if not integer + BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); + BOOST_CHECK_EQUAL(feeRate.GetFee(8), 1); // Special case: returns 1 instead of 0 + BOOST_CHECK_EQUAL(feeRate.GetFee(9), 1); + BOOST_CHECK_EQUAL(feeRate.GetFee(121), 14); + BOOST_CHECK_EQUAL(feeRate.GetFee(122), 15); + BOOST_CHECK_EQUAL(feeRate.GetFee(999), 122); + BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 123); + BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 1107); +} + +BOOST_AUTO_TEST_SUITE_END() From faf756ae4ed63a31f073c09f3d0f25c13971cb98 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 9 Mar 2016 12:54:55 +0100 Subject: [PATCH 0323/1223] [amount] Make GetFee() monotonic This reverts the hard-to-read and buggy code introduced in d88af560111863c3e9c1ae855dcc287f04dffb02 and adds documentation --- src/amount.cpp | 6 +++--- src/amount.h | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/amount.cpp b/src/amount.cpp index a3abd8cd8..d03ed5cfa 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -19,10 +19,10 @@ CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) CAmount CFeeRate::GetFee(size_t nSize) const { - CAmount nFee = nSatoshisPerK*nSize / 1000; + CAmount nFee = nSatoshisPerK * nSize / 1000; - if (nFee == 0 && nSatoshisPerK > 0) - nFee = nSatoshisPerK; + if (nFee == 0 && nSize != 0 && nSatoshisPerK != 0) + nFee = CAmount(1); return nFee; } diff --git a/src/amount.h b/src/amount.h index a48b17d51..9aba6525c 100644 --- a/src/amount.h +++ b/src/amount.h @@ -42,10 +42,14 @@ public: explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } CFeeRate(const CAmount& nFeePaid, size_t nSize); CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } - - CAmount GetFee(size_t size) const; // unit returned is satoshis - CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes - + /** + * Return the fee in satoshis for the given size in bytes. + */ + CAmount GetFee(size_t size) const; + /** + * Return the fee in satoshis for a size of 1000 bytes + */ + CAmount GetFeePerK() const { return GetFee(1000); } friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; } friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; } friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; } From e38781da40f862d4fa45bd23923d8665709e6f7a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 17 Mar 2016 20:23:29 -0400 Subject: [PATCH 0324/1223] Tests: fix missing import in mempool_packages --- qa/rpc-tests/mempool_packages.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 6109cb026..bc3f9e051 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -7,6 +7,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import COIN MAX_ANCESTORS = 25 MAX_DESCENDANTS = 25 From 5fd2318d2dbb870939e101ce45b192d00fadacc5 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 18 Mar 2016 09:03:58 +0800 Subject: [PATCH 0325/1223] [Depends] Miniupnpc 1.9.20160209 2016/01/24: Change miniwget to return HTTP status code Increments API_VERSION to 16 2016/01/22: Improve UPNPIGD_IsConnected() to check if WAN address is not private. Parse HTTP response status line in miniwget.c --- depends/packages/miniupnpc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 3d5a6df97..45fa03631 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=1.9.20151026 +$(package)_version=1.9.20160209 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=f3cf9a5a31588a917d4d9237e5bc50f84d00c5aa48e27ed50d9b88dfa6a25d47 +$(package)_sha256_hash=572171eacc1d72537ce47b6f4571260757ab7bcfdaf54c3a55c7f88594d94b6f define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" From c85f4757b856c617684a8fef85c95ca9973ae91c Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 18 Mar 2016 09:06:08 +0800 Subject: [PATCH 0326/1223] [Depends] Latest config.guess & config.sub --- depends/config.guess | 90 +++++++++++++++++++++++--------------------- depends/config.sub | 12 +++--- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/depends/config.guess b/depends/config.guess index fba6e87a0..373a659a0 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-11-19' +timestamp='2016-02-11' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ timestamp='2015-11-19' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -237,6 +237,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -268,42 +272,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -376,16 +380,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -410,7 +414,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -635,13 +639,13 @@ EOF sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -684,7 +688,7 @@ EOF test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -700,9 +704,9 @@ EOF if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -807,14 +811,14 @@ EOF echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -919,7 +923,7 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -1285,7 +1289,7 @@ EOF UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -1309,7 +1313,7 @@ EOF exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1340,7 +1344,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1394,7 +1398,7 @@ EOF echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs + echo x86_64-unknown-onefs exit ;; esac @@ -1405,9 +1409,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/depends/config.sub b/depends/config.sub index ea8747d30..6223dde93 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-11-22' +timestamp='2016-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2015-11-22' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -520,7 +520,7 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) + asmjs) basic_machine=asmjs-unknown ;; aux) @@ -1382,7 +1382,7 @@ case $os in | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ From 0f176927f88084f2f1ce329656878d122fb64623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 18 Mar 2016 04:14:19 +0000 Subject: [PATCH 0327/1223] Improve COutPoint less operator --- src/primitives/transaction.h | 3 ++- src/uint256.h | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 07ae39e0b..e124dca36 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -34,7 +34,8 @@ public: friend bool operator<(const COutPoint& a, const COutPoint& b) { - return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + int cmp = a.hash.Compare(b.hash); + return cmp < 0 || (cmp == 0 && a.n < b.n); } friend bool operator==(const COutPoint& a, const COutPoint& b) diff --git a/src/uint256.h b/src/uint256.h index 4495000f2..bcdb6dd7c 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -42,9 +42,11 @@ public: memset(data, 0, sizeof(data)); } - friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; } - friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; } - friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; } + inline int Compare(const base_blob& other) const { return memcmp(data, other.data, sizeof(data)); } + + friend inline bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } + friend inline bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } + friend inline bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } std::string GetHex() const; void SetHex(const char* psz); From 65751a3cf2421a9419172949cad9dc49b7383551 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 20 Feb 2016 23:37:13 +0100 Subject: [PATCH 0328/1223] Add CHECKSEQUENCEVERIFY softfork through BIP9 --- src/chainparams.cpp | 17 ++++++++++++++++- src/consensus/params.h | 1 + src/main.cpp | 5 +++++ src/rpc/blockchain.cpp | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 35e090a0b..f48937d67 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -86,7 +86,13 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 - /** + + // Deployment of BIP68, BIP112, and BIP113. + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 + + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce * a large 32-bit integer with any alignment. @@ -172,6 +178,12 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 + + // Deployment of BIP68, BIP112, and BIP113. + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -240,6 +252,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; diff --git a/src/consensus/params.h b/src/consensus/params.h index 7c3a8e84c..4f3480b89 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -15,6 +15,7 @@ namespace Consensus { enum DeploymentPos { DEPLOYMENT_TESTDUMMY, + DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. MAX_VERSION_BITS_DEPLOYMENTS }; diff --git a/src/main.cpp b/src/main.cpp index 1bc88326b..cfa69817b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2262,6 +2262,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; } + // Start enforcing CHECKSEQUENCEVERIFY using versionbits logic. + if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { + flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + } + int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a110dff0d..f5d75c20b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -681,6 +681,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); + bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV)); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); From 478fba6d5213a3f1ffeca5feeacf28aaf6844fd6 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Tue, 16 Feb 2016 16:33:31 +0000 Subject: [PATCH 0329/1223] Soft fork logic for BIP113 --- src/main.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cfa69817b..857bf218b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3276,12 +3276,18 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; const Consensus::Params& consensusParams = Params().GetConsensus(); + // Start enforcing BIP113 (Median Time Past) using versionbits logic. + int nLockTimeFlags = 0; + if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { + nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST; + } + + int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) + ? pindexPrev->GetMedianTimePast() + : block.GetBlockTime(); + // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, block.vtx) { - int nLockTimeFlags = 0; - int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) - ? pindexPrev->GetMedianTimePast() - : block.GetBlockTime(); if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) { return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction"); } From 02c243580295a7f1c0298fcd9afc2e76b607e724 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Tue, 16 Feb 2016 16:37:43 +0000 Subject: [PATCH 0330/1223] Soft fork logic for BIP68 --- src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 857bf218b..f74cb3057 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2262,9 +2262,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; } - // Start enforcing CHECKSEQUENCEVERIFY using versionbits logic. + // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. + int nLockTimeFlags = 0; if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; } int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; @@ -2275,7 +2277,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); std::vector prevheights; - int nLockTimeFlags = 0; CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; From 12c89c918534f8e615e80381b692d89d6b09d174 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 19 Feb 2016 19:52:31 +0000 Subject: [PATCH 0331/1223] Policy: allow transaction version 2 relay policy. This commit introduces a way to gracefully bump the default transaction version in a two step process. --- src/policy/policy.cpp | 2 +- src/primitives/transaction.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 332abc430..e3ed7be00 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -55,7 +55,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) bool IsStandardTx(const CTransaction& tx, std::string& reason) { - if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { + if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; return false; } diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 07ae39e0b..9f7d6f394 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -206,8 +206,15 @@ private: void UpdateHash() const; public: + // Default transaction version. static const int32_t CURRENT_VERSION=1; + // Changing the default transaction version requires a two step process: first + // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date + // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and + // MAX_STANDARD_VERSION will be equal. + static const int32_t MAX_STANDARD_VERSION=2; + // The local variables are made const to prevent unintended modification // without updating the cached hash value. However, CTransaction is not // actually immutable; deserialization and assignment are implemented, From 19d73d540c8de4a73b5b2a05bebd762e74890a20 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 10 Mar 2016 18:36:55 -0500 Subject: [PATCH 0332/1223] Add RPC test for BIP 68/112/113 soft fork. This RPC test will test both the activation mechanism of the first versionbits soft fork as well as testing many code branches of the consensus logic for BIP's 68, 112, and 113. --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/bip68-112-113-p2p.py | 547 ++++++++++++++++++++++++++++++ 2 files changed, 548 insertions(+) create mode 100755 qa/rpc-tests/bip68-112-113-p2p.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index f15eaacbd..cbc10abd2 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -83,6 +83,7 @@ if EXEEXT == ".exe" and "-win" not in opts: #Tests testScripts = [ + 'bip68-112-113-p2p.py', 'wallet.py', 'listtransactions.py', 'receivedby.py', diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py new file mode 100755 index 000000000..c226f4dad --- /dev/null +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -0,0 +1,547 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.mininode import ToHex, CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block +from test_framework.comptool import TestInstance, TestManager +from test_framework.script import * +from binascii import unhexlify +import cStringIO +import time + +''' +This test is meant to exercise activation of the first version bits soft fork +This soft fork will activate the following BIPS: +BIP 68 - nSequence relative lock times +BIP 112 - CHECKSEQUENCEVERIFY +BIP 113 - MedianTimePast semantics for nLockTime + +regtest lock-in with 108/144 block signalling +activation after a further 144 blocks + +mine 82 blocks whose coinbases will be used to generate inputs for our tests +mine 61 blocks to transition from DEFINED to STARTED +mine 144 blocks only 100 of which are signaling readiness in order to fail to change state this period +mine 144 blocks with 108 signaling and verify STARTED->LOCKED_IN +mine 140 blocks and seed block chain with the 82 inputs will use for our tests at height 572 +mine 3 blocks and verify still at LOCKED_IN and test that enforcement has not triggered +mine 1 block and test that enforcement has triggered (which triggers ACTIVE) +Test BIP 113 is enforced +Mine 4 blocks so next height is 580 and test BIP 68 is enforced for time and height +Mine 1 block so next height is 581 and test BIP 68 now passes time but not height +Mine 1 block so next height is 582 and test BIP 68 now passes time and height +Test that BIP 112 is enforced + +Various transactions will be used to test that the BIPs rules are not enforced before the soft fork activates +And that after the soft fork activates transactions pass and fail as they should according to the rules. +For each BIP, transactions of versions 1 and 2 will be tested. +---------------- +BIP 113: +bip113tx - modify the nLocktime variable + +BIP 68: +bip68txs - 16 txs with nSequence relative locktime of 10 with various bits set as per the relative_locktimes below + +BIP 112: +bip112txs_vary_nSequence - 16 txs with nSequence relative_locktimes of 10 evaluated against 10 OP_CSV OP_DROP +bip112txs_vary_nSequence_9 - 16 txs with nSequence relative_locktimes of 9 evaluated against 10 OP_CSV OP_DROP +bip112txs_vary_OP_CSV - 16 txs with nSequence = 10 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP +bip112txs_vary_OP_CSV_9 - 16 txs with nSequence = 9 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP +bip112tx_special - test negative argument to OP_CSV +''' + +base_relative_locktime = 10 +seq_disable_flag = 1<<31 +seq_random_high_bit = 1<<25 +seq_type_flag = 1<<22 +seq_random_low_bit = 1<<18 + +# b31,b25,b22,b18 represent the 31st, 25th, 22nd and 18th bits respectively in the nSequence field +# relative_locktimes[b31][b25][b22][b18] is a base_relative_locktime with the indicated bits set if their indices are 1 +relative_locktimes = [] +for b31 in xrange(2): + b25times = [] + for b25 in xrange(2): + b22times = [] + for b22 in xrange(2): + b18times = [] + for b18 in xrange(2): + rlt = base_relative_locktime + if (b31): + rlt = rlt | seq_disable_flag + if (b25): + rlt = rlt | seq_random_high_bit + if (b22): + rlt = rlt | seq_type_flag + if (b18): + rlt = rlt | seq_random_low_bit + b18times.append(rlt) + b22times.append(b18times) + b25times.append(b22times) + relative_locktimes.append(b25times) + +def all_rlt_txs(txarray): + txs = [] + for b31 in xrange(2): + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + txs.append(txarray[b31][b25][b22][b18]) + return txs + +class BIP68_112_113Test(ComparisonTestFramework): + def __init__(self): + self.num_nodes = 1 + + def setup_network(self): + # Must set the blockversion for this test + self.nodes = start_nodes(1, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=4']], + binary=[self.options.testbinary]) + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + test.run() + + def send_generic_input_tx(self, node, coinbases): + amount = Decimal("49.99") + return node.sendrawtransaction(ToHex(self.sign_transaction(node, self.create_transaction(node, node.getblock(coinbases.pop())['tx'][0], self.nodeaddress, amount)))) + + def create_transaction(self, node, txid, to_address, amount): + inputs = [{ "txid" : txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + tx = CTransaction() + f = cStringIO.StringIO(unhexlify(rawtx)) + tx.deserialize(f) + return tx + + def sign_transaction(self, node, unsignedtx): + rawtx = ToHex(unsignedtx) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + f = cStringIO.StringIO(unhexlify(signresult['hex'])) + tx.deserialize(f) + return tx + + def generate_blocks(self, number, version, test_blocks = []): + for i in xrange(number): + block = self.create_test_block([], version) + test_blocks.append([block, True]) + self.last_block_time += 600 + self.tip = block.sha256 + self.tipheight += 1 + return test_blocks + + def create_test_block(self, txs, version = 536870912): + block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600) + block.nVersion = version + block.vtx.extend(txs) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + return block + + def get_bip9_status(self, key): + info = self.nodes[0].getblockchaininfo() + for row in info['bip9_softforks']: + if row['id'] == key: + return row + raise IndexError ('key:"%s" not found' % key) + + def create_bip68txs(self, bip68inputs, txversion, locktime_delta = 0): + txs = [] + assert(len(bip68inputs) >= 16) + i = 0 + for b31 in xrange(2): + b25txs = [] + for b25 in xrange(2): + b22txs = [] + for b22 in xrange(2): + b18txs = [] + for b18 in xrange(2): + tx = self.create_transaction(self.nodes[0], bip68inputs[i], self.nodeaddress, Decimal("49.98")) + i += 1 + tx.nVersion = txversion + tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta + b18txs.append(self.sign_transaction(self.nodes[0], tx)) + b22txs.append(b18txs) + b25txs.append(b22txs) + txs.append(b25txs) + return txs + + def create_bip112special(self, input, txversion): + tx = self.create_transaction(self.nodes[0], input, self.nodeaddress, Decimal("49.98")) + tx.nVersion = txversion + signtx = self.sign_transaction(self.nodes[0], tx) + signtx.vin[0].scriptSig = CScript([-1, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + return signtx + + def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta = 0): + txs = [] + assert(len(bip112inputs) >= 16) + i = 0 + for b31 in xrange(2): + b25txs = [] + for b25 in xrange(2): + b22txs = [] + for b22 in xrange(2): + b18txs = [] + for b18 in xrange(2): + tx = self.create_transaction(self.nodes[0], bip112inputs[i], self.nodeaddress, Decimal("49.98")) + i += 1 + if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed + tx.vin[0].nSequence = base_relative_locktime + locktime_delta + else: # vary nSequence instead, OP_CSV is fixed + tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta + tx.nVersion = txversion + signtx = self.sign_transaction(self.nodes[0], tx) + if (varyOP_CSV): + signtx.vin[0].scriptSig = CScript([relative_locktimes[b31][b25][b22][b18], OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + else: + signtx.vin[0].scriptSig = CScript([base_relative_locktime, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + b18txs.append(signtx) + b22txs.append(b18txs) + b25txs.append(b22txs) + txs.append(b25txs) + return txs + + def get_tests(self): + long_past_time = int(time.time()) - 600 * 1000 # enough to build up to 1000 blocks 10 minutes apart without worrying about getting into the future + self.nodes[0].setmocktime(long_past_time - 100) # enough so that the generated blocks will still all be before long_past_time + self.coinbase_blocks = self.nodes[0].generate(1 + 16 + 2*32 + 1) # 82 blocks generated for inputs + self.nodes[0].setmocktime(0) # set time back to present so yielded blocks aren't in the future as we advance last_block_time + self.tipheight = 82 # height of the next block to build + self.last_block_time = long_past_time + self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.nodeaddress = self.nodes[0].getnewaddress() + + assert_equal(self.get_bip9_status('csv')['status'], 'defined') + test_blocks = self.generate_blocks(61, 4) + yield TestInstance(test_blocks, sync_every_block=False) # 1 + # Advanced from DEFINED to STARTED, height = 143 + assert_equal(self.get_bip9_status('csv')['status'], 'started') + + # Fail to achieve LOCKED_IN 100 out of 144 signal bit 0 + # using a variety of bits to simulate multiple parallel softforks + test_blocks = self.generate_blocks(50, 536870913) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks(24, 536936448, test_blocks) # 0x20010000 (signalling not) + yield TestInstance(test_blocks, sync_every_block=False) # 2 + # Failed to advance past STARTED, height = 287 + assert_equal(self.get_bip9_status('csv')['status'], 'started') + + # 108 out of 144 signal bit 0 to achieve lock-in + # using a variety of bits to simulate multiple parallel softforks + test_blocks = self.generate_blocks(58, 536870913) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks(10, 536936448, test_blocks) # 0x20010000 (signalling not) + yield TestInstance(test_blocks, sync_every_block=False) # 3 + # Advanced from STARTED to LOCKED_IN, height = 431 + assert_equal(self.get_bip9_status('csv')['status'], 'locked_in') + + # 140 more version 4 blocks + test_blocks = self.generate_blocks(140, 4) + yield TestInstance(test_blocks, sync_every_block=False) # 4 + + ### Inputs at height = 572 + # Put inputs for all tests in the chain at height 572 (tip now = 571) (time increases by 600s per block) + # Note we reuse inputs for v1 and v2 txs so must test these separately + # 16 normal inputs + bip68inputs = [] + for i in xrange(16): + bip68inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) + # 2 sets of 16 inputs with 10 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) + bip112basicinputs = [] + for j in xrange(2): + inputs = [] + for i in xrange(16): + inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) + bip112basicinputs.append(inputs) + # 2 sets of 16 varied inputs with (relative_lock_time) OP_CSV OP_DROP (actually will be prepended to spending scriptSig) + bip112diverseinputs = [] + for j in xrange(2): + inputs = [] + for i in xrange(16): + inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) + bip112diverseinputs.append(inputs) + # 1 special input with -1 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) + bip112specialinput = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks) + # 1 normal input + bip113input = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks) + + self.nodes[0].setmocktime(self.last_block_time + 600) + inputblockhash = self.nodes[0].generate(1)[0] # 1 block generated for inputs to be in chain at height 572 + self.nodes[0].setmocktime(0) + self.tip = int("0x" + inputblockhash + "L", 0) + self.tipheight += 1 + self.last_block_time += 600 + assert_equal(len(self.nodes[0].getblock(inputblockhash,True)["tx"]), 82+1) + + # 2 more version 4 blocks + test_blocks = self.generate_blocks(2, 4) + yield TestInstance(test_blocks, sync_every_block=False) # 5 + # Not yet advanced to ACTIVE, height = 574 (will activate for block 576, not 575) + assert_equal(self.get_bip9_status('csv')['status'], 'locked_in') + + # Test both version 1 and version 2 transactions for all tests + # BIP113 test transaction will be modified before each use to put in appropriate block time + bip113tx_v1 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) + bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE + bip113tx_v2 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98")) + bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE + bip113tx_v2.nVersion = 2 + + # For BIP68 test all 16 relative sequence locktimes + bip68txs_v1 = self.create_bip68txs(bip68inputs, 1) + bip68txs_v2 = self.create_bip68txs(bip68inputs, 2) + + # For BIP112 test: + # 16 relative sequence locktimes of 10 against 10 OP_CSV OP_DROP inputs + bip112txs_vary_nSequence_v1 = self.create_bip112txs(bip112basicinputs[0], False, 1) + bip112txs_vary_nSequence_v2 = self.create_bip112txs(bip112basicinputs[0], False, 2) + # 16 relative sequence locktimes of 9 against 10 OP_CSV OP_DROP inputs + bip112txs_vary_nSequence_9_v1 = self.create_bip112txs(bip112basicinputs[1], False, 1, -1) + bip112txs_vary_nSequence_9_v2 = self.create_bip112txs(bip112basicinputs[1], False, 2, -1) + # sequence lock time of 10 against 16 (relative_lock_time) OP_CSV OP_DROP inputs + bip112txs_vary_OP_CSV_v1 = self.create_bip112txs(bip112diverseinputs[0], True, 1) + bip112txs_vary_OP_CSV_v2 = self.create_bip112txs(bip112diverseinputs[0], True, 2) + # sequence lock time of 9 against 16 (relative_lock_time) OP_CSV OP_DROP inputs + bip112txs_vary_OP_CSV_9_v1 = self.create_bip112txs(bip112diverseinputs[1], True, 1, -1) + bip112txs_vary_OP_CSV_9_v2 = self.create_bip112txs(bip112diverseinputs[1], True, 2, -1) + # -1 OP_CSV OP_DROP input + bip112tx_special_v1 = self.create_bip112special(bip112specialinput, 1) + bip112tx_special_v2 = self.create_bip112special(bip112specialinput, 2) + + + ### TESTING ### + ################################## + ### Before Soft Forks Activate ### + ################################## + # All txs should pass + ### Version 1 txs ### + success_txs = [] + # add BIP113 tx and -1 CSV tx + bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block + bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + success_txs.append(bip113signed1) + success_txs.append(bip112tx_special_v1) + # add BIP 68 txs + success_txs.extend(all_rlt_txs(bip68txs_v1)) + # add BIP 112 with seq=10 txs + success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1)) + success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v1)) + # try BIP 112 with seq=9 txs + success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1)) + success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v1)) + yield TestInstance([[self.create_test_block(success_txs), True]]) # 6 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + ### Version 2 txs ### + success_txs = [] + # add BIP113 tx and -1 CSV tx + bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block + bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + success_txs.append(bip113signed2) + success_txs.append(bip112tx_special_v2) + # add BIP 68 txs + success_txs.extend(all_rlt_txs(bip68txs_v2)) + # add BIP 112 with seq=10 txs + success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v2)) + success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v2)) + # try BIP 112 with seq=9 txs + success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) + success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v2)) + yield TestInstance([[self.create_test_block(success_txs), True]]) # 7 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + + # 1 more version 4 block to get us to height 575 so the fork should now be active for the next block + test_blocks = self.generate_blocks(1, 4) + yield TestInstance(test_blocks, sync_every_block=False) # 8 + assert_equal(self.get_bip9_status('csv')['status'], 'active') + + + ################################# + ### After Soft Forks Activate ### + ################################# + ### BIP 113 ### + # BIP 113 tests should now fail regardless of version number if nLockTime isn't satisfied by new rules + bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block + bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block + bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + for bip113tx in [bip113signed1, bip113signed2]: + yield TestInstance([[self.create_test_block([bip113tx]), False]]) # 9,10 + # BIP 113 tests should now pass if the locktime is < MTP + bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # = MTP of prior block (not <) but < time put on current block + bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) + bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # = MTP of prior block (not <) but < time put on current block + bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) + for bip113tx in [bip113signed1, bip113signed2]: + yield TestInstance([[self.create_test_block([bip113tx]), True]]) # 11,12 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + # Next block height = 580 after 4 blocks of random version + test_blocks = self.generate_blocks(4, 1234) + yield TestInstance(test_blocks, sync_every_block=False) # 13 + + ### BIP 68 ### + ### Version 1 txs ### + # All still pass + success_txs = [] + success_txs.extend(all_rlt_txs(bip68txs_v1)) + yield TestInstance([[self.create_test_block(success_txs), True]]) # 14 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + ### Version 2 txs ### + bip68success_txs = [] + # All txs with SEQUENCE_LOCKTIME_DISABLE_FLAG set pass + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + bip68success_txs.append(bip68txs_v2[1][b25][b22][b18]) + yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 15 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + # All txs without flag fail as we are at delta height = 8 < 10 and delta time = 8 * 600 < 10 * 512 + bip68timetxs = [] + for b25 in xrange(2): + for b18 in xrange(2): + bip68timetxs.append(bip68txs_v2[0][b25][1][b18]) + for tx in bip68timetxs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 16 - 19 + bip68heighttxs = [] + for b25 in xrange(2): + for b18 in xrange(2): + bip68heighttxs.append(bip68txs_v2[0][b25][0][b18]) + for tx in bip68heighttxs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 20 - 23 + + # Advance one block to 581 + test_blocks = self.generate_blocks(1, 1234) + yield TestInstance(test_blocks, sync_every_block=False) # 24 + + # Height txs should fail and time txs should now pass 9 * 600 > 10 * 512 + bip68success_txs.extend(bip68timetxs) + yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 25 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + for tx in bip68heighttxs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 26 - 29 + + # Advance one block to 582 + test_blocks = self.generate_blocks(1, 1234) + yield TestInstance(test_blocks, sync_every_block=False) # 30 + + # All BIP 68 txs should pass + bip68success_txs.extend(bip68heighttxs) + yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 31 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + + ### BIP 112 ### + ### Version 1 txs ### + # -1 OP_CSV tx should fail + yield TestInstance([[self.create_test_block([bip112tx_special_v1]), False]]) #32 + # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass + success_txs = [] + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + success_txs.append(bip112txs_vary_OP_CSV_v1[1][b25][b22][b18]) + success_txs.append(bip112txs_vary_OP_CSV_9_v1[1][b25][b22][b18]) + yield TestInstance([[self.create_test_block(success_txs), True]]) # 33 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + # If SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV, version 1 txs should now fail + fail_txs = [] + fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1)) + fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1)) + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + fail_txs.append(bip112txs_vary_OP_CSV_v1[0][b25][b22][b18]) + fail_txs.append(bip112txs_vary_OP_CSV_9_v1[0][b25][b22][b18]) + + for tx in fail_txs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 34 - 81 + + ### Version 2 txs ### + # -1 OP_CSV tx should fail + yield TestInstance([[self.create_test_block([bip112tx_special_v2]), False]]) #82 + + # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met) + success_txs = [] + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + success_txs.append(bip112txs_vary_OP_CSV_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV + success_txs.append(bip112txs_vary_OP_CSV_9_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV_9 + + yield TestInstance([[self.create_test_block(success_txs), True]]) # 83 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + ## SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV for all remaining txs ## + # All txs with nSequence 11 should fail either due to earlier mismatch or failing the CSV check + fail_txs = [] + fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) # 16/16 of vary_nSequence_9 + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + fail_txs.append(bip112txs_vary_OP_CSV_9_v2[0][b25][b22][b18]) # 16/16 of vary_OP_CSV_9 + + for tx in fail_txs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 84 - 107 + + # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail + fail_txs = [] + for b25 in xrange(2): + for b22 in xrange(2): + for b18 in xrange(2): + fail_txs.append(bip112txs_vary_nSequence_v2[1][b25][b22][b18]) # 8/16 of vary_nSequence + for tx in fail_txs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 108-115 + + # If sequencelock types mismatch, tx should fail + fail_txs = [] + for b25 in xrange(2): + for b18 in xrange(2): + fail_txs.append(bip112txs_vary_nSequence_v2[0][b25][1][b18]) # 12/16 of vary_nSequence + fail_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][1][b18]) # 12/16 of vary_OP_CSV + for tx in fail_txs: + yield TestInstance([[self.create_test_block([tx]), False]]) # 116-123 + + # Remaining txs should pass, just test masking works properly + success_txs = [] + for b25 in xrange(2): + for b18 in xrange(2): + success_txs.append(bip112txs_vary_nSequence_v2[0][b25][0][b18]) # 16/16 of vary_nSequence + success_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][0][b18]) # 16/16 of vary_OP_CSV + yield TestInstance([[self.create_test_block(success_txs), True]]) # 124 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + # Additional test, of checking that comparison of two time types works properly + time_txs = [] + for b25 in xrange(2): + for b18 in xrange(2): + tx = bip112txs_vary_OP_CSV_v2[0][b25][1][b18] + tx.vin[0].nSequence = base_relative_locktime | seq_type_flag + signtx = self.sign_transaction(self.nodes[0], tx) + time_txs.append(signtx) + yield TestInstance([[self.create_test_block(time_txs), True]]) # 125 + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + ### Missing aspects of test + ## Testing empty stack fails + + +if __name__ == '__main__': + BIP68_112_113Test().main() From 68d4282774d6a60c609301cddad0b652f16df4d9 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 17 Mar 2016 12:48:05 -0400 Subject: [PATCH 0333/1223] Fix calculation of balances and available coins. No longer consider coins which aren't in our mempool. Add test for regression in abandonconflict.py --- qa/rpc-tests/abandonconflict.py | 6 ++++++ src/wallet/wallet.cpp | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index 38028df07..a83aa97fc 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -83,6 +83,12 @@ class AbandonConflictTest(BitcoinTestFramework): # inputs are still spent, but change not received newbalance = self.nodes[0].getbalance() assert(newbalance == balance - Decimal("24.9996")) + # Unconfirmed received funds that are not in mempool, also shouldn't show + # up in unconfirmed balance + unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance() + assert(unconfbalance == newbalance) + # Also shouldn't show up in listunspent + assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)]) balance = newbalance # Abandon original transaction and verify inputs are available again diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1ef055e55..f1e61c710 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1578,7 +1578,7 @@ CAmount CWallet::GetUnconfirmedBalance() const for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; - if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) + if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && pcoin->InMempool()) nTotal += pcoin->GetAvailableCredit(); } } @@ -1623,7 +1623,7 @@ CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; - if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) + if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && pcoin->InMempool()) nTotal += pcoin->GetAvailableWatchOnlyCredit(); } } @@ -1668,6 +1668,11 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if (nDepth < 0) continue; + // We should not consider coins which aren't at least in our mempool + // It's possible for these to be conflicted via ancestors which we may never be able to detect + if (nDepth == 0 && !pcoin->InMempool()) + continue; + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { isminetype mine = IsMine(pcoin->vout[i]); if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && From bbb9d1d1231099122a5b0ad5dd86f3f93ce22724 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Mon, 7 Mar 2016 19:44:09 +0000 Subject: [PATCH 0334/1223] Remove p2p alert handling --- src/Makefile.am | 2 - src/Makefile.test.include | 2 +- src/alert.cpp | 266 --------------------------------- src/alert.h | 113 -------------- src/main.cpp | 62 -------- src/qt/clientmodel.cpp | 1 - src/test/alert_tests.cpp | 279 +++++++---------------------------- src/test/data/alertTests.raw | Bin 1279 -> 0 bytes 8 files changed, 52 insertions(+), 673 deletions(-) delete mode 100644 src/alert.cpp delete mode 100644 src/alert.h delete mode 100644 src/test/data/alertTests.raw diff --git a/src/Makefile.am b/src/Makefile.am index 7765ea43e..6ad7aabae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,7 +87,6 @@ endif # bitcoin core # BITCOIN_CORE_H = \ addrman.h \ - alert.h \ base58.h \ bloom.h \ chain.h \ @@ -176,7 +175,6 @@ libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CP libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ - alert.cpp \ bloom.cpp \ chain.cpp \ checkpoints.cpp \ diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 57f9ac50e..7e7bf8abe 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -29,7 +29,7 @@ JSON_TEST_FILES = \ test/data/tx_valid.json \ test/data/sighash.json -RAW_TEST_FILES = test/data/alertTests.raw +RAW_TEST_FILES = GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) diff --git a/src/alert.cpp b/src/alert.cpp deleted file mode 100644 index eb1cd5e7f..000000000 --- a/src/alert.cpp +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "alert.h" - -#include "clientversion.h" -#include "net.h" -#include "pubkey.h" -#include "timedata.h" -#include "ui_interface.h" -#include "util.h" -#include "utilstrencodings.h" - -#include -#include -#include - -#include -#include -#include -#include - -using namespace std; - -map mapAlerts; -CCriticalSection cs_mapAlerts; - -void CUnsignedAlert::SetNull() -{ - nVersion = 1; - nRelayUntil = 0; - nExpiration = 0; - nID = 0; - nCancel = 0; - setCancel.clear(); - nMinVer = 0; - nMaxVer = 0; - setSubVer.clear(); - nPriority = 0; - - strComment.clear(); - strStatusBar.clear(); - strReserved.clear(); -} - -std::string CUnsignedAlert::ToString() const -{ - std::string strSetCancel; - BOOST_FOREACH(int n, setCancel) - strSetCancel += strprintf("%d ", n); - std::string strSetSubVer; - BOOST_FOREACH(const std::string& str, setSubVer) - strSetSubVer += "\"" + str + "\" "; - return strprintf( - "CAlert(\n" - " nVersion = %d\n" - " nRelayUntil = %d\n" - " nExpiration = %d\n" - " nID = %d\n" - " nCancel = %d\n" - " setCancel = %s\n" - " nMinVer = %d\n" - " nMaxVer = %d\n" - " setSubVer = %s\n" - " nPriority = %d\n" - " strComment = \"%s\"\n" - " strStatusBar = \"%s\"\n" - ")\n", - nVersion, - nRelayUntil, - nExpiration, - nID, - nCancel, - strSetCancel, - nMinVer, - nMaxVer, - strSetSubVer, - nPriority, - strComment, - strStatusBar); -} - -void CAlert::SetNull() -{ - CUnsignedAlert::SetNull(); - vchMsg.clear(); - vchSig.clear(); -} - -bool CAlert::IsNull() const -{ - return (nExpiration == 0); -} - -uint256 CAlert::GetHash() const -{ - return Hash(this->vchMsg.begin(), this->vchMsg.end()); -} - -bool CAlert::IsInEffect() const -{ - return (GetAdjustedTime() < nExpiration); -} - -bool CAlert::Cancels(const CAlert& alert) const -{ - if (!IsInEffect()) - return false; // this was a no-op before 31403 - return (alert.nID <= nCancel || setCancel.count(alert.nID)); -} - -bool CAlert::AppliesTo(int nVersion, const std::string& strSubVerIn) const -{ - // TODO: rework for client-version-embedded-in-strSubVer ? - return (IsInEffect() && - nMinVer <= nVersion && nVersion <= nMaxVer && - (setSubVer.empty() || setSubVer.count(strSubVerIn))); -} - -bool CAlert::AppliesToMe() const -{ - return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector())); -} - -bool CAlert::RelayTo(CNode* pnode) const -{ - if (!IsInEffect()) - return false; - // don't relay to nodes which haven't sent their version message - if (pnode->nVersion == 0) - return false; - // returns true if wasn't already contained in the set - if (pnode->setKnown.insert(GetHash()).second) - { - if (AppliesTo(pnode->nVersion, pnode->strSubVer) || - AppliesToMe() || - GetAdjustedTime() < nRelayUntil) - { - pnode->PushMessage(NetMsgType::ALERT, *this); - return true; - } - } - return false; -} - -bool CAlert::CheckSignature(const std::vector& alertKey) const -{ - CPubKey key(alertKey); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CAlert::CheckSignature(): verify signature failed"); - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedAlert*)this; - return true; -} - -CAlert CAlert::getAlertByHash(const uint256 &hash) -{ - CAlert retval; - { - LOCK(cs_mapAlerts); - map::iterator mi = mapAlerts.find(hash); - if(mi != mapAlerts.end()) - retval = mi->second; - } - return retval; -} - -bool CAlert::ProcessAlert(const std::vector& alertKey, bool fThread) -{ - if (!CheckSignature(alertKey)) - return false; - if (!IsInEffect()) - return false; - - // alert.nID=max is reserved for if the alert key is - // compromised. It must have a pre-defined message, - // must never expire, must apply to all versions, - // and must cancel all previous - // alerts or it will be ignored (so an attacker can't - // send an "everything is OK, don't panic" version that - // cannot be overridden): - int maxInt = std::numeric_limits::max(); - if (nID == maxInt) - { - if (!( - nExpiration == maxInt && - nCancel == (maxInt-1) && - nMinVer == 0 && - nMaxVer == maxInt && - setSubVer.empty() && - nPriority == maxInt && - strStatusBar == "URGENT: Alert key compromised, upgrade required" - )) - return false; - } - - { - LOCK(cs_mapAlerts); - // Cancel previous alerts - for (map::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) - { - const CAlert& alert = (*mi).second; - if (Cancels(alert)) - { - LogPrint("alert", "cancelling alert %d\n", alert.nID); - uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); - mapAlerts.erase(mi++); - } - else if (!alert.IsInEffect()) - { - LogPrint("alert", "expiring alert %d\n", alert.nID); - uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); - mapAlerts.erase(mi++); - } - else - mi++; - } - - // Check if this alert has been cancelled - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) - { - const CAlert& alert = item.second; - if (alert.Cancels(*this)) - { - LogPrint("alert", "alert already cancelled by %d\n", alert.nID); - return false; - } - } - - // Add to mapAlerts - mapAlerts.insert(make_pair(GetHash(), *this)); - // Notify UI and -alertnotify if it applies to me - if(AppliesToMe()) - { - uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); - Notify(strStatusBar, fThread); - } - } - - LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); - return true; -} - -void -CAlert::Notify(const std::string& strMessage, bool fThread) -{ - std::string strCmd = GetArg("-alertnotify", ""); - if (strCmd.empty()) return; - - // Alert text should be plain ascii coming from a trusted source, but to - // be safe we first strip anything not in safeChars, then add single quotes around - // the whole string before passing it to the shell: - std::string singleQuote("'"); - std::string safeStatus = SanitizeString(strMessage); - safeStatus = singleQuote+safeStatus+singleQuote; - boost::replace_all(strCmd, "%s", safeStatus); - - if (fThread) - boost::thread t(runCommand, strCmd); // thread runs free - else - runCommand(strCmd); -} diff --git a/src/alert.h b/src/alert.h deleted file mode 100644 index 8cb86e338..000000000 --- a/src/alert.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_ALERT_H -#define BITCOIN_ALERT_H - -#include "serialize.h" -#include "sync.h" - -#include -#include -#include -#include - -class CAlert; -class CNode; -class uint256; - -extern std::map mapAlerts; -extern CCriticalSection cs_mapAlerts; - -/** Alerts are for notifying old versions if they become too obsolete and - * need to upgrade. The message is displayed in the status bar. - * Alert messages are broadcast as a vector of signed data. Unserializing may - * not read the entire buffer if the alert is for a newer version, but older - * versions can still relay the original data. - */ -class CUnsignedAlert -{ -public: - int nVersion; - int64_t nRelayUntil; // when newer nodes stop relaying to newer nodes - int64_t nExpiration; - int nID; - int nCancel; - std::set setCancel; - int nMinVer; // lowest version inclusive - int nMaxVer; // highest version inclusive - std::set setSubVer; // empty matches all - int nPriority; - - // Actions - std::string strComment; - std::string strStatusBar; - std::string strReserved; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(nRelayUntil); - READWRITE(nExpiration); - READWRITE(nID); - READWRITE(nCancel); - READWRITE(setCancel); - READWRITE(nMinVer); - READWRITE(nMaxVer); - READWRITE(setSubVer); - READWRITE(nPriority); - - READWRITE(LIMITED_STRING(strComment, 65536)); - READWRITE(LIMITED_STRING(strStatusBar, 256)); - READWRITE(LIMITED_STRING(strReserved, 256)); - } - - void SetNull(); - - std::string ToString() const; -}; - -/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ -class CAlert : public CUnsignedAlert -{ -public: - std::vector vchMsg; - std::vector vchSig; - - CAlert() - { - SetNull(); - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(vchMsg); - READWRITE(vchSig); - } - - void SetNull(); - bool IsNull() const; - uint256 GetHash() const; - bool IsInEffect() const; - bool Cancels(const CAlert& alert) const; - bool AppliesTo(int nVersion, const std::string& strSubVerIn) const; - bool AppliesToMe() const; - bool RelayTo(CNode* pnode) const; - bool CheckSignature(const std::vector& alertKey) const; - bool ProcessAlert(const std::vector& alertKey, bool fThread = true); // fThread means run -alertnotify in a free-running thread - static void Notify(const std::string& strMessage, bool fThread); - - /* - * Get copy of (active) alert object by hash. Returns a null alert if it is not found. - */ - static CAlert getAlertByHash(const uint256 &hash); -}; - -#endif // BITCOIN_ALERT_H diff --git a/src/main.cpp b/src/main.cpp index 1bc88326b..d5fb047aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,6 @@ #include "main.h" #include "addrman.h" -#include "alert.h" #include "arith_uint256.h" #include "chainparams.h" #include "checkpoints.h" @@ -4213,14 +4212,8 @@ void static CheckBlockIndex(const Consensus::Params& consensusParams) assert(nNodes == forward.size()); } -////////////////////////////////////////////////////////////////////////////// -// -// CAlert -// - std::string GetWarnings(const std::string& strFor) { - int nPriority = 0; string strStatusBar; string strRPC; string strGUI; @@ -4236,37 +4229,20 @@ std::string GetWarnings(const std::string& strFor) // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { - nPriority = 1000; strStatusBar = strGUI = strMiscWarning; } if (fLargeWorkForkFound) { - nPriority = 2000; strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { - nPriority = 2000; strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } - // Alerts - { - LOCK(cs_mapAlerts); - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) - { - const CAlert& alert = item.second; - if (alert.AppliesToMe() && alert.nPriority > nPriority) - { - nPriority = alert.nPriority; - strStatusBar = strGUI = alert.strStatusBar; - } - } - } - if (strFor == "gui") return strGUI; else if (strFor == "statusbar") @@ -4588,13 +4564,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } - // Relay alerts - { - LOCK(cs_mapAlerts); - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) - item.second.RelayTo(pfrom); - } - pfrom->fSuccessfullyConnected = true; string remoteAddr; @@ -5302,37 +5271,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (fAlerts && strCommand == NetMsgType::ALERT) - { - CAlert alert; - vRecv >> alert; - - uint256 alertHash = alert.GetHash(); - if (pfrom->setKnown.count(alertHash) == 0) - { - if (alert.ProcessAlert(chainparams.AlertKey())) - { - // Relay - pfrom->setKnown.insert(alertHash); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - alert.RelayTo(pnode); - } - } - else { - // Small DoS penalty so peers that send us lots of - // duplicate/expired/invalid-signature/whatever alerts - // eventually get banned. - // This isn't a Misbehaving(100) (immediate ban) because the - // peer might be an older or different implementation with - // a different signature key, etc. - Misbehaving(pfrom->GetId(), 10); - } - } - } - - else if (strCommand == NetMsgType::FILTERLOAD) { CBloomFilter filter; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index fb502b3c8..71a12c27f 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -8,7 +8,6 @@ #include "guiconstants.h" #include "peertablemodel.h" -#include "alert.h" #include "chainparams.h" #include "checkpoints.h" #include "clientversion.h" diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 87d35be41..ed3cce2de 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -4,253 +4,76 @@ // Unit tests for alert system -#include "alert.h" -#include "chain.h" #include "chainparams.h" -#include "clientversion.h" -#include "data/alertTests.raw.h" #include "main.h" // For PartitionCheck -#include "serialize.h" -#include "streams.h" -#include "utilstrencodings.h" #include "test/testutil.h" #include "test/test_bitcoin.h" -#include - -#include -#include #include -#if 0 -// -// alertTests contains 7 alerts, generated with this code: -// (SignAndSave code not shown, alert signing key is secret) -// -{ - CAlert alert; - alert.nRelayUntil = 60; - alert.nExpiration = 24 * 60 * 60; - alert.nID = 1; - alert.nCancel = 0; // cancels previous messages up to this ID number - alert.nMinVer = 0; // These versions are protocol versions - alert.nMaxVer = 999001; - alert.nPriority = 1; - alert.strComment = "Alert comment"; - alert.strStatusBar = "Alert 1"; +BOOST_FIXTURE_TEST_SUITE(Alert_tests, TestingSetup) - SignAndSave(alert, "test/alertTests"); - - alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); - alert.strStatusBar = "Alert 1 for Satoshi 0.1.0"; - SignAndSave(alert, "test/alertTests"); - - alert.setSubVer.insert(std::string("/Satoshi:0.2.0/")); - alert.strStatusBar = "Alert 1 for Satoshi 0.1.0, 0.2.0"; - SignAndSave(alert, "test/alertTests"); - - alert.setSubVer.clear(); - ++alert.nID; - alert.nCancel = 1; - alert.nPriority = 100; - alert.strStatusBar = "Alert 2, cancels 1"; - SignAndSave(alert, "test/alertTests"); - - alert.nExpiration += 60; - ++alert.nID; - SignAndSave(alert, "test/alertTests"); - - ++alert.nID; - alert.nMinVer = 11; - alert.nMaxVer = 22; - SignAndSave(alert, "test/alertTests"); - - ++alert.nID; - alert.strStatusBar = "Alert 2 for Satoshi 0.1.0"; - alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); - SignAndSave(alert, "test/alertTests"); - - ++alert.nID; - alert.nMinVer = 0; - alert.nMaxVer = 999999; - alert.strStatusBar = "Evil Alert'; /bin/ls; echo '"; - alert.setSubVer.clear(); - SignAndSave(alert, "test/alertTests"); -} -#endif - -struct ReadAlerts : public TestingSetup -{ - ReadAlerts() - { - std::vector vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests)); - CDataStream stream(vch, SER_DISK, CLIENT_VERSION); - try { - while (!stream.eof()) - { - CAlert alert; - stream >> alert; - alerts.push_back(alert); - } - } - catch (const std::exception&) { } - } - ~ReadAlerts() { } - - static std::vector read_lines(boost::filesystem::path filepath) - { - std::vector result; - - std::ifstream f(filepath.string().c_str()); - std::string line; - while (std::getline(f,line)) - result.push_back(line); - - return result; - } - - std::vector alerts; -}; - -BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts) - - -BOOST_AUTO_TEST_CASE(AlertApplies) -{ - SetMockTime(11); - const std::vector& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); - - BOOST_FOREACH(const CAlert& alert, alerts) - { - BOOST_CHECK(alert.CheckSignature(alertKey)); - } - - BOOST_CHECK(alerts.size() >= 3); - - // Matches: - BOOST_CHECK(alerts[0].AppliesTo(1, "")); - BOOST_CHECK(alerts[0].AppliesTo(999001, "")); - BOOST_CHECK(alerts[0].AppliesTo(1, "/Satoshi:11.11.11/")); - - BOOST_CHECK(alerts[1].AppliesTo(1, "/Satoshi:0.1.0/")); - BOOST_CHECK(alerts[1].AppliesTo(999001, "/Satoshi:0.1.0/")); - - BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.1.0/")); - BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.2.0/")); - - // Don't match: - BOOST_CHECK(!alerts[0].AppliesTo(-1, "")); - BOOST_CHECK(!alerts[0].AppliesTo(999002, "")); - - BOOST_CHECK(!alerts[1].AppliesTo(1, "")); - BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0")); - BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.1.0")); - BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0/")); - BOOST_CHECK(!alerts[1].AppliesTo(-1, "/Satoshi:0.1.0/")); - BOOST_CHECK(!alerts[1].AppliesTo(999002, "/Satoshi:0.1.0/")); - BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.2.0/")); - - BOOST_CHECK(!alerts[2].AppliesTo(1, "/Satoshi:0.3.0/")); - - SetMockTime(0); -} - - -BOOST_AUTO_TEST_CASE(AlertNotify) -{ - SetMockTime(11); - const std::vector& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); - - boost::filesystem::path temp = GetTempPath() / - boost::filesystem::unique_path("alertnotify-%%%%.txt"); - - mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); - - BOOST_FOREACH(CAlert alert, alerts) - alert.ProcessAlert(alertKey, false); - - std::vector r = read_lines(temp); - BOOST_CHECK_EQUAL(r.size(), 4u); - -// Windows built-in echo semantics are different than posixy shells. Quotes and -// whitespace are printed literally. - -#ifndef WIN32 - BOOST_CHECK_EQUAL(r[0], "Alert 1"); - BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1"); - BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1"); - BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed -#else - BOOST_CHECK_EQUAL(r[0], "'Alert 1' "); - BOOST_CHECK_EQUAL(r[1], "'Alert 2, cancels 1' "); - BOOST_CHECK_EQUAL(r[2], "'Alert 2, cancels 1' "); - BOOST_CHECK_EQUAL(r[3], "'Evil Alert; /bin/ls; echo ' "); -#endif - boost::filesystem::remove(temp); - - SetMockTime(0); -} static bool falseFunc() { return false; } BOOST_AUTO_TEST_CASE(PartitionAlert) -{ - // Test PartitionCheck - CCriticalSection csDummy; - CBlockIndex indexDummy[100]; - CChainParams& params = Params(CBaseChainParams::MAIN); - int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; + { + // Test PartitionCheck + CCriticalSection csDummy; + CBlockIndex indexDummy[100]; + CChainParams& params = Params(CBaseChainParams::MAIN); + int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; - // Generate fake blockchain timestamps relative to - // an arbitrary time: - int64_t now = 1427379054; - SetMockTime(now); - for (int i = 0; i < 100; i++) - { - indexDummy[i].phashBlock = NULL; - if (i == 0) indexDummy[i].pprev = NULL; - else indexDummy[i].pprev = &indexDummy[i-1]; - indexDummy[i].nHeight = i; - indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing; - // Other members don't matter, the partition check code doesn't - // use them - } + // Generate fake blockchain timestamps relative to + // an arbitrary time: + int64_t now = 1427379054; + SetMockTime(now); + for (int i = 0; i < 100; i++) + { + indexDummy[i].phashBlock = NULL; + if (i == 0) indexDummy[i].pprev = NULL; + else indexDummy[i].pprev = &indexDummy[i-1]; + indexDummy[i].nHeight = i; + indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing; + // Other members don't matter, the partition check code doesn't + // use them + } - strMiscWarning = ""; + strMiscWarning = ""; - // Test 1: chain with blocks every nPowTargetSpacing seconds, - // as normal, no worries: - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); + // Test 1: chain with blocks every nPowTargetSpacing seconds, + // as normal, no worries: + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); - // Test 2: go 3.5 hours without a block, expect a warning: - now += 3*60*60+30*60; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; + // Test 2: go 3.5 hours without a block, expect a warning: + now += 3*60*60+30*60; + SetMockTime(now); + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(!strMiscWarning.empty()); + BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); + strMiscWarning = ""; - // Test 3: test the "partition alerts only go off once per day" - // code: - now += 60*10; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); + // Test 3: test the "partition alerts only go off once per day" + // code: + now += 60*10; + SetMockTime(now); + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(strMiscWarning.empty()); - // Test 4: get 2.5 times as many blocks as expected: - now += 60*60*24; // Pretend it is a day later - SetMockTime(now); - int64_t quickSpacing = nPowTargetSpacing*2/5; - for (int i = 0; i < 100; i++) // Tweak chain timestamps: + // Test 4: get 2.5 times as many blocks as expected: + now += 60*60*24; // Pretend it is a day later + SetMockTime(now); + int64_t quickSpacing = nPowTargetSpacing*2/5; + for (int i = 0; i < 100; i++) // Tweak chain timestamps: indexDummy[i].nTime = now - (100-i)*quickSpacing; - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(!strMiscWarning.empty()); + BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); + strMiscWarning = ""; - SetMockTime(0); -} + SetMockTime(0); + } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/test/data/alertTests.raw b/src/test/data/alertTests.raw deleted file mode 100644 index 01f50680b95aa307a1a013b643ded4ae0bc47162..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1279 zcmZ={WME*h0b&qn2n6vM7$78=$-oe4#}5(Vb<9aEDp5$z&&^HED`AK53>n-FT$vOZ zT6;>jOMiNBjj`hU_HgHQ?~0yVcV6r{KVN{qoVTd1?j)0f{?x_?$@^IxUUY29f16*- z{-FM@nZvZ(TZ|lvBLA-{pO8$HOBng}gA+^gi!(B<4D<~34D>;|P+cYob(un1evtxH zu>x2zgPVa1lY-RE%g6XV)mGXqWBmT=!_|Y)_kR4}7A7R>c0E!g1h&KK=J$_^x?-%R>l_4VpRoijgP z&DbIlds%@=!Hs|Q$%9_UR_lD=jto@ZWi)^P&3X0fwJdjAvK+dmdHF6@N3p;h#SLVL z0Wkw{0R?f?PV@b-k5Wyi>i4_%Bo<$lHv6ySF0|S7Vr$;KnH3w}K4Ve{5mx)@H;>VG zV)PxY7R{(M)t&dXdm1tqJ%LW&jLQ5abT(~;1uVuU5DK-_v|qEX;l z`;Ea8OG>`yYWv(O?P7~*yl?IK{6}Bi%Enc$ObUtn4ofyOb8$Z~I;nGod;9)Xj~<*9 zKa_r_FRL*-b5> Date: Sun, 6 Mar 2016 10:07:25 +0000 Subject: [PATCH 0335/1223] Update alert notification and GUI --- src/main.cpp | 28 ++++++++++++++++++++++++---- src/qt/clientmodel.cpp | 26 ++++++-------------------- src/qt/clientmodel.h | 2 +- src/ui_interface.h | 5 ++--- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d5fb047aa..6c193a25e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1565,6 +1565,26 @@ bool fLargeWorkForkFound = false; bool fLargeWorkInvalidChainFound = false; CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL; +static void AlertNotify(const std::string& strMessage, bool fThread) +{ + uiInterface.NotifyAlertChanged(); + std::string strCmd = GetArg("-alertnotify", ""); + if (strCmd.empty()) return; + + // Alert text should be plain ascii coming from a trusted source, but to + // be safe we first strip anything not in safeChars, then add single quotes around + // the whole string before passing it to the shell: + std::string singleQuote("'"); + std::string safeStatus = SanitizeString(strMessage); + safeStatus = singleQuote+safeStatus+singleQuote; + boost::replace_all(strCmd, "%s", safeStatus); + + if (fThread) + boost::thread t(runCommand, strCmd); // thread runs free + else + runCommand(strCmd); +} + void CheckForkWarningConditions() { AssertLockHeld(cs_main); @@ -1584,7 +1604,7 @@ void CheckForkWarningConditions() { std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") + pindexBestForkBase->phashBlock->ToString() + std::string("'"); - CAlert::Notify(warning, true); + AlertNotify(warning, true); } if (pindexBestForkTip && pindexBestForkBase) { @@ -2115,7 +2135,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const if (!strWarning.empty()) { strMiscWarning = strWarning; - CAlert::Notify(strWarning, true); + AlertNotify(strWarning, true); lastAlertTime = now; } } @@ -2545,7 +2565,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { if (state == THRESHOLD_ACTIVE) { strMiscWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit); if (!fWarned) { - CAlert::Notify(strMiscWarning, true); + AlertNotify(strMiscWarning, true); fWarned = true; } } else { @@ -2567,7 +2587,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: strMiscWarning = _("Warning: Unknown block versions being mined! It's possible unknown rules are in effect"); if (!fWarned) { - CAlert::Notify(strMiscWarning, true); + AlertNotify(strMiscWarning, true); fWarned = true; } } diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 71a12c27f..d3edfedff 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -121,20 +121,8 @@ void ClientModel::updateNumConnections(int numConnections) Q_EMIT numConnectionsChanged(numConnections); } -void ClientModel::updateAlert(const QString &hash, int status) +void ClientModel::updateAlert() { - // Show error message notification for new alert - if(status == CT_NEW) - { - uint256 hash_256; - hash_256.SetHex(hash.toStdString()); - CAlert alert = CAlert::getAlertByHash(hash_256); - if(!alert.IsNull()) - { - Q_EMIT message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); - } - } - Q_EMIT alertsChanged(getStatusBarWarnings()); } @@ -226,12 +214,10 @@ static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConn Q_ARG(int, newNumConnections)); } -static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) +static void NotifyAlertChanged(ClientModel *clientmodel) { - qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status); - QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(hash.GetHex())), - Q_ARG(int, status)); + qDebug() << "NotifyAlertChanged"; + QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection); } static void BannedListChanged(ClientModel *clientmodel) @@ -265,7 +251,7 @@ void ClientModel::subscribeToCoreSignals() // Connect signals to client uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); - uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this)); uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2)); } @@ -275,7 +261,7 @@ void ClientModel::unsubscribeFromCoreSignals() // Disconnect signals from client uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); - uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this)); uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 62c9f71ac..2fef6131c 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -103,7 +103,7 @@ Q_SIGNALS: public Q_SLOTS: void updateTimer(); void updateNumConnections(int numConnections); - void updateAlert(const QString &hash, int status); + void updateAlert(); void updateBanlist(); }; diff --git a/src/ui_interface.h b/src/ui_interface.h index 967d24327..0b51d52e6 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -83,10 +83,9 @@ public: boost::signals2::signal NotifyNumConnectionsChanged; /** - * New, updated or cancelled alert. - * @note called with lock cs_mapAlerts held. + * Status bar alerts changed. */ - boost::signals2::signal NotifyAlertChanged; + boost::signals2::signal NotifyAlertChanged; /** A wallet has been loaded. */ boost::signals2::signal LoadWallet; From 01fdfeffc4515ea43748230139a3bcee2eec3865 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sun, 6 Mar 2016 11:15:20 +0000 Subject: [PATCH 0336/1223] Remove `-alerts` option --- src/init.cpp | 3 --- src/main.cpp | 1 - src/main.h | 3 --- 3 files changed, 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index a39256c6e..b430bcd58 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -315,7 +315,6 @@ std::string HelpMessage(HelpMessageMode mode) string strUsage = HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("Print this help message and exit")); strUsage += HelpMessageOpt("-version", _("Print version and exit")); - strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS)); strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); if (showDebug) @@ -1002,8 +1001,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); - fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS); - // Option to startup with mocktime set (used for regression testing): SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op diff --git a/src/main.cpp b/src/main.cpp index 6c193a25e..e78ce4cdf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,7 +74,6 @@ bool fCheckBlockIndex = false; bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; -bool fAlerts = DEFAULT_ALERTS; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT; diff --git a/src/main.h b/src/main.h index 6936b5379..7ec48d9d0 100644 --- a/src/main.h +++ b/src/main.h @@ -42,8 +42,6 @@ class CValidationState; struct CNodeStateStats; struct LockPoints; -/** Default for accepting alerts from the P2P network. */ -static const bool DEFAULT_ALERTS = true; /** Default for DEFAULT_WHITELISTRELAY. */ static const bool DEFAULT_WHITELISTRELAY = true; /** Default for DEFAULT_WHITELISTFORCERELAY. */ @@ -155,7 +153,6 @@ extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; /** Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendrawtransaction) */ extern CAmount maxTxFee; -extern bool fAlerts; /** If the tip is older than this (in seconds), the node is considered to be in initial block download. */ extern int64_t nMaxTipAge; extern bool fEnableReplacement; From 1b77471bd62b31b6682c5e40d2d8bf88db3034c7 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sun, 6 Mar 2016 10:38:53 +0000 Subject: [PATCH 0337/1223] Remove alert keys --- src/chainparams.cpp | 2 -- src/chainparams.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 35e090a0b..508c4de16 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -95,7 +95,6 @@ public: pchMessageStart[1] = 0xbe; pchMessageStart[2] = 0xb4; pchMessageStart[3] = 0xd9; - vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; nPruneAfterHeight = 100000; @@ -176,7 +175,6 @@ public: pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; pchMessageStart[3] = 0x07; - vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; nPruneAfterHeight = 1000; diff --git a/src/chainparams.h b/src/chainparams.h index 88bc66676..59202f548 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -54,7 +54,6 @@ public: const Consensus::Params& GetConsensus() const { return consensus; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } - const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } const CBlock& GenesisBlock() const { return genesis; } @@ -80,8 +79,6 @@ protected: Consensus::Params consensus; CMessageHeader::MessageStartChars pchMessageStart; - //! Raw pub key bytes for the broadcast alert signing key. - std::vector vAlertPubKey; int nDefaultPort; uint64_t nPruneAfterHeight; std::vector vSeeds; From ad7210408c5d2f7d13534da4f4ff1ff3afa82b3a Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Wed, 16 Mar 2016 09:13:50 +0000 Subject: [PATCH 0338/1223] Formatting --- src/test/alert_tests.cpp | 98 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index ed3cce2de..70f1f1227 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -18,62 +18,62 @@ BOOST_FIXTURE_TEST_SUITE(Alert_tests, TestingSetup) static bool falseFunc() { return false; } BOOST_AUTO_TEST_CASE(PartitionAlert) - { - // Test PartitionCheck - CCriticalSection csDummy; - CBlockIndex indexDummy[100]; - CChainParams& params = Params(CBaseChainParams::MAIN); - int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; +{ + // Test PartitionCheck + CCriticalSection csDummy; + CBlockIndex indexDummy[100]; + CChainParams& params = Params(CBaseChainParams::MAIN); + int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; - // Generate fake blockchain timestamps relative to - // an arbitrary time: - int64_t now = 1427379054; - SetMockTime(now); - for (int i = 0; i < 100; i++) - { - indexDummy[i].phashBlock = NULL; - if (i == 0) indexDummy[i].pprev = NULL; - else indexDummy[i].pprev = &indexDummy[i-1]; - indexDummy[i].nHeight = i; - indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing; - // Other members don't matter, the partition check code doesn't - // use them - } + // Generate fake blockchain timestamps relative to + // an arbitrary time: + int64_t now = 1427379054; + SetMockTime(now); + for (int i = 0; i < 100; i++) + { + indexDummy[i].phashBlock = NULL; + if (i == 0) indexDummy[i].pprev = NULL; + else indexDummy[i].pprev = &indexDummy[i-1]; + indexDummy[i].nHeight = i; + indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing; + // Other members don't matter, the partition check code doesn't + // use them + } - strMiscWarning = ""; + strMiscWarning = ""; - // Test 1: chain with blocks every nPowTargetSpacing seconds, - // as normal, no worries: - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); + // Test 1: chain with blocks every nPowTargetSpacing seconds, + // as normal, no worries: + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); - // Test 2: go 3.5 hours without a block, expect a warning: - now += 3*60*60+30*60; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; + // Test 2: go 3.5 hours without a block, expect a warning: + now += 3*60*60+30*60; + SetMockTime(now); + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(!strMiscWarning.empty()); + BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); + strMiscWarning = ""; - // Test 3: test the "partition alerts only go off once per day" - // code: - now += 60*10; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); + // Test 3: test the "partition alerts only go off once per day" + // code: + now += 60*10; + SetMockTime(now); + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(strMiscWarning.empty()); - // Test 4: get 2.5 times as many blocks as expected: - now += 60*60*24; // Pretend it is a day later - SetMockTime(now); - int64_t quickSpacing = nPowTargetSpacing*2/5; - for (int i = 0; i < 100; i++) // Tweak chain timestamps: + // Test 4: get 2.5 times as many blocks as expected: + now += 60*60*24; // Pretend it is a day later + SetMockTime(now); + int64_t quickSpacing = nPowTargetSpacing*2/5; + for (int i = 0; i < 100; i++) // Tweak chain timestamps: indexDummy[i].nTime = now - (100-i)*quickSpacing; - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; + PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); + BOOST_CHECK(!strMiscWarning.empty()); + BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); + strMiscWarning = ""; - SetMockTime(0); - } + SetMockTime(0); +} BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 6601ce508eaf2d0d853f35637a946938d31e8463 Mon Sep 17 00:00:00 2001 From: Thomas Kerin Date: Fri, 18 Mar 2016 18:20:04 +0000 Subject: [PATCH 0339/1223] protocol.h/cpp: Removes NetMsgType::ALERT --- src/protocol.cpp | 2 -- src/protocol.h | 7 ------- 2 files changed, 9 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index c1c7c0b96..1ddb65b79 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -28,7 +28,6 @@ const char *GETADDR="getaddr"; const char *MEMPOOL="mempool"; const char *PING="ping"; const char *PONG="pong"; -const char *ALERT="alert"; const char *NOTFOUND="notfound"; const char *FILTERLOAD="filterload"; const char *FILTERADD="filteradd"; @@ -64,7 +63,6 @@ const static std::string allNetMessageTypes[] = { NetMsgType::MEMPOOL, NetMsgType::PING, NetMsgType::PONG, - NetMsgType::ALERT, NetMsgType::NOTFOUND, NetMsgType::FILTERLOAD, NetMsgType::FILTERADD, diff --git a/src/protocol.h b/src/protocol.h index c8b8d20ea..5504f213f 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -163,13 +163,6 @@ extern const char *PING; * @see https://bitcoin.org/en/developer-reference#pong */ extern const char *PONG; -/** - * The alert message warns nodes of problems that may affect them or the rest - * of the network. - * @since protocol version 311. - * @see https://bitcoin.org/en/developer-reference#alert - */ -extern const char *ALERT; /** * The notfound message is a reply to a getdata message which requested an * object the receiving node does not have available for relay. From cfd519e942aecd763449157a4a5ed602bcddd3a1 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 18 Mar 2016 19:11:27 +0000 Subject: [PATCH 0340/1223] Add release note documentation --- doc/release-notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 707f2357f..43e1e3fb9 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -51,6 +51,8 @@ The following outputs are affected by this change: ### P2P protocol and network code +The p2p alert system has been removed in #7692 and the 'alert' message is no longer supported. + ### Validation ### Build system From c90036f6645dea7c19e033c11240567371407017 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Thu, 17 Mar 2016 17:23:33 -0700 Subject: [PATCH 0341/1223] Always disconnect old nodes which request filtered connections. --- doc/bips.md | 2 +- src/init.cpp | 2 -- src/main.cpp | 2 +- src/main.h | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/bips.md b/doc/bips.md index e73add013..2552a7f03 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -17,6 +17,6 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). -* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, but only enforced for peer versions `>=70011` as of **v0.12.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579)). +* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). diff --git a/src/init.cpp b/src/init.cpp index 637b69ab0..96bb26f6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -369,8 +369,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), DEFAULT_PEERBLOOMFILTERS)); - if (showDebug) - strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", DEFAULT_ENFORCENODEBLOOM)); strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); diff --git a/src/main.cpp b/src/main.cpp index 027a36394..d74c88d23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4377,7 +4377,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pfrom->nVersion >= NO_BLOOM_VERSION) { Misbehaving(pfrom->GetId(), 100); return false; - } else if (GetBoolArg("-enforcenodebloom", DEFAULT_ENFORCENODEBLOOM)) { + } else { pfrom->fDisconnect = true; return false; } diff --git a/src/main.h b/src/main.h index 5ba2be251..7230d326e 100644 --- a/src/main.h +++ b/src/main.h @@ -122,7 +122,6 @@ static const bool DEFAULT_ENABLE_REPLACEMENT = true; static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; static const bool DEFAULT_PEERBLOOMFILTERS = true; -static const bool DEFAULT_ENFORCENODEBLOOM = false; struct BlockHasher { From cf5c786fc3244b6aedcc4a2f839f5248f95fafa1 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 19 Mar 2016 15:24:00 +0800 Subject: [PATCH 0342/1223] [build-aux] Update Boost & check macros to latest serials --- build-aux/m4/ax_boost_base.m4 | 20 +- build-aux/m4/ax_boost_program_options.m4 | 7 +- build-aux/m4/ax_boost_system.m4 | 5 +- build-aux/m4/ax_check_compile_flag.m4 | 12 +- build-aux/m4/ax_check_link_flag.m4 | 13 +- build-aux/m4/ax_check_preproc_flag.m4 | 12 +- build-aux/m4/ax_gcc_func_attribute.m4 | 8 +- build-aux/m4/ax_pthread.m4 | 505 +++++++++++++++-------- 8 files changed, 379 insertions(+), 203 deletions(-) diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 3f24d5ddc..45d948933 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 23 +#serial 26 AC_DEFUN([AX_BOOST_BASE], [ @@ -95,8 +95,8 @@ if test "x$want_boost" = "xyes"; then x86_64) libsubdirs="lib64 libx32 lib lib64" ;; - ppc64|s390x|sparc64|aarch64) - libsubdirs="lib64 lib lib64" + ppc64|s390x|sparc64|aarch64|ppc64le) + libsubdirs="lib64 lib lib64 ppc64le" ;; esac @@ -170,7 +170,7 @@ if test "x$want_boost" = "xyes"; then AC_MSG_RESULT(yes) succeeded=yes found_system=yes - ],[: + ],[ ]) AC_LANG_POP([C++]) @@ -179,6 +179,10 @@ if test "x$want_boost" = "xyes"; then dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version if test "x$succeeded" != "xyes"; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + BOOST_LDFLAGS= _version=0 if test "$ac_boost_path" != ""; then if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then @@ -191,6 +195,12 @@ if test "x$want_boost" = "xyes"; then VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done + dnl if nothing found search for layout used in Windows distributions + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$ac_boost_path/boost" && test -r "$ac_boost_path/boost"; then + BOOST_CPPFLAGS="-I$ac_boost_path" + fi + fi fi else if test "$cross_compiling" != yes; then @@ -253,7 +263,7 @@ if test "x$want_boost" = "xyes"; then AC_MSG_RESULT(yes) succeeded=yes found_system=yes - ],[: + ],[ ]) AC_LANG_POP([C++]) fi diff --git a/build-aux/m4/ax_boost_program_options.m4 b/build-aux/m4/ax_boost_program_options.m4 index f59144185..2bdb59371 100644 --- a/build-aux/m4/ax_boost_program_options.m4 +++ b/build-aux/m4/ax_boost_program_options.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 22 +#serial 24 AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], [ @@ -63,9 +63,9 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], AC_CACHE_CHECK([whether the Boost::Program_Options library is available], ax_cv_boost_program_options, [AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::program_options::options_description generic("Generic options"); + [[boost::program_options::error err("Error message"); return 0;]])], ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no) AC_LANG_POP([C++]) @@ -74,7 +74,6 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` if test "x$ax_boost_user_program_options_lib" = "x"; then - ax_lib= for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.dylib* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.dylib.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a.*$;\1;'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 9c78280fc..1c05450cb 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 17 +#serial 18 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -68,9 +68,10 @@ AC_DEFUN([AX_BOOST_SYSTEM], ax_cv_boost_system, [AC_LANG_PUSH([C++]) CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS= AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::system::system_category]])], + [[boost::system::error_category *a = 0;]])], ax_cv_boost_system=yes, ax_cv_boost_system=no) CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) diff --git a/build-aux/m4/ax_check_compile_flag.m4 b/build-aux/m4/ax_check_compile_flag.m4 index c3a8d695a..ca3639715 100644 --- a/build-aux/m4/ax_check_compile_flag.m4 +++ b/build-aux/m4/ax_check_compile_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # @@ -53,19 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_check_link_flag.m4 b/build-aux/m4/ax_check_link_flag.m4 index e2d0d363e..eb01a6ce1 100644 --- a/build-aux/m4/ax_check_link_flag.m4 +++ b/build-aux/m4/ax_check_link_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. # @@ -53,18 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_LINK_FLAG], -[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS $4 $1" - AC_LINK_IFELSE([AC_LANG_PROGRAM()], + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) LDFLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_check_preproc_flag.m4 b/build-aux/m4/ax_check_preproc_flag.m4 index b1cfef6b8..ca1d5ee2b 100644 --- a/build-aux/m4/ax_check_preproc_flag.m4 +++ b/build-aux/m4/ax_check_preproc_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the # preprocessor to issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_PREPROC_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG. # @@ -53,19 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_PREPROC_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ ax_check_save_flags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $4 $1" - AC_PREPROC_IFELSE([AC_LANG_PROGRAM()], + AC_PREPROC_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) CPPFLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_gcc_func_attribute.m4 b/build-aux/m4/ax_gcc_func_attribute.m4 index 275ca63a2..c788ca9bd 100644 --- a/build-aux/m4/ax_gcc_func_attribute.m4 +++ b/build-aux/m4/ax_gcc_func_attribute.m4 @@ -31,6 +31,7 @@ # cold # const # constructor +# constructor_priority for constructor attribute with priority # deprecated # destructor # dllexport @@ -73,7 +74,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 2 +#serial 3 AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) @@ -103,6 +104,9 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [const], [ int foo( void ) __attribute__(($1)); ], + [constructor_priority], [ + int foo( void ) __attribute__((__constructor__(65535/2))); + ], [constructor], [ int foo( void ) __attribute__(($1)); ], @@ -180,6 +184,8 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [visibility], [ int foo_def( void ) __attribute__(($1("default"))); int foo_hid( void ) __attribute__(($1("hidden"))); + int foo_int( void ) __attribute__(($1("internal"))); + int foo_pro( void ) __attribute__(($1("protected"))); ], [warning], [ int foo( void ) __attribute__(($1(""))); diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index d383ad5c6..d218d1af7 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -19,10 +19,10 @@ # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" @@ -30,8 +30,8 @@ # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -82,35 +82,40 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 21 +#serial 22 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). +# requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test x"$ax_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -123,7 +128,7 @@ fi # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -132,186 +137,334 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case ${host_os} in - solaris*) +case $host_os in - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: + freebsd*) - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" - ;; + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; esac -# Clang doesn't consider unrecognized options an error unless we specify -# -Werror. We throw in some extra Clang-specific options to ensure that -# this doesn't happen for GCC, which also accepts -Werror. +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) -AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) -save_CFLAGS="$CFLAGS" -ax_pthread_extra_flags="-Werror" -CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], - [AC_MSG_RESULT([yes])], - [ax_pthread_extra_flags= - AC_MSG_RESULT([no])]) -CFLAGS="$save_CFLAGS" +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; + aix* | freebsd*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - if test x"$ax_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac +# Are we compiling with Clang? - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) +ax_pthread_clang_warning=no - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = xyes; then - break; - fi +if test "x$ax_pthread_clang" = "xyes"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" done fi # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT([$attr_name]) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - # TODO: What about Clang on Solaris? - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT([$flag]) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -321,12 +474,12 @@ AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : else - ax_pthread_ok=no - $2 + ax_pthread_ok=no + $2 fi AC_LANG_POP ])dnl AX_PTHREAD From fad13b1612b5de16d94c78c1a464d431a4f770bf Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 19 Mar 2016 15:19:29 +0100 Subject: [PATCH 0343/1223] [amount] Preempt issues with negative fee rates --- src/amount.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amount.cpp b/src/amount.cpp index d03ed5cfa..68806ff06 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -21,7 +21,7 @@ CAmount CFeeRate::GetFee(size_t nSize) const { CAmount nFee = nSatoshisPerK * nSize / 1000; - if (nFee == 0 && nSize != 0 && nSatoshisPerK != 0) + if (nFee == 0 && nSize != 0 && nSatoshisPerK > 0) nFee = CAmount(1); return nFee; From fab3890156c849e6b04309152d7a9bfcfcb98396 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 15 Nov 2015 20:41:48 +0100 Subject: [PATCH 0344/1223] [qa] rpc-test: Normalize assert() --- qa/rpc-tests/fundrawtransaction.py | 34 ++++++++++------------ qa/rpc-tests/getblocktemplate_proposals.py | 10 ++----- qa/rpc-tests/httpbasics.py | 26 ++++++++--------- qa/rpc-tests/wallet.py | 4 +-- qa/rpc-tests/zapwallettxes.py | 10 ++----- 5 files changed, 34 insertions(+), 50 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 0287965b9..445871281 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -71,7 +71,7 @@ class RawTransactionsTest(BitcoinTestFramework): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enought inputs + assert(len(dec_tx['vin']) > 0) #test if we have enought inputs ############################## # simple test with two coins # @@ -84,7 +84,7 @@ class RawTransactionsTest(BitcoinTestFramework): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs + assert(len(dec_tx['vin']) > 0) #test if we have enough inputs ############################## # simple test with two coins # @@ -97,7 +97,7 @@ class RawTransactionsTest(BitcoinTestFramework): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert_equal(len(dec_tx['vin']) > 0, True) + assert(len(dec_tx['vin']) > 0) assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') @@ -116,7 +116,7 @@ class RawTransactionsTest(BitcoinTestFramework): for out in dec_tx['vout']: totalOut += out['value'] - assert_equal(len(dec_tx['vin']) > 0, True) + assert(len(dec_tx['vin']) > 0) assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') @@ -130,7 +130,7 @@ class RawTransactionsTest(BitcoinTestFramework): utx = aUtx break - assert_equal(utx!=False, True) + assert(utx!=False) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 1.0 } @@ -159,7 +159,7 @@ class RawTransactionsTest(BitcoinTestFramework): utx = aUtx break - assert_equal(utx!=False, True) + assert(utx!=False) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance } @@ -189,7 +189,7 @@ class RawTransactionsTest(BitcoinTestFramework): utx = aUtx break - assert_equal(utx!=False, True) + assert(utx!=False) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 1.0 } @@ -234,7 +234,7 @@ class RawTransactionsTest(BitcoinTestFramework): utx2 = aUtx - assert_equal(utx!=False, True) + assert(utx!=False) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 6.0 } @@ -276,7 +276,7 @@ class RawTransactionsTest(BitcoinTestFramework): utx2 = aUtx - assert_equal(utx!=False, True) + assert(utx!=False) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 } @@ -306,14 +306,11 @@ class RawTransactionsTest(BitcoinTestFramework): rawtx = self.nodes[2].createrawtransaction(inputs, outputs) dec_tx = self.nodes[2].decoderawtransaction(rawtx) - errorString = "" try: rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + raise AssertionError("Spent more than available") except JSONRPCException,e: - errorString = e.error['message'] - - assert("Insufficient" in errorString) - + assert("Insufficient" in e.error['message']) ############################################################ @@ -462,12 +459,11 @@ class RawTransactionsTest(BitcoinTestFramework): self.is_network_split=False self.sync_all() - error = False try: self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) - except: - error = True - assert(error) + raise AssertionError("Wallet unlocked without passphrase") + except JSONRPCException as e: + assert('walletpassphrase' in e.error['message']) oldBalance = self.nodes[0].getbalance() @@ -580,7 +576,7 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(len(res_dec["vin"]), 1) assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) - assert_equal("fee" in result.keys(), True) + assert("fee" in result.keys()) assert_greater_than(result["changepos"], -1) ############################################################### diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index f83b5f140..d2cb4ab8d 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -120,10 +120,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): # Test 3: Truncated final tx lastbyte = txlist[-1].pop() - try: - assert_template(node, tmpl, txlist, 'n/a') - except JSONRPCException: - pass # Expected + assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') txlist[-1].append(lastbyte) # Test 4: Add an invalid tx to the end (duplicate of gen tx) @@ -144,10 +141,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): # Test 7: Bad tx count txlist.append(b'') - try: - assert_template(node, tmpl, txlist, 'n/a') - except JSONRPCException: - pass # Expected + assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') txlist.pop() # Test 8: Bad bits diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index eb548aee9..c231676ec 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -37,14 +37,14 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert('"error":null' in out1) + assert(conn.sock!=None) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) out2 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert('"error":null' in out1) #must also response with a correct json-rpc message + assert(conn.sock!=None) #according to http/1.1 connection must still be open! conn.close() #same should be if we add keep-alive because this should be the std. behaviour @@ -54,14 +54,14 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert('"error":null' in out1) + assert(conn.sock!=None) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) out2 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert('"error":null' in out1) #must also response with a correct json-rpc message + assert(conn.sock!=None) #according to http/1.1 connection must still be open! conn.close() #now do the same with "Connection: close" @@ -71,8 +71,8 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, False) #now the connection must be closed after the response + assert('"error":null' in out1) + assert(conn.sock==None) #now the connection must be closed after the response #node1 (2nd node) is running with disabled keep-alive option urlNode1 = urlparse.urlparse(self.nodes[1].url) @@ -83,7 +83,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) + assert('"error":null' in out1) #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on urlNode2 = urlparse.urlparse(self.nodes[2].url) @@ -94,8 +94,8 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default + assert('"error":null' in out1) + assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default # Check excessive request size conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index e52d4e766..f686e6be6 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -252,7 +252,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Invalid amount" in errorString, True) + assert("Invalid amount" in errorString) errorString = "" try: @@ -260,7 +260,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("not an integer" in errorString, True) + assert("not an integer" in errorString) #check if wallet or blochchain maintenance changes the balance self.sync_all() diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 1ee0f79ac..1ba4ded24 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -65,14 +65,8 @@ class ZapWalletTXesTest (BitcoinTestFramework): #restart bitcoind with zapwallettxes self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) - aException = False - try: - tx3 = self.nodes[0].gettransaction(txid3) - except JSONRPCException,e: - print e - aException = True - - assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now + assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3]) + #there must be a expection because the unconfirmed wallettx0 must be gone by now tx0 = self.nodes[0].gettransaction(txid0) assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed From c5825d2d73ca7b0d76fb857554eea4176aed2b5f Mon Sep 17 00:00:00 2001 From: Denis Lukianov Date: Mon, 21 Mar 2016 03:16:19 +0000 Subject: [PATCH 0345/1223] Correct importaddress help reference to importpubkey --- src/wallet/rpcdump.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 9ec28e7b9..6e50f9242 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -192,7 +192,7 @@ UniValue importaddress(const UniValue& params, bool fHelp) "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" "\nNote: This call can take minutes to complete if rescan is true.\n" - "If you have the full public key, you should call importpublickey instead of this.\n" + "If you have the full public key, you should call importpubkey instead of this.\n" "\nExamples:\n" "\nImport a script with rescan\n" + HelpExampleCli("importaddress", "\"myscript\"") + From 71527a0f31ae67edad0a7fcda59c75a6ce5666ca Mon Sep 17 00:00:00 2001 From: NicolasDorier Date: Wed, 16 Mar 2016 14:30:04 +0900 Subject: [PATCH 0346/1223] Test of BIP9 fork activation of mtp, csv, sequence_lock --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/bip9-softforks.py | 220 ++++++++++++++++++++++++ qa/rpc-tests/test_framework/comptool.py | 4 + 3 files changed, 225 insertions(+) create mode 100755 qa/rpc-tests/bip9-softforks.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index cbc10abd2..b32d8d93a 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -119,6 +119,7 @@ testScripts = [ 'p2p-versionbits-warning.py', ] testScriptsExt = [ + 'bip9-softforks.py', 'bip65-cltv.py', 'bip65-cltv-p2p.py', 'bip68-sequence.py', diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py new file mode 100755 index 000000000..cbb1b7d4c --- /dev/null +++ b/qa/rpc-tests/bip9-softforks.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.mininode import CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block +from test_framework.comptool import TestInstance, TestManager +from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP +from binascii import hexlify, unhexlify +import cStringIO +import time +import itertools + +''' +This test is meant to exercise BIP forks +Connect to a single node. +regtest lock-in with 108/144 block signalling +activation after a further 144 blocks +mine 2 block and save coinbases for later use +mine 141 blocks to transition from DEFINED to STARTED +mine 100 blocks signalling readiness and 44 not in order to fail to change state this period +mine 108 blocks signalling readiness and 36 blocks not signalling readiness (STARTED->LOCKED_IN) +mine a further 143 blocks (LOCKED_IN) +test that enforcement has not triggered (which triggers ACTIVE) +test that enforcement has triggered +''' + + + +class BIP9SoftForksTest(ComparisonTestFramework): + + def __init__(self): + self.num_nodes = 1 + + def setup_network(self): + self.nodes = start_nodes(1, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']], + binary=[self.options.testbinary]) + + def run_test(self): + self.test = TestManager(self, self.options.tmpdir) + self.test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + self.test.run() + + def create_transaction(self, node, coinbase, to_address, amount): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + tx = CTransaction() + f = cStringIO.StringIO(unhexlify(rawtx)) + tx.deserialize(f) + tx.nVersion = 2 + return tx + + def sign_transaction(self, node, tx): + signresult = node.signrawtransaction(hexlify(tx.serialize())) + tx = CTransaction() + f = cStringIO.StringIO(unhexlify(signresult['hex'])) + tx.deserialize(f) + return tx + + def generate_blocks(self, number, version, test_blocks = []): + for i in xrange(number): + block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block.nVersion = version + block.rehash() + block.solve() + test_blocks.append([block, True]) + self.last_block_time += 1 + self.tip = block.sha256 + self.height += 1 + return test_blocks + + def get_bip9_status(self, key): + info = self.nodes[0].getblockchaininfo() + for row in info['bip9_softforks']: + if row['id'] == key: + return row + raise IndexError ('key:"%s" not found' % key) + + + def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature): + # generate some coins for later + self.coinbase_blocks = self.nodes[0].generate(2) + self.height = 3 # height of the next block to build + self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.nodeaddress = self.nodes[0].getnewaddress() + self.last_block_time = time.time() + + assert_equal(self.get_bip9_status(bipName)['status'], 'defined') + + # Test 1 + # Advance from DEFINED to STARTED + test_blocks = self.generate_blocks(141, 4) + yield TestInstance(test_blocks, sync_every_block=False) + + assert_equal(self.get_bip9_status(bipName)['status'], 'started') + + # Test 2 + # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 + # using a variety of bits to simulate multiple parallel softforks + test_blocks = self.generate_blocks(50, activated_version) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks(24, 4, test_blocks) # 0x20010000 (signalling not) + yield TestInstance(test_blocks, sync_every_block=False) + + assert_equal(self.get_bip9_status(bipName)['status'], 'started') + + # Test 3 + # 108 out of 144 signal bit 1 to achieve LOCKED_IN + # using a variety of bits to simulate multiple parallel softforks + test_blocks = self.generate_blocks(58, activated_version) # 0x20000001 (signalling ready) + test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not) + test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready) + test_blocks = self.generate_blocks(10, 4, test_blocks) # 0x20010000 (signalling not) + yield TestInstance(test_blocks, sync_every_block=False) + + assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') + + # Test 4 + # 143 more version 536870913 blocks (waiting period-1) + test_blocks = self.generate_blocks(143, 4) + yield TestInstance(test_blocks, sync_every_block=False) + + assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') + + # Test 5 + # Check that the new rule is enforced + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], self.nodeaddress, 1.0) + invalidate(spendtx) + spendtx = self.sign_transaction(self.nodes[0], spendtx) + spendtx.rehash() + invalidatePostSignature(spendtx) + spendtx.rehash() + block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block.nVersion = activated_version + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + + self.last_block_time += 1 + self.tip = block.sha256 + self.height += 1 + yield TestInstance([[block, True]]) + + assert_equal(self.get_bip9_status(bipName)['status'], 'active') + + # Test 6 + # Check that the new sequence lock rules are enforced + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[1], self.nodeaddress, 1.0) + invalidate(spendtx) + spendtx = self.sign_transaction(self.nodes[0], spendtx) + spendtx.rehash() + invalidatePostSignature(spendtx) + spendtx.rehash() + + block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block.nVersion = 5 + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + self.last_block_time += 1 + yield TestInstance([[block, False]]) + + # Restart all + stop_nodes(self.nodes) + wait_bitcoinds() + shutil.rmtree(self.options.tmpdir) + self.setup_chain() + self.setup_network() + self.test.clear_all_connections() + self.test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + + + + def get_tests(self): + for test in itertools.chain( + self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing), + self.test_BIP('csv', 536870913, self.mtp_invalidate, self.donothing), + self.test_BIP('csv', 536870913, self.donothing, self.csv_invalidate) + ): + yield test + + def donothing(self, tx): + return + + def csv_invalidate(self, tx): + '''Modify the signature in vin 0 of the tx to fail CSV + Prepends -1 CSV DROP in the scriptSig itself. + ''' + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP3, OP_DROP] + + list(CScript(tx.vin[0].scriptSig))) + + def sequence_lock_invalidate(self, tx): + '''Modify the nSequence to make it fails once sequence lock rule is activated (high timespan) + ''' + tx.vin[0].nSequence = 0x00FFFFFF + tx.nLockTime = 0 + + def mtp_invalidate(self, tx): + '''Modify the nLockTime to make it fails once MTP rule is activated + ''' + # Disable Sequence lock, Activate nLockTime + tx.vin[0].nSequence = 0x90FFFFFF + tx.nLockTime = self.last_block_time + +if __name__ == '__main__': + BIP9SoftForksTest().main() \ No newline at end of file diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index a4cd4d0a8..d8fcd807f 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -193,6 +193,10 @@ class TestManager(object): # associated NodeConn test_node.add_connection(self.connections[-1]) + def clear_all_connections(self): + self.connections = [] + self.test_nodes = [] + def wait_for_disconnections(self): def disconnected(): return all(node.closed for node in self.test_nodes) From fe00ca758a0f1ab2db3f7441c04780630a9df11a Mon Sep 17 00:00:00 2001 From: Andrew C Date: Sat, 12 Mar 2016 11:41:51 -0500 Subject: [PATCH 0347/1223] Create generatetoaddress rpc Creates the generatetoaddress rpc which is virtually identical to the generate rpc except that it takes an argument for the address to mine to. It does not rely on wallet functionality. The mining code shared by generate and generatetoaddress has been moved to another method to reduce duplication. --- src/rpc/client.cpp | 3 ++ src/rpc/mining.cpp | 109 +++++++++++++++++++++++++++++++-------------- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + 4 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 45fb6c164..89420b93d 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -29,6 +29,9 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getaddednodeinfo", 0 }, { "generate", 0 }, { "generate", 1 }, + { "generatetoaddress", 0 }, + { "generatetoaddress", 1 }, + { "generatetoaddress", 2 }, { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, { "sendtoaddress", 1 }, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index c33082fca..a2abbb323 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "base58.h" #include "amount.h" #include "chain.h" #include "chainparams.h" @@ -93,42 +94,12 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -UniValue generate(const UniValue& params, bool fHelp) +UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript) { - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "generate numblocks ( maxtries )\n" - "\nMine up to numblocks blocks immediately (before the RPC call returns)\n" - "\nArguments:\n" - "1. numblocks (numeric, required) How many blocks are generated immediately.\n" - "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" - "\nResult\n" - "[ blockhashes ] (array) hashes of blocks generated\n" - "\nExamples:\n" - "\nGenerate 11 blocks\n" - + HelpExampleCli("generate", "11") - ); - static const int nInnerLoopCount = 0x10000; int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; - int nGenerate = params[0].get_int(); - uint64_t nMaxTries = 1000000; - if (params.size() > 1) { - nMaxTries = params[1].get_int(); - } - - boost::shared_ptr coinbaseScript; - GetMainSignals().ScriptForMining(coinbaseScript); - - // If the keypool is exhausted, no script is returned at all. Catch this. - if (!coinbaseScript) - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - - //throw an error if no script was provided - if (coinbaseScript->reserveScript.empty()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); { // Don't keep cs_main locked LOCK(cs_main); @@ -164,12 +135,84 @@ UniValue generate(const UniValue& params, bool fHelp) ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); - //mark script as important because it was used at least for one coinbase output - coinbaseScript->KeepScript(); + //mark script as important because it was used at least for one coinbase output if the script came from the wallet + if (keepScript) + { + coinbaseScript->KeepScript(); + } } return blockHashes; } +UniValue generate(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "generate numblocks ( maxtries )\n" + "\nMine up to numblocks blocks immediately (before the RPC call returns)\n" + "\nArguments:\n" + "1. numblocks (numeric, required) How many blocks are generated immediately.\n" + "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" + "\nResult\n" + "[ blockhashes ] (array) hashes of blocks generated\n" + "\nExamples:\n" + "\nGenerate 11 blocks\n" + + HelpExampleCli("generate", "11") + ); + + int nGenerate = params[0].get_int(); + uint64_t nMaxTries = 1000000; + if (params.size() > 1) { + nMaxTries = params[1].get_int(); + } + + boost::shared_ptr coinbaseScript; + GetMainSignals().ScriptForMining(coinbaseScript); + + // If the keypool is exhausted, no script is returned at all. Catch this. + if (!coinbaseScript) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + + //throw an error if no script was provided + if (coinbaseScript->reserveScript.empty()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); + + return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true); +} + +UniValue generatetoaddress(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 3) + throw runtime_error( + "generatetoaddress numblocks address (maxtries)\n" + "\nMine blocks immediately to a specified address (before the RPC call returns)\n" + "\nArguments:\n" + "1. numblocks (numeric, required) How many blocks are generated immediately.\n" + "2. address (string, required) The address to send the newly generated bitcoin to.\n" + "3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" + "\nResult\n" + "[ blockhashes ] (array) hashes of blocks generated\n" + "\nExamples:\n" + "\nGenerate 11 blocks to myaddress\n" + + HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + ); + + int nGenerate = params[0].get_int(); + uint64_t nMaxTries = 1000000; + if (params.size() > 2) { + nMaxTries = params[2].get_int(); + } + + CBitcoinAddress address(params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address"); + + boost::shared_ptr coinbaseScript(new CReserveScript()); + coinbaseScript->reserveScript = GetScriptForDestination(address.Get()); + + return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false); +} + UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 33fa1437e..1303a3bb1 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -299,6 +299,7 @@ static const CRPCCommand vRPCCommands[] = /* Coin generation */ { "generating", "generate", &generate, true }, + { "generating", "generatetoaddress", &generatetoaddress, true }, /* Raw transactions */ { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 38cb32e7f..35e114fee 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -193,6 +193,7 @@ extern UniValue listbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp); +extern UniValue generatetoaddress(const UniValue& params, bool fHelp); extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); extern UniValue getmininginfo(const UniValue& params, bool fHelp); extern UniValue prioritisetransaction(const UniValue& params, bool fHelp); From d5c5c713e67368802b6a4ab2b6b69962364c251b Mon Sep 17 00:00:00 2001 From: Andrew C Date: Mon, 14 Mar 2016 17:54:34 -0400 Subject: [PATCH 0348/1223] RPC tests for generatetoaddress Adds two RPC tests for the generatetoaddress RPC, one in the wallet, and one when the wallet is disabled. The wallet RPC Test mines Bitcoin to another node's address and checks that that node has received the Bitcoin. The RPC test without the wallet mines Bitcoin to an arbitrary address and checks that it works. It then mines to an arbitrary invalid address and checks that that fails. --- qa/rpc-tests/disablewallet.py | 14 ++++++++++++++ qa/rpc-tests/wallet.py | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 6964348d5..5af815846 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -29,5 +29,19 @@ class DisableWalletTest (BitcoinTestFramework): x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') assert(x['isvalid'] == True) + # Checking mining to an address without a wallet + try: + self.nodes[0].generatetoaddress(1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') + except JSONRPCException,e: + assert("Invalid address" not in e.error['message']) + assert("ProcessNewBlock, block not accepted" not in e.error['message']) + assert("Couldn't create new block" not in e.error['message']) + + try: + self.nodes[0].generatetoaddress(1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy') + raise AssertionError("Must not mine to invalid address!") + except JSONRPCException,e: + assert("Invalid address" in e.error['message']) + if __name__ == '__main__': DisableWalletTest ().main () diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index f686e6be6..df176601a 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -262,6 +262,18 @@ class WalletTest (BitcoinTestFramework): assert("not an integer" in errorString) + # Mine a block from node0 to an address from node1 + cbAddr = self.nodes[1].getnewaddress() + blkHash = self.nodes[0].generatetoaddress(1, cbAddr)[0] + cbTxId = self.nodes[0].getblock(blkHash)['tx'][0] + self.sync_all() + + # Check that the txid and balance is found by node1 + try: + self.nodes[1].gettransaction(cbTxId) + except JSONRPCException,e: + assert("Invalid or non-wallet transaction id" not in e.error['message']) + #check if wallet or blochchain maintenance changes the balance self.sync_all() blocks = self.nodes[0].generate(2) From 9e072a6e66efbda7d39bf61eded21d2b324323be Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 12 Feb 2016 15:57:15 -0500 Subject: [PATCH 0349/1223] Implement "feefilter" P2P message. The "feefilter" p2p message is used to inform other nodes of your mempool min fee which is the feerate that any new transaction must meet to be accepted to your mempool. This will allow them to filter invs to you according to this feerate. --- src/init.cpp | 1 + src/main.cpp | 73 +++++++++++++++++++++++----- src/main.h | 8 ++- src/net.cpp | 20 +++++--- src/net.h | 10 +++- src/policy/fees.cpp | 19 ++++++++ src/policy/fees.h | 13 +++++ src/protocol.cpp | 4 +- src/protocol.h | 7 ++- src/rpc/rawtransaction.cpp | 5 +- src/test/txvalidationcache_tests.cpp | 2 +- src/txmempool.cpp | 10 ++++ src/txmempool.h | 1 + src/version.h | 5 +- src/wallet/wallet.cpp | 6 ++- 15 files changed, 152 insertions(+), 32 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index f53d7d3c3..38ac91b2a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -330,6 +330,7 @@ std::string HelpMessage(HelpMessageMode mode) } strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); + strUsage += HelpMessageOpt("-feefilter", strprintf(_("Tell other nodes to filter invs to us by our mempool min fee (default: %u)"), DEFAULT_FEEFILTER)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file on startup")); strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); strUsage += HelpMessageOpt("-maxmempool=", strprintf(_("Keep the transaction memory pool below megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE)); diff --git a/src/main.cpp b/src/main.cpp index fc443cfb7..36189f4ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,10 +17,12 @@ #include "init.h" #include "merkleblock.h" #include "net.h" +#include "policy/fees.h" #include "policy/policy.h" #include "pow.h" #include "primitives/block.h" #include "primitives/transaction.h" +#include "random.h" #include "script/script.h" #include "script/sigcache.h" #include "script/standard.h" @@ -81,6 +83,7 @@ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CTxMemPool mempool(::minRelayTxFee); +FeeFilterRounder filterRounder(::minRelayTxFee); struct COrphanTx { CTransaction tx; @@ -987,7 +990,7 @@ std::string FormatStateMessage(const CValidationState &state) } bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee, + bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector& vHashTxnToUncache) { const uint256 hash = tx.GetHash(); @@ -1144,6 +1147,9 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps, lp); unsigned int nSize = entry.GetTxSize(); + if (txFeeRate) { + *txFeeRate = CFeeRate(nFees, nSize); + } // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction @@ -1392,10 +1398,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) + bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) { std::vector vHashTxToUncache; - bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache); + bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, txFeeRate, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache); if (!res) { BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache) pcoinsTip->Uncache(hashTx); @@ -2620,7 +2626,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons // ignore validation errors in resurrected transactions list removed; CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, NULL, true)) { mempool.removeRecursive(tx, removed); } else if (mempool.exists(tx.GetHash())) { vHashUpdate.push_back(tx.GetHash()); @@ -4916,10 +4922,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->setAskFor.erase(inv.hash); mapAlreadyAskedFor.erase(inv); - if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) - { + CFeeRate txFeeRate = CFeeRate(0); + if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, &txFeeRate)) { mempool.check(pcoinsTip); - RelayTransaction(tx); + RelayTransaction(tx, txFeeRate); vWorkQueue.push_back(inv.hash); LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n", @@ -4950,10 +4956,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (setMisbehaving.count(fromPeer)) continue; - if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) - { + CFeeRate orphanFeeRate = CFeeRate(0); + if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2, &orphanFeeRate)) { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); - RelayTransaction(orphanTx); + RelayTransaction(orphanTx, orphanFeeRate); vWorkQueue.push_back(orphanHash); vEraseQueue.push_back(orphanHash); } @@ -5006,7 +5012,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS = 0; if (!state.IsInvalid(nDoS) || nDoS == 0) { LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id); - RelayTransaction(tx); + RelayTransaction(tx, txFeeRate); } else { LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->id, FormatStateMessage(state)); } @@ -5200,6 +5206,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue; } + if (pfrom->minFeeFilter) { + CFeeRate feeRate; + mempool.lookupFeeRate(hash, feeRate); + LOCK(pfrom->cs_feeFilter); + if (feeRate.GetFeePerK() < pfrom->minFeeFilter) + continue; + } vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { pfrom->PushMessage(NetMsgType::INV, vInv); @@ -5362,8 +5375,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } - else - { + else if (strCommand == NetMsgType::FEEFILTER) { + CAmount newFeeFilter = 0; + vRecv >> newFeeFilter; + if (MoneyRange(newFeeFilter)) { + { + LOCK(pfrom->cs_feeFilter); + pfrom->minFeeFilter = newFeeFilter; + } + LogPrint("net", "received: feefilter of %s from peer=%d\n", CFeeRate(newFeeFilter).ToString(), pfrom->id); + } + } + + else { // Ignore unknown commands for extensibility LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id); } @@ -5845,6 +5869,29 @@ bool SendMessages(CNode* pto) if (!vGetData.empty()) pto->PushMessage(NetMsgType::GETDATA, vGetData); + // + // Message: feefilter + // + // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay + if (pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && + !(pto->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { + CAmount currentFilter = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + int64_t timeNow = GetTimeMicros(); + if (timeNow > pto->nextSendTimeFeeFilter) { + CAmount filterToSend = filterRounder.round(currentFilter); + if (filterToSend != pto->lastSentFeeFilter) { + pto->PushMessage(NetMsgType::FEEFILTER, filterToSend); + pto->lastSentFeeFilter = filterToSend; + } + pto->nextSendTimeFeeFilter = PoissonNextSend(timeNow, AVG_FEEFILTER_BROADCAST_INTERVAL); + } + // If the fee filter has changed substantially and it's still more than MAX_FEEFILTER_CHANGE_DELAY + // until scheduled broadcast, then move the broadcast to within MAX_FEEFILTER_CHANGE_DELAY. + else if (timeNow + MAX_FEEFILTER_CHANGE_DELAY * 1000000 < pto->nextSendTimeFeeFilter && + (currentFilter < 3 * pto->lastSentFeeFilter / 4 || currentFilter > 4 * pto->lastSentFeeFilter / 3)) { + pto->nextSendTimeFeeFilter = timeNow + (insecure_rand() % MAX_FEEFILTER_CHANGE_DELAY) * 1000000; + } + } } return true; } diff --git a/src/main.h b/src/main.h index a011ba4e5..0bfcfab21 100644 --- a/src/main.h +++ b/src/main.h @@ -102,6 +102,10 @@ static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30; /** Average delay between trickled inventory broadcasts in seconds. * Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */ static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; +/** Average delay between feefilter broadcasts in seconds. */ +static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60; +/** Maximum feefilter broadcast delay after significant change. */ +static const unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60; static const unsigned int DEFAULT_LIMITFREERELAY = 15; static const bool DEFAULT_RELAYPRIORITY = true; @@ -117,6 +121,8 @@ static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; static const bool DEFAULT_TESTSAFEMODE = false; /** Default for -mempoolreplacement */ static const bool DEFAULT_ENABLE_REPLACEMENT = true; +/** Default for using fee filter */ +static const bool DEFAULT_FEEFILTER = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; @@ -282,7 +288,7 @@ void PruneAndFlush(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); + bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state); diff --git a/src/net.cpp b/src/net.cpp index b589692d1..e8cc753a4 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2053,20 +2053,15 @@ public: instance_of_cnetcleanup; - - - - - -void RelayTransaction(const CTransaction& tx) +void RelayTransaction(const CTransaction& tx, CFeeRate feerate) { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(10000); ss << tx; - RelayTransaction(tx, ss); + RelayTransaction(tx, feerate, ss); } -void RelayTransaction(const CTransaction& tx, const CDataStream& ss) +void RelayTransaction(const CTransaction& tx, CFeeRate feerate, const CDataStream& ss) { CInv inv(MSG_TX, tx.GetHash()); { @@ -2087,6 +2082,11 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss) { if(!pnode->fRelayTxes) continue; + { + LOCK(pnode->cs_feeFilter); + if (feerate.GetFeePerK() < pnode->minFeeFilter) + continue; + } LOCK(pnode->cs_filter); if (pnode->pfilter) { @@ -2390,6 +2390,10 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); + minFeeFilter = 0; + lastSentFeeFilter = 0; + nextSendTimeFeeFilter = 0; + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; diff --git a/src/net.h b/src/net.h index ec296e2ab..ab9eb68d8 100644 --- a/src/net.h +++ b/src/net.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_NET_H #define BITCOIN_NET_H +#include "amount.h" #include "bloom.h" #include "compat.h" #include "limitedmap.h" @@ -415,6 +416,11 @@ public: int64_t nMinPingUsecTime; // Whether a ping is requested. bool fPingQueued; + // Minimum fee rate with which to filter inv's to this node + CAmount minFeeFilter; + CCriticalSection cs_feeFilter; + CAmount lastSentFeeFilter; + int64_t nextSendTimeFeeFilter; CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false); ~CNode(); @@ -766,8 +772,8 @@ public: class CTransaction; -void RelayTransaction(const CTransaction& tx); -void RelayTransaction(const CTransaction& tx, const CDataStream& ss); +void RelayTransaction(const CTransaction& tx, CFeeRate feerate); +void RelayTransaction(const CTransaction& tx, CFeeRate feerate, const CDataStream& ss); /** Access to the (IP) address database (peers.dat) */ class CAddrDB diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index de3c060d6..7b0e8b7d0 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -8,6 +8,7 @@ #include "amount.h" #include "primitives/transaction.h" +#include "random.h" #include "streams.h" #include "txmempool.h" #include "util.h" @@ -580,3 +581,21 @@ void CBlockPolicyEstimator::Read(CAutoFile& filein) priStats.Read(filein); nBestSeenHeight = nFileBestSeenHeight; } + +FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee) +{ + CAmount minFeeLimit = minIncrementalFee.GetFeePerK() / 2; + feeset.insert(0); + for (double bucketBoundary = minFeeLimit; bucketBoundary <= MAX_FEERATE; bucketBoundary *= FEE_SPACING) { + feeset.insert(bucketBoundary); + } +} + +CAmount FeeFilterRounder::round(CAmount currentMinFee) +{ + std::set::iterator it = feeset.lower_bound(currentMinFee); + if ((it != feeset.begin() && insecure_rand() % 3 != 0) || it == feeset.end()) { + it--; + } + return *it; +} diff --git a/src/policy/fees.h b/src/policy/fees.h index 3fa31c39e..cdd984de7 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -286,4 +286,17 @@ private: CFeeRate feeLikely, feeUnlikely; double priLikely, priUnlikely; }; + +class FeeFilterRounder +{ +public: + /** Create new FeeFilterRounder */ + FeeFilterRounder(const CFeeRate& minIncrementalFee); + + /** Quantize a minimum fee for privacy purpose before broadcast **/ + CAmount round(CAmount currentMinFee); + +private: + std::set feeset; +}; #endif /*BITCOIN_POLICYESTIMATOR_H */ diff --git a/src/protocol.cpp b/src/protocol.cpp index 1ddb65b79..8c4bd0572 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -34,6 +34,7 @@ const char *FILTERADD="filteradd"; const char *FILTERCLEAR="filterclear"; const char *REJECT="reject"; const char *SENDHEADERS="sendheaders"; +const char *FEEFILTER="feefilter"; }; static const char* ppszTypeName[] = @@ -68,7 +69,8 @@ const static std::string allNetMessageTypes[] = { NetMsgType::FILTERADD, NetMsgType::FILTERCLEAR, NetMsgType::REJECT, - NetMsgType::SENDHEADERS + NetMsgType::SENDHEADERS, + NetMsgType::FEEFILTER }; const static std::vector allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); diff --git a/src/protocol.h b/src/protocol.h index 5504f213f..1b049e52a 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -211,7 +211,12 @@ extern const char *REJECT; * @see https://bitcoin.org/en/developer-reference#sendheaders */ extern const char *SENDHEADERS; - +/** + * The feefilter message tells the receiving peer not to inv us any txs + * which do not meet the specified min fee rate. + * @since protocol version 70013 as described by BIP133 + */ +extern const char *FEEFILTER; }; /* Get a vector of all valid message types (see above) */ diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index de89fdeb0..c72339313 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -818,11 +818,12 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) const CCoins* existingCoins = view.AccessCoins(hashTx); bool fHaveMempool = mempool.exists(hashTx); bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000; + CFeeRate txFeeRate = CFeeRate(0); if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; bool fMissingInputs; - if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, nMaxRawTxFee)) { + if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, &txFeeRate, false, nMaxRawTxFee)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { @@ -835,7 +836,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) } else if (fHaveChain) { throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); } - RelayTransaction(tx); + RelayTransaction(tx, txFeeRate); return hashTx.GetHex(); } diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index c29e30792..237b26329 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0); + return AcceptToMemoryPool(mempool, state, tx, false, NULL, NULL, true, 0); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 088e5edde..52c779311 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -771,6 +771,16 @@ bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const return true; } +bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const +{ + LOCK(cs); + indexed_transaction_set::const_iterator i = mapTx.find(hash); + if (i == mapTx.end()) + return false; + feeRate = CFeeRate(i->GetFee(), i->GetTxSize()); + return true; +} + CFeeRate CTxMemPool::estimateFee(int nBlocks) const { LOCK(cs); diff --git a/src/txmempool.h b/src/txmempool.h index 665bb44cf..9dbb37dad 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -600,6 +600,7 @@ public: } bool lookup(uint256 hash, CTransaction& result) const; + bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const; /** Estimate fee rate needed to get into the next nBlocks * If no answer can be given at nBlocks, return an estimate diff --git a/src/version.h b/src/version.h index af2eb8eab..0e1d8a63c 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70012; +static const int PROTOCOL_VERSION = 70013; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -36,4 +36,7 @@ static const int NO_BLOOM_VERSION = 70011; //! "sendheaders" command and announcing blocks with headers starts with this version static const int SENDHEADERS_VERSION = 70012; +//! "feefilter" tells peers to filter invs to you by fee starts with this version +static const int FEEFILTER_VERSION = 70013; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1ef055e55..654e61707 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1268,7 +1268,9 @@ bool CWalletTx::RelayWalletTransaction() { if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); - RelayTransaction((CTransaction)*this); + CFeeRate feeRate; + mempool.lookupFeeRate(GetHash(), feeRate); + RelayTransaction((CTransaction)*this, feeRate); return true; } } @@ -3231,5 +3233,5 @@ int CMerkleTx::GetBlocksToMaturity() const bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, NULL, false, nAbsurdFee); } From 5fa66e4682a59047d2ed2934760ccc052fd85f50 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 4 Mar 2016 15:08:10 -0500 Subject: [PATCH 0350/1223] Create SingleNodeConnCB class for RPC tests --- qa/rpc-tests/maxuploadtarget.py | 1 - qa/rpc-tests/test_framework/comptool.py | 14 --------- qa/rpc-tests/test_framework/mininode.py | 40 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 2517bed47..e4127500c 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -7,7 +7,6 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.comptool import wait_until import time ''' diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index a4cd4d0a8..e3f9b4323 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -27,20 +27,6 @@ generator that returns TestInstance objects. See below for definition. global mininode_lock -def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): - attempt = 0 - elapsed = 0 - - while attempt < attempts and elapsed < timeout: - with mininode_lock: - if predicate(): - return True - attempt += 1 - elapsed += 0.05 - time.sleep(0.05) - - return False - class RejectResult(object): ''' Outcome that expects rejection of a transaction or block. diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 934d0c7a7..5b6bb190e 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1008,6 +1008,20 @@ class msg_reject(object): return "msg_reject: %s %d %s [%064x]" \ % (self.message, self.code, self.reason, self.data) +# Helper function +def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): + attempt = 0 + elapsed = 0 + + while attempt < attempts and elapsed < timeout: + with mininode_lock: + if predicate(): + return True + attempt += 1 + elapsed += 0.05 + time.sleep(0.05) + + return False # This is what a callback should look like for NodeConn # Reimplement the on_* functions to provide handling for events @@ -1085,6 +1099,32 @@ class NodeConnCB(object): def on_mempool(self, conn): pass def on_pong(self, conn, message): pass +# More useful callbacks and functions for NodeConnCB's which have a single NodeConn +class SingleNodeConnCB(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + + def add_connection(self, conn): + self.connection = conn + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_pong(self, conn, message): + self.last_pong = message + + # Sync up with the node + def sync_with_ping(self, timeout=30): + def received_pong(): + return (self.last_pong.nonce == self.ping_counter) + self.send_message(msg_ping(nonce=self.ping_counter)) + success = wait_until(received_pong, timeout) + self.ping_counter += 1 + return success # The actual NodeConn class # This class provides an interface for a p2p connection to a specified node From b536a6fc83ee20cfb80da8bcb5f21c664ec7b5fe Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 4 Mar 2016 16:11:49 -0500 Subject: [PATCH 0351/1223] Add p2p test for feefilter --- qa/pull-tester/rpc-tests.py | 3 +- qa/rpc-tests/p2p-feefilter.py | 99 +++++++++++++++++++++++++ qa/rpc-tests/test_framework/mininode.py | 21 +++++- 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100755 qa/rpc-tests/p2p-feefilter.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index f15eaacbd..74be96da7 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -127,7 +127,6 @@ testScriptsExt = [ 'getblocktemplate_proposals.py', 'txn_doublespend.py', 'txn_clone.py --mineblock', - 'pruning.py', 'forknotify.py', 'invalidateblock.py', # 'rpcbind_test.py', #temporary, bug in libevent, see #6655 @@ -137,6 +136,8 @@ testScriptsExt = [ 'mempool_packages.py', 'maxuploadtarget.py', 'replace-by-fee.py', + 'p2p-feefilter.py', + 'pruning.py', # leave pruning last as it takes a REALLY long time ] #Enable ZMQ tests diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py new file mode 100755 index 000000000..f85c18dcd --- /dev/null +++ b/qa/rpc-tests/p2p-feefilter.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python2 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time + +''' +FeeFilterTest -- test processing of feefilter messages +''' + +def hashToHex(hash): + return format(hash, '064x').decode('utf-8') + +# Wait up to 60 secs to see if the testnode has received all the expected invs +def allInvsMatch(invsExpected, testnode): + for x in xrange(60): + with mininode_lock: + if (sorted(invsExpected) == sorted(testnode.txinvs)): + return True; + time.sleep(1) + return False; + +# TestNode: bare-bones "peer". Used to track which invs are received from a node +# and to send the node feefilter messages. +class TestNode(SingleNodeConnCB): + def __init__(self): + SingleNodeConnCB.__init__(self) + self.txinvs = [] + + def on_inv(self, conn, message): + for i in message.inv: + if (i.type == 1): + self.txinvs.append(hashToHex(i.hash)) + + def clear_invs(self): + with mininode_lock: + self.txinvs = [] + + def send_filter(self, feerate): + self.send_message(msg_feefilter(feerate)) + self.sync_with_ping() + +class FeeFilterTest(BitcoinTestFramework): + def setup_network(self): + # Node1 will be used to generate txs which should be relayed from Node0 + # to our test node + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros"])) + connect_nodes(self.nodes[0], 1) + + def run_test(self): + node1 = self.nodes[1] + # Get out of IBD + node1.generate(1) + sync_blocks(self.nodes) + + # Setup the p2p connections and start up the network thread. + test_node = TestNode() + connection = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node) + test_node.add_connection(connection) + NetworkThread().start() + test_node.wait_for_verack() + + # Test that invs are received for all txs at feerate of 20 sat/byte + node1.settxfee(Decimal("0.00020000")) + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + assert(allInvsMatch(txids, test_node)) + test_node.clear_invs() + + # Set a filter of 15 sat/byte + test_node.send_filter(15000) + + # Test that txs are still being received (paying 20 sat/byte) + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + assert(allInvsMatch(txids, test_node)) + test_node.clear_invs() + + # Change tx fee rate to 10 sat/byte and test they are no longer received + node1.settxfee(Decimal("0.00010000")) + [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + sync_mempools(self.nodes) # must be sure node 0 has received all txs + time.sleep(10) # wait 10 secs to be sure its doesn't relay any + assert(allInvsMatch([], test_node)) + test_node.clear_invs() + + # Remove fee filter and check that txs are received again + test_node.send_filter(0) + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + assert(allInvsMatch(txids, test_node)) + test_node.clear_invs() + +if __name__ == '__main__': + FeeFilterTest().main() diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 5b6bb190e..20386c642 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1023,6 +1023,23 @@ def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): return False +class msg_feefilter(object): + command = "feefilter" + + def __init__(self, feerate=0L): + self.feerate = feerate + + def deserialize(self, f): + self.feerate = struct.unpack(" Date: Fri, 4 Mar 2016 16:25:19 -0500 Subject: [PATCH 0352/1223] modify release-notes.md and bips.md --- doc/bips.md | 1 + doc/release-notes.md | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/doc/bips.md b/doc/bips.md index 2552a7f03..b8efabbcf 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -20,3 +20,4 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). +* [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). diff --git a/doc/release-notes.md b/doc/release-notes.md index 43e1e3fb9..806d174eb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -53,6 +53,15 @@ The following outputs are affected by this change: The p2p alert system has been removed in #7692 and the 'alert' message is no longer supported. + +Fee filtering of invs (BIP 133) +------------------------------------ + +The optional new p2p message "feefilter" is implemented and the protocol +version is bumped to 70013. Upon receiving a feefilter message from a peer, +a node will not send invs for any transactions which do not meet the filter +feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) + ### Validation ### Build system From 25340b7cd58c3451ae91c7b501fdff70ef05ec80 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 15 Mar 2016 10:30:37 +0100 Subject: [PATCH 0353/1223] [Wallet] refactor wallet/init interaction --- src/init.cpp | 86 ++--------------------- src/init.h | 2 - src/test/test_bitcoin.cpp | 1 - src/wallet/wallet.cpp | 143 ++++++++++++++++++++++++++++---------- src/wallet/wallet.h | 11 ++- 5 files changed, 118 insertions(+), 125 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 637b69ab0..957583870 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -63,9 +63,6 @@ using namespace std; -#ifdef ENABLE_WALLET -CWallet* pwalletMain = NULL; -#endif bool fFeeEstimatesInitialized = false; static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_REST_ENABLE = false; @@ -946,56 +943,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET - if (mapArgs.count("-mintxfee")) - { - CAmount n = 0; - if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) - CWallet::minTxFee = CFeeRate(n); - else - return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); - } - if (mapArgs.count("-fallbackfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) - return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); - CWallet::fallbackFee = CFeeRate(nFeePerK); - } - if (mapArgs.count("-paytxfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); - payTxFee = CFeeRate(nFeePerK, 1000); - if (payTxFee < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), - mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); - } - } - if (mapArgs.count("-maxtxfee")) - { - CAmount nMaxFee = 0; - if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); - if (nMaxFee > HIGH_MAX_TX_FEE) - InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); - maxTxFee = nMaxFee; - if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), - mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); - } - } - nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); - fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); - - std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + if (!CWallet::ParameterInteraction()) + return false; #endif // ENABLE_WALLET fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); @@ -1032,11 +981,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), _(PACKAGE_NAME))); std::string strDataDir = GetDataDir().string(); -#ifdef ENABLE_WALLET - // Wallet file must be a plain filename without a directory - if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile)) - return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir)); -#endif + // Make sure only a single Bitcoin process is using the data directory. boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. @@ -1097,20 +1042,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 5: verify wallet database integrity #ifdef ENABLE_WALLET if (!fDisableWallet) { - LogPrintf("Using wallet %s\n", strWalletFile); - uiInterface.InitMessage(_("Verifying wallet...")); - - std::string warningString; - std::string errorString; - - if (!CWallet::Verify(strWalletFile, warningString, errorString)) + if (!CWallet::Verify()) return false; - - if (!warningString.empty()) - InitWarning(warningString); - if (!errorString.empty()) - return InitError(errorString); - } // (!fDisableWallet) #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization @@ -1421,16 +1354,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pwalletMain = NULL; LogPrintf("Wallet disabled!\n"); } else { - std::string warningString; - std::string errorString; - pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString); - if (!warningString.empty()) - InitWarning(warningString); - if (!errorString.empty()) - { - LogPrintf("%s", errorString); - return InitError(errorString); - } + CWallet::InitLoadWallet(); if (!pwalletMain) return false; } diff --git a/src/init.h b/src/init.h index af1b94b72..63e07ccb3 100644 --- a/src/init.h +++ b/src/init.h @@ -16,8 +16,6 @@ namespace boost class thread_group; } // namespace boost -extern CWallet* pwalletMain; - void StartShutdown(); bool ShutdownRequested(); /** Interrupt threads */ diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 39586d7bb..9159a4499 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -29,7 +29,6 @@ #include CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h -CWallet* pwalletMain; extern bool fPrintToConsole; extern void noui_connect(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bcfefa27f..026bf9ac5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -33,6 +33,7 @@ using namespace std; +CWallet* pwalletMain = NULL; /** Transaction fee set by the user */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; @@ -364,8 +365,33 @@ void CWallet::Flush(bool shutdown) bitdb.Flush(shutdown); } -bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString) +bool static UIError(const std::string &str) { + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); + return false; +} + +void static UIWarning(const std::string &str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); +} + +static std::string AmountErrMsg(const char * const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); +} + +bool CWallet::Verify() +{ + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + + LogPrintf("Using wallet %s\n", walletFile); + uiInterface.InitMessage(_("Verifying wallet...")); + + // Wallet file must be a plain filename without a directory + if (walletFile != boost::filesystem::basename(walletFile) + boost::filesystem::extension(walletFile)) + return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string())); + if (!bitdb.Open(GetDataDir())) { // try moving the database env out of the way @@ -381,9 +407,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er // try again if (!bitdb.Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env - string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()); - errorString += msg; - return true; + return UIError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); } } @@ -399,14 +423,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { - warningString += strprintf(_("Warning: Wallet file corrupt, data salvaged!" + UIWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!" " Original %s saved as %s in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), - walletFile, "wallet.{timestamp}.bak", GetDataDir()); + walletFile, "wallet.{timestamp}.bak", GetDataDir())); } if (r == CDBEnv::RECOVER_FAIL) - errorString += strprintf(_("%s corrupt, salvage failed"), walletFile); + return UIError(strprintf(_("%s corrupt, salvage failed"), walletFile)); } return true; @@ -2992,20 +3016,20 @@ std::string CWallet::GetWalletHelpString(bool showDebug) return strUsage; } -CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString) +bool CWallet::InitLoadWallet() { + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + // needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; if (GetBoolArg("-zapwallettxes", false)) { uiInterface.InitMessage(_("Zapping all transactions from wallet...")); - CWallet *tempWallet = new CWallet(strWalletFile); + CWallet *tempWallet = new CWallet(walletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { - errorString = strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile); - uiInterface.InitMessage(strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile)); - return NULL; + return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); } delete tempWallet; @@ -3016,32 +3040,27 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall int64_t nStart = GetTimeMillis(); bool fFirstRun = true; - CWallet *walletInstance = new CWallet(strWalletFile); + CWallet *walletInstance = new CWallet(walletFile); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) - errorString += strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile) + "\n"; + return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - warningString += strprintf(_("Error reading %s! All keys read correctly, but transaction data" + UIWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect."), - strWalletFile); + walletFile)); } else if (nLoadWalletRet == DB_TOO_NEW) - errorString += strprintf(_("Error loading %s: Wallet requires newer version of %s"), - strWalletFile, _(PACKAGE_NAME)) + - "\n"; + return UIError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), + walletFile, _(PACKAGE_NAME))); else if (nLoadWalletRet == DB_NEED_REWRITE) { - errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n"; - LogPrintf("%s", errorString); + return UIError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); } else - errorString += strprintf(_("Error loading %s"), strWalletFile) + "\n"; - - if (!errorString.empty()) - return NULL; + return UIError(strprintf(_("Error loading %s"), walletFile)); } if (GetBoolArg("-upgradewallet", fFirstRun)) @@ -3057,8 +3076,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); if (nMaxVersion < walletInstance->GetVersion()) { - errorString += _("Cannot downgrade wallet") + "\n"; - return NULL; + return UIError(_("Cannot downgrade wallet")); } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3072,10 +3090,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) - { - errorString += _("Cannot write default address") += "\n"; - return NULL; - } + return UIError(_("Cannot write default address") += "\n"); } walletInstance->SetBestChain(chainActive.GetLocator()); @@ -3090,7 +3105,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall pindexRescan = chainActive.Genesis(); else { - CWalletDB walletdb(strWalletFile); + CWalletDB walletdb(walletFile); CBlockLocator locator; if (walletdb.ReadBestBlock(locator)) pindexRescan = FindForkInGlobalIndex(chainActive, locator); @@ -3109,10 +3124,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall block = block->pprev; if (pindexRescan != block) - { - errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"); - return NULL; - } + return UIError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); } uiInterface.InitMessage(_("Rescanning...")); @@ -3126,7 +3138,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall // Restore wallet transaction metadata after -zapwallettxes=1 if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") { - CWalletDB walletdb(strWalletFile); + CWalletDB walletdb(walletFile); BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) { @@ -3150,7 +3162,62 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall } walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); - return walletInstance; + pwalletMain = walletInstance; + return true; +} + +bool CWallet::ParameterInteraction() +{ + if (mapArgs.count("-mintxfee")) + { + CAmount n = 0; + if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) + CWallet::minTxFee = CFeeRate(n); + else + return UIError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + } + if (mapArgs.count("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) + return UIError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + UIWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); + } + if (mapArgs.count("-paytxfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) + return UIError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + UIWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + payTxFee = CFeeRate(nFeePerK, 1000); + if (payTxFee < ::minRelayTxFee) + { + return UIError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), + mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); + } + } + if (mapArgs.count("-maxtxfee")) + { + CAmount nMaxFee = 0; + if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) + return UIError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); + if (nMaxFee > HIGH_MAX_TX_FEE) + UIWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + maxTxFee = nMaxFee; + if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) + { + return UIError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); + } + } + nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); + + return true; } CKeyPool::CKeyPool() diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d009211a9..257d6f2e7 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -28,6 +28,8 @@ #include +extern CWallet* pwalletMain; + /** * Settings */ @@ -840,7 +842,7 @@ public: void Flush(bool shutdown=false); //! Verify the wallet database and perform salvage if required - static bool Verify(const std::string& walletFile, std::string& warningString, std::string& errorString); + static bool Verify(); /** * Address book entry changed. @@ -875,8 +877,11 @@ public: /* Returns the wallets help message */ static std::string GetWalletHelpString(bool showDebug); - /* initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ - static CWallet* InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString); + /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ + static bool InitLoadWallet(); + + /* Wallets parameter interaction */ + static bool ParameterInteraction(); }; /** A key allocated from the key pool. */ From 4856f1d6712cdb2eac8712e379fd1e351583d78f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 22 Mar 2016 08:40:10 +0100 Subject: [PATCH 0354/1223] [Qt] Debug window: replace "Build date" with "Datadir" The build date does only makes sense for custom/self-compiled bitcoin-core versions because we are using static build-dates for our deterministic release builds. Having a quick option to get the current datadir is much more valuable for debug purposes. --- src/qt/clientmodel.cpp | 5 +++++ src/qt/clientmodel.h | 1 + src/qt/forms/debugwindow.ui | 7 +++++-- src/qt/rpcconsole.cpp | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index d3edfedff..65637cd61 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -193,6 +193,11 @@ QString ClientModel::formatClientStartupTime() const return QDateTime::fromTime_t(nClientStartupTime).toString(); } +QString ClientModel::dataDir() const +{ + return QString::fromStdString(GetDataDir().string()); +} + void ClientModel::updateBanlist() { banTableModel->refresh(); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 2fef6131c..db010f05c 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -76,6 +76,7 @@ public: bool isReleaseVersion() const; QString clientName() const; QString formatClientStartupTime() const; + QString dataDir() const; private: OptionsModel *optionsModel; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index a5ac0a7d2..c17efcf1b 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -141,12 +141,12 @@ - Build date + Datadir - + IBeamCursor @@ -156,6 +156,9 @@ Qt::PlainText + + true + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index e8ee3042d..42112c42f 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -444,7 +444,7 @@ void RPCConsole::setClientModel(ClientModel *model) ui->clientVersion->setText(model->formatFullVersion()); ui->clientUserAgent->setText(model->formatSubVersion()); ui->clientName->setText(model->clientName()); - ui->buildDate->setText(model->formatBuildDate()); + ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); From bb16c8894becfba8764b13d448ba6e7e7f1608c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Tue, 8 Mar 2016 00:15:17 +0000 Subject: [PATCH 0355/1223] Prevent multiple calls to CWallet::AvailableCoins --- src/wallet/wallet.cpp | 10 ++++++---- src/wallet/wallet.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 654e61707..51a2ad78d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1841,10 +1841,9 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int return true; } -bool CWallet::SelectCoins(const CAmount& nTargetValue, set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const +bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& nTargetValue, set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const { - vector vCoins; - AvailableCoins(vCoins, true, coinControl); + vector vCoins(vAvailableCoins); // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs) @@ -2010,6 +2009,9 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt { LOCK2(cs_main, cs_wallet); { + std::vector vAvailableCoins; + AvailableCoins(vAvailableCoins, true, coinControl); + nFeeRet = 0; // Start with no fee and loop until there is enough fee while (true) @@ -2059,7 +2061,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Choose coins to use set > setCoins; CAmount nValueIn = 0; - if (!SelectCoins(nValueToSelect, setCoins, nValueIn, coinControl)) + if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coinControl)) { strFailReason = _("Insufficient funds"); return false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d009211a9..e37d972a1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -544,7 +544,7 @@ private: * all coins from coinControl are selected; Never select unconfirmed coins * if they are not ours */ - bool SelectCoins(const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; + bool SelectCoins(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; CWalletDB *pwalletdbEncryption; From f11c5a3cbd2833be124e66272aea274fda534626 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 23 Mar 2016 11:55:46 +0100 Subject: [PATCH 0356/1223] devtools: make github-merge.py use py3 This makes github-merge.py the first developer tool to go all Python 3 (for context see #7717). The changes are straightforward as the script already was `from __future__ import division,print_function,unicode_literals`. However urllib2 changed name, and json will only accept unicode data not bytes. This retains py2 compatibility for now: not strictly necessary as it's not used by the build system - but it was easy. --- contrib/devtools/github-merge.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index c8dcaae26..9a62fccbb 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2016 Bitcoin Core Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,6 +19,11 @@ import os,sys from sys import stdin,stdout,stderr import argparse import subprocess +import json,codecs +try: + from urllib.request import Request,urlopen +except: + from urllib2 import Request,urlopen # External tools (can be overridden using environment) GIT = os.getenv('GIT','git') @@ -38,7 +43,7 @@ def git_config_get(option, default=None): Get named configuration option from git repository. ''' try: - return subprocess.check_output([GIT,'config','--get',option]).rstrip() + return subprocess.check_output([GIT,'config','--get',option]).rstrip().decode('utf-8') except subprocess.CalledProcessError as e: return default @@ -47,18 +52,19 @@ def retrieve_pr_title(repo,pull): Retrieve pull request title from github. Return None if no title can be found, or an error happens. ''' - import urllib2,json try: - req = urllib2.Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) - result = urllib2.urlopen(req) - result = json.load(result) - return result['title'] + req = Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) + result = urlopen(req) + reader = codecs.getreader('utf-8') + obj = json.load(reader(result)) + return obj['title'] except Exception as e: print('Warning: unable to retrieve pull title from github: %s' % e) return None def ask_prompt(text): print(text,end=" ",file=stderr) + stderr.flush() reply = stdin.readline().rstrip() print("",file=stderr) return reply From 7eb702954ed0e297c5ded548e6c4f11f55313b7a Mon Sep 17 00:00:00 2001 From: instagibbs Date: Thu, 18 Feb 2016 16:31:12 -0800 Subject: [PATCH 0357/1223] Add importprunedfunds rpc call --- qa/pull-tester/rpc-tests.py | 2 + qa/rpc-tests/importprunedfunds.py | 119 ++++++++++++++++++++++++++++++ src/merkleblock.cpp | 14 ++-- src/merkleblock.h | 9 ++- src/rpc/rawtransaction.cpp | 3 +- src/test/bloom_tests.cpp | 23 +++--- src/test/pmt_tests.cpp | 8 +- src/wallet/rpcdump.cpp | 67 +++++++++++++++++ src/wallet/rpcwallet.cpp | 2 + 9 files changed, 224 insertions(+), 23 deletions(-) create mode 100755 qa/rpc-tests/importprunedfunds.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 74be96da7..10b51fef7 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -116,6 +116,7 @@ testScripts = [ 'invalidtxrequest.py', 'abandonconflict.py', 'p2p-versionbits-warning.py', + 'importprunedfunds.py', ] testScriptsExt = [ 'bip65-cltv.py', @@ -127,6 +128,7 @@ testScriptsExt = [ 'getblocktemplate_proposals.py', 'txn_doublespend.py', 'txn_clone.py --mineblock', + 'pruning.py', 'forknotify.py', 'invalidateblock.py', # 'rpcbind_test.py', #temporary, bug in libevent, see #6655 diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py new file mode 100755 index 000000000..bac144cd7 --- /dev/null +++ b/qa/rpc-tests/importprunedfunds.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import decimal + +class ImportPrunedFundsTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + self.nodes = start_nodes(2, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + self.is_network_split=False + self.sync_all() + + def run_test (self): + import time + begintime = int(time.time()) + + print "Mining blocks..." + self.nodes[0].generate(101) + + # sync + self.sync_all() + + # address + address1 = self.nodes[0].getnewaddress() + # pubkey + address2 = self.nodes[0].getnewaddress() + address2_pubkey = self.nodes[0].validateaddress(address2)['pubkey'] # Using pubkey + # privkey + address3 = self.nodes[0].getnewaddress() + address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey + + #Check only one address + address_info = self.nodes[0].validateaddress(address1) + assert_equal(address_info['ismine'], True) + + self.sync_all() + + #Node 1 sync test + assert_equal(self.nodes[1].getblockcount(),101) + + #Address Test - before import + address_info = self.nodes[1].validateaddress(address1) + assert_equal(address_info['iswatchonly'], False) + assert_equal(address_info['ismine'], False) + + address_info = self.nodes[1].validateaddress(address2) + assert_equal(address_info['iswatchonly'], False) + assert_equal(address_info['ismine'], False) + + address_info = self.nodes[1].validateaddress(address3) + assert_equal(address_info['iswatchonly'], False) + assert_equal(address_info['ismine'], False) + + #Send funds to self + txnid1 = self.nodes[0].sendtoaddress(address1, 0.1) + self.nodes[0].generate(1) + rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex'] + proof1 = self.nodes[0].gettxoutproof([txnid1]) + + txnid2 = self.nodes[0].sendtoaddress(address2, 0.05) + self.nodes[0].generate(1) + rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex'] + proof2 = self.nodes[0].gettxoutproof([txnid2]) + + + txnid3 = self.nodes[0].sendtoaddress(address3, 0.025) + self.nodes[0].generate(1) + rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex'] + proof3 = self.nodes[0].gettxoutproof([txnid3]) + + self.sync_all() + + #Import with no affiliated address + try: + result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "") + except JSONRPCException,e: + errorString = e.error['message'] + + assert('No addresses' in errorString) + + balance1 = self.nodes[1].getbalance("", 0, True) + assert_equal(balance1, Decimal(0)) + + #Import with affiliated address with no rescan + self.nodes[1].importaddress(address2, "", False) + result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2, "") + balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + assert_equal(balance2, Decimal('0.05')) + + #Import with private key with no rescan + self.nodes[1].importprivkey(address3_privkey, "", False) + result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3, "") + balance3 = Decimal(self.nodes[1].getbalance("", 0, False)) + assert_equal(balance3, Decimal('0.025')) + balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + assert_equal(balance3, Decimal('0.075')) + + #Addresses Test - after import + address_info = self.nodes[1].validateaddress(address1) + assert_equal(address_info['iswatchonly'], False) + assert_equal(address_info['ismine'], False) + address_info = self.nodes[1].validateaddress(address2) + assert_equal(address_info['iswatchonly'], True) + assert_equal(address_info['ismine'], False) + address_info = self.nodes[1].validateaddress(address3) + assert_equal(address_info['iswatchonly'], False) + assert_equal(address_info['ismine'], True) + +if __name__ == '__main__': + ImportPrunedFundsTest ().main () diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 8447f924e..dca4973cc 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -95,7 +95,7 @@ void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const st } } -uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch) { +uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex) { if (nBitsUsed >= vBits.size()) { // overflowed the bits array - failure fBad = true; @@ -110,14 +110,16 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns return uint256(); } const uint256 &hash = vHash[nHashUsed++]; - if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid + if (height==0 && fParentOfMatch) { // in case of height 0, we have a matched txid vMatch.push_back(hash); + vnIndex.push_back(pos); + } return hash; } else { // otherwise, descend into the subtrees to extract matched txids and hashes - uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; + uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch, vnIndex), right; if (pos*2+1 < CalcTreeWidth(height-1)) { - right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); + right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch, vnIndex); if (right == left) { // The left and right branches should never be identical, as the transaction // hashes covered by them must each be unique. @@ -147,7 +149,7 @@ CPartialMerkleTree::CPartialMerkleTree(const std::vector &vTxid, const CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} -uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { +uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::vector &vnIndex) { vMatch.clear(); // An empty set will not work if (nTransactions == 0) @@ -167,7 +169,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { nHeight++; // traverse the partial tree unsigned int nBitsUsed = 0, nHashUsed = 0; - uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); + uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch, vnIndex); // verify that no problems occurred during the tree traversal if (fBad) return uint256(); diff --git a/src/merkleblock.h b/src/merkleblock.h index 996cd1262..835cbcce5 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -75,9 +75,9 @@ protected: /** * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild. - * it returns the hash of the respective node. + * it returns the hash of the respective node and its respective index. */ - uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch); + uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex); public: @@ -110,10 +110,11 @@ public: CPartialMerkleTree(); /** - * extract the matching txid's represented by this partial merkle tree. + * extract the matching txid's represented by this partial merkle tree + * and their respective indices within the partial tree. * returns the merkle root, or 0 in case of failure */ - uint256 ExtractMatches(std::vector &vMatch); + uint256 ExtractMatches(std::vector &vMatch, std::vector &vnIndex); }; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index c72339313..34dd3b30f 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -303,7 +303,8 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp) UniValue res(UniValue::VARR); vector vMatch; - if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot) + vector vIndex; + if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) return res; LOCK(cs_main); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 98f9de767..9557000dd 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -204,7 +204,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8); vector vMatched; - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + vector vIndex; + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -221,7 +222,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7); - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -249,7 +250,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + vector vIndex; + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -275,7 +277,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3); - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -303,7 +305,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + vector vIndex; + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -326,7 +329,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3); - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -353,7 +356,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + vector vIndex; + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -392,7 +396,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6); vector vMatched; - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + vector vIndex; + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); @@ -409,7 +414,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); - BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); + BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 113b9437e..2f3f60788 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -88,7 +88,8 @@ BOOST_AUTO_TEST_CASE(pmt_test1) // extract merkle root and matched txids from copy std::vector vMatchTxid2; - uint256 merkleRoot2 = pmt2.ExtractMatches(vMatchTxid2); + std::vector vIndex; + uint256 merkleRoot2 = pmt2.ExtractMatches(vMatchTxid2, vIndex); // check that it has the same merkle root as the original, and a valid one BOOST_CHECK(merkleRoot1 == merkleRoot2); @@ -102,7 +103,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) CPartialMerkleTreeTester pmt3(pmt2); pmt3.Damage(); std::vector vMatchTxid3; - uint256 merkleRoot3 = pmt3.ExtractMatches(vMatchTxid3); + uint256 merkleRoot3 = pmt3.ExtractMatches(vMatchTxid3, vIndex); BOOST_CHECK(merkleRoot3 != merkleRoot1); } } @@ -122,7 +123,8 @@ BOOST_AUTO_TEST_CASE(pmt_malleability) CPartialMerkleTree tree(vTxid, vMatch); std::vector vTxid2; - BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull()); + std::vector vIndex; + BOOST_CHECK(tree.ExtractMatches(vTxid, vIndex).IsNull()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 6e50f9242..899ed1b3d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -13,6 +13,8 @@ #include "util.h" #include "utiltime.h" #include "wallet.h" +#include "merkleblock.h" +#include "core_io.h" #include #include @@ -243,6 +245,71 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } +UniValue importprunedfunds(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 2 || params.size() > 3) + throw runtime_error( + "importprunedfunds\n" + "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n" + "\nArguments:\n" + "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" + "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" + "3. \"label\" (string, optional) An optional label\n" + ); + + CTransaction tx; + if (!DecodeHexTx(tx, params[0].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + uint256 hashTx = tx.GetHash(); + CWalletTx wtx(pwalletMain,tx); + + CDataStream ssMB(ParseHexV(params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CMerkleBlock merkleBlock; + ssMB >> merkleBlock; + + string strLabel = ""; + if (params.size() == 3) + strLabel = params[2].get_str(); + + //Search partial merkle tree in proof for our transaction and index in valid block + vector vMatch; + vector vIndex; + unsigned int txnIndex = 0; + if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) { + + LOCK(cs_main); + + if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()])) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); + + vector::const_iterator it; + if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof"); + } + + txnIndex = vIndex[it - vMatch.begin()]; + } + else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock"); + } + + wtx.nIndex = txnIndex; + wtx.hashBlock = merkleBlock.header.GetHash(); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (pwalletMain->IsMine(tx)) { + CWalletDB walletdb(pwalletMain->strWalletFile, "r+", false); + pwalletMain->AddToWallet(wtx, false, &walletdb); + return NullUniValue; + } + + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); +} + UniValue importpubkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 759f894cc..fbe95a14c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2503,6 +2503,7 @@ extern UniValue importaddress(const UniValue& params, bool fHelp); extern UniValue importpubkey(const UniValue& params, bool fHelp); extern UniValue dumpwallet(const UniValue& params, bool fHelp); extern UniValue importwallet(const UniValue& params, bool fHelp); +extern UniValue importprunedfunds(const UniValue& params, bool fHelp); const CRPCCommand vWalletRPCCommands[] = { // category name actor (function) okSafeMode @@ -2529,6 +2530,7 @@ const CRPCCommand vWalletRPCCommands[] = { "wallet", "importprivkey", &importprivkey, true }, { "wallet", "importwallet", &importwallet, true }, { "wallet", "importaddress", &importaddress, true }, + { "wallet", "importprunedfunds", &importprunedfunds, true }, { "wallet", "importpubkey", &importpubkey, true }, { "wallet", "keypoolrefill", &keypoolrefill, true }, { "wallet", "listaccounts", &listaccounts, false }, From f1bb13c93da5d4bedf9dd2cd7357008376e9a2b4 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Mon, 7 Mar 2016 08:51:06 -0500 Subject: [PATCH 0358/1223] Added companion removeprunedfunds call. --- qa/rpc-tests/importprunedfunds.py | 21 +++++++++++++++++ src/wallet/rpcdump.cpp | 38 ++++++++++++++++++++++++++++++ src/wallet/rpcwallet.cpp | 2 ++ src/wallet/wallet.cpp | 25 ++++++++++++++++++++ src/wallet/wallet.h | 1 + src/wallet/walletdb.cpp | 39 +++++++++++++++++++++++++++++++ src/wallet/walletdb.h | 1 + 7 files changed, 127 insertions(+) diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index bac144cd7..5cbdcde9a 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -115,5 +115,26 @@ class ImportPrunedFundsTest(BitcoinTestFramework): assert_equal(address_info['iswatchonly'], False) assert_equal(address_info['ismine'], True) + #Remove transactions + + try: + self.nodes[1].removeprunedfunds(txnid1) + except JSONRPCException,e: + errorString = e.error['message'] + + assert('does not exist' in errorString) + + balance1 = Decimal(self.nodes[1].getbalance("", 0, True)) + assert_equal(balance1, Decimal('0.075')) + + + self.nodes[1].removeprunedfunds(txnid2) + balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + assert_equal(balance2, Decimal('0.025')) + + self.nodes[1].removeprunedfunds(txnid3) + balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + assert_equal(balance3, Decimal('0.0')) + if __name__ == '__main__': ImportPrunedFundsTest ().main () diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 899ed1b3d..bb40cf724 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -310,6 +310,44 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); } +UniValue removeprunedfunds(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "removeprunedfunds \"txid\"\n" + "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will effect wallet balances.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The hex-encoded id of the transaction you are deleting\n" + "\nExamples:\n" + + HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(params[0].get_str()); + vector vHash; + vHash.push_back(hash); + vector vHashOut; + + if(pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction."); + } + + if(vHashOut.empty()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); + } + + ThreadFlushWalletDB(pwalletMain->strWalletFile); + + return NullUniValue; +} + UniValue importpubkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fbe95a14c..29f7802c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2504,6 +2504,7 @@ extern UniValue importpubkey(const UniValue& params, bool fHelp); extern UniValue dumpwallet(const UniValue& params, bool fHelp); extern UniValue importwallet(const UniValue& params, bool fHelp); extern UniValue importprunedfunds(const UniValue& params, bool fHelp); +extern UniValue removeprunedfunds(const UniValue& params, bool fHelp); const CRPCCommand vWalletRPCCommands[] = { // category name actor (function) okSafeMode @@ -2552,6 +2553,7 @@ const CRPCCommand vWalletRPCCommands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, + { "wallet", "removeprunedfunds", &removeprunedfunds, true }, }; void walletRegisterRPCCommands() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7d1928dd6..801ef9868 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2362,6 +2362,31 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) return DB_LOAD_OK; } +DBErrors CWallet::ZapSelectTx(vector& vHashIn, vector& vHashOut) +{ + if (!fFileBacked) + return DB_LOAD_OK; + DBErrors nZapSelectTxRet = CWalletDB(strWalletFile,"cr+").ZapSelectTx(this, vHashIn, vHashOut); + if (nZapSelectTxRet == DB_NEED_REWRITE) + { + if (CDB::Rewrite(strWalletFile, "\x04pool")) + { + LOCK(cs_wallet); + setKeyPool.clear(); + // Note: can't top-up keypool here, because wallet is locked. + // User will be prompted to unlock wallet the next operation + // that requires a new key. + } + } + + if (nZapSelectTxRet != DB_LOAD_OK) + return nZapSelectTxRet; + + MarkDirty(); + + return DB_LOAD_OK; + +} DBErrors CWallet::ZapWalletTx(std::vector& vWtx) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index e37d972a1..5db36f52d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -792,6 +792,7 @@ public: DBErrors LoadWallet(bool& fFirstRunRet); DBErrors ZapWalletTx(std::vector& vWtx); + DBErrors ZapSelectTx(std::vector& vHashIn, std::vector& vHashOut); bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0a4a1dae2..f2b5408e9 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -785,6 +785,45 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector& vTxHash, vec return result; } +DBErrors CWalletDB::ZapSelectTx(CWallet* pwallet, vector& vTxHashIn, vector& vTxHashOut) +{ + // build list of wallet TXs and hashes + vector vTxHash; + vector vWtx; + DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); + if (err != DB_LOAD_OK) { + return err; + } + + std::sort(vTxHash.begin(), vTxHash.end()); + std::sort(vTxHashIn.begin(), vTxHashIn.end()); + + // erase each matching wallet TX + bool delerror = false; + vector::iterator it = vTxHashIn.begin(); + BOOST_FOREACH (uint256 hash, vTxHash) { + while (it < vTxHashIn.end() && (*it) < hash) { + it++; + } + if (it == vTxHashIn.end()) { + break; + } + else if ((*it) == hash) { + pwallet->mapWallet.erase(hash); + if(!EraseTx(hash)) { + LogPrint("db", "Transaction was found for deletion but returned database error: %s\n", hash.GetHex()); + delerror = true; + } + vTxHashOut.push_back(hash); + } + } + + if (delerror) { + return DB_CORRUPT; + } + return DB_LOAD_OK; +} + DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector& vWtx) { // build list of wallet TXs diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 7e8cc4084..fe6c36634 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -130,6 +130,7 @@ public: DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); + DBErrors ZapSelectTx(CWallet* pwallet, std::vector& vHashIn, std::vector& vHashOut); static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, const std::string& filename); From 263de3d1c80c8a0aa54acd4d6708a4078d479b70 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Mar 2016 17:46:06 +0100 Subject: [PATCH 0359/1223] [Wallet][RPC] add abandoned status to listtransactions --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 759f894cc..8f7c64983 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1346,6 +1346,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) WalletTxToJSON(wtx, entry); + entry.push_back(Pair("abandoned", wtx.isAbandoned())); ret.push_back(entry); } } From df9e9233dc4fce68e48beb45699cd255911578c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 23 Mar 2016 15:44:18 +0000 Subject: [PATCH 0360/1223] Fix lockunspents help message --- src/wallet/rpcwallet.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8f7c64983..1d2350596 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2099,16 +2099,17 @@ UniValue lockunspent(const UniValue& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" + "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n" "\nUpdates list of temporarily unspendable outputs.\n" "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n" + "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n" "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n" "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n" "is always cleared (by virtue of process exit) when a node stops or fails.\n" "Also see the listunspent call\n" "\nArguments:\n" "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n" - "2. \"transactions\" (string, required) A json array of objects. Each object the txid (string) vout (numeric)\n" + "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n" " [ (json array of json objects)\n" " {\n" " \"txid\":\"id\", (string) The transaction id\n" From fc737d127fb53dbfd31d3d677e157b27f17d5b09 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 24 Mar 2016 21:48:45 +0100 Subject: [PATCH 0361/1223] [Qt] remove unused formatBuildDate method --- src/qt/clientmodel.cpp | 5 ----- src/qt/clientmodel.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 65637cd61..697736cc8 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -173,11 +173,6 @@ QString ClientModel::formatSubVersion() const return QString::fromStdString(strSubVersion); } -QString ClientModel::formatBuildDate() const -{ - return QString::fromStdString(CLIENT_DATE); -} - bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index db010f05c..109f95a2a 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -72,7 +72,6 @@ public: QString formatFullVersion() const; QString formatSubVersion() const; - QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; QString formatClientStartupTime() const; From 018b60c5ea703ed12edcde034a185f79e77e5576 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 25 Mar 2016 14:21:24 +0100 Subject: [PATCH 0362/1223] test_framework: detect failure of bitcoind startup Replace the `bitcoin-cli -rpcwait` after spawning bitcoind with our own loop that detects when bitcoind exits prematurely. And if one node fails to start, stop the others. This prevents a hang in such a case (see #7463). --- qa/rpc-tests/test_framework/util.py | 60 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 8d4bd52b9..f069c32a6 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -16,6 +16,7 @@ import shutil import subprocess import time import re +import errno from . import coverage from .authproxy import AuthServiceProxy, JSONRPCException @@ -130,11 +131,33 @@ def initialize_datadir(dirname, n): f.write("listenonion=0\n") return datadir +def rpc_url(i, rpchost=None): + return "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + +def wait_for_bitcoind_start(process, url, i): + ''' + Wait for bitcoind to start. This means that RPC is accessible and fully initialized. + Raise an exception if bitcoind exits during initialization. + ''' + while True: + if process.poll() is not None: + raise Exception('bitcoind exited with status %i during initialization' % process.returncode) + try: + rpc = get_rpc_proxy(url, i) + blocks = rpc.getblockcount() + break # break out of loop on success + except IOError as e: + if e.errno != errno.ECONNREFUSED: # Port not yet open? + raise # unknown IO error + except JSONRPCException as e: # Initialization phase + if e.error['code'] != -28: # RPC in warmup? + raise # unkown JSON RPC exception + time.sleep(0.25) + def initialize_chain(test_dir): """ Create (or copy from cache) a 200-block-long chain and 4 wallets. - bitcoind and bitcoin-cli must be in search path. """ if (not os.path.isdir(os.path.join("cache","node0")) @@ -147,7 +170,6 @@ def initialize_chain(test_dir): if os.path.isdir(os.path.join("cache","node"+str(i))): shutil.rmtree(os.path.join("cache","node"+str(i))) - devnull = open(os.devnull, "w") # Create cache directories, run bitcoinds: for i in range(4): datadir=initialize_datadir("cache", i) @@ -156,19 +178,15 @@ def initialize_chain(test_dir): args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount" - subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir, - "-rpcwait", "getblockcount"], stdout=devnull) + print "initialize_chain: bitcoind started, waiting for RPC to come up" + wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed" - devnull.close() + print "initialize_chain: RPC succesfully started" rpcs = [] - for i in range(4): try: - url = "http://rt:rt@127.0.0.1:%d" % (rpc_port(i),) - rpcs.append(get_rpc_proxy(url, i)) + rpcs.append(get_rpc_proxy(rpc_url(i), i)) except: sys.stderr.write("Error connecting to "+url+"\n") sys.exit(1) @@ -243,17 +261,12 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) - devnull = open(os.devnull, "w") if os.getenv("PYTHON_DEBUG", ""): - print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount" - subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] + - _rpchost_to_args(rpchost) + - ["-rpcwait", "getblockcount"], stdout=devnull) + print "start_node: bitcoind started, waiting for RPC to come up" + url = rpc_url(i, rpchost) + wait_for_bitcoind_start(bitcoind_processes[i], url, i) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: calling bitcoin-cli -rpcwait getblockcount returned" - devnull.close() - url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) - + print "start_node: RPC succesfully started" proxy = get_rpc_proxy(url, i, timeout=timewait) if COVERAGE_DIR: @@ -267,7 +280,14 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): """ if extra_args is None: extra_args = [ None for i in range(num_nodes) ] if binary is None: binary = [ None for i in range(num_nodes) ] - return [ start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]) for i in range(num_nodes) ] + rpcs = [] + try: + for i in range(num_nodes): + rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i])) + except: # If one node failed to start, stop the others + stop_nodes(rpcs) + raise + return rpcs def log_filename(dirname, n_node, logname): return os.path.join(dirname, "node"+str(n_node), "regtest", logname) From d7b80b54fbb73acc92ddee84697ac4cc10d4d336 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 28 Mar 2016 11:44:19 +0200 Subject: [PATCH 0363/1223] test_framework: Avoid infinite loop in encoding Decimal Avoid an infinite loop in encoding, by ensuring EncodeDecimal returns a string. round(Decimal) used to convert it to float, but it no longer does in python 3.x. Strings are supported since #6380, so just use that. --- qa/rpc-tests/test_framework/authproxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index fba469a0d..cfc254da0 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -61,7 +61,7 @@ class JSONRPCException(Exception): def EncodeDecimal(o): if isinstance(o, decimal.Decimal): - return round(o, 8) + return str(o) raise TypeError(repr(o) + " is not JSON serializable") class AuthServiceProxy(object): From e7e48ba66cb597621a30945da9ca7fc36a6dc84c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 28 Mar 2016 12:28:49 +0200 Subject: [PATCH 0364/1223] test_framework: Py3.4 compat: Specify timeout parameter by name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed in version 3.4: The strict parameter was removed. HTTP 0.9-style “Simple Responses” are not longer supported. (https://docs.python.org/3/library/http.client.html) Source: https://github.com/jgarzik/python-bitcoinrpc/commit/7ebeebb4f61917fe590d980cb4f9aefdce2c8f25 --- qa/rpc-tests/test_framework/authproxy.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index cfc254da0..1eb277259 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -92,11 +92,10 @@ class AuthServiceProxy(object): self.__conn = connection elif self.__url.scheme == 'https': self.__conn = httplib.HTTPSConnection(self.__url.hostname, port, - None, None, False, - timeout) + timeout=timeout) else: self.__conn = httplib.HTTPConnection(self.__url.hostname, port, - False, timeout) + timeout=timeout) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): From fa3fafc96076afb15fa77e01d5f6aff88a333a7e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 28 Mar 2016 21:47:13 +0200 Subject: [PATCH 0365/1223] [qa] wallet: Wait for reindex to catch up --- qa/rpc-tests/wallet.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index df176601a..e6ce39711 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -279,6 +279,7 @@ class WalletTest (BitcoinTestFramework): blocks = self.nodes[0].generate(2) self.sync_all() balance_nodes = [self.nodes[i].getbalance() for i in range(3)] + block_count = self.nodes[0].getblockcount() maintenance = [ '-rescan', @@ -292,6 +293,9 @@ class WalletTest (BitcoinTestFramework): stop_nodes(self.nodes) wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) + while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: + # reindex will leave rpc warm up "early"; Wait for it to finish + time.sleep(0.1) assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) # Exercise listsinceblock with the last two blocks From cef8bdf5d747d42c3be473d7ef38052eebd5e9bd Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 24 Mar 2016 21:43:14 +0100 Subject: [PATCH 0366/1223] [Wallet][RPC] add missing abandon status documentation --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1d2350596..d6b63bf12 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1439,6 +1439,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"vout\": n, (numeric) the vout value\n" " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" + " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable).\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions. Negative confirmations indicate the\n" " transaction conflicts with the block chain\n" From 7d5e31a82bbf39b9e1a5f0afe5ad9cbf4df9778b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 29 Mar 2016 11:17:47 +0200 Subject: [PATCH 0367/1223] [Qt] remove trailing output-index from transaction-id The trailing output-index leads to cases where the user can't look-up the transaction ID in various systems. --- src/qt/transactiondesc.cpp | 3 ++- src/qt/transactionrecord.cpp | 7 +++---- src/qt/transactionrecord.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 5cb4cd5af..5abefc144 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -240,7 +240,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty()) strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "
"; - strHTML += "" + tr("Transaction ID") + ": " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "
"; + strHTML += "" + tr("Transaction ID") + ": " + rec->getTxID() + "
"; + strHTML += "" + tr("Output index") + ": " + QString::number(rec->getOutputIndex()) + "
"; // Message from normal bitcoin:URI (bitcoin:123...?message=example) Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5b16b108e..97b77cc93 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -260,11 +260,10 @@ bool TransactionRecord::statusUpdateNeeded() QString TransactionRecord::getTxID() const { - return formatSubTxId(hash, idx); + return QString::fromStdString(hash.ToString()); } -QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout) +int TransactionRecord::getOutputIndex() const { - return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout)); + return idx; } - diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 49753ee31..95ab98c10 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -128,8 +128,8 @@ public: /** Return the unique identifier for this transaction (part) */ QString getTxID() const; - /** Format subtransaction id */ - static QString formatSubTxId(const uint256 &hash, int vout); + /** Return the output index of the subtransaction */ + int getOutputIndex() const; /** Update status from core wallet tx. */ From e1523cee5808bb792cd99f037f06b736af4e23fb Mon Sep 17 00:00:00 2001 From: mruddy Date: Tue, 29 Mar 2016 14:40:00 +0000 Subject: [PATCH 0368/1223] P2P: add maxtimeadjustment command line option --- src/init.cpp | 2 ++ src/timedata.cpp | 2 +- src/timedata.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 38ac91b2a..0fb714612 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -27,6 +27,7 @@ #include "script/standard.h" #include "script/sigcache.h" #include "scheduler.h" +#include "timedata.h" #include "txdb.h" #include "txmempool.h" #include "torcontrol.h" @@ -365,6 +366,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxconnections=", strprintf(_("Maintain at most connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER)); strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER)); + strUsage += HelpMessageOpt("-maxtimeadjustment", strprintf(_("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)"), DEFAULT_MAX_TIME_ADJUSTMENT)); strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); diff --git a/src/timedata.cpp b/src/timedata.cpp index 4d2f8d1e3..b6bcf86fb 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -83,7 +83,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) int64_t nMedian = vTimeOffsets.median(); std::vector vSorted = vTimeOffsets.sorted(); // Only let other nodes change our time by so much - if (abs64(nMedian) < 70 * 60) + if (abs64(nMedian) <= std::max(0, GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT))) { nTimeOffset = nMedian; } diff --git a/src/timedata.h b/src/timedata.h index 2296baf11..9f2499c85 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -10,6 +10,8 @@ #include #include +static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 70 * 60; + class CNetAddr; /** From faa9f01461fea8e3665371f658d7f0dc919851eb Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 29 Mar 2016 16:48:42 +0200 Subject: [PATCH 0369/1223] [qa] Don't run pruning.py twice --- qa/pull-tester/rpc-tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 10b51fef7..d5d5f1061 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -128,7 +128,6 @@ testScriptsExt = [ 'getblocktemplate_proposals.py', 'txn_doublespend.py', 'txn_clone.py --mineblock', - 'pruning.py', 'forknotify.py', 'invalidateblock.py', # 'rpcbind_test.py', #temporary, bug in libevent, see #6655 From 18f05c765c800126b74a6d5b7f33cef7c9aae1b7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 20 Mar 2016 17:51:52 +0000 Subject: [PATCH 0370/1223] build: python 3 compatibility Ubuntu 16.04 "xenial xerus" does not come with Python 2.x by default. It is possible to install a python-2.7 package, but this has its own problem: no `python` or `python2` symlink (see #7717). This fixes the following scripts to work with python 3: - `make check` (bctest,py, bitcoin-util-test.py) - `make translate` (extract_strings_qt.py) - `make symbols-check` (symbol-check.py) - `make security-check` (security-check.py) Explicitly call the python commands using $(PYTHON) instead of relying on the interpreter line at the top of the scripts. --- Makefile.am | 6 +- configure.ac | 2 +- contrib/devtools/security-check.py | 34 +++---- contrib/devtools/symbol-check.py | 63 ++++++------- contrib/macdeploy/custom_dsstore.py | 6 +- contrib/macdeploy/macdeployqtplus | 136 ++++++++++++++-------------- share/qt/extract_strings_qt.py | 9 +- src/Makefile.qt.include | 2 +- src/Makefile.test.include | 2 +- src/test/bctest.py | 2 +- src/test/bitcoin-util-test.py | 2 +- 11 files changed, 135 insertions(+), 129 deletions(-) diff --git a/Makefile.am b/Makefile.am index d6cbd7cb1..0929a59ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,7 +110,7 @@ osx_volname: if BUILD_DARWIN $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) - $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) + $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) deploydir: $(OSX_DMG) else @@ -134,10 +134,10 @@ $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIF $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ $(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) - $< "$@" "$(OSX_VOLNAME)" + $(PYTHON) $< "$@" "$(OSX_VOLNAME)" $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) - INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 + INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 deploydir: $(APP_DIST_EXTRAS) endif diff --git a/configure.ac b/configure.ac index 939dfeaab..8596307f3 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(JAVA, java) -AC_PATH_PROG(PYTHON, python) +AC_PATH_PROGS([PYTHON], [python3 python2.7 python2 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 0319f739c..301fea85c 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -5,7 +5,7 @@ Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. Needs `readelf` (for ELF) and `objdump` (for PE). ''' -from __future__ import division,print_function +from __future__ import division,print_function,unicode_literals import subprocess import sys import os @@ -23,9 +23,9 @@ def check_ELF_PIE(executable): raise IOError('Error opening file') ok = False - for line in stdout.split('\n'): + for line in stdout.split(b'\n'): line = line.split() - if len(line)>=2 and line[0] == 'Type:' and line[1] == 'DYN': + if len(line)>=2 and line[0] == b'Type:' and line[1] == b'DYN': ok = True return ok @@ -38,17 +38,17 @@ def get_ELF_program_headers(executable): in_headers = False count = 0 headers = [] - for line in stdout.split('\n'): - if line.startswith('Program Headers:'): + for line in stdout.split(b'\n'): + if line.startswith(b'Program Headers:'): in_headers = True - if line == '': + if line == b'': in_headers = False if in_headers: if count == 1: # header line - ofs_typ = line.find('Type') - ofs_offset = line.find('Offset') - ofs_flags = line.find('Flg') - ofs_align = line.find('Align') + ofs_typ = line.find(b'Type') + ofs_offset = line.find(b'Offset') + ofs_flags = line.find(b'Flg') + ofs_align = line.find(b'Align') if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1: raise ValueError('Cannot parse elfread -lW output') elif count > 1: @@ -65,9 +65,9 @@ def check_ELF_NX(executable): have_wx = False have_gnu_stack = False for (typ, flags) in get_ELF_program_headers(executable): - if typ == 'GNU_STACK': + if typ == b'GNU_STACK': have_gnu_stack = True - if 'W' in flags and 'E' in flags: # section is both writable and executable + if b'W' in flags and b'E' in flags: # section is both writable and executable have_wx = True return have_gnu_stack and not have_wx @@ -84,7 +84,7 @@ def check_ELF_RELRO(executable): # However, the dynamic linker need to write to this area so these are RW. # Glibc itself takes care of mprotecting this area R after relocations are finished. # See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347 - if typ == 'GNU_RELRO': + if typ == b'GNU_RELRO': have_gnu_relro = True have_bindnow = False @@ -92,9 +92,9 @@ def check_ELF_RELRO(executable): (stdout, stderr) = p.communicate() if p.returncode: raise IOError('Error opening file') - for line in stdout.split('\n'): + for line in stdout.split(b'\n'): tokens = line.split() - if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]): + if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2]): have_bindnow = True return have_gnu_relro and have_bindnow @@ -107,8 +107,8 @@ def check_ELF_Canary(executable): if p.returncode: raise IOError('Error opening file') ok = False - for line in stdout.split('\n'): - if '__stack_chk_fail' in line: + for line in stdout.split(b'\n'): + if b'__stack_chk_fail' in line: ok = True return ok diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 4ad5136f7..e26c0fbb9 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -11,7 +11,7 @@ Example usage: find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py ''' -from __future__ import division, print_function +from __future__ import division, print_function, unicode_literals import subprocess import re import sys @@ -47,28 +47,28 @@ MAX_VERSIONS = { # Ignore symbols that are exported as part of every executable IGNORE_EXPORTS = { -'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used' +b'_edata', b'_end', b'_init', b'__bss_start', b'_fini', b'_IO_stdin_used' } READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') # Allowed NEEDED libraries ALLOWED_LIBRARIES = { # bitcoind and bitcoin-qt -'libgcc_s.so.1', # GCC base support -'libc.so.6', # C library -'libpthread.so.0', # threading -'libanl.so.1', # DNS resolve -'libm.so.6', # math library -'librt.so.1', # real-time (clock) -'ld-linux-x86-64.so.2', # 64-bit dynamic linker -'ld-linux.so.2', # 32-bit dynamic linker +b'libgcc_s.so.1', # GCC base support +b'libc.so.6', # C library +b'libpthread.so.0', # threading +b'libanl.so.1', # DNS resolve +b'libm.so.6', # math library +b'librt.so.1', # real-time (clock) +b'ld-linux-x86-64.so.2', # 64-bit dynamic linker +b'ld-linux.so.2', # 32-bit dynamic linker # bitcoin-qt only -'libX11-xcb.so.1', # part of X11 -'libX11.so.6', # part of X11 -'libxcb.so.1', # part of X11 -'libfontconfig.so.1', # font support -'libfreetype.so.6', # font parsing -'libdl.so.2' # programming interface to dynamic linker +b'libX11-xcb.so.1', # part of X11 +b'libX11.so.6', # part of X11 +b'libxcb.so.1', # part of X11 +b'libfontconfig.so.1', # font support +b'libfreetype.so.6', # font parsing +b'libdl.so.2' # programming interface to dynamic linker } class CPPFilt(object): @@ -81,7 +81,8 @@ class CPPFilt(object): self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE) def __call__(self, mangled): - self.proc.stdin.write(mangled + '\n') + self.proc.stdin.write(mangled + b'\n') + self.proc.stdin.flush() return self.proc.stdout.readline().rstrip() def close(self): @@ -99,24 +100,24 @@ def read_symbols(executable, imports=True): if p.returncode: raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) syms = [] - for line in stdout.split('\n'): + for line in stdout.split(b'\n'): line = line.split() - if len(line)>7 and re.match('[0-9]+:$', line[0]): - (sym, _, version) = line[7].partition('@') - is_import = line[6] == 'UND' - if version.startswith('@'): + if len(line)>7 and re.match(b'[0-9]+:$', line[0]): + (sym, _, version) = line[7].partition(b'@') + is_import = line[6] == b'UND' + if version.startswith(b'@'): version = version[1:] if is_import == imports: syms.append((sym, version)) return syms def check_version(max_versions, version): - if '_' in version: - (lib, _, ver) = version.rpartition('_') + if b'_' in version: + (lib, _, ver) = version.rpartition(b'_') else: lib = version ver = '0' - ver = tuple([int(x) for x in ver.split('.')]) + ver = tuple([int(x) for x in ver.split(b'.')]) if not lib in max_versions: return False return ver <= max_versions[lib] @@ -127,10 +128,10 @@ def read_libraries(filename): if p.returncode: raise IOError('Error opening file') libraries = [] - for line in stdout.split('\n'): + for line in stdout.split(b'\n'): tokens = line.split() - if len(tokens)>2 and tokens[1] == '(NEEDED)': - match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) + if len(tokens)>2 and tokens[1] == b'(NEEDED)': + match = re.match(b'^Shared library: \[(.*)\]$', b' '.join(tokens[2:])) if match: libraries.append(match.group(1)) else: @@ -144,18 +145,18 @@ if __name__ == '__main__': # Check imported symbols for sym,version in read_symbols(filename, True): if version and not check_version(MAX_VERSIONS, version): - print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) + print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym).decode('utf-8'), version.decode('utf-8'))) retval = 1 # Check exported symbols for sym,version in read_symbols(filename, False): if sym in IGNORE_EXPORTS: continue - print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) + print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym).decode('utf-8'))) retval = 1 # Check dependency libraries for library_name in read_libraries(filename): if library_name not in ALLOWED_LIBRARIES: - print('%s: NEEDED library %s is not allowed' % (filename, library_name)) + print('%s: NEEDED library %s is not allowed' % (filename, library_name.decode('utf-8'))) retval = 1 exit(retval) diff --git a/contrib/macdeploy/custom_dsstore.py b/contrib/macdeploy/custom_dsstore.py index 8481e903a..03e2325fc 100755 --- a/contrib/macdeploy/custom_dsstore.py +++ b/contrib/macdeploy/custom_dsstore.py @@ -2,7 +2,7 @@ # Copyright (c) 2013-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. - +from __future__ import division,print_function,unicode_literals import biplist from ds_store import DSStore from mac_alias import Alias @@ -14,7 +14,7 @@ package_name_ns = sys.argv[2] ds = DSStore.open(output_file, 'w+') ds['.']['bwsp'] = { 'ShowStatusBar': False, - 'WindowBounds': '{{300, 280}, {500, 343}}', + 'WindowBounds': b'{{300, 280}, {500, 343}}', 'ContainerShowSidebar': False, 'SidebarWidth': 0, 'ShowTabView': False, @@ -28,7 +28,7 @@ icvp = { 'gridOffsetX': 0.0, 'textSize': 12.0, 'viewOptionsVersion': 1, - 'backgroundImageAlias': '\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00', + 'backgroundImageAlias': b'\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00', 'backgroundColorBlue': 1.0, 'iconSize': 96.0, 'backgroundColorGreen': 1.0, diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 7e6270c74..685ed8e5b 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -1,5 +1,5 @@ #!/usr/bin/env python - +from __future__ import division, print_function, unicode_literals # # Copyright (C) 2011 Patrick "p2k" Schneider # @@ -201,7 +201,7 @@ class DeploymentInfo(object): def getFrameworks(binaryPath, verbose): if verbose >= 3: - print "Inspecting with otool: " + binaryPath + print("Inspecting with otool: " + binaryPath) otoolbin=os.getenv("OTOOL", "otool") otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) o_stdout, o_stderr = otool.communicate() @@ -222,8 +222,8 @@ def getFrameworks(binaryPath, verbose): info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) if info is not None: if verbose >= 3: - print "Found framework:" - print info + print("Found framework:") + print(info) libraries.append(info) return libraries @@ -234,24 +234,24 @@ def runInstallNameTool(action, *args): def changeInstallName(oldName, newName, binaryPath, verbose): if verbose >= 3: - print "Using install_name_tool:" - print " in", binaryPath - print " change reference", oldName - print " to", newName + print("Using install_name_tool:") + print(" in", binaryPath) + print(" change reference", oldName) + print(" to", newName) runInstallNameTool("change", oldName, newName, binaryPath) def changeIdentification(id, binaryPath, verbose): if verbose >= 3: - print "Using install_name_tool:" - print " change identification in", binaryPath - print " to", id + print("Using install_name_tool:") + print(" change identification in", binaryPath) + print(" to", id) runInstallNameTool("id", id, binaryPath) def runStrip(binaryPath, verbose): stripbin=os.getenv("STRIP", "strip") if verbose >= 3: - print "Using strip:" - print " stripped", binaryPath + print("Using strip:") + print(" stripped", binaryPath) subprocess.check_call([stripbin, "-x", binaryPath]) def copyFramework(framework, path, verbose): @@ -274,8 +274,8 @@ def copyFramework(framework, path, verbose): shutil.copy2(fromPath, toPath) if verbose >= 3: - print "Copied:", fromPath - print " to:", toPath + print("Copied:", fromPath) + print(" to:", toPath) permissions = os.stat(toPath) if not permissions.st_mode & stat.S_IWRITE: @@ -288,14 +288,14 @@ def copyFramework(framework, path, verbose): if not os.path.exists(linkfrom): os.symlink(linkto, linkfrom) if verbose >= 2: - print "Linked:", linkfrom, "->", linkto + print("Linked:", linkfrom, "->", linkto) fromResourcesDir = framework.sourceResourcesDirectory if os.path.exists(fromResourcesDir): toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True) if verbose >= 3: - print "Copied resources:", fromResourcesDir - print " to:", toResourcesDir + print("Copied resources:", fromResourcesDir) + print(" to:", toResourcesDir) fromContentsDir = framework.sourceVersionContentsDirectory if not os.path.exists(fromContentsDir): fromContentsDir = framework.sourceContentsDirectory @@ -304,16 +304,16 @@ def copyFramework(framework, path, verbose): shutil.copytree(fromContentsDir, toContentsDir, symlinks=True) contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory) if verbose >= 3: - print "Copied Contents:", fromContentsDir - print " to:", toContentsDir + print("Copied Contents:", fromContentsDir) + print(" to:", toContentsDir) elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True) if verbose >= 3: - print "Copied for libQtGui:", qtMenuNibSourcePath - print " to:", qtMenuNibDestinationPath + print("Copied for libQtGui:", qtMenuNibSourcePath) + print(" to:", qtMenuNibDestinationPath) return toPath @@ -326,7 +326,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym deploymentInfo.deployedFrameworks.append(framework.frameworkName) if verbose >= 2: - print "Processing", framework.frameworkName, "..." + print("Processing", framework.frameworkName, "...") # Get the Qt path from one of the Qt frameworks if deploymentInfo.qtPath is None and framework.isQtFramework(): @@ -334,7 +334,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath): if verbose >= 2: - print framework.frameworkName, "already deployed, skipping." + print(framework.frameworkName, "already deployed, skipping.") continue # install_name_tool the new id into the binary @@ -366,7 +366,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym def deployFrameworksForAppBundle(applicationBundle, strip, verbose): frameworks = getFrameworks(applicationBundle.binaryPath, verbose) if len(frameworks) == 0 and verbose >= 1: - print "Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path) + print("Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path)) return DeploymentInfo() else: return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) @@ -444,7 +444,7 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): for pluginDirectory, pluginName in plugins: if verbose >= 2: - print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..." + print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...") sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) @@ -454,8 +454,8 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): destinationPath = os.path.join(destinationDirectory, pluginName) shutil.copy2(sourcePath, destinationPath) if verbose >= 3: - print "Copied:", sourcePath - print " to:", destinationPath + print("Copied:", sourcePath) + print(" to:", destinationPath) if strip: runStrip(destinationPath, verbose) @@ -525,7 +525,7 @@ if config.translations_dir and config.translations_dir[0]: for p in config.add_resources: if verbose >= 3: - print "Checking for \"%s\"..." % p + print("Checking for \"%s\"..." % p) if not os.path.exists(p): if verbose >= 1: sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p)) @@ -535,7 +535,7 @@ for p in config.add_resources: if len(config.fancy) == 1: if verbose >= 3: - print "Fancy: Importing plistlib..." + print("Fancy: Importing plistlib...") try: import plistlib except ImportError: @@ -545,7 +545,7 @@ if len(config.fancy) == 1: p = config.fancy[0] if verbose >= 3: - print "Fancy: Loading \"%s\"..." % p + print("Fancy: Loading \"%s\"..." % p) if not os.path.exists(p): if verbose >= 1: sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p)) @@ -559,23 +559,23 @@ if len(config.fancy) == 1: sys.exit(1) try: - assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) - assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str) - assert not fancy.has_key("icon_size") or isinstance(fancy["icon_size"], int) - assert not fancy.has_key("applications_symlink") or isinstance(fancy["applications_symlink"], bool) - if fancy.has_key("items_position"): + assert "window_bounds" not in fancy or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) + assert "background_picture" not in fancy or isinstance(fancy["background_picture"], str) + assert "icon_size" not in fancy or isinstance(fancy["icon_size"], int) + assert "applications_symlink" not in fancy or isinstance(fancy["applications_symlink"], bool) + if "items_position" in fancy: assert isinstance(fancy["items_position"], dict) - for key, value in fancy["items_position"].iteritems(): + for key, value in fancy["items_position"].items(): assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int) except: if verbose >= 1: sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p)) sys.exit(1) - if fancy.has_key("background_picture"): + if "background_picture" in fancy: bp = fancy["background_picture"] if verbose >= 3: - print "Fancy: Resolving background picture \"%s\"..." % bp + print("Fancy: Resolving background picture \"%s\"..." % bp) if not os.path.exists(bp): bp = os.path.join(os.path.dirname(p), bp) if not os.path.exists(bp): @@ -591,7 +591,7 @@ else: if os.path.exists("dist"): if verbose >= 2: - print "+ Removing old dist folder +" + print("+ Removing old dist folder +") shutil.rmtree("dist") @@ -607,9 +607,9 @@ else: target = os.path.join("dist", "Bitcoin-Qt.app") if verbose >= 2: - print "+ Copying source bundle +" + print("+ Copying source bundle +") if verbose >= 3: - print app_bundle, "->", target + print(app_bundle, "->", target) os.mkdir("dist") shutil.copytree(app_bundle, target, symlinks=True) @@ -619,7 +619,7 @@ applicationBundle = ApplicationBundleInfo(target) # ------------------------------------------------ if verbose >= 2: - print "+ Deploying frameworks +" + print("+ Deploying frameworks +") try: deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) @@ -638,7 +638,7 @@ except RuntimeError as e: if config.plugins: if verbose >= 2: - print "+ Deploying plugins +" + print("+ Deploying plugins +") try: deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) @@ -664,7 +664,7 @@ else: for lng_file in add_qt_tr: p = os.path.join(qt_tr_dir, lng_file) if verbose >= 3: - print "Checking for \"%s\"..." % p + print("Checking for \"%s\"..." % p) if not os.path.exists(p): if verbose >= 1: sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file)) @@ -673,7 +673,7 @@ else: # ------------------------------------------------ if verbose >= 2: - print "+ Installing qt.conf +" + print("+ Installing qt.conf +") f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") f.write(qt_conf) @@ -682,22 +682,22 @@ f.close() # ------------------------------------------------ if len(add_qt_tr) > 0 and verbose >= 2: - print "+ Adding Qt translations +" + print("+ Adding Qt translations +") for lng_file in add_qt_tr: if verbose >= 3: - print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file) + print(os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file)) shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file)) # ------------------------------------------------ if len(config.add_resources) > 0 and verbose >= 2: - print "+ Adding additional resources +" + print("+ Adding additional resources +") for p in config.add_resources: t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p)) if verbose >= 3: - print p, "->", t + print(p, "->", t) if os.path.isdir(p): shutil.copytree(p, t, symlinks=True) else: @@ -706,10 +706,10 @@ for p in config.add_resources: # ------------------------------------------------ if config.sign and 'CODESIGNARGS' not in os.environ: - print "You must set the CODESIGNARGS environment variable. Skipping signing." + print("You must set the CODESIGNARGS environment variable. Skipping signing.") elif config.sign: if verbose >= 1: - print "Code-signing app bundle %s"%(target,) + print("Code-signing app bundle %s"%(target,)) subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True) # ------------------------------------------------ @@ -734,7 +734,7 @@ if config.dmg is not None: def runHDIUtil(verb, image_basename, **kwargs): hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] - if kwargs.has_key("capture_stdout"): + if "capture_stdout" in kwargs: del kwargs["capture_stdout"] run = subprocess.check_output else: @@ -744,7 +744,7 @@ if config.dmg is not None: hdiutil_args.append("-verbose") run = subprocess.check_call - for key, value in kwargs.iteritems(): + for key, value in kwargs.items(): hdiutil_args.append("-" + key) if not value is True: hdiutil_args.append(str(value)) @@ -753,9 +753,9 @@ if config.dmg is not None: if verbose >= 2: if fancy is None: - print "+ Creating .dmg disk image +" + print("+ Creating .dmg disk image +") else: - print "+ Preparing .dmg disk image +" + print("+ Preparing .dmg disk image +") if config.dmg != "": dmg_name = config.dmg @@ -770,7 +770,7 @@ if config.dmg is not None: sys.exit(e.returncode) else: if verbose >= 3: - print "Determining size of \"dist\"..." + print("Determining size of \"dist\"...") size = 0 for path, dirs, files in os.walk("dist"): for file in files: @@ -778,14 +778,14 @@ if config.dmg is not None: size += int(size * 0.15) if verbose >= 3: - print "Creating temp image for modification..." + print("Creating temp image for modification...") try: runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=volname, ov=True) except subprocess.CalledProcessError as e: sys.exit(e.returncode) if verbose >= 3: - print "Attaching temp image..." + print("Attaching temp image...") try: output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True) except subprocess.CalledProcessError as e: @@ -796,13 +796,13 @@ if config.dmg is not None: disk_name = m.group(1) if verbose >= 2: - print "+ Applying fancy settings +" + print("+ Applying fancy settings +") - if fancy.has_key("background_picture"): + if "background_picture" in fancy: bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"])) os.mkdir(os.path.dirname(bg_path)) if verbose >= 3: - print fancy["background_picture"], "->", bg_path + print(fancy["background_picture"], "->", bg_path) shutil.copy2(fancy["background_picture"], bg_path) else: bg_path = None @@ -839,8 +839,8 @@ if config.dmg is not None: itemscript = Template('set position of item "${item}" of container window to {${position}}') items_positions = [] - if fancy.has_key("items_position"): - for name, position in fancy["items_position"].iteritems(): + if "items_position" in fancy: + for name, position in fancy["items_position"].items(): params = { "item" : name, "position" : ",".join([str(p) for p in position]) } items_positions.append(itemscript.substitute(params)) @@ -851,9 +851,9 @@ if config.dmg is not None: "background_commands" : "", "items_positions" : "\n ".join(items_positions) } - if fancy.has_key("window_bounds"): + if "window_bounds" in fancy: params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]]) - if fancy.has_key("icon_size"): + if "icon_size" in fancy: params["icon_size"] = str(fancy["icon_size"]) if bg_path is not None: # Set background file, then call SetFile to make it invisible. @@ -873,7 +873,7 @@ if config.dmg is not None: print("Error running osascript.") if verbose >= 2: - print "+ Finalizing .dmg disk image +" + print("+ Finalizing .dmg disk image +") time.sleep(5) try: @@ -886,6 +886,6 @@ if config.dmg is not None: # ------------------------------------------------ if verbose >= 2: - print "+ Done +" + print("+ Done +") sys.exit(0) diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 2a6e4b930..7728a4377 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -1,8 +1,9 @@ #!/usr/bin/python ''' -Extract _("...") strings for translation and convert to Qt4 stringdefs so that +Extract _("...") strings for translation and convert to Qt stringdefs so that they can be picked up by Qt linguist. ''' +from __future__ import division,print_function,unicode_literals from subprocess import Popen, PIPE import glob import operator @@ -52,10 +53,14 @@ files = sys.argv[1:] # xgettext -n --keyword=_ $FILES XGETTEXT=os.getenv('XGETTEXT', 'xgettext') +if not XGETTEXT: + print('Cannot extract strings: xgettext utility is not installed or not configured.',file=sys.stderr) + print('Please install package "gettext" and re-run \'./configure\'.',file=sys.stderr) + exit(1) child = Popen([XGETTEXT,'--output=-','-n','--keyword=_'] + files, stdout=PIPE) (out, err) = child.communicate() -messages = parse_po(out) +messages = parse_po(out.decode('utf-8')) f = open(OUT_CPP, 'w') f.write(""" diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index ca4e1e70d..357e4c47f 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -391,7 +391,7 @@ SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" - $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" ../share/qt/extract_strings_qt.py $^ + $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^ translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 57f9ac50e..86b27ae68 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -129,7 +129,7 @@ bitcoin_test_clean : FORCE check-local: @echo "Running test/bitcoin-util-test.py..." - $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py + $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/bitcoin-util-test.py $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check if EMBEDDED_UNIVALUE $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check diff --git a/src/test/bctest.py b/src/test/bctest.py index 3a8d0ea51..8105b87ff 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -1,7 +1,7 @@ # Copyright 2014 BitPay, Inc. # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. - +from __future__ import division,print_function,unicode_literals import subprocess import os import json diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 20afb16a9..95dd3e81b 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -2,7 +2,7 @@ # Copyright 2014 BitPay, Inc. # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. - +from __future__ import division,print_function,unicode_literals import os import bctest import buildenv From 3e55b3a00450279522900ca96e5cf79162169019 Mon Sep 17 00:00:00 2001 From: accraze Date: Wed, 30 Mar 2016 07:29:56 -0700 Subject: [PATCH 0371/1223] [doc] added depends cross compile info --- doc/build-unix.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index 5b519b804..c1e92d8d1 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -248,3 +248,26 @@ Additional Configure Flags A list of additional configure flags can be displayed with: ./configure --help + + + +ARM Cross-compilation +------------------- +These steps can be performed on, for example, an Ubuntu VM. The depends system +will also work on other Linux distributions, however the commands for +installing the toolchain will be different. + +First install the toolchain: + + sudo apt-get install g++-arm-linux-gnueabihf + +To build executables for ARM: + + cd depends + make HOST=arm-linux-gnueabihf NO_QT=1 + cd .. + ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ + make + + +For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. \ No newline at end of file From ae2156f1235eb3c5ba294544ab04b5dd7509c7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Wed, 30 Mar 2016 20:26:10 +0200 Subject: [PATCH 0372/1223] Clear the input line after activating autocomplete --- src/qt/rpcconsole.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 42112c42f..d8647d902 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -459,6 +459,8 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); + // clear the lineEdit after activating from QCompleter + connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection); } } From 40234ba89f00afe96daf807acf61e6a23f8a81fa Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Wed, 30 Mar 2016 19:38:02 +0100 Subject: [PATCH 0373/1223] Fix comments in tests --- qa/rpc-tests/bip68-112-113-p2p.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index c226f4dad..7d3c59be3 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -383,9 +383,9 @@ class BIP68_112_113Test(ComparisonTestFramework): for bip113tx in [bip113signed1, bip113signed2]: yield TestInstance([[self.create_test_block([bip113tx]), False]]) # 9,10 # BIP 113 tests should now pass if the locktime is < MTP - bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # = MTP of prior block (not <) but < time put on current block + bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1) - bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # = MTP of prior block (not <) but < time put on current block + bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2) for bip113tx in [bip113signed1, bip113signed2]: yield TestInstance([[self.create_test_block([bip113tx]), True]]) # 11,12 @@ -490,7 +490,7 @@ class BIP68_112_113Test(ComparisonTestFramework): self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) ## SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV for all remaining txs ## - # All txs with nSequence 11 should fail either due to earlier mismatch or failing the CSV check + # All txs with nSequence 9 should fail either due to earlier mismatch or failing the CSV check fail_txs = [] fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) # 16/16 of vary_nSequence_9 for b25 in xrange(2): From fb8a8cf2e610920e9eee61c19ed6080af064bb43 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 29 Mar 2016 19:43:02 +0200 Subject: [PATCH 0374/1223] rpc: Register calls where they are defined Split out methods to every module, apart from 'help' and 'stop' which are implemented in rpcserver.cpp itself. - This makes it easier to add or remove RPC commands - no longer everything that includes rpcserver.h has to be rebuilt when there's a change there. - Cleans up `rpc/server.h` by getting rid of the huge cluttered list of function definitions. - Removes most of the bitcoin-specific code from rpcserver.cpp and .h. Continues #7307 for the non-wallet. --- src/Makefile.am | 1 + src/init.cpp | 4 ++- src/rest.cpp | 3 ++ src/rpc/blockchain.cpp | 28 +++++++++++++++++ src/rpc/mining.cpp | 24 ++++++++++++++ src/rpc/misc.cpp | 18 +++++++++++ src/rpc/net.cpp | 22 +++++++++++++ src/rpc/rawtransaction.cpp | 20 ++++++++++++ src/rpc/register.h | 32 +++++++++++++++++++ src/rpc/server.cpp | 64 -------------------------------------- src/rpc/server.h | 59 ----------------------------------- src/test/rpc_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 7 ++++- src/wallet/rpcwallet.cpp | 14 +++------ src/wallet/rpcwallet.h | 4 ++- 15 files changed, 165 insertions(+), 137 deletions(-) create mode 100644 src/rpc/register.h diff --git a/src/Makefile.am b/src/Makefile.am index 6ad7aabae..1e54512cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -130,6 +130,7 @@ BITCOIN_CORE_H = \ rpc/client.h \ rpc/protocol.h \ rpc/server.h \ + rpc/register.h \ scheduler.h \ script/sigcache.h \ script/sign.h \ diff --git a/src/init.cpp b/src/init.cpp index 38ac91b2a..0c371b288 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,6 +24,7 @@ #include "net.h" #include "policy/policy.h" #include "rpc/server.h" +#include "rpc/register.h" #include "script/standard.h" #include "script/sigcache.h" #include "scheduler.h" @@ -913,10 +914,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fPruneMode = true; } + RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); if (!fDisableWallet) - walletRegisterRPCCommands(); + RegisterWalletRPCCommands(tableRPC); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); diff --git a/src/rest.cpp b/src/rest.cpp index ebdccc940..2dff8d7da 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -273,6 +273,9 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa return rest_block(req, strURIPart, false); } +// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp +UniValue getblockchaininfo(const UniValue& params, bool fHelp); + static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a110dff0d..b947609b1 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -911,3 +911,31 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) return NullUniValue; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "blockchain", "getblockchaininfo", &getblockchaininfo, true }, + { "blockchain", "getbestblockhash", &getbestblockhash, true }, + { "blockchain", "getblockcount", &getblockcount, true }, + { "blockchain", "getblock", &getblock, true }, + { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getblockheader", &getblockheader, true }, + { "blockchain", "getchaintips", &getchaintips, true }, + { "blockchain", "getdifficulty", &getdifficulty, true }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, + { "blockchain", "getrawmempool", &getrawmempool, true }, + { "blockchain", "gettxout", &gettxout, true }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, + { "blockchain", "verifychain", &verifychain, true }, + + /* Not shown in help */ + { "hidden", "invalidateblock", &invalidateblock, true }, + { "hidden", "reconsiderblock", &reconsiderblock, true }, +}; + +void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index a2abbb323..b63ee2288 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -781,3 +781,27 @@ UniValue estimatesmartpriority(const UniValue& params, bool fHelp) result.push_back(Pair("blocks", answerFound)); return result; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "mining", "getnetworkhashps", &getnetworkhashps, true }, + { "mining", "getmininginfo", &getmininginfo, true }, + { "mining", "prioritisetransaction", &prioritisetransaction, true }, + { "mining", "getblocktemplate", &getblocktemplate, true }, + { "mining", "submitblock", &submitblock, true }, + + { "generating", "generate", &generate, true }, + { "generating", "generatetoaddress", &generatetoaddress, true }, + + { "util", "estimatefee", &estimatefee, true }, + { "util", "estimatepriority", &estimatepriority, true }, + { "util", "estimatesmartfee", &estimatesmartfee, true }, + { "util", "estimatesmartpriority", &estimatesmartpriority, true }, +}; + +void RegisterMiningRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0aab9c304..e8a099b44 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -396,3 +396,21 @@ UniValue setmocktime(const UniValue& params, bool fHelp) return NullUniValue; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ + { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ + { "util", "createmultisig", &createmultisig, true }, + { "util", "verifymessage", &verifymessage, true }, + + /* Not shown in help */ + { "hidden", "setmocktime", &setmocktime, true }, +}; + +void RegisterMiscRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 065214a98..017cd6ca3 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -626,3 +626,25 @@ UniValue clearbanned(const UniValue& params, bool fHelp) return NullUniValue; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "network", "getconnectioncount", &getconnectioncount, true }, + { "network", "ping", &ping, true }, + { "network", "getpeerinfo", &getpeerinfo, true }, + { "network", "addnode", &addnode, true }, + { "network", "disconnectnode", &disconnectnode, true }, + { "network", "getaddednodeinfo", &getaddednodeinfo, true }, + { "network", "getnettotals", &getnettotals, true }, + { "network", "getnetworkinfo", &getnetworkinfo, true }, + { "network", "setban", &setban, true }, + { "network", "listbanned", &listbanned, true }, + { "network", "clearbanned", &clearbanned, true }, +}; + +void RegisterNetRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 34dd3b30f..de8cd68f6 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -841,3 +841,23 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) return hashTx.GetHex(); } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "rawtransactions", "getrawtransaction", &getrawtransaction, true }, + { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, + { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true }, + { "rawtransactions", "decodescript", &decodescript, true }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, + { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ + + { "blockchain", "gettxoutproof", &gettxoutproof, true }, + { "blockchain", "verifytxoutproof", &verifytxoutproof, true }, +}; + +void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/register.h b/src/rpc/register.h new file mode 100644 index 000000000..01aa58a25 --- /dev/null +++ b/src/rpc/register.h @@ -0,0 +1,32 @@ +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPCREGISTER_H +#define BITCOIN_RPCREGISTER_H + +/** These are in one header file to avoid creating tons of single-function + * headers for everything under src/rpc/ */ +class CRPCTable; + +/** Register block chain RPC commands */ +void RegisterBlockchainRPCCommands(CRPCTable &tableRPC); +/** Register P2P networking RPC commands */ +void RegisterNetRPCCommands(CRPCTable &tableRPC); +/** Register miscellaneous RPC commands */ +void RegisterMiscRPCCommands(CRPCTable &tableRPC); +/** Register mining RPC commands */ +void RegisterMiningRPCCommands(CRPCTable &tableRPC); +/** Register raw transaction RPC commands */ +void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); + +static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) +{ + RegisterBlockchainRPCCommands(tableRPC); + RegisterNetRPCCommands(tableRPC); + RegisterMiscRPCCommands(tableRPC); + RegisterMiningRPCCommands(tableRPC); + RegisterRawTransactionRPCCommands(tableRPC); +} + +#endif diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 1303a3bb1..8326fe14d 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -256,72 +256,8 @@ static const CRPCCommand vRPCCommands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- /* Overall control/query calls */ - { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "control", "help", &help, true }, { "control", "stop", &stop, true }, - - /* P2P networking */ - { "network", "getnetworkinfo", &getnetworkinfo, true }, - { "network", "addnode", &addnode, true }, - { "network", "disconnectnode", &disconnectnode, true }, - { "network", "getaddednodeinfo", &getaddednodeinfo, true }, - { "network", "getconnectioncount", &getconnectioncount, true }, - { "network", "getnettotals", &getnettotals, true }, - { "network", "getpeerinfo", &getpeerinfo, true }, - { "network", "ping", &ping, true }, - { "network", "setban", &setban, true }, - { "network", "listbanned", &listbanned, true }, - { "network", "clearbanned", &clearbanned, true }, - - /* Block chain and UTXO */ - { "blockchain", "getblockchaininfo", &getblockchaininfo, true }, - { "blockchain", "getbestblockhash", &getbestblockhash, true }, - { "blockchain", "getblockcount", &getblockcount, true }, - { "blockchain", "getblock", &getblock, true }, - { "blockchain", "getblockhash", &getblockhash, true }, - { "blockchain", "getblockheader", &getblockheader, true }, - { "blockchain", "getchaintips", &getchaintips, true }, - { "blockchain", "getdifficulty", &getdifficulty, true }, - { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, - { "blockchain", "getrawmempool", &getrawmempool, true }, - { "blockchain", "gettxout", &gettxout, true }, - { "blockchain", "gettxoutproof", &gettxoutproof, true }, - { "blockchain", "verifytxoutproof", &verifytxoutproof, true }, - { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, - { "blockchain", "verifychain", &verifychain, true }, - - /* Mining */ - { "mining", "getblocktemplate", &getblocktemplate, true }, - { "mining", "getmininginfo", &getmininginfo, true }, - { "mining", "getnetworkhashps", &getnetworkhashps, true }, - { "mining", "prioritisetransaction", &prioritisetransaction, true }, - { "mining", "submitblock", &submitblock, true }, - - /* Coin generation */ - { "generating", "generate", &generate, true }, - { "generating", "generatetoaddress", &generatetoaddress, true }, - - /* Raw transactions */ - { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, - { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true }, - { "rawtransactions", "decodescript", &decodescript, true }, - { "rawtransactions", "getrawtransaction", &getrawtransaction, true }, - { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, - { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ - - /* Utility functions */ - { "util", "createmultisig", &createmultisig, true }, - { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ - { "util", "verifymessage", &verifymessage, true }, - { "util", "estimatefee", &estimatefee, true }, - { "util", "estimatepriority", &estimatepriority, true }, - { "util", "estimatesmartfee", &estimatesmartfee, true }, - { "util", "estimatesmartpriority", &estimatesmartpriority, true }, - - /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true }, - { "hidden", "reconsiderblock", &reconsiderblock, true }, - { "hidden", "setmocktime", &setmocktime, true }, }; CRPCTable::CRPCTable() diff --git a/src/rpc/server.h b/src/rpc/server.h index 35e114fee..a7ed710ce 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -181,65 +181,6 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri extern void EnsureWalletIsUnlocked(); -extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpc/net.cpp -extern UniValue getpeerinfo(const UniValue& params, bool fHelp); -extern UniValue ping(const UniValue& params, bool fHelp); -extern UniValue addnode(const UniValue& params, bool fHelp); -extern UniValue disconnectnode(const UniValue& params, bool fHelp); -extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp); -extern UniValue getnettotals(const UniValue& params, bool fHelp); -extern UniValue setban(const UniValue& params, bool fHelp); -extern UniValue listbanned(const UniValue& params, bool fHelp); -extern UniValue clearbanned(const UniValue& params, bool fHelp); - -extern UniValue generate(const UniValue& params, bool fHelp); -extern UniValue generatetoaddress(const UniValue& params, bool fHelp); -extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); -extern UniValue getmininginfo(const UniValue& params, bool fHelp); -extern UniValue prioritisetransaction(const UniValue& params, bool fHelp); -extern UniValue getblocktemplate(const UniValue& params, bool fHelp); -extern UniValue submitblock(const UniValue& params, bool fHelp); -extern UniValue estimatefee(const UniValue& params, bool fHelp); -extern UniValue estimatepriority(const UniValue& params, bool fHelp); -extern UniValue estimatesmartfee(const UniValue& params, bool fHelp); -extern UniValue estimatesmartpriority(const UniValue& params, bool fHelp); - -extern UniValue verifymessage(const UniValue& params, bool fHelp); -extern UniValue createmultisig(const UniValue& params, bool fHelp); -extern UniValue validateaddress(const UniValue& params, bool fHelp); -extern UniValue getinfo(const UniValue& params, bool fHelp); -extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); -extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); -extern UniValue setmocktime(const UniValue& params, bool fHelp); - -extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rpc/rawtransaction.cpp -extern UniValue listunspent(const UniValue& params, bool fHelp); -extern UniValue lockunspent(const UniValue& params, bool fHelp); -extern UniValue listlockunspent(const UniValue& params, bool fHelp); -extern UniValue createrawtransaction(const UniValue& params, bool fHelp); -extern UniValue decoderawtransaction(const UniValue& params, bool fHelp); -extern UniValue decodescript(const UniValue& params, bool fHelp); -extern UniValue signrawtransaction(const UniValue& params, bool fHelp); -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); -extern UniValue gettxoutproof(const UniValue& params, bool fHelp); -extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); - -extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpc/blockchain.cpp -extern UniValue getbestblockhash(const UniValue& params, bool fHelp); -extern UniValue getdifficulty(const UniValue& params, bool fHelp); -extern UniValue settxfee(const UniValue& params, bool fHelp); -extern UniValue getmempoolinfo(const UniValue& params, bool fHelp); -extern UniValue getrawmempool(const UniValue& params, bool fHelp); -extern UniValue getblockhash(const UniValue& params, bool fHelp); -extern UniValue getblockheader(const UniValue& params, bool fHelp); -extern UniValue getblock(const UniValue& params, bool fHelp); -extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp); -extern UniValue gettxout(const UniValue& params, bool fHelp); -extern UniValue verifychain(const UniValue& params, bool fHelp); -extern UniValue getchaintips(const UniValue& params, bool fHelp); -extern UniValue invalidateblock(const UniValue& params, bool fHelp); -extern UniValue reconsiderblock(const UniValue& params, bool fHelp); - bool StartRPC(); void InterruptRPC(); void StopRPC(); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index d6309ca38..1976ee2cb 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -36,7 +36,7 @@ UniValue CallRPC(string args) string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); UniValue params = RPCConvertValues(strMethod, vArgs); - + BOOST_CHECK(tableRPC[strMethod]); rpcfn_type method = tableRPC[strMethod]->actor; try { UniValue result = (*method)(params, false); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index dadc8b948..1f2e034b0 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -17,6 +17,8 @@ #include "txdb.h" #include "txmempool.h" #include "ui_interface.h" +#include "rpc/server.h" +#include "rpc/register.h" #ifdef ENABLE_WALLET #include "wallet/db.h" #include "wallet/wallet.h" @@ -53,9 +55,12 @@ BasicTestingSetup::~BasicTestingSetup() TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { const CChainParams& chainparams = Params(); + // Ideally we'd move all the RPC tests to the functional testing framework + // instead of unit tests, but for now we need these here. + RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET bitdb.MakeMock(); - walletRegisterRPCCommands(); + RegisterWalletRPCCommands(tableRPC); #endif ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a1733bae7..61c9846e1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2509,7 +2509,7 @@ extern UniValue importwallet(const UniValue& params, bool fHelp); extern UniValue importprunedfunds(const UniValue& params, bool fHelp); extern UniValue removeprunedfunds(const UniValue& params, bool fHelp); -const CRPCCommand vWalletRPCCommands[] = +static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, @@ -2559,14 +2559,8 @@ const CRPCCommand vWalletRPCCommands[] = { "wallet", "removeprunedfunds", &removeprunedfunds, true }, }; -void walletRegisterRPCCommands() +void RegisterWalletRPCCommands(CRPCTable &tableRPC) { - unsigned int vcidx; - for (vcidx = 0; vcidx < ARRAYLEN(vWalletRPCCommands); vcidx++) - { - const CRPCCommand *pcmd; - - pcmd = &vWalletRPCCommands[vcidx]; - tableRPC.appendCommand(pcmd->name, pcmd); - } + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); } diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 42e8021af..a5de7e2de 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_WALLET_RPCWALLET_H #define BITCOIN_WALLET_RPCWALLET_H -void walletRegisterRPCCommands(); +class CRPCTable; + +void RegisterWalletRPCCommands(CRPCTable &tableRPC); #endif //BITCOIN_WALLET_RPCWALLET_H From eff736e55e84441f9509285e83a1a6ee9a0c6e69 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 29 Mar 2016 16:46:20 +0200 Subject: [PATCH 0375/1223] Reformat version in UpdateTip and other messages Also remove the hardly-readable nBits from UpdateTip's log message. --- src/main.cpp | 8 ++++---- src/primitives/block.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 36189f4ff..d22b4c80e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2549,8 +2549,8 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("%s: new best=%s height=%d bits=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nBits, + LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utx)\n", __func__, + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nVersion, log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); @@ -3284,8 +3284,8 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(v%d)", version - 1), - strprintf("rejected nVersion=%d block", version - 1)); + return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", version - 1), + strprintf("rejected nVersion=0x%08x block", version - 1)); return true; } diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 59e949d71..6fb33230a 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -18,7 +18,7 @@ uint256 CBlockHeader::GetHash() const std::string CBlock::ToString() const { std::stringstream s; - s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", + s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", GetHash().ToString(), nVersion, hashPrevBlock.ToString(), From fa524d9ddbad0a03f9eb974100fb3b6001045645 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 19 Mar 2016 21:36:32 +0100 Subject: [PATCH 0376/1223] [qa] Use python2/3 syntax --- qa/pull-tester/rpc-tests.py | 8 +-- qa/rpc-tests/bip65-cltv-p2p.py | 4 +- qa/rpc-tests/bip68-112-113-p2p.py | 6 +-- qa/rpc-tests/bip9-softforks.py | 8 +-- qa/rpc-tests/bipdersig-p2p.py | 4 +- qa/rpc-tests/decodescript.py | 4 +- qa/rpc-tests/disablewallet.py | 4 +- qa/rpc-tests/fundrawtransaction.py | 8 +-- qa/rpc-tests/importprunedfunds.py | 4 +- qa/rpc-tests/keypool.py | 6 +-- qa/rpc-tests/listtransactions.py | 4 +- qa/rpc-tests/rawtransactions.py | 2 +- qa/rpc-tests/rest.py | 9 ++-- qa/rpc-tests/smartfees.py | 2 +- qa/rpc-tests/test_framework/blockstore.py | 7 +-- qa/rpc-tests/test_framework/blocktools.py | 4 +- qa/rpc-tests/test_framework/comptool.py | 6 +-- qa/rpc-tests/test_framework/mininode.py | 51 ++++++++++--------- qa/rpc-tests/test_framework/socks5.py | 2 +- qa/rpc-tests/test_framework/test_framework.py | 4 +- qa/rpc-tests/wallet.py | 6 +-- 21 files changed, 78 insertions(+), 75 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index d794dbe80..6d3bda10e 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -32,13 +32,13 @@ import re from tests_config import * #If imported values are not defined then set to zero (or disabled) -if not vars().has_key('ENABLE_WALLET'): +if 'ENABLE_WALLET' not in vars(): ENABLE_WALLET=0 -if not vars().has_key('ENABLE_BITCOIND'): +if 'ENABLE_BITCOIND' not in vars(): ENABLE_BITCOIND=0 -if not vars().has_key('ENABLE_UTILS'): +if 'ENABLE_UTILS' not in vars(): ENABLE_UTILS=0 -if not vars().has_key('ENABLE_ZMQ'): +if 'ENABLE_ZMQ' not in vars(): ENABLE_ZMQ=0 # python-zmq may not be installed. Handle this gracefully and with some helpful info diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index bbd518cf5..316c5fe09 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -11,7 +11,7 @@ from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP from binascii import unhexlify -import cStringIO +from io import BytesIO import time def cltv_invalidate(tx): @@ -60,7 +60,7 @@ class BIP65Test(ComparisonTestFramework): rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(signresult['hex'])) + f = BytesIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 7d3c59be3..f391cb0b7 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -11,7 +11,7 @@ from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import * from binascii import unhexlify -import cStringIO +from io import BytesIO import time ''' @@ -119,7 +119,7 @@ class BIP68_112_113Test(ComparisonTestFramework): outputs = { to_address : amount } rawtx = node.createrawtransaction(inputs, outputs) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(rawtx)) + f = BytesIO(unhexlify(rawtx)) tx.deserialize(f) return tx @@ -127,7 +127,7 @@ class BIP68_112_113Test(ComparisonTestFramework): rawtx = ToHex(unsignedtx) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(signresult['hex'])) + f = BytesIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index cbb1b7d4c..445c04494 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -11,7 +11,7 @@ from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP from binascii import hexlify, unhexlify -import cStringIO +from io import BytesIO import time import itertools @@ -53,7 +53,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): outputs = { to_address : amount } rawtx = node.createrawtransaction(inputs, outputs) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(rawtx)) + f = BytesIO(unhexlify(rawtx)) tx.deserialize(f) tx.nVersion = 2 return tx @@ -61,7 +61,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): def sign_transaction(self, node, tx): signresult = node.signrawtransaction(hexlify(tx.serialize())) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(signresult['hex'])) + f = BytesIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx @@ -217,4 +217,4 @@ class BIP9SoftForksTest(ComparisonTestFramework): tx.nLockTime = self.last_block_time if __name__ == '__main__': - BIP9SoftForksTest().main() \ No newline at end of file + BIP9SoftForksTest().main() diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 544e4a967..f0d81a6f4 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -11,7 +11,7 @@ from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript from binascii import unhexlify -import cStringIO +from io import BytesIO import time # A canonical signature consists of: @@ -68,7 +68,7 @@ class BIP66Test(ComparisonTestFramework): rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = cStringIO.StringIO(unhexlify(signresult['hex'])) + f = BytesIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 490808d49..2dfafac2f 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -7,7 +7,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import * from binascii import hexlify, unhexlify -from cStringIO import StringIO +from io import BytesIO class DecodeScriptTest(BitcoinTestFramework): """Tests decoding scripts via RPC command "decodescript".""" @@ -131,7 +131,7 @@ class DecodeScriptTest(BitcoinTestFramework): assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) txSave = CTransaction() - txSave.deserialize(StringIO(unhexlify(tx))) + txSave.deserialize(BytesIO(unhexlify(tx))) # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 5af815846..cb868029f 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -32,7 +32,7 @@ class DisableWalletTest (BitcoinTestFramework): # Checking mining to an address without a wallet try: self.nodes[0].generatetoaddress(1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') - except JSONRPCException,e: + except JSONRPCException as e: assert("Invalid address" not in e.error['message']) assert("ProcessNewBlock, block not accepted" not in e.error['message']) assert("Couldn't create new block" not in e.error['message']) @@ -40,7 +40,7 @@ class DisableWalletTest (BitcoinTestFramework): try: self.nodes[0].generatetoaddress(1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy') raise AssertionError("Must not mine to invalid address!") - except JSONRPCException,e: + except JSONRPCException as e: assert("Invalid address" in e.error['message']) if __name__ == '__main__': diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 445871281..82f2f4f5c 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -209,7 +209,7 @@ class RawTransactionsTest(BitcoinTestFramework): matchingOuts = 0 for i, out in enumerate(dec_tx['vout']): totalOut += out['value'] - if outputs.has_key(out['scriptPubKey']['addresses'][0]): + if out['scriptPubKey']['addresses'][0] in outputs: matchingOuts+=1 else: assert_equal(i, rawtxfund['changepos']) @@ -249,7 +249,7 @@ class RawTransactionsTest(BitcoinTestFramework): matchingOuts = 0 for out in dec_tx['vout']: totalOut += out['value'] - if outputs.has_key(out['scriptPubKey']['addresses'][0]): + if out['scriptPubKey']['addresses'][0] in outputs: matchingOuts+=1 assert_equal(matchingOuts, 1) @@ -291,7 +291,7 @@ class RawTransactionsTest(BitcoinTestFramework): matchingOuts = 0 for out in dec_tx['vout']: totalOut += out['value'] - if outputs.has_key(out['scriptPubKey']['addresses'][0]): + if out['scriptPubKey']['addresses'][0] in outputs: matchingOuts+=1 assert_equal(matchingOuts, 2) @@ -309,7 +309,7 @@ class RawTransactionsTest(BitcoinTestFramework): try: rawtxfund = self.nodes[2].fundrawtransaction(rawtx) raise AssertionError("Spent more than available") - except JSONRPCException,e: + except JSONRPCException as e: assert("Insufficient" in e.error['message']) diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index 5cbdcde9a..db875800d 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -82,7 +82,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework): #Import with no affiliated address try: result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "") - except JSONRPCException,e: + except JSONRPCException as e: errorString = e.error['message'] assert('No addresses' in errorString) @@ -119,7 +119,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework): try: self.nodes[1].removeprunedfunds(txnid1) - except JSONRPCException,e: + except JSONRPCException as e: errorString = e.error['message'] assert('does not exist' in errorString) diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 95d0d6832..5253d49c3 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -46,7 +46,7 @@ class KeyPoolTest(BitcoinTestFramework): try: addr = nodes[0].getnewaddress() raise AssertionError('Keypool should be exhausted after one address') - except JSONRPCException,e: + except JSONRPCException as e: assert(e.error['code']==-12) # put three new keys in the keypool @@ -66,7 +66,7 @@ class KeyPoolTest(BitcoinTestFramework): try: addr = nodes[0].getrawchangeaddress() raise AssertionError('Keypool should be exhausted after three addresses') - except JSONRPCException,e: + except JSONRPCException as e: assert(e.error['code']==-12) # refill keypool with three new addresses @@ -84,7 +84,7 @@ class KeyPoolTest(BitcoinTestFramework): try: nodes[0].generate(1) raise AssertionError('Keypool should be exhausted after three addesses') - except JSONRPCException,e: + except JSONRPCException as e: assert(e.error['code']==-12) def setup_chain(self): diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index da1e98dc3..c4eca519b 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -8,12 +8,12 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import CTransaction, COIN -import cStringIO +from io import BytesIO import binascii def txFromHex(hexstring): tx = CTransaction() - f = cStringIO.StringIO(binascii.unhexlify(hexstring)) + f = BytesIO(binascii.unhexlify(hexstring)) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index dd9e5e28a..9f660c8bd 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -59,7 +59,7 @@ class RawTransactionsTest(BitcoinTestFramework): errorString = "" try: rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) - except JSONRPCException,e: + except JSONRPCException as e: errorString = e.error['message'] assert("Missing inputs" in errorString) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 8c8353650..3c8a405bd 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -11,8 +11,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from struct import * +from io import BytesIO +from codecs import encode import binascii -import StringIO try: import http.client as httplib @@ -146,7 +147,7 @@ class RESTTest (BitcoinTestFramework): binaryRequest += pack("i", 0) bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) - output = StringIO.StringIO() + output = BytesIO() output.write(bin_response) output.seek(0) chainHeight = unpack("i", output.read(4))[0] @@ -233,7 +234,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(response_hex.status, 200) assert_greater_than(int(response_hex.getheader('content-length')), 160) response_hex_str = response_hex.read() - assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160]) + assert_equal(encode(response_str, "hex")[0:160], response_hex_str[0:160]) # compare with hex block header response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) @@ -241,7 +242,7 @@ class RESTTest (BitcoinTestFramework): assert_greater_than(int(response_header_hex.getheader('content-length')), 160) response_header_hex_str = response_header_hex.read() assert_equal(response_hex_str[0:160], response_header_hex_str[0:160]) - assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160]) + assert_equal(encode(response_header_str, "hex")[0:160], response_header_hex_str[0:160]) # check json format block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json') diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index b209ae0c1..6274cd053 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -105,7 +105,7 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True): print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]]) delta = 1.0e-6 # account for rounding error last_e = max(fees_seen) - for e in filter(lambda x: x >= 0, all_estimates): + for e in [x for x in all_estimates if x >= 0]: # Estimates should be within the bounds of what transactions fees actually were: if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen): raise AssertionError("Estimated fee (%f) out of range (%f,%f)" diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index b9775b477..73d9ffbb2 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -3,8 +3,9 @@ # and for constructing a getheaders message # -from mininode import * +from .mininode import * import dbm +from io import BytesIO class BlockStore(object): def __init__(self, datadir): @@ -21,7 +22,7 @@ class BlockStore(object): serialized_block = self.blockDB[repr(blockhash)] except KeyError: return None - f = cStringIO.StringIO(serialized_block) + f = BytesIO(serialized_block) ret = CBlock() ret.deserialize(f) ret.calc_sha256() @@ -115,7 +116,7 @@ class TxStore(object): serialized_tx = self.txDB[repr(txhash)] except KeyError: return None - f = cStringIO.StringIO(serialized_tx) + f = BytesIO(serialized_tx) ret = CTransaction() ret.deserialize(f) ret.calc_sha256() diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index b075f69c4..425e6dcdd 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -4,8 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from mininode import * -from script import CScript, OP_TRUE, OP_CHECKSIG +from .mininode import * +from .script import CScript, OP_TRUE, OP_CHECKSIG # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index f19edbf06..6279070fb 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -4,9 +4,9 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from mininode import * -from blockstore import BlockStore, TxStore -from util import p2p_port +from .mininode import * +from .blockstore import BlockStore, TxStore +from .util import p2p_port ''' This is a tool for comparing two or more bitcoinds to each other diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 20386c642..07d1827df 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -24,7 +24,8 @@ import binascii import time import sys import random -import cStringIO +from io import BytesIO +from codecs import encode import hashlib from threading import RLock from threading import Thread @@ -75,12 +76,12 @@ def deser_string(f): def ser_string(s): if len(s) < 253: - return chr(len(s)) + s + return struct.pack("B", len(s)) + s elif len(s) < 0x10000: - return chr(253) + struct.pack(" Date: Sun, 20 Mar 2016 18:18:32 +0100 Subject: [PATCH 0377/1223] [qa] rpc-tests: Properly use integers, floats --- qa/rpc-tests/bip65-cltv-p2p.py | 2 +- qa/rpc-tests/bip68-sequence.py | 6 +-- qa/rpc-tests/bip9-softforks.py | 2 +- qa/rpc-tests/bipdersig-p2p.py | 2 +- qa/rpc-tests/fundrawtransaction.py | 2 +- qa/rpc-tests/listtransactions.py | 2 +- qa/rpc-tests/maxuploadtarget.py | 2 +- qa/rpc-tests/p2p-acceptblock.py | 2 +- qa/rpc-tests/p2p-fullblocktest.py | 4 +- qa/rpc-tests/pruning.py | 6 +-- qa/rpc-tests/replace-by-fee.py | 50 +++++++++++------------ qa/rpc-tests/smartfees.py | 2 +- qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/mininode.py | 4 +- qa/rpc-tests/test_framework/netutil.py | 2 +- 15 files changed, 45 insertions(+), 45 deletions(-) diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 316c5fe09..54559c354 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -70,7 +70,7 @@ class BIP65Test(ComparisonTestFramework): height = 3 # height of the next block to build self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = time.time() + self.last_block_time = int(time.time()) ''' 98 more version 3 blocks ''' test_blocks = [] diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 84f941da3..377a35b68 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -61,7 +61,7 @@ class BIP68Test(BitcoinTestFramework): utxo = utxos[0] tx1 = CTransaction() - value = satoshi_round(utxo["amount"] - self.relayfee)*COIN + value = int(satoshi_round(utxo["amount"] - self.relayfee)*COIN) # Check that the disable flag disables relative locktime. # If sequence locks were used, this would require 1 block for the @@ -179,8 +179,8 @@ class BIP68Test(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value)) value += utxos[j]["amount"]*COIN # Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output - tx_size = len(ToHex(tx))/2 + 120*num_inputs + 50 - tx.vout.append(CTxOut(value-self.relayfee*tx_size*COIN/1000, CScript([b'a']))) + tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50 + tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a']))) rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"] try: diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 445c04494..98975e719 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -91,7 +91,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): self.height = 3 # height of the next block to build self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = time.time() + self.last_block_time = int(time.time()) assert_equal(self.get_bip9_status(bipName)['status'], 'defined') diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index f0d81a6f4..95be385d9 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -78,7 +78,7 @@ class BIP66Test(ComparisonTestFramework): height = 3 # height of the next block to build self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = time.time() + self.last_block_time = int(time.time()) ''' 98 more version 2 blocks ''' test_blocks = [] diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 82f2f4f5c..82c9e48a4 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -48,7 +48,7 @@ class RawTransactionsTest(BitcoinTestFramework): watchonly_address = self.nodes[0].getnewaddress() watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] - watchonly_amount = 200 + watchonly_amount = Decimal(200) self.nodes[3].importpubkey(watchonly_pubkey, "", True) watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index c4eca519b..8fe72d95d 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -192,7 +192,7 @@ class ListTransactionsTest(BitcoinTestFramework): # Replace tx3, and check that tx4 becomes unknown tx3_b = tx3_modified - tx3_b.vout[0].nValue -= 0.004 * COIN # bump the fee + tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index e4127500c..be45fecb5 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -177,7 +177,7 @@ class MaxUploadTest(BitcoinTestFramework): max_bytes_per_day = 200*1024*1024 daily_buffer = 144 * MAX_BLOCK_SIZE max_bytes_available = max_bytes_per_day - daily_buffer - success_count = max_bytes_available / old_block_size + success_count = max_bytes_available // old_block_size # 144MB will be reserved for relaying new blocks, so expect this to # succeed for ~70 tries. diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index bf355780c..e429fcc5f 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -150,7 +150,7 @@ class AcceptBlockTest(BitcoinTestFramework): # 2. Send one block that builds on each tip. # This should be accepted. blocks_h2 = [] # the height 2 blocks on each node's chain - block_time = time.time() + 1 + block_time = int(time.time()) + 1 for i in xrange(2): blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2[i].solve() diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index b1e8ca53e..131350c98 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -269,7 +269,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) # Test that a block with a lot of checksigs is okay - lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1)) + lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50 - 1)) tip(13) block(15, spend=out5, script=lots_of_checksigs) yield accepted() @@ -277,7 +277,7 @@ class FullBlockTest(ComparisonTestFramework): # Test that a block with too many checksigs is rejected out6 = get_spendable_output() - too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50)) + too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50)) block(16, spend=out6, script=too_many_checksigs) yield rejected(RejectResult(16, 'bad-blk-sigops')) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index b0f4b88ae..dd2adea95 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -15,7 +15,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * def calc_usage(blockdir): - return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024) + return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.) class PruneTest(BitcoinTestFramework): @@ -56,7 +56,7 @@ class PruneTest(BitcoinTestFramework): self.nodes[1].generate(200) sync_blocks(self.nodes[0:2]) self.nodes[0].generate(150) - # Then mine enough full blocks to create more than 550MB of data + # Then mine enough full blocks to create more than 550MiB of data for i in xrange(645): self.mine_full_block(self.nodes[0], self.address[0]) @@ -66,7 +66,7 @@ class PruneTest(BitcoinTestFramework): if not os.path.isfile(self.prunedir+"blk00000.dat"): raise AssertionError("blk00000.dat is missing, pruning too early") print "Success" - print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir) + print "Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir) print "Mining 25 more blocks should cause the first block file to be pruned" # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this for i in xrange(25): diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index eded24f40..b951900c4 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -119,7 +119,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): def test_simple_doublespend(self): """Simple doublespend""" - tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] @@ -143,7 +143,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Extra 0.1 BTC fee tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))] tx1b_hex = txToHex(tx1b) tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) @@ -235,7 +235,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): _total_txs=_total_txs): yield x - fee = 0.0001*COIN + fee = int(0.0001*COIN) n = MAX_REPLACEMENT_LIMIT tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) assert_equal(len(tree_txs), n) @@ -268,7 +268,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Try again, but with more total transactions than the "max txs # double-spent at once" anti-DoS limit. for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2): - fee = 0.0001*COIN + fee = int(0.0001*COIN) tx0_outpoint = make_utxo(self.nodes[0], initial_nValue) tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) assert_equal(len(tree_txs), n) @@ -291,7 +291,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): def test_replacement_feeperkb(self): """Replacement requires fee-per-KB to be higher""" - tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] @@ -303,7 +303,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # rejected. tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*999000]))] + tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))] tx1b_hex = txToHex(tx1b) try: @@ -315,12 +315,12 @@ class ReplaceByFeeTest(BitcoinTestFramework): def test_spends_of_conflicting_outputs(self): """Replacements that spend conflicting tx outputs are rejected""" - utxo1 = make_utxo(self.nodes[0], 1.2*COIN) - utxo2 = make_utxo(self.nodes[0], 3.0*COIN) + utxo1 = make_utxo(self.nodes[0], int(1.2*COIN)) + utxo2 = make_utxo(self.nodes[0], 3*COIN) tx1a = CTransaction() tx1a.vin = [CTxIn(utxo1, nSequence=0)] - tx1a.vout = [CTxOut(1.1*COIN, CScript([b'a']))] + tx1a.vout = [CTxOut(int(1.1*COIN), CScript([b'a']))] tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) @@ -343,7 +343,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Spend tx1a's output to test the indirect case. tx1b = CTransaction() tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] - tx1b.vout = [CTxOut(1.0*COIN, CScript([b'a']))] + tx1b.vout = [CTxOut(1*COIN, CScript([b'a']))] tx1b_hex = txToHex(tx1b) tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) tx1b_txid = int(tx1b_txid, 16) @@ -363,12 +363,12 @@ class ReplaceByFeeTest(BitcoinTestFramework): def test_new_unconfirmed_inputs(self): """Replacements that add new unconfirmed inputs are rejected""" - confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN) - unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False) + confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN)) + unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False) tx1 = CTransaction() tx1.vin = [CTxIn(confirmed_utxo)] - tx1.vout = [CTxOut(1.0*COIN, CScript([b'a']))] + tx1.vout = [CTxOut(1*COIN, CScript([b'a']))] tx1_hex = txToHex(tx1) tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True) @@ -392,7 +392,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Start by creating a single transaction with many outputs initial_nValue = 10*COIN utxo = make_utxo(self.nodes[0], initial_nValue) - fee = 0.0001*COIN + fee = int(0.0001*COIN) split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1)) actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1) @@ -445,7 +445,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): def test_opt_in(self): """ Replacing should only work if orig tx opted in """ - tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) # Create a non-opting in transaction tx1a = CTransaction() @@ -457,7 +457,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Shouldn't be able to double-spend tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))] tx1b_hex = txToHex(tx1b) try: @@ -468,7 +468,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): print tx1b_txid assert(False) - tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) # Create a different non-opting in transaction tx2a = CTransaction() @@ -480,7 +480,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Still shouldn't be able to double-spend tx2b = CTransaction() tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] - tx2b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))] tx2b_hex = txToHex(tx2b) try: @@ -500,19 +500,19 @@ class ReplaceByFeeTest(BitcoinTestFramework): tx3a = CTransaction() tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff), CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)] - tx3a.vout = [CTxOut(0.9*COIN, CScript([b'c'])), CTxOut(0.9*COIN, CScript([b'd']))] + tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))] tx3a_hex = txToHex(tx3a) self.nodes[0].sendrawtransaction(tx3a_hex, True) tx3b = CTransaction() tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] - tx3b.vout = [CTxOut(0.5*COIN, CScript([b'e']))] + tx3b.vout = [CTxOut(int(0.5*COIN), CScript([b'e']))] tx3b_hex = txToHex(tx3b) tx3c = CTransaction() tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)] - tx3c.vout = [CTxOut(0.5*COIN, CScript([b'f']))] + tx3c.vout = [CTxOut(int(0.5*COIN), CScript([b'f']))] tx3c_hex = txToHex(tx3c) self.nodes[0].sendrawtransaction(tx3b_hex, True) @@ -525,7 +525,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # correctly used by replacement logic # 1. Check that feeperkb uses modified fees - tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) tx1a = CTransaction() tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] @@ -536,7 +536,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Higher fee, but the actual fee per KB is much lower. tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] - tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))] + tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))] tx1b_hex = txToHex(tx1b) # Verify tx1b cannot replace tx1a. @@ -556,7 +556,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): assert(tx1b_txid in self.nodes[0].getrawmempool()) # 2. Check that absolute fee checks use modified fee. - tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) tx2a = CTransaction() tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)] @@ -567,7 +567,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Lower fee, but we'll prioritise it tx2b = CTransaction() tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] - tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))] + tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))] tx2b.rehash() tx2b_hex = txToHex(tx2b) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 6274cd053..2c064ad8a 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -219,7 +219,7 @@ class EstimateFeeTest(BitcoinTestFramework): from_index = random.randint(1,2) (txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo, self.memutxo, Decimal("0.005"), min_fee, min_fee) - tx_kbytes = (len(txhex)/2)/1000.0 + tx_kbytes = (len(txhex) // 2) / 1000.0 self.fees_per_kb.append(float(fee)/tx_kbytes) sync_mempools(self.nodes[0:3],.1) mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"] diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 425e6dcdd..afa0f5f9b 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -29,7 +29,7 @@ def serialize_script_num(value): neg = value < 0 absvalue = -value if neg else value while (absvalue): - r.append(chr(absvalue & 0xff)) + r.append(int(absvalue & 0xff)) absvalue >>= 8 if r[-1] & 0x80: r.append(0x80 if neg else 0) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 07d1827df..0c40730f9 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -641,7 +641,7 @@ class msg_version(object): def __init__(self): self.nVersion = MY_VERSION self.nServices = 1 - self.nTime = time.time() + self.nTime = int(time.time()) self.addrTo = CAddress() self.addrFrom = CAddress() self.nNonce = random.getrandbits(64) @@ -986,7 +986,7 @@ class msg_reject(object): def __init__(self): self.message = "" - self.code = "" + self.code = 0 self.reason = "" self.data = 0L diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index 50daa8793..4e4c81d39 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -45,7 +45,7 @@ def _convert_ip_port(array): # convert host from mangled-per-four-bytes form as used by kernel host = binascii.unhexlify(host) host_out = '' - for x in range(0, len(host)/4): + for x in range(0, len(host) // 4): (val,) = struct.unpack('=I', host[x*4:(x+1)*4]) host_out += '%08x' % val From faaa3c9b6546d9a64cece4ff0223f0b167feb6ff Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 31 Mar 2016 18:33:15 +0200 Subject: [PATCH 0378/1223] [qa] mininode: Catch exceptions in got_data --- qa/rpc-tests/test_framework/mininode.py | 75 +++++++++++++------------ 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 0c40730f9..b06905301 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1252,43 +1252,46 @@ class NodeConn(asyncore.dispatcher): self.sendbuf = self.sendbuf[sent:] def got_data(self): - while True: - if len(self.recvbuf) < 4: - return - if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]: - raise ValueError("got garbage %s" % repr(self.recvbuf)) - if self.ver_recv < 209: - if len(self.recvbuf) < 4 + 12 + 4: + try: + while True: + if len(self.recvbuf) < 4: return - command = self.recvbuf[4:4+12].split("\x00", 1)[0] - msglen = struct.unpack(" Date: Fri, 1 Apr 2016 21:31:48 +0200 Subject: [PATCH 0379/1223] Fix typo: Optimizaton -> Optimization --- src/versionbits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/versionbits.cpp b/src/versionbits.cpp index fbb60c0fc..78feb8ab0 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -25,7 +25,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* break; } if (pindexPrev->GetMedianTimePast() < nTimeStart) { - // Optimizaton: don't recompute down further, as we know every earlier block will be before the start time + // Optimization: don't recompute down further, as we know every earlier block will be before the start time cache[pindexPrev] = THRESHOLD_DEFINED; break; } From 10d3ae102afb89b3f50cd27f9ee657e5a542eb1b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 1 Apr 2016 14:35:57 +0200 Subject: [PATCH 0380/1223] devtools: Auto-set branch to merge to in github-merge As we are already using the API to retrieve the pull request title, also retrieve the base branch. This makes sure that pull requests for 0.12 automatically end up in 0.12, and pull requests for master automatically end up in master, and so on. It is still possible to override the branch from the command line or using the `githubmerge.branch` git option. --- contrib/devtools/github-merge.py | 34 +++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 9a62fccbb..f82362fe4 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -47,9 +47,9 @@ def git_config_get(option, default=None): except subprocess.CalledProcessError as e: return default -def retrieve_pr_title(repo,pull): +def retrieve_pr_info(repo,pull): ''' - Retrieve pull request title from github. + Retrieve pull request information from github. Return None if no title can be found, or an error happens. ''' try: @@ -57,9 +57,9 @@ def retrieve_pr_title(repo,pull): result = urlopen(req) reader = codecs.getreader('utf-8') obj = json.load(reader(result)) - return obj['title'] + return obj except Exception as e: - print('Warning: unable to retrieve pull title from github: %s' % e) + print('Warning: unable to retrieve pull information from github: %s' % e) return None def ask_prompt(text): @@ -69,13 +69,13 @@ def ask_prompt(text): print("",file=stderr) return reply -def parse_arguments(branch): +def parse_arguments(): epilog = ''' In addition, you can set the following git configuration variables: githubmerge.repository (mandatory), user.signingkey (mandatory), githubmerge.host (default: git@github.com), - githubmerge.branch (default: master), + githubmerge.branch (no default), githubmerge.testcmd (default: none). ''' parser = argparse.ArgumentParser(description='Utility to merge, sign and push github pull requests', @@ -83,14 +83,14 @@ def parse_arguments(branch): parser.add_argument('pull', metavar='PULL', type=int, nargs=1, help='Pull request ID to merge') parser.add_argument('branch', metavar='BRANCH', type=str, nargs='?', - default=branch, help='Branch to merge against (default: '+branch+')') + default=None, help='Branch to merge against (default: githubmerge.branch setting, or base branch for pull, or \'master\')') return parser.parse_args() def main(): # Extract settings from git repo repo = git_config_get('githubmerge.repository') host = git_config_get('githubmerge.host','git@github.com') - branch = git_config_get('githubmerge.branch','master') + opt_branch = git_config_get('githubmerge.branch',None) testcmd = git_config_get('githubmerge.testcmd') signingkey = git_config_get('user.signingkey') if repo is None: @@ -105,9 +105,20 @@ def main(): host_repo = host+":"+repo # shortcut for push/pull target # Extract settings from command line - args = parse_arguments(branch) + args = parse_arguments() pull = str(args.pull[0]) - branch = args.branch + + # Receive pull information from github + info = retrieve_pr_info(repo,pull) + if info is None: + exit(1) + title = info['title'] + # precedence order for destination branch argument: + # - command line argument + # - githubmerge.branch setting + # - base branch for pull (as retrieved from github) + # - 'master' + branch = args.branch or opt_branch or info['base']['ref'] or 'master' # Initialize source branches head_branch = 'pull/'+pull+'/head' @@ -147,7 +158,6 @@ def main(): try: # Create unsigned merge commit. - title = retrieve_pr_title(repo,pull) if title: firstline = 'Merge #%s: %s' % (pull,title) else: @@ -165,7 +175,7 @@ def main(): print("ERROR: Creating merge failed (already merged?).",file=stderr) exit(4) - print('%s#%s%s %s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title)) + print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET)) subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) print() # Run test command if configured. From 444480649f08e6037f8ac178224b30a82e9ad72e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 2 Apr 2016 11:51:49 +0200 Subject: [PATCH 0381/1223] [qa] mininode: Combine struct.pack format strings --- qa/rpc-tests/test_framework/mininode.py | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index b06905301..53f5e8805 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -78,10 +78,10 @@ def ser_string(s): if len(s) < 253: return struct.pack("B", len(s)) + s elif len(s) < 0x10000: - return struct.pack("B", 253) + struct.pack(" Date: Mon, 21 Mar 2016 18:29:17 +0100 Subject: [PATCH 0382/1223] [ui] Move InitError, InitWarning, AmountErrMsg --- src/Makefile.am | 1 + src/init.cpp | 18 ------------ src/test/test_bitcoin.cpp | 2 -- src/ui_interface.cpp | 24 +++++++++++++++ src/ui_interface.h | 8 +++++ src/wallet/wallet.cpp | 61 +++++++++++++++------------------------ 6 files changed, 56 insertions(+), 58 deletions(-) create mode 100644 src/ui_interface.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 1e54512cb..10aa550a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -323,6 +323,7 @@ libbitcoin_util_a_SOURCES = \ rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ + ui_interface.cpp \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ diff --git a/src/init.cpp b/src/init.cpp index 3667820a2..038b28cc3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -94,7 +94,6 @@ enum BindFlags { }; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; -CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h ////////////////////////////////////////////////////////////////////////////// // @@ -266,18 +265,6 @@ void HandleSIGHUP(int) fReopenDebugLog = true; } -bool static InitError(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); - return false; -} - -bool static InitWarning(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); - return true; -} - bool static Bind(const CService &addr, unsigned int flags) { if (!(flags & BF_EXPLICIT) && IsLimited(addr)) return false; @@ -742,11 +729,6 @@ static std::string ResolveErrMsg(const char * const optname, const std::string& return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); } -static std::string AmountErrMsg(const char * const optname, const std::string& strValue) -{ - return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); -} - void InitLogging() { fPrintToConsole = GetBoolArg("-printtoconsole", false); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 97b999625..730f04f97 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -30,8 +30,6 @@ #include #include -CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h - extern bool fPrintToConsole; extern void noui_connect(); diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp new file mode 100644 index 000000000..c778e40a9 --- /dev/null +++ b/src/ui_interface.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "ui_interface.h" +#include "util.h" + +CClientUIInterface uiInterface; + +bool InitError(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); + return false; +} + +void InitWarning(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); +} + +std::string AmountErrMsg(const char* const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); +} diff --git a/src/ui_interface.h b/src/ui_interface.h index 0b51d52e6..a27918c50 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -100,6 +100,14 @@ public: boost::signals2::signal BannedListChanged; }; +/** Show warning message **/ +void InitWarning(const std::string& str); + +/** Show error message **/ +bool InitError(const std::string& str); + +std::string AmountErrMsg(const char* const optname, const std::string& strValue); + extern CClientUIInterface uiInterface; #endif // BITCOIN_UI_INTERFACE_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e8c946671..21d641f24 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -23,6 +23,7 @@ #include "timedata.h" #include "txmempool.h" #include "util.h" +#include "ui_interface.h" #include "utilmoneystr.h" #include @@ -365,22 +366,6 @@ void CWallet::Flush(bool shutdown) bitdb.Flush(shutdown); } -bool static UIError(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); - return false; -} - -void static UIWarning(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); -} - -static std::string AmountErrMsg(const char * const optname, const std::string& strValue) -{ - return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); -} - bool CWallet::Verify() { std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); @@ -390,7 +375,7 @@ bool CWallet::Verify() // Wallet file must be a plain filename without a directory if (walletFile != boost::filesystem::basename(walletFile) + boost::filesystem::extension(walletFile)) - return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string())); + return InitError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string())); if (!bitdb.Open(GetDataDir())) { @@ -407,7 +392,7 @@ bool CWallet::Verify() // try again if (!bitdb.Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env - return UIError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); + return InitError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); } } @@ -423,14 +408,14 @@ bool CWallet::Verify() CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { - UIWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!" + InitWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!" " Original %s saved as %s in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), walletFile, "wallet.{timestamp}.bak", GetDataDir())); } if (r == CDBEnv::RECOVER_FAIL) - return UIError(strprintf(_("%s corrupt, salvage failed"), walletFile)); + return InitError(strprintf(_("%s corrupt, salvage failed"), walletFile)); } return true; @@ -3055,7 +3040,7 @@ bool CWallet::InitLoadWallet() CWallet *tempWallet = new CWallet(walletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { - return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); } delete tempWallet; @@ -3071,22 +3056,22 @@ bool CWallet::InitLoadWallet() if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) - return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - UIWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" + InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect."), walletFile)); } else if (nLoadWalletRet == DB_TOO_NEW) - return UIError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), + return InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME))); else if (nLoadWalletRet == DB_NEED_REWRITE) { - return UIError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); + return InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); } else - return UIError(strprintf(_("Error loading %s"), walletFile)); + return InitError(strprintf(_("Error loading %s"), walletFile)); } if (GetBoolArg("-upgradewallet", fFirstRun)) @@ -3102,7 +3087,7 @@ bool CWallet::InitLoadWallet() LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); if (nMaxVersion < walletInstance->GetVersion()) { - return UIError(_("Cannot downgrade wallet")); + return InitError(_("Cannot downgrade wallet")); } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3116,7 +3101,7 @@ bool CWallet::InitLoadWallet() if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) - return UIError(_("Cannot write default address") += "\n"); + return InitError(_("Cannot write default address") += "\n"); } walletInstance->SetBestChain(chainActive.GetLocator()); @@ -3150,7 +3135,7 @@ bool CWallet::InitLoadWallet() block = block->pprev; if (pindexRescan != block) - return UIError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); + return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); } uiInterface.InitMessage(_("Rescanning...")); @@ -3200,28 +3185,28 @@ bool CWallet::ParameterInteraction() if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else - return UIError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); } if (mapArgs.count("-fallbackfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) - return UIError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - UIWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return UIError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); + return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - UIWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) { - return UIError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), + return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); } } @@ -3229,13 +3214,13 @@ bool CWallet::ParameterInteraction() { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return UIError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); if (nMaxFee > HIGH_MAX_TX_FEE) - UIWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) { - return UIError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); } } From 4b9dfd6d81581e1b821d3a503335a1fa78471655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 2 Apr 2016 18:54:12 +0200 Subject: [PATCH 0383/1223] Add note about using the Qt official binary installer. --- doc/build-osx.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index c3cb1b789..296e0aa1f 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,6 +1,6 @@ Mac OS X Build Instructions and Notes ==================================== -This guide will show you how to build bitcoind (headless client) for OS X. +This guide will show you how to build Bitcoin Core for OS X. Notes ----- @@ -114,6 +114,16 @@ you can monitor its process by looking at the debug.log file, like this: Other commands: ------- - ./bitcoind -daemon # to start the bitcoin daemon. + ./bitcoind -daemon # to start the bitcoin daemon. ./bitcoin-cli --help # for a list of command-line options. ./bitcoin-cli help # When the daemon is running, to get a list of RPC commands + +Using Qt official installer while building +------------------------------------------ + +If you prefer to use the latest Qt installed from the official binary +installer over the brew version, you have to make several changes to +the installed tree and its binaries (all these changes are contained +in the brew version already). The changes needed are described in +[#7714](https://github.com/bitcoin/bitcoin/issues/7714). We do not +support building Bitcoin Core this way though. From 190c1e234d0454d4eb93536992674770fc1e68bb Mon Sep 17 00:00:00 2001 From: JeremyRand Date: Sat, 2 Apr 2016 22:10:28 +0000 Subject: [PATCH 0384/1223] Doc: change Precise to Trusty in gitian-building.md https://github.com/bitcoin/bitcoin/commit/2cecb2460002bc645e47e8517b21099b0faec818 changed "precise" to "trusty" in the shell command, but didn't change the text above it accordingly. This commit fixes that. --- doc/gitian-building.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 54993d13a..69d79b3c6 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -313,7 +313,7 @@ Setting up the Gitian image ------------------------- Gitian needs a virtual image of the operating system to build in. -Currently this is Ubuntu Precise x86_64. +Currently this is Ubuntu Trusty x86_64. This image will be copied and used every time that a build is started to make sure that the build is deterministic. Creating the image will take a while, but only has to be done once. From fada0c422c081ba53a324aaf63c0a750cb56498e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 11:49:36 +0200 Subject: [PATCH 0385/1223] [doc] Fix doxygen comments for members --- doc/developer-notes.md | 6 ++++++ src/chainparams.cpp | 4 ++-- src/main.cpp | 8 ++++---- src/main.h | 14 ++++++------- src/policy/fees.h | 4 ++-- src/rpc/client.cpp | 4 ++-- src/script/interpreter.cpp | 12 ++++++------ src/script/standard.h | 2 +- src/txmempool.h | 40 +++++++++++++++++++------------------- src/utiltime.cpp | 2 +- src/wallet/wallet.h | 8 ++++---- 11 files changed, 55 insertions(+), 49 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 358792251..8affb2158 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -71,6 +71,12 @@ To describe a member or variable use: int var; //!< Detailed description after the member ``` +or +```cpp +//! Description before the member +int var; +``` + Also OK: ```c++ /// diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 965d13169..5c7d19012 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -266,8 +266,8 @@ public: assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. - vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. + vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. + vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; diff --git a/src/main.cpp b/src/main.cpp index 2c0b3bfee..b68c6affa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -194,10 +194,10 @@ namespace { /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ struct QueuedBlock { uint256 hash; - CBlockIndex *pindex; //! Optional. - int64_t nTime; //! Time of "getdata" request in microseconds. - bool fValidatedHeaders; //! Whether this block has validated headers at the time of request. - int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer) + CBlockIndex* pindex; //!< Optional. + int64_t nTime; //!< Time of "getdata" request in microseconds. + bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. + int64_t nTimeDisconnect; //!< The timeout for this block request (for disconnecting a slow peer) }; map::iterator> > mapBlocksInFlight; diff --git a/src/main.h b/src/main.h index 0bfcfab21..3ea9dc500 100644 --- a/src/main.h +++ b/src/main.h @@ -469,13 +469,13 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, class CBlockFileInfo { public: - unsigned int nBlocks; //! number of blocks stored in file - unsigned int nSize; //! number of used bytes of block file - unsigned int nUndoSize; //! number of used bytes in the undo file - unsigned int nHeightFirst; //! lowest height of block in file - unsigned int nHeightLast; //! highest height of block in file - uint64_t nTimeFirst; //! earliest time of block in file - uint64_t nTimeLast; //! latest time of block in file + unsigned int nBlocks; //!< number of blocks stored in file + unsigned int nSize; //!< number of used bytes of block file + unsigned int nUndoSize; //!< number of used bytes in the undo file + unsigned int nHeightFirst; //!< lowest height of block in file + unsigned int nHeightLast; //!< highest height of block in file + uint64_t nTimeFirst; //!< earliest time of block in file + uint64_t nTimeLast; //!< latest time of block in file ADD_SERIALIZE_METHODS; diff --git a/src/policy/fees.h b/src/policy/fees.h index cdd984de7..463f62f71 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -265,8 +265,8 @@ public: void Read(CAutoFile& filein); private: - CFeeRate minTrackedFee; //! Passed to constructor to avoid dependency on main - double minTrackedPriority; //! Set to AllowFreeThreshold + CFeeRate minTrackedFee; //!< Passed to constructor to avoid dependency on main + double minTrackedPriority; //!< Set to AllowFreeThreshold unsigned int nBestSeenHeight; struct TxStatsInfo { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 89420b93d..033987af5 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -18,8 +18,8 @@ using namespace std; class CRPCConvertParam { public: - std::string methodName; //! method whose params want conversion - int paramIdx; //! 0-based idx of param to convert + std::string methodName; //!< method whose params want conversion + int paramIdx; //!< 0-based idx of param to convert }; static const CRPCConvertParam vRPCConvertParams[] = diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 149a4f015..9c47f7c6c 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1015,12 +1015,12 @@ namespace { */ class CTransactionSignatureSerializer { private: - const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) - const CScript &scriptCode; //! output script being consumed - const unsigned int nIn; //! input index of txTo being signed - const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set - const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE - const bool fHashNone; //! whether the hashtype is SIGHASH_NONE + const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) + const CScript& scriptCode; //!< output script being consumed + const unsigned int nIn; //!< input index of txTo being signed + const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set + const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE + const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE public: CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : diff --git a/src/script/standard.h b/src/script/standard.h index 64bf010ec..f348da8e1 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -27,7 +27,7 @@ public: CScriptID(const uint160& in) : uint160(in) {} }; -static const unsigned int MAX_OP_RETURN_RELAY = 83; //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes) +static const unsigned int MAX_OP_RETURN_RELAY = 83; //!< bytes (+1 for OP_RETURN, +2 for the pushdata opcodes) extern bool fAcceptDatacarrier; extern unsigned nMaxDatacarrierBytes; diff --git a/src/txmempool.h b/src/txmempool.h index 9dbb37dad..de4ba0b37 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -74,28 +74,28 @@ class CTxMemPoolEntry { private: CTransaction tx; - CAmount nFee; //! Cached to avoid expensive parent-transaction lookups - size_t nTxSize; //! ... and avoid recomputing tx size - size_t nModSize; //! ... and modified size for priority - size_t nUsageSize; //! ... and total memory usage - int64_t nTime; //! Local time when entering the mempool - double entryPriority; //! Priority when entering the mempool - unsigned int entryHeight; //! Chain height when entering the mempool - bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool - CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain - bool spendsCoinbase; //! keep track of transactions that spend a coinbase - unsigned int sigOpCount; //! Legacy sig ops plus P2SH sig op count - int64_t feeDelta; //! Used for determining the priority of the transaction for mining in a block - LockPoints lockPoints; //! Track the height and time at which tx was final + CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups + size_t nTxSize; //!< ... and avoid recomputing tx size + size_t nModSize; //!< ... and modified size for priority + size_t nUsageSize; //!< ... and total memory usage + int64_t nTime; //!< Local time when entering the mempool + double entryPriority; //!< Priority when entering the mempool + unsigned int entryHeight; //!< Chain height when entering the mempool + bool hadNoDependencies; //!< Not dependent on any other txs when it entered the mempool + CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain + bool spendsCoinbase; //!< keep track of transactions that spend a coinbase + unsigned int sigOpCount; //!< Legacy sig ops plus P2SH sig op count + int64_t feeDelta; //!< Used for determining the priority of the transaction for mining in a block + LockPoints lockPoints; //!< Track the height and time at which tx was final // Information about descendants of this transaction that are in the // mempool; if we remove this transaction we must remove all of these // descendants as well. if nCountWithDescendants is 0, treat this entry as // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be // correct. - uint64_t nCountWithDescendants; //! number of descendant transactions - uint64_t nSizeWithDescendants; //! ... and size - CAmount nModFeesWithDescendants; //! ... and total fees (all including us) + uint64_t nCountWithDescendants; //!< number of descendant transactions + uint64_t nSizeWithDescendants; //!< ... and size + CAmount nModFeesWithDescendants; //!< ... and total fees (all including us) // Analogous statistics for ancestor transactions uint64_t nCountWithAncestors; @@ -399,18 +399,18 @@ public: class CTxMemPool { private: - uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check. + uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check. unsigned int nTransactionsUpdated; CBlockPolicyEstimator* minerPolicyEstimator; - uint64_t totalTxSize; //! sum of all mempool tx' byte sizes - uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) + uint64_t totalTxSize; //!< sum of all mempool tx' byte sizes + uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves) CFeeRate minReasonableRelayFee; mutable int64_t lastRollingFeeUpdate; mutable bool blockSinceLastRollingFeeBump; - mutable double rollingMinimumFeeRate; //! minimum fee to get into the pool, decreases exponentially + mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially void trackPackageRemoved(const CFeeRate& rate); diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 91b40d999..da590f888 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -14,7 +14,7 @@ using namespace std; -static int64_t nMockTime = 0; //! For unit testing +static int64_t nMockTime = 0; //!< For unit testing int64_t GetTime() { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 867f33a7b..96d5d4e1e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -228,11 +228,11 @@ public: mapValue_t mapValue; std::vector > vOrderForm; unsigned int fTimeReceivedIsTxTime; - unsigned int nTimeReceived; //! time received by this node + unsigned int nTimeReceived; //!< time received by this node unsigned int nTimeSmart; char fFromMe; std::string strFromAccount; - int64_t nOrderPos; //! position in ordered transaction list + int64_t nOrderPos; //!< position in ordered transaction list // memory only mutable bool fDebitCached; @@ -324,7 +324,7 @@ public: } READWRITE(*(CMerkleTx*)this); - std::vector vUnused; //! Used to be vtxPrev + std::vector vUnused; //!< Used to be vtxPrev READWRITE(vUnused); READWRITE(mapValue); READWRITE(vOrderForm); @@ -465,7 +465,7 @@ public: std::string strOtherAccount; std::string strComment; mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list + int64_t nOrderPos; //!< position in ordered transaction list uint64_t nEntryNo; CAccountingEntry() From faef3b710fe2ced7cc94a82847c547865a64fd92 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 14:39:48 +0200 Subject: [PATCH 0386/1223] [travis] Print the commit which was evaluated --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 31b3d6d96..3f1af5301 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,6 +64,7 @@ before_script: - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: + - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" @@ -79,4 +80,6 @@ script: - if [ "$RUN_TESTS" = "true" ]; then make check; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi after_script: + - echo "Commit, which was evaluated by travis in this build job:" + - echo $TRAVIS_COMMIT_LOG - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi From f063863d1fc964aec80d8a0acfde623543573823 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 31 Mar 2016 14:50:10 +0200 Subject: [PATCH 0387/1223] build: Remove unnecessary executables from gitian release This removes the following executables from the binary gitian release: - test_bitcoin-qt[.exe] - bench_bitcoin[.exe] @jonasschnelli and me discussed this on IRC a few days ago - unlike the normal `bitcoin_tests` which is useful to see if it is safe to run bitcoin on a certain OS/environment combination, there is no good reason to include these. Better to leave them out to reduce the download size. Sizes from the 0.12 release: ``` 2.4M bitcoin-0.12.0/bin/bench_bitcoin.exe 22M bitcoin-0.12.0/bin/test_bitcoin-qt.exe ``` --- configure.ac | 21 ++++++++++++--------- contrib/gitian-descriptors/gitian-linux.yml | 2 +- contrib/gitian-descriptors/gitian-osx.yml | 2 +- contrib/gitian-descriptors/gitian-win.yml | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 1e894f576..ec5656814 100644 --- a/configure.ac +++ b/configure.ac @@ -98,6 +98,11 @@ AC_ARG_ENABLE(tests, [use_tests=$enableval], [use_tests=yes]) +AC_ARG_ENABLE(gui-tests, + AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), + [use_gui_tests=$enableval], + [use_gui_tests=$use_tests]) + AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), [use_bench=$enableval], @@ -919,8 +924,8 @@ else fi dnl these are only used when qt is enabled +BUILD_TEST_QT="" if test x$bitcoin_enable_qt != xno; then - BUILD_QT=qt dnl enable dbus support AC_MSG_CHECKING([whether to build GUI with support for D-Bus]) if test x$bitcoin_enable_qt_dbus != xno; then @@ -950,9 +955,9 @@ if test x$bitcoin_enable_qt != xno; then fi AC_MSG_CHECKING([whether to build test_bitcoin-qt]) - if test x$use_tests$bitcoin_enable_qt_test = xyesyes; then + if test x$use_gui_tests$bitcoin_enable_qt_test = xyesyes; then AC_MSG_RESULT([yes]) - BUILD_TEST_QT="test" + BUILD_TEST_QT="yes" else AC_MSG_RESULT([no]) fi @@ -963,9 +968,10 @@ AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) - BUILD_TEST="test" + BUILD_TEST="yes" else AC_MSG_RESULT([no]) + BUILD_TEST="" fi AC_MSG_CHECKING([whether to reduce exports]) @@ -983,9 +989,9 @@ AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) -AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests = xyes]) +AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) -AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$use_tests$bitcoin_enable_qt_test = xyesyes]) +AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) @@ -1026,9 +1032,6 @@ AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) -AC_SUBST(BUILD_TEST) -AC_SUBST(BUILD_QT) -AC_SUBST(BUILD_TEST_QT) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 1f2c4f999..13941f5d5 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -26,7 +26,7 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu" - CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests LDFLAGS=-static-libstdc++" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm strip" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 6f68ae08c..c430932f9 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -36,7 +36,7 @@ files: script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" - CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index f0fbff3e1..9f7322f0b 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -29,7 +29,7 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" - CONFIGFLAGS="--enable-reduce-exports" + CONFIGFLAGS="--enable-reduce-exports --disable-gui-tests" FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip" FAKETIME_PROGS="date makensis zip" From 60361ca4816dd5b2d10408db3194fb77fcac8720 Mon Sep 17 00:00:00 2001 From: mruddy Date: Sun, 3 Apr 2016 14:30:00 +0000 Subject: [PATCH 0388/1223] RPC: fix generatetoaddress failing to parse address and add unit test --- src/rpc/client.cpp | 1 - src/test/rpc_tests.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 89420b93d..b040d2bc8 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -30,7 +30,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "generate", 0 }, { "generate", 1 }, { "generatetoaddress", 0 }, - { "generatetoaddress", 1 }, { "generatetoaddress", 2 }, { "getnetworkhashps", 0 }, { "getnetworkhashps", 1 }, diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 1976ee2cb..bbda6a48f 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -11,6 +11,7 @@ #include "test/test_bitcoin.h" #include +#include #include #include @@ -308,4 +309,27 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128"); } +BOOST_AUTO_TEST_CASE(rpc_convert_values_generatetoaddress) +{ + UniValue result; + + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"))); + BOOST_CHECK_EQUAL(result[0].get_int(), 101); + BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"); + + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"))); + BOOST_CHECK_EQUAL(result[0].get_int(), 101); + BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"); + + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a")("9"))); + BOOST_CHECK_EQUAL(result[0].get_int(), 1); + BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"); + BOOST_CHECK_EQUAL(result[2].get_int(), 9); + + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU")("9"))); + BOOST_CHECK_EQUAL(result[0].get_int(), 1); + BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"); + BOOST_CHECK_EQUAL(result[2].get_int(), 9); +} + BOOST_AUTO_TEST_SUITE_END() From fa24456d0c4cd0f6571bcf3d8f1f51d8d4242a3e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 20:35:57 +0200 Subject: [PATCH 0389/1223] [qa] httpbasics: Actually test second connection --- qa/rpc-tests/httpbasics.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index c231676ec..eff4c6e80 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -37,13 +37,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert('"error":null' in out1) + assert(b'"error":null' in out1) assert(conn.sock!=None) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read() - assert('"error":null' in out1) #must also response with a correct json-rpc message + out1 = conn.getresponse().read() + assert(b'"error":null' in out1) #must also response with a correct json-rpc message assert(conn.sock!=None) #according to http/1.1 connection must still be open! conn.close() @@ -54,13 +54,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert('"error":null' in out1) + assert(b'"error":null' in out1) assert(conn.sock!=None) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read() - assert('"error":null' in out1) #must also response with a correct json-rpc message + out1 = conn.getresponse().read() + assert(b'"error":null' in out1) #must also response with a correct json-rpc message assert(conn.sock!=None) #according to http/1.1 connection must still be open! conn.close() @@ -71,7 +71,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert('"error":null' in out1) + assert(b'"error":null' in out1) assert(conn.sock==None) #now the connection must be closed after the response #node1 (2nd node) is running with disabled keep-alive option @@ -83,7 +83,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert('"error":null' in out1) + assert(b'"error":null' in out1) #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on urlNode2 = urlparse.urlparse(self.nodes[2].url) @@ -94,7 +94,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read() - assert('"error":null' in out1) + assert(b'"error":null' in out1) assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default # Check excessive request size From fac724c78f281168ea174c36cada4f95112aea6d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 20 Mar 2016 18:56:13 +0100 Subject: [PATCH 0390/1223] [qa] maxblocksinflight: Actually enable test --- qa/rpc-tests/maxblocksinflight.py | 52 ++++++++++++++----------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index 0313bce73..ad633f661 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -41,40 +41,36 @@ class TestManager(NodeConnCB): self.disconnectOkay = False def run(self): - try: - fail = False - self.connection.rpc.generate(1) # Leave IBD + self.connection.rpc.generate(1) # Leave IBD - numBlocksToGenerate = [ 8, 16, 128, 1024 ] - for count in range(len(numBlocksToGenerate)): - current_invs = [] - for i in range(numBlocksToGenerate[count]): - current_invs.append(CInv(2, random.randrange(0, 1<<256))) - if len(current_invs) >= 50000: - self.connection.send_message(msg_inv(current_invs)) - current_invs = [] - if len(current_invs) > 0: + numBlocksToGenerate = [8, 16, 128, 1024] + for count in range(len(numBlocksToGenerate)): + current_invs = [] + for i in range(numBlocksToGenerate[count]): + current_invs.append(CInv(2, random.randrange(0, 1 << 256))) + if len(current_invs) >= 50000: self.connection.send_message(msg_inv(current_invs)) - - # Wait and see how many blocks were requested - time.sleep(2) + current_invs = [] + if len(current_invs) > 0: + self.connection.send_message(msg_inv(current_invs)) - total_requests = 0 - with mininode_lock: - for key in self.blockReqCounts: - total_requests += self.blockReqCounts[key] - if self.blockReqCounts[key] > 1: - raise AssertionError("Error, test failed: block %064x requested more than once" % key) - if total_requests > MAX_REQUESTS: - raise AssertionError("Error, too many blocks (%d) requested" % total_requests) - print "Round %d: success (total requests: %d)" % (count, total_requests) - except AssertionError as e: - print "TEST FAILED: ", e.args + # Wait and see how many blocks were requested + time.sleep(2) + + total_requests = 0 + with mininode_lock: + for key in self.blockReqCounts: + total_requests += self.blockReqCounts[key] + if self.blockReqCounts[key] > 1: + raise AssertionError("Error, test failed: block %064x requested more than once" % key) + if total_requests > MAX_REQUESTS: + raise AssertionError("Error, too many blocks (%d) requested" % total_requests) + print "Round %d: success (total requests: %d)" % (count, total_requests) self.disconnectOkay = True self.connection.disconnect_node() - + class MaxBlocksInFlightTest(BitcoinTestFramework): def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", @@ -86,7 +82,7 @@ class MaxBlocksInFlightTest(BitcoinTestFramework): initialize_chain_clean(self.options.tmpdir, 1) def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) From ffff866da83209dcaa463d8b9539d3f539f83a97 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 21:20:14 +0200 Subject: [PATCH 0391/1223] [qa] Remove misleading "errorString syntax" --- qa/rpc-tests/importprunedfunds.py | 10 ++++++---- qa/rpc-tests/rawtransactions.py | 6 +++--- qa/rpc-tests/wallet.py | 19 +++++++------------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index db875800d..a9324196e 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -83,9 +83,10 @@ class ImportPrunedFundsTest(BitcoinTestFramework): try: result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "") except JSONRPCException as e: - errorString = e.error['message'] + assert('No addresses' in e.error['message']) + else: + assert(False) - assert('No addresses' in errorString) balance1 = self.nodes[1].getbalance("", 0, True) assert_equal(balance1, Decimal(0)) @@ -120,9 +121,10 @@ class ImportPrunedFundsTest(BitcoinTestFramework): try: self.nodes[1].removeprunedfunds(txnid1) except JSONRPCException as e: - errorString = e.error['message'] + assert('does not exist' in e.error['message']) + else: + assert(False) - assert('does not exist' in errorString) balance1 = Decimal(self.nodes[1].getbalance("", 0, True)) assert_equal(balance1, Decimal('0.075')) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 9f660c8bd..762a6d6a3 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -56,13 +56,13 @@ class RawTransactionsTest(BitcoinTestFramework): rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtx = self.nodes[2].signrawtransaction(rawtx) - errorString = "" try: rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) except JSONRPCException as e: - errorString = e.error['message'] + assert("Missing inputs" in e.error['message']) + else: + assert(False) - assert("Missing inputs" in errorString) ######################### # RAW TX MULTISIG TESTS # diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index cb876aae5..8fdcea50b 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -245,22 +245,20 @@ class WalletTest (BitcoinTestFramework): txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) - #this should fail - errorString = "" try: txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") except JSONRPCException as e: - errorString = e.error['message'] + assert("Invalid amount" in e.error['message']) + else: + raise AssertionError("Must not parse invalid amounts") - assert("Invalid amount" in errorString) - errorString = "" try: - self.nodes[0].generate("2") #use a string to as block amount parameter must fail because it's not interpreted as amount + self.nodes[0].generate("2") + raise AssertionError("Must not accept strings as numeric") except JSONRPCException as e: - errorString = e.error['message'] + assert("not an integer" in e.error['message']) - assert("not an integer" in errorString) # Mine a block from node0 to an address from node1 cbAddr = self.nodes[1].getnewaddress() @@ -269,10 +267,7 @@ class WalletTest (BitcoinTestFramework): self.sync_all() # Check that the txid and balance is found by node1 - try: - self.nodes[1].gettransaction(cbTxId) - except JSONRPCException as e: - assert("Invalid or non-wallet transaction id" not in e.error['message']) + self.nodes[1].gettransaction(cbTxId) #check if wallet or blochchain maintenance changes the balance self.sync_all() From 8efed3bc93a15fc715fd4f3cca50f44685872b5e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Mar 2016 17:54:54 +0100 Subject: [PATCH 0392/1223] [Qt] Support for abandoned/abandoning transactions --- src/Makefile.qt.include | 3 +- src/qt/bitcoin.qrc | 1 + src/qt/guiconstants.h | 2 ++ src/qt/res/icons/transaction_abandoned.png | Bin 0 -> 1473 bytes src/qt/transactiondesc.cpp | 2 +- src/qt/transactionrecord.cpp | 2 ++ src/qt/transactionrecord.h | 1 + src/qt/transactiontablemodel.cpp | 10 +++++++ src/qt/transactionview.cpp | 33 +++++++++++++++++++-- src/qt/transactionview.h | 2 ++ src/qt/walletmodel.cpp | 15 ++++++++++ src/qt/walletmodel.h | 3 ++ 12 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 src/qt/res/icons/transaction_abandoned.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index ca4e1e70d..247ca3f1d 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -268,7 +268,8 @@ RES_ICONS = \ qt/res/icons/tx_output.png \ qt/res/icons/tx_mined.png \ qt/res/icons/warning.png \ - qt/res/icons/verify.png + qt/res/icons/verify.png \ + qt/res/icons/transaction_abandoned.png BITCOIN_QT_CPP = \ qt/bantablemodel.cpp \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index dcd3b4ae2..24b0bae3e 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -49,6 +49,7 @@ res/icons/fontbigger.png res/icons/fontsmaller.png res/icons/chevron.png + res/icons/transaction_abandoned.png res/movies/spinner-000.png diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 5ceffcd70..4b2c10dd4 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -29,6 +29,8 @@ static const bool DEFAULT_SPLASHSCREEN = true; #define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255) /* Transaction list -- TX status decoration - offline */ #define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192) +/* Transaction list -- TX status decoration - danger, tx needs attention */ +#define COLOR_TX_STATUS_DANGER QColor(200, 100, 100) /* Transaction list -- TX status decoration - default color */ #define COLOR_BLACK QColor(0, 0, 0) diff --git a/src/qt/res/icons/transaction_abandoned.png b/src/qt/res/icons/transaction_abandoned.png new file mode 100644 index 0000000000000000000000000000000000000000..8ca6445c20f263b3dd479806a524e3f09b8f9e63 GIT binary patch literal 1473 zcmchX`8(8k0LMSynaoU+ab$|ek)tO~D$$@ah8aiFk|SEjIxB=3gH0I63^{UbMX?sC zZJ%}I2uX;qb*;sq7)x%$jF53HQLLVRY5#$Jp7;Cx`uY9K>yFhWQyf+n3jn~GT`;!U zCF@HusNHSSckci|B*Dy>Y8x`NFhcdl-@>;o`R}hiX`$rdLBrX{x>Tyos9;o{;Ex$5 zD5rafqo_i{1@%d)M6|T>19{`)%?D%O3||+g5?1dU#vIaXDWuk*Djz(tRjwhg;w&EK z?9jI>JZB76wwg%i{7)~ww&adPsY(_0t0hjxWhnulXh7IQQ3hDZ3d1r4S(oUaebDtl zl{Lnarf83cxZgClcU~x_+q-~DXbc3g#p|p)9dc+0;m#(8zz-L`u&%1vCq7ObcW;bS zY%wZoC$*-hP9BNLq(BVb&Fn*9R>SdP1BzOBVj z5FUwaSYS%Y9HR`c3M>XUYt+*f(OdHpxld%~(z{b#z1NZdIrPoB4Fmy_W*M*y*ov%C zRLZtQ^_~;Jl3hf(6_ZUTeJGfAE?=p>QtI688XO^=|LUd_xR0!MK{_wWDxUWc_HV8f& zm|D!xuya#V^@8t7p%*d_d&PrF6s&H_xnRzTyt1uTLN(=VXJ$*9a?~LS@IQuS4pj@R zd9#^8v;dxH8*h~qDAvrAXYf|rc%r1hs%BpHKZ3579+1642FG|-XSMq zPXpTs7brFu@Ll6P?Jm)8Kx*1nzEs9O=OiS5vXr7v-sb`s4S-uSW?c$ zGVL5W_>-ip!4JBQa`QDP`BIJE!jM%@f);p3PJD)7{<%IhHJGvR7$QKWdf3;wL12I! zwv26?;#Xk7c$Mk%B)BSDEJ`ji%5lAF?x_Qc!CjgDAl+8`!D>LZsN;7Q6XRdbd$J9m1Zbk@h) z7WwvvFS14JuMIev*{_EawY?Mo+w0L(PE8iAYbx=AOZ*?3tmXR6B*lX~ zWG2n}a^n7qE`&G)V0w2qY?5p;Cmo6ajPp%2HO{lA1 2 * 60 && wtx.GetRequestCount() == 0) return tr("%1/offline").arg(nDepth); else if (nDepth == 0) - return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))); + return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))) + (wtx.isAbandoned() ? ", "+tr("abandoned") : ""); else if (nDepth < 6) return tr("%1/unconfirmed").arg(nDepth); else diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5b16b108e..1efeda93e 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -239,6 +239,8 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) else if (status.depth == 0) { status.status = TransactionStatus::Unconfirmed; + if (wtx.isAbandoned()) + status.status = TransactionStatus::Abandoned; } else if (status.depth < RecommendedNumConfirmations) { diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 49753ee31..330cd48cf 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -33,6 +33,7 @@ public: Unconfirmed, /**< Not yet mined into a block **/ Confirming, /**< Confirmed, but waiting for the recommended number of confirmations **/ Conflicted, /**< Conflicts with other transaction or mempool **/ + Abandoned, /**< Abandoned from the wallet **/ /// Generated (mined) transactions Immature, /**< Mined but waiting for maturity */ MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index d2a52b302..b29ecf834 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -312,6 +312,9 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons case TransactionStatus::Unconfirmed: status = tr("Unconfirmed"); break; + case TransactionStatus::Abandoned: + status = tr("Abandoned"); + break; case TransactionStatus::Confirming: status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations); break; @@ -468,6 +471,8 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) return COLOR_TX_STATUS_OFFLINE; case TransactionStatus::Unconfirmed: return QIcon(":/icons/transaction_0"); + case TransactionStatus::Abandoned: + return QIcon(":/icons/transaction_abandoned"); case TransactionStatus::Confirming: switch(wtx->status.depth) { @@ -573,6 +578,11 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Qt::TextAlignmentRole: return column_alignments[index.column()]; case Qt::ForegroundRole: + // Use the "danger" color for abandoned transactions + if(rec->status.status == TransactionStatus::Abandoned) + { + return COLOR_TX_STATUS_DANGER; + } // Non-confirmed (but not immature) as transactions are grey if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature) { diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index a4d4c7a35..a352228c3 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -37,7 +37,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0) + transactionView(0), abandonAction(0) { // Build filter row setContentsMargins(0,0,0,0); @@ -137,6 +137,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa transactionView = view; // Actions + abandonAction = new QAction(tr("Abandon transaction"), this); QAction *copyAddressAction = new QAction(tr("Copy address"), this); QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); @@ -153,8 +154,10 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyTxIDAction); contextMenu->addAction(copyTxHexAction); contextMenu->addAction(copyTxPlainText); - contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); + contextMenu->addSeparator(); + contextMenu->addAction(abandonAction); + contextMenu->addAction(editLabelAction); mapperThirdPartyTxUrls = new QSignalMapper(this); @@ -170,6 +173,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + connect(abandonAction, SIGNAL(triggered()), this, SLOT(abandonTx())); connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); @@ -360,12 +364,37 @@ void TransactionView::exportClicked() void TransactionView::contextualMenu(const QPoint &point) { QModelIndex index = transactionView->indexAt(point); + QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + + // check if transaction can be abandoned, disable context menu action in case it doesn't + uint256 hash; + hash.SetHex(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString()); + abandonAction->setEnabled(model->transactionCanBeAbandoned(hash)); + if(index.isValid()) { contextMenu->exec(QCursor::pos()); } } +void TransactionView::abandonTx() +{ + if(!transactionView || !transactionView->selectionModel()) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + + // get the hash from the TxHashRole (QVariant / QString) + uint256 hash; + QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString(); + hash.SetHex(hashQStr.toStdString()); + + // Abandon the wallet transaction over the walletModel + model->abandonTransaction(hash); + + // Update the table + model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, false); +} + void TransactionView::copyAddress() { GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 2cfbd471b..e9b9d5b6b 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -75,6 +75,7 @@ private: QFrame *dateRangeWidget; QDateTimeEdit *dateFrom; QDateTimeEdit *dateTo; + QAction *abandonAction; QWidget *createDateRangeWidget(); @@ -97,6 +98,7 @@ private Q_SLOTS: void copyTxPlainText(); void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); + void abandonTx(); Q_SIGNALS: void doubleClicked(const QModelIndex&); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index cf38c64eb..ce230d6ae 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -668,3 +668,18 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t else return wallet->AddDestData(dest, key, sRequest); } + +bool WalletModel::transactionCanBeAbandoned(uint256 hash) const +{ + LOCK2(cs_main, wallet->cs_wallet); + const CWalletTx *wtx = wallet->GetWalletTx(hash); + if (!wtx || wtx->isAbandoned() || wtx->GetDepthInMainChain() > 0 || wtx->InMempool()) + return false; + return true; +} + +bool WalletModel::abandonTransaction(uint256 hash) const +{ + LOCK2(cs_main, wallet->cs_wallet); + return wallet->AbandonTransaction(hash); +} diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 7a47eda86..e5470bf61 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -200,6 +200,9 @@ public: void loadReceiveRequests(std::vector& vReceiveRequests); bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); + bool transactionCanBeAbandoned(uint256 hash) const; + bool abandonTransaction(uint256 hash) const; + private: CWallet *wallet; bool fHaveWatchOnly; From 0087f2684891d9f208a1d91758e662d0538d54ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 2 Apr 2016 16:32:42 +0200 Subject: [PATCH 0393/1223] Use relative paths instead of absolute paths --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 1e54512cb..d91e959cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -479,7 +479,7 @@ endif %.pb.cc %.pb.h: %.proto @test -f $(PROTOC) - $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $( Date: Mon, 4 Apr 2016 22:21:00 +0000 Subject: [PATCH 0394/1223] RPC: add versionHex in getblock and getblockheader JSON results; expand data in getblockchaininfo bip9_softforks field. --- qa/rpc-tests/blockchain.py | 1 + src/rpc/blockchain.cpp | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 272a5dc15..8f59ee741 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -82,6 +82,7 @@ class BlockchainTest(BitcoinTestFramework): assert isinstance(header['mediantime'], int) assert isinstance(header['nonce'], int) assert isinstance(header['version'], int) + assert isinstance(int(header['versionHex'], 16), int) assert isinstance(header['difficulty'], Decimal) if __name__ == '__main__': diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f1c9d9f7a..34637b9f7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -70,6 +70,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion))); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); result.push_back(Pair("time", (int64_t)blockindex->nTime)); result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); @@ -98,6 +99,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); UniValue txs(UniValue::VARR); BOOST_FOREACH(const CTransaction&tx, block.vtx) @@ -316,6 +318,7 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" @@ -375,6 +378,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"size\" : n, (numeric) The block size\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"tx\" : [ (array of string) The transaction ids\n" " \"transactionid\" (string) The transaction id\n" @@ -608,13 +612,20 @@ static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Param { UniValue rv(UniValue::VOBJ); rv.push_back(Pair("id", name)); - switch (VersionBitsTipState(consensusParams, id)) { + const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); + switch (thresholdState) { case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; } + if (THRESHOLD_STARTED == thresholdState) + { + rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit)); + } + rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime)); + rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout)); return rv; } @@ -653,6 +664,9 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " {\n" " \"id\": \"xxxx\", (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" + " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" + " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" " ]\n" "}\n" From dc4ec6d3dbb5018cdc059eebb55994fab5d23679 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 4 Apr 2016 15:48:18 -0400 Subject: [PATCH 0395/1223] depends: create a hostid and buildid and add option for salts These add very simple sanity checks to ensure that the build/host toolchains have not changed since the last run. If they have, all ids will change and packages will be rebuilt. For more complicated usage (like parsing dpkg), HOST_ID_SALT/BUILD_ID_SALT may be used to introduce arbitrary data to the ids. --- depends/Makefile | 18 +++++++++++++++++- depends/README.md | 2 ++ depends/funcs.mk | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index ef5a20e6c..7ae14524e 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -15,6 +15,8 @@ BASEDIR = $(CURDIR) HASH_LENGTH:=11 DOWNLOAD_CONNECT_TIMEOUT:=10 DOWNLOAD_RETRIES:=3 +HOST_ID_SALT ?= salt +BUILD_ID_SALT ?= salt host:=$(BUILD) ifneq ($(HOST),) @@ -73,6 +75,20 @@ include builders/$(build_os).mk include builders/default.mk include packages/packages.mk +build_id_string:=$(BUILD_ID_SALT) +build_id_string+=$(shell $(build_CC) --version 2>/dev/null) +build_id_string+=$(shell $(build_AR) --version 2>/dev/null) +build_id_string+=$(shell $(build_CXX) --version 2>/dev/null) +build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) +build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) + +$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) +$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) + qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) qt_native_packages_$(NO_QT) = $(qt_native_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) @@ -90,7 +106,7 @@ include funcs.mk toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin) final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) -final_build_id+=$(shell echo -n $(final_build_id_long) | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) +final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) $(AT)rm -rf $(@D) $(AT)mkdir -p $(@D) diff --git a/depends/README.md b/depends/README.md index d85e652c6..271bbd80b 100644 --- a/depends/README.md +++ b/depends/README.md @@ -38,6 +38,8 @@ The following can be set when running make: make FOO=bar NO_WALLET: Don't download/build/cache libs needed to enable the wallet NO_UPNP: Don't download/build/cache packages needed for enabling upnp DEBUG: disable some optimizations and enable more runtime checking + HOST_ID_SALT: Optional salt to use when generating host package ids + BUILD_ID_SALT: Optional salt to use when generating build package ids If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitcoin's configure. In this case, `--disable-wallet`. diff --git a/depends/funcs.mk b/depends/funcs.mk index 050a9b132..45bb96dd4 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -39,7 +39,7 @@ define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) -$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps)) +$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) final_build_id_long+=$($(package)_build_id_long) From fe740f14690f70fbb84287595049afc719a5bd3b Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 3 Mar 2016 01:01:30 -0500 Subject: [PATCH 0396/1223] depends: fix fallback downloads In some cases, failed downloads wouldn't trigger a fallback download attempt. Namely, checksum mismatches. --- depends/funcs.mk | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 45bb96dd4..15e404e42 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -19,15 +19,19 @@ define int_get_all_dependencies $(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies)))) endef -define fetch_file -(test -f $$($(1)_source_dir)/$(4) || \ - ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \ - ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \ - $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \ +define fetch_file_inner + ( mkdir -p $$($(1)_download_dir) && echo Fetching $(3) from $(2) && \ + $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" && \ echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \ $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \ mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \ - rm -rf $$($(1)_download_dir) )) + rm -rf $$($(1)_download_dir) ) +endef + +define fetch_file + ( test -f $$($(1)_source_dir)/$(4) || \ + ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \ + $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5)))) endef define int_get_build_recipe_hash From bb717f43756cf2754b6ed6fc54d52b535ed25fb2 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 4 Apr 2016 15:44:02 -0400 Subject: [PATCH 0397/1223] depends: fix "unexpected operator" error during "make download" --- depends/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 7ae14524e..3ddfc85a4 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -147,9 +147,9 @@ endef define check_or_remove_sources mkdir -p $($(package)_source_dir); cd $($(package)_source_dir); \ - $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \ - ( if test -f $($(package)_all_sources); then echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; fi; \ - rm -f $($(package)_all_sources) $($(1)_fetched)) + test -f $($(package)_fetched) && ( $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \ + ( echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; \ + rm -f $($(package)_all_sources) $($(1)_fetched))) || true endef check-packages: From 11d9f6b8b82df04e9cf0ba7d8434eaa3fe394ee5 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 4 Apr 2016 18:20:20 -0400 Subject: [PATCH 0398/1223] depends: qt/cctools: fix checksum checksum tests Checksums were being verified after download, but not again before extraction --- depends/packages/native_cctools.mk | 4 ++++ depends/packages/qt.mk | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 1c1bcf199..b5603a8d4 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -17,6 +17,10 @@ $(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clan endef define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 901b761fd..77df77b73 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -108,8 +108,8 @@ endef define $(package)_extract_cmds mkdir -p $($(package)_extract_dir) && \ echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir qtbase && \ tar --strip-components=1 -xf $($(package)_source) -C qtbase && \ From fac9ca2ec69bc629dbbd81c83e5bf67690e52c96 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 5 Apr 2016 12:49:53 +0200 Subject: [PATCH 0399/1223] [travis] echo $TRAVIS_COMMIT_RANGE --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f1af5301..95ef36bf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,6 +80,6 @@ script: - if [ "$RUN_TESTS" = "true" ]; then make check; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi after_script: - - echo "Commit, which was evaluated by travis in this build job:" + - echo $TRAVIS_COMMIT_RANGE - echo $TRAVIS_COMMIT_LOG - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi From c7c664191fd6ca4843cfe9d00abf8f2362b9550f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 14:54:18 +0200 Subject: [PATCH 0400/1223] Fix JSON pretty printing in script_tests --- src/test/script_tests.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 30e3f37e1..8f927f8f9 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -381,6 +381,18 @@ public: return creditTx.vout[0].scriptPubKey; } }; + +std::string JSONPrettyPrint(const UniValue& univalue) +{ + std::string ret = univalue.write(4); + // Workaround for libunivalue pretty printer, which puts a space between comma's and newlines + size_t pos = 0; + while ((pos = ret.find(" \n", pos)) != std::string::npos) { + ret.replace(pos, 2, "\n"); + pos++; + } + return ret; +} } BOOST_AUTO_TEST_CASE(script_build) @@ -651,11 +663,11 @@ BOOST_AUTO_TEST_CASE(script_build) for (unsigned int idx = 0; idx < json_good.size(); idx++) { const UniValue& tv = json_good[idx]; - tests_good.insert(tv.get_array().write(1,4)); + tests_good.insert(JSONPrettyPrint(tv.get_array())); } for (unsigned int idx = 0; idx < json_bad.size(); idx++) { const UniValue& tv = json_bad[idx]; - tests_bad.insert(tv.get_array().write(1,4)); + tests_bad.insert(JSONPrettyPrint(tv.get_array())); } } @@ -664,7 +676,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_FOREACH(TestBuilder& test, good) { test.Test(true); - std::string str = test.GetJSON().write(1,4); + std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); @@ -674,7 +686,7 @@ BOOST_AUTO_TEST_CASE(script_build) } BOOST_FOREACH(TestBuilder& test, bad) { test.Test(false); - std::string str = test.GetJSON().write(1,4); + std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); From d03e46625ac95954bb9ecbc2cf73ffd8de6b8a13 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 14:26:01 +0200 Subject: [PATCH 0401/1223] Fix formatting of NOPs for generated script tests --- src/core_write.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core_write.cpp b/src/core_write.cpp index b660e86c3..6f9e2266a 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -35,7 +35,7 @@ string FormatScript(const CScript& script) } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) { ret += strprintf("%i ", op - OP_1NEGATE - 1); continue; - } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) { + } else if (op >= OP_NOP && op <= OP_NOP10) { string str(GetOpName(op)); if (str.substr(0, 3) == string("OP_")) { ret += str.substr(3, string::npos) + " "; @@ -45,7 +45,7 @@ string FormatScript(const CScript& script) if (vch.size() > 0) { ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it)); } else { - ret += strprintf("0x%x", HexStr(it2, it)); + ret += strprintf("0x%x ", HexStr(it2, it)); } continue; } From 269281b7cc56e728fa64803fc7509ab3a0ce1805 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 14:08:13 +0200 Subject: [PATCH 0402/1223] Fix some misconstructed tests They claimed to be testing P2SH scripts with non-push scriptSigs, but 1) they were not enabling P2SH 2) they have push-only scriptSigs Fix this, and add a few more related cases. --- src/test/data/script_invalid.json | 16 ++++++++-------- src/test/data/script_valid.json | 12 ++++++++++++ src/test/script_tests.cpp | 14 ++++++++++---- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 9e9113298..b9f150eac 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -845,18 +845,18 @@ "SIG_PUSHONLY" ], [ - "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", - "", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", + "P2SH", "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", - "EVAL_FALSE" + "SIG_PUSHONLY" ], [ - "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "SIGPUSHONLY", - "P2SH(P2PK) with non-push scriptSig", - "EVAL_FALSE" + "P2SH(P2PK) with non-push scriptSig but not P2SH", + "SIG_PUSHONLY" ], [ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index e5f0d17b0..29ccbd92f 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -882,6 +882,18 @@ "", "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" ], +[ + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", + "", + "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY" +], +[ + "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP8", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "", + "P2PK with non-push scriptSig but with P2SH validation" +], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 8f927f8f9..4ecb56de8 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -628,12 +628,18 @@ BOOST_AUTO_TEST_CASE(script_build) bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem()); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with non-push scriptSig but with P2SH validation", 0 + ).PushSig(keys.key2).Add(CScript() << OP_NOP8)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0 - ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY - ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + "P2SH(P2PK) with non-push scriptSig but not P2SH", SCRIPT_VERIFY_SIGPUSHONLY, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); From 3373c43505cf76b63e7aa81b0d745d14765bd610 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 29 Mar 2016 15:16:16 -0300 Subject: [PATCH 0403/1223] [doc] Update port in tor.md Tor Browser Bundle spawns the Tor process and listens on port 9150, it doesn't randomly pick a port. [ci skip] (cherry picked from commit 1b63cf98347b2a62915425576930f55c2126c2ff) --- doc/tor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tor.md b/doc/tor.md index be4125544..43e922718 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -3,7 +3,7 @@ TOR SUPPORT IN BITCOIN It is possible to run Bitcoin as a Tor hidden service, and connect to such services. -The following directions assume you have a Tor proxy running on port 9050. Many distributions default to having a SOCKS proxy listening on port 9050, but others may not. In particular, the Tor Browser Bundle defaults to listening on a random port. See [Tor Project FAQ:TBBSocksPort](https://www.torproject.org/docs/faq.html.en#TBBSocksPort) for how to properly +The following directions assume you have a Tor proxy running on port 9050. Many distributions default to having a SOCKS proxy listening on port 9050, but others may not. In particular, the Tor Browser Bundle defaults to listening on port 9150. See [Tor Project FAQ:TBBSocksPort](https://www.torproject.org/docs/faq.html.en#TBBSocksPort) for how to properly configure Tor. From 76da7613517d05aca31c2cee42b5ebf3d5c54974 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 15:45:10 +0200 Subject: [PATCH 0404/1223] Make script_error a mandatory 4th field for script_tests --- src/test/data/script_invalid.json | 1024 ++++++++++++------------- src/test/data/script_valid.json | 1166 +++++++++++++++-------------- src/test/script_tests.cpp | 15 +- 3 files changed, 1119 insertions(+), 1086 deletions(-) diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index b9f150eac..1427cb630 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -1,524 +1,524 @@ [ -["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], +["Format is: [scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], ["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], ["nSequences are max."], -["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation", "EVAL_FALSE"], -[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that.", "EVAL_FALSE"], -[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], -[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], -["", "", "P2SH,STRICTENC","", "EVAL_FALSE"], -["", "NOP", "P2SH,STRICTENC","", "EVAL_FALSE"], -["", "NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP","NOP", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP","NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["", "", "P2SH,STRICTENC","EVAL_FALSE"], +["", "NOP", "P2SH,STRICTENC","EVAL_FALSE"], +["", "NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP","NOP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP","NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], -["DEPTH", "", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["DEPTH", "", "P2SH,STRICTENC", "EVAL_FALSE"], -["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes","BAD_OPCODE"], -["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes","BAD_OPCODE"], -["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes","BAD_OPCODE"], +["0x4c01","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA1 with not enough bytes"], +["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA2 with not enough bytes"], +["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA4 with not enough bytes"], -["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved","BAD_OPCODE"], -["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack","EVAL_FALSE"], -["0","NOP", "P2SH,STRICTENC","","EVAL_FALSE"], -["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional", "BAD_OPCODE"], -["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"], -["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"], -["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"], -["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"], +["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC","BAD_OPCODE", "0x50 is reserved"], +["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC","EVAL_FALSE", "0x51 through 0x60 push 1 through 16 onto stack"], +["0","NOP", "P2SH,STRICTENC","EVAL_FALSE",""], +["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VER non-functional"], +["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], +["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], +["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], -["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"], -["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["0 NOTIF", "123", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1 IF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF/ENDIF can't span scriptSig/scriptPubKey"], +["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["0 NOTIF", "123", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["0", "DUP IF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0", "IF 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "DUP IF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "IF 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs", "OP_RETURN"], -["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"], +["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "OP_RETURN", "Multiple ELSEs"], +["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], -["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence", "UNBALANCED_CONDITIONAL"], -["1", "ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "Malformed IF/ELSE/ENDIF sequence"], +["1", "ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "RETURN", "P2SH,STRICTENC", "", "OP_RETURN"], -["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"], +["1", "RETURN", "P2SH,STRICTENC", "OP_RETURN"], +["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], -["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format", "OP_RETURN"], -["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"], +["1", "RETURN 'data'", "P2SH,STRICTENC", "OP_RETURN", "canonical prunable txout format"], +["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], -["0", "VERIFY 1", "P2SH,STRICTENC", "", "VERIFY"], -["1", "VERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1", "VERIFY 0", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["0", "VERIFY 1", "P2SH,STRICTENC", "VERIFY"], +["1", "VERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "VERIFY 0", "P2SH,STRICTENC", "EVAL_FALSE"], -["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey", "INVALID_ALTSTACK_OPERATION"], +["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION", "alt stack not shared between sig/pubkey"], -["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1 NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1 0 NIP", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "0 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "-1 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["NOP", "0 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "-1 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["NOP", "ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "", "EQUALVERIFY"], -["NOP", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["NOP", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 2", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "2 3 2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 0 NIP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], +["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "-1 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "0 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "-1 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 2", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2 3 2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"], -["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"], -["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"], -["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"], -["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled", "DISABLED_OPCODE"], -["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled", "DISABLED_OPCODE"], +["'a' 'b'", "CAT", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], +["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], +["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], +["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], +["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "LEFT disabled"], +["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "RIGHT disabled"], -["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled", "DISABLED_OPCODE"], -["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled", "DISABLED_OPCODE"], -["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled", "DISABLED_OPCODE"], -["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled", "DISABLED_OPCODE"], -["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled", "DISABLED_OPCODE"], -["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled", "DISABLED_OPCODE"], -["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled", "DISABLED_OPCODE"], -["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled", "DISABLED_OPCODE"], -["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled", "DISABLED_OPCODE"], -["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled", "DISABLED_OPCODE"], -["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled", "DISABLED_OPCODE"], +["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "INVERT disabled"], +["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "AND disabled"], +["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "OR disabled"], +["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "XOR disabled"], +["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2MUL disabled"], +["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2DIV disabled"], +["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MUL disabled"], +["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "DIV disabled"], +["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MOD disabled"], +["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "LSHIFT disabled"], +["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "RSHIFT disabled"], -["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items", "INVALID_STACK_OPERATION"], -["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items", "INVALID_STACK_OPERATION"], -["0 1","EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are no stack items"], +["0", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are not 2 stack items"], +["0 1","EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"], -["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"], -["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range", "UNKNOWN_ERROR"], -["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand", "UNKNOWN_ERROR"], +["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], +["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], +["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NUMEQUAL must be in numeric range"], +["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NOT is an arithmetic operand"], -["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], -["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"], +["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], -["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig", "DISCOURAGE_UPGRADABLE_NOPS"], +["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], ["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", - "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript", "DISCOURAGE_UPGRADABLE_NOPS"], + "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], -["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved", "BAD_OPCODE"], -["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed", "BAD_OPCODE"], -["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], -["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"], +["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], +["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP10 invalid if executed"], +["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately", "UNBALANCED_CONDITIONAL"], +["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "invalid because scriptSig and scriptPubKey are processed separately"], -["NOP", "RIPEMD160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "SHA1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "SHA256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "HASH160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "HASH256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "RIPEMD160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], ["NOP", "'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", "P2SH,STRICTENC", -">520 byte push", -"PUSH_SIZE"], +"PUSH_SIZE", +">520 byte push"], ["0", "IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", "P2SH,STRICTENC", -">520 byte push in non-executed IF branch", -"PUSH_SIZE"], +"PUSH_SIZE", +">520 byte push in non-executed IF branch"], ["1", "0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", -">201 opcodes executed. 0x61 is NOP", -"OP_COUNT"], +"OP_COUNT", +">201 opcodes executed. 0x61 is NOP"], ["0", "IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1", "P2SH,STRICTENC", -">201 opcodes including non-executed IF branch. 0x61 is NOP", -"OP_COUNT"], +"OP_COUNT", +">201 opcodes including non-executed IF branch. 0x61 is NOP"], ["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "P2SH,STRICTENC", -">1,000 stack size (0x6f is 3DUP)", -"STACK_SIZE"], +"STACK_SIZE", +">1,000 stack size (0x6f is 3DUP)"], ["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "P2SH,STRICTENC", -">1,000 stack+altstack size", -"STACK_SIZE"], +"STACK_SIZE", +">1,000 stack+altstack size"], ["NOP", "0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", -"10,001-byte scriptPubKey", -"SCRIPT_SIZE"], +"SCRIPT_SIZE", +"10,001-byte scriptPubKey"], -["NOP1","NOP10", "P2SH,STRICTENC", "", "EVAL_FALSE"], +["NOP1","NOP10", "P2SH,STRICTENC", "EVAL_FALSE"], -["1","VER", "P2SH,STRICTENC", "OP_VER is reserved", "BAD_OPCODE"], -["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved", "BAD_OPCODE"], -["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved", "BAD_OPCODE"], -["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved", "BAD_OPCODE"], -["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved", "BAD_OPCODE"], -["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved", "BAD_OPCODE"], -["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1", "BAD_OPCODE"], +["1","VER", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER is reserved"], +["1","VERIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERIF is reserved"], +["1","VERNOTIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERNOTIF is reserved"], +["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"], +["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"], +["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"], +["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == OP_NOP10 + 1"], -["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"], -["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"], -["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes", "UNKNOWN_ERROR"], -["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"], -["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"], +["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], +["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], +["-2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "Because we use a sign bit, -2147483648 is also 5 bytes"], +["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], +["2147483648", "1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], -["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)", "UNKNOWN_ERROR"], -["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers", "UNKNOWN_ERROR"], +["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"], +["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLAND on 5-byte integers"], -["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF", "UNBALANCED_CONDITIONAL"], -["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF", "UNBALANCED_CONDITIONAL"], -["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over", "UNBALANCED_CONDITIONAL"], +["1", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "ENDIF without IF"], +["1", "IF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF without ENDIF"], +["1 IF 1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IFs don't carry over"], -["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode", "UNBALANCED_CONDITIONAL"], -["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors", "UNBALANCED_CONDITIONAL"], -["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,", "INVALID_STACK_OPERATION"], +["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "The following tests check the if(stack.size() < N) tests in each opcode"], +["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "They are here to catch copy-and-paste errors"], +["NOP", "VERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "Most of them are duplicated elsewhere,"], -["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?", "INVALID_STACK_OPERATION"], -["1", "FROMALTSTACK", "P2SH,STRICTENC", "", "INVALID_ALTSTACK_OPERATION"], -["1", "2DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "2DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1", "3DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1 1", "2OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1 1", "2SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "IFDUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1 1 3", "PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["0", "PICK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1 1 3", "ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["0", "ROLL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1", "ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "TUCK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "but, hey, more is always better, right?"], +["1", "FROMALTSTACK", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION"], +["1", "2DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "3DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1", "2OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1", "2SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "IFDUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 3", "PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0", "PICK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 3", "ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0", "ROLL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "TUCK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "EQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "EQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1ADD 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "1SUB 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "NEGATE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "ABS 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "NOT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "1ADD 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1SUB 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "NEGATE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "ABS 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "NOT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "ADD", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "SUB", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "BOOLAND", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "BOOLOR", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "NUMEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "LESSTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "GREATERTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "MIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1", "MAX", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["1 1", "WITHIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["1", "ADD", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SUB", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "BOOLAND", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "BOOLOR", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "LESSTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "GREATERTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "MIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "MAX", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "WITHIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "SHA1 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "SHA256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "HASH160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], -["NOP", "HASH256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"], +["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA1 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], ["Increase CHECKSIG and CHECKMULTISIG negative test coverage"], -["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items", "INVALID_STACK_OPERATION"], -["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items", "INVALID_STACK_OPERATION"], -["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items", "INVALID_STACK_OPERATION"], -["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative", "PUBKEY_COUNT"], -["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack", "INVALID_STACK_OPERATION"], -["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative", "SIG_COUNT"], -["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack", "INVALID_STACK_OPERATION"], -["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode","EVAL_FALSE"], +["", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are no stack items"], +["0", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are not 2 stack items"], +["", "CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are no stack items"], +["", "-1 CHECKMULTISIG NOT", "STRICTENC", "PUBKEY_COUNT", "CHECKMULTISIG must error when the specified number of pubkeys is negative"], +["", "1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"], +["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "SIG_COUNT", "CHECKMULTISIG must error when the specified number of signatures is negative"], +["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough signatures on the stack"], +["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "EVAL_FALSE", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"], ["", "0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG", "P2SH,STRICTENC", -"202 CHECKMULTISIGS, fails due to 201 op limit", -"OP_COUNT"], +"OP_COUNT", +"202 CHECKMULTISIGS, fails due to 201 op limit"], ["1", "0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY", "P2SH,STRICTENC", -"", -"INVALID_STACK_OPERATION"], +"INVALID_STACK_OPERATION", +""], ["", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", "P2SH,STRICTENC", -"Fails due to 201 sig op limit", -"OP_COUNT"], +"OP_COUNT", +"Fails due to 201 sig op limit"], ["1", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", "P2SH,STRICTENC", -"", -"OP_COUNT"], +"OP_COUNT", +""], -["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20", "PUBKEY_COUNT"], -["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys", "SIG_COUNT"], +["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "PUBKEY_COUNT", "nPubKeys > 20"], +["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "SIG_COUNT", "nSigs > nPubKeys"], -["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()", "SIG_PUSHONLY"], -["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "", "SIG_PUSHONLY"], +["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY", "Tests for Script.IsPushOnly()"], +["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY"], -["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail", "BAD_OPCODE"], -["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail", "BAD_OPCODE"], +["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED in P2SH should fail"], +["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER in P2SH should fail"], -["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution", "EVAL_FALSE"], +["0x00", "'00' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE", "Basic OP_0 execution"], ["MINIMALDATA enforcement for PUSHDATAs"], -["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0", "MINIMALDATA"], -["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE", "MINIMALDATA"], -["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16", "MINIMALDATA"], -["0x01 0x02", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x03", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x04", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x05", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x06", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x07", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x08", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x09", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0a", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0b", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0c", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0d", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0e", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x0f", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], -["0x01 0x10", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"], +["0x4c 0x00", "DROP 1", "MINIMALDATA", "MINIMALDATA", "Empty vector minimally represented by OP_0"], +["0x01 0x81", "DROP 1", "MINIMALDATA", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"], +["0x01 0x01", "DROP 1", "MINIMALDATA", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"], +["0x01 0x02", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x03", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x04", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x05", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x06", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x07", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x08", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x09", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0a", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0b", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0c", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0d", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0e", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0f", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x10", "DROP 1", "MINIMALDATA", "MINIMALDATA"], ["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA1 of 72 bytes minimally represented by direct push", - "MINIMALDATA"], + "MINIMALDATA", + "PUSHDATA1 of 72 bytes minimally represented by direct push"], ["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1", - "MINIMALDATA"], + "MINIMALDATA", + "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"], ["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2", - "MINIMALDATA"], + "MINIMALDATA", + "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"], ["MINIMALDATA enforcement for numeric arguments"], -["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], -["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0", "UNKNOWN_ERROR"], -["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"], -["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"], -["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"], -["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"], -["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"], -["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff", "UNKNOWN_ERROR"], -["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f", "UNKNOWN_ERROR"], -["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff", "UNKNOWN_ERROR"], -["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f", "UNKNOWN_ERROR"], +["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "0x80 (negative zero) numequals 0"], +["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], +["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], +["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], +["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], +["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff"], +["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xff7f"], +["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffffff"], +["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff7f"], ["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"], -["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "UNKNOWN_ERROR"], +["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], ["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"], @@ -528,349 +528,349 @@ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", "STRICTENC", - "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded.", - "PUBKEYTYPE" + "PUBKEYTYPE", + "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." ], [ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", "STRICTENC", - "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid.", - "SIG_DER" + "SIG_DER", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." ], [ "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", "P2SH,STRICTENC", - "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs", - "SIG_DER" + "SIG_DER", + "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" ], ["Increase DERSIG test coverage"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG", "SIG_DER"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG", "SIG_DER"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG", "SIG_DER"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG", "SIG_DER"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG", "SIG_DER"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG", "SIG_DER"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG", "SIG_DER"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG", "SIG_DER"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Overly long signature is incorrectly encoded for DERSIG"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Missing S is incorrectly encoded for DERSIG"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "S with invalid S length is incorrectly encoded for DERSIG"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer R is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer S is incorrectly encoded for DERSIG"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length R is incorrectly encoded for DERSIG"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", - "P2PK, bad sig", - "EVAL_FALSE" + "EVAL_FALSE", + "P2PK, bad sig" ], [ "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", "", - "P2PKH, bad pubkey", - "EQUALVERIFY" + "EQUALVERIFY", + "P2PKH, bad pubkey" ], [ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", - "P2PK anyonecanpay marked with normal hashtype", - "EVAL_FALSE" + "EVAL_FALSE", + "P2PK anyonecanpay marked with normal hashtype" ], [ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", - "P2SH(P2PK), bad redeemscript", - "EVAL_FALSE" + "EVAL_FALSE", + "P2SH(P2PK), bad redeemscript" ], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "P2SH", - "P2SH(P2PKH), bad sig", - "EQUALVERIFY" + "EQUALVERIFY", + "P2SH(P2PKH), bad sig" ], [ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", - "3-of-3, 2 sigs", - "EVAL_FALSE" + "EVAL_FALSE", + "3-of-3, 2 sigs" ], [ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", - "P2SH(2-of-3), 1 sig", - "EVAL_FALSE" + "EVAL_FALSE", + "P2SH(2-of-3), 1 sig" ], [ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too much R padding", - "SIG_DER" + "SIG_DER", + "P2PK with too much R padding" ], [ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too much S padding", - "SIG_DER" + "SIG_DER", + "P2PK with too much S padding" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "P2PK with too little R padding", - "SIG_DER" + "SIG_DER", + "P2PK with too little R padding" ], [ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", - "P2PK NOT with bad sig with too much R padding", - "SIG_DER" + "SIG_DER", + "P2PK NOT with bad sig with too much R padding" ], [ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", - "P2PK NOT with too much R padding but no DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "P2PK NOT with too much R padding but no DERSIG" ], [ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "DERSIG", - "P2PK NOT with too much R padding", - "SIG_DER" + "SIG_DER", + "P2PK NOT with too much R padding" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 1, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 1, with DERSIG" ], [ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", - "BIP66 example 2, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 2, without DERSIG" ], [ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "DERSIG", - "BIP66 example 2, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 2, with DERSIG" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 3, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 3, without DERSIG" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 3, with DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 3, with DERSIG" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 5, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 5, without DERSIG" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "DERSIG", - "BIP66 example 5, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 5, with DERSIG" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "DERSIG", - "BIP66 example 6, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 6, with DERSIG" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 7, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 7, with DERSIG" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", - "BIP66 example 8, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 8, without DERSIG" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", - "BIP66 example 8, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 8, with DERSIG" ], [ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 9, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 9, without DERSIG" ], [ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 9, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 9, with DERSIG" ], [ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", - "BIP66 example 10, with DERSIG", - "SIG_DER" + "SIG_DER", + "BIP66 example 10, with DERSIG" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 11, without DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 11, without DERSIG" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "DERSIG", - "BIP66 example 11, with DERSIG", - "EVAL_FALSE" + "EVAL_FALSE", + "BIP66 example 11, with DERSIG" ], [ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "DERSIG", - "P2PK with multi-byte hashtype, with DERSIG", - "SIG_DER" + "SIG_DER", + "P2PK with multi-byte hashtype, with DERSIG" ], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S", - "P2PK with high S", - "SIG_HIGH_S" + "SIG_HIGH_S", + "P2PK with high S" ], [ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "STRICTENC", - "P2PK with hybrid pubkey", - "PUBKEYTYPE" + "PUBKEYTYPE", + "P2PK with hybrid pubkey" ], [ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", - "P2PK NOT with hybrid pubkey but no STRICTENC", - "EVAL_FALSE" + "EVAL_FALSE", + "P2PK NOT with hybrid pubkey but no STRICTENC" ], [ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", - "P2PK NOT with hybrid pubkey", - "PUBKEYTYPE" + "PUBKEYTYPE", + "P2PK NOT with hybrid pubkey" ], [ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "STRICTENC", - "P2PK NOT with invalid hybrid pubkey", - "PUBKEYTYPE" + "PUBKEYTYPE", + "P2PK NOT with invalid hybrid pubkey" ], [ "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201", "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", "STRICTENC", - "1-of-2 with the first 1 hybrid pubkey", - "PUBKEYTYPE" + "PUBKEYTYPE", + "1-of-2 with the first 1 hybrid pubkey" ], [ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "STRICTENC", - "P2PK with undefined hashtype", - "SIG_HASHTYPE" + "SIG_HASHTYPE", + "P2PK with undefined hashtype" ], [ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", "STRICTENC", - "P2PK NOT with invalid sig and undefined hashtype", - "SIG_HASHTYPE" + "SIG_HASHTYPE", + "P2PK NOT with invalid sig and undefined hashtype" ], [ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "NULLDUMMY", - "3-of-3 with nonzero dummy", - "SIG_NULLDUMMY" + "SIG_NULLDUMMY", + "3-of-3 with nonzero dummy" ], [ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", "NULLDUMMY", - "3-of-3 NOT with invalid sig with nonzero dummy", - "SIG_NULLDUMMY" + "SIG_NULLDUMMY", + "3-of-3 NOT with invalid sig with nonzero dummy" ], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "SIGPUSHONLY", - "2-of-2 with two identical keys and sigs pushed using OP_DUP", - "SIG_PUSHONLY" + "SIG_PUSHONLY", + "2-of-2 with two identical keys and sigs pushed using OP_DUP" ], [ "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "P2SH", - "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", - "SIG_PUSHONLY" + "SIG_PUSHONLY", + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" ], [ "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "SIGPUSHONLY", - "P2SH(P2PK) with non-push scriptSig but not P2SH", - "SIG_PUSHONLY" + "SIG_PUSHONLY", + "P2SH(P2PK) with non-push scriptSig but not P2SH" ], [ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "CLEANSTACK,P2SH", - "P2PK with unnecessary input", - "CLEANSTACK" + "CLEANSTACK", + "P2PK with unnecessary input" ], [ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "CLEANSTACK,P2SH", - "P2SH with unnecessary input", - "CLEANSTACK" + "CLEANSTACK", + "P2SH with unnecessary input" ], ["The End"] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 29ccbd92f..4e86ee78b 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -1,674 +1,674 @@ [ -["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], +["Format is: [scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], ["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], ["nSequences are max."], -["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"], -[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "and multiple spaces should not change that."], -[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "Similarly whitespace around and between symbols"], -["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"], -[" 1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"], -["1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"], -[" 1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"], +["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "Test the test: we should have an empty stack after scriptSig evaluation"], +[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "and multiple spaces should not change that."], +[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK", "Similarly whitespace around and between symbols"], +["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK"], +[" 1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK"], +["1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK"], +[" 1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK"], -["1", "", "P2SH,STRICTENC"], -["0x02 0x01 0x00", "", "P2SH,STRICTENC", "all bytes are significant, not only the last one"], -["0x09 0x00000000 0x00000000 0x10", "", "P2SH,STRICTENC", "equals zero when cast to Int64"], +["1", "", "P2SH,STRICTENC", "OK"], +["0x02 0x01 0x00", "", "P2SH,STRICTENC", "OK", "all bytes are significant, not only the last one"], +["0x09 0x00000000 0x00000000 0x10", "", "P2SH,STRICTENC", "OK", "equals zero when cast to Int64"], -["0x01 0x0b", "11 EQUAL", "P2SH,STRICTENC", "push 1 byte"], -["0x02 0x417a", "'Az' EQUAL", "P2SH,STRICTENC"], +["0x01 0x0b", "11 EQUAL", "P2SH,STRICTENC", "OK", "push 1 byte"], +["0x02 0x417a", "'Az' EQUAL", "P2SH,STRICTENC", "OK"], ["0x4b 0x417a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a", - "'Azzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' EQUAL", "P2SH,STRICTENC", "push 75 bytes"], + "'Azzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' EQUAL", "P2SH,STRICTENC", "OK", "push 75 bytes"], -["0x4c 0x01 0x07","7 EQUAL", "P2SH,STRICTENC", "0x4c is OP_PUSHDATA1"], -["0x4d 0x0100 0x08","8 EQUAL", "P2SH,STRICTENC", "0x4d is OP_PUSHDATA2"], -["0x4e 0x01000000 0x09","9 EQUAL", "P2SH,STRICTENC", "0x4e is OP_PUSHDATA4"], +["0x4c 0x01 0x07","7 EQUAL", "P2SH,STRICTENC", "OK", "0x4c is OP_PUSHDATA1"], +["0x4d 0x0100 0x08","8 EQUAL", "P2SH,STRICTENC", "OK", "0x4d is OP_PUSHDATA2"], +["0x4e 0x01000000 0x09","9 EQUAL", "P2SH,STRICTENC", "OK", "0x4e is OP_PUSHDATA4"], -["0x4c 0x00","0 EQUAL", "P2SH,STRICTENC"], -["0x4d 0x0000","0 EQUAL", "P2SH,STRICTENC"], -["0x4e 0x00000000","0 EQUAL", "P2SH,STRICTENC"], -["0x4f 1000 ADD","999 EQUAL", "P2SH,STRICTENC"], -["0", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved (ok if not executed)"], -["0x51", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack"], -["1","NOP", "P2SH,STRICTENC"], -["0", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional (ok if not executed)"], -["0", "IF RESERVED RESERVED1 RESERVED2 ELSE 1 ENDIF", "P2SH,STRICTENC", "RESERVED ok in un-executed IF"], +["0x4c 0x00","0 EQUAL", "P2SH,STRICTENC", "OK"], +["0x4d 0x0000","0 EQUAL", "P2SH,STRICTENC", "OK"], +["0x4e 0x00000000","0 EQUAL", "P2SH,STRICTENC", "OK"], +["0x4f 1000 ADD","999 EQUAL", "P2SH,STRICTENC", "OK"], +["0", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "OK", "0x50 is reserved (ok if not executed)"], +["0x51", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "OK", "0x51 through 0x60 push 1 through 16 onto stack"], +["1","NOP", "P2SH,STRICTENC", "OK"], +["0", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "VER non-functional (ok if not executed)"], +["0", "IF RESERVED RESERVED1 RESERVED2 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "RESERVED ok in un-executed IF"], -["1", "DUP IF ENDIF", "P2SH,STRICTENC"], -["1", "IF 1 ENDIF", "P2SH,STRICTENC"], -["1", "DUP IF ELSE ENDIF", "P2SH,STRICTENC"], -["1", "IF 1 ELSE ENDIF", "P2SH,STRICTENC"], -["0", "IF ELSE 1 ENDIF", "P2SH,STRICTENC"], +["1", "DUP IF ENDIF", "P2SH,STRICTENC", "OK"], +["1", "IF 1 ENDIF", "P2SH,STRICTENC", "OK"], +["1", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "OK"], +["1", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], -["1 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], +["1 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["1 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["1 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["0 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], -["1 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"], -["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], -["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"], +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "OK"], -["0", "IF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "Multiple ELSE's are valid and executed inverts on each ELSE encountered"], -["1", "IF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC"], -["1", "IF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["1", "IF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"], -["'' 1", "IF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC"], +["0", "IF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "OK", "Multiple ELSE's are valid and executed inverts on each ELSE encountered"], +["1", "IF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC", "OK"], +["1", "IF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["1", "IF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "OK"], +["'' 1", "IF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC", "OK"], -["1", "NOTIF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "Multiple ELSE's are valid and execution inverts on each ELSE encountered"], -["0", "NOTIF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC"], -["0", "NOTIF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "NOTIF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"], -["'' 0", "NOTIF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC"], +["1", "NOTIF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "OK", "Multiple ELSE's are valid and execution inverts on each ELSE encountered"], +["0", "NOTIF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC", "OK"], +["0", "NOTIF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "NOTIF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "OK"], +["'' 0", "NOTIF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC", "OK"], -["0", "IF 1 IF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 1 IF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "Nested ELSE ELSE"], -["1", "NOTIF 0 NOTIF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 0 NOTIF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"], +["0", "IF 1 IF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 1 IF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "OK", "Nested ELSE ELSE"], +["1", "NOTIF 0 NOTIF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 0 NOTIF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "OK"], -["0", "IF RETURN ENDIF 1", "P2SH,STRICTENC", "RETURN only works if executed"], +["0", "IF RETURN ENDIF 1", "P2SH,STRICTENC", "OK", "RETURN only works if executed"], -["1 1", "VERIFY", "P2SH,STRICTENC"], -["1 0x05 0x01 0x00 0x00 0x00 0x00", "VERIFY", "P2SH,STRICTENC", "values >4 bytes can be cast to boolean"], -["1 0x01 0x80", "IF 0 ENDIF", "P2SH,STRICTENC", "negative 0 is false"], +["1 1", "VERIFY", "P2SH,STRICTENC", "OK"], +["1 0x05 0x01 0x00 0x00 0x00 0x00", "VERIFY", "P2SH,STRICTENC", "OK", "values >4 bytes can be cast to boolean"], +["1 0x01 0x80", "IF 0 ENDIF", "P2SH,STRICTENC", "OK", "negative 0 is false"], -["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL", "P2SH,STRICTENC"], -["'gavin_was_here' TOALTSTACK 11 FROMALTSTACK", "'gavin_was_here' EQUALVERIFY 11 EQUAL", "P2SH,STRICTENC"], +["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL", "P2SH,STRICTENC", "OK"], +["'gavin_was_here' TOALTSTACK 11 FROMALTSTACK", "'gavin_was_here' EQUALVERIFY 11 EQUAL", "P2SH,STRICTENC", "OK"], -["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"], -["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"], -["0x05 0x0100000000 IFDUP", "DEPTH 2 EQUALVERIFY 0x05 0x0100000000 EQUAL", "P2SH,STRICTENC", "IFDUP dups non ints"], -["0 DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"], -["0 1", "NIP", "P2SH,STRICTENC"], -["1 0", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC"], -["22 21 20", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "ROT 22 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "ROT DROP 20 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "ROT DROP DROP 21 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "ROT ROT 21 EQUAL", "P2SH,STRICTENC"], -["22 21 20", "ROT ROT ROT 20 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 24 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT DROP 25 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2DROP 20 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2DROP DROP 21 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2DROP 2DROP 22 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2DROP 2DROP DROP 23 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2ROT 22 EQUAL", "P2SH,STRICTENC"], -["25 24 23 22 21 20", "2ROT 2ROT 2ROT 20 EQUAL", "P2SH,STRICTENC"], -["1 0", "SWAP 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"], -["0 1", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC"], -["13 14", "2DUP ROT EQUALVERIFY EQUAL", "P2SH,STRICTENC"], -["-1 0 1 2", "3DUP DEPTH 7 EQUALVERIFY ADD ADD 3 EQUALVERIFY 2DROP 0 EQUALVERIFY", "P2SH,STRICTENC"], -["1 2 3 5", "2OVER ADD ADD 8 EQUALVERIFY ADD ADD 6 EQUAL", "P2SH,STRICTENC"], -["1 3 5 7", "2SWAP ADD 4 EQUALVERIFY ADD 12 EQUAL", "P2SH,STRICTENC"], -["0", "SIZE 0 EQUAL", "P2SH,STRICTENC"], -["1", "SIZE 1 EQUAL", "P2SH,STRICTENC"], -["127", "SIZE 1 EQUAL", "P2SH,STRICTENC"], -["128", "SIZE 2 EQUAL", "P2SH,STRICTENC"], -["32767", "SIZE 2 EQUAL", "P2SH,STRICTENC"], -["32768", "SIZE 3 EQUAL", "P2SH,STRICTENC"], -["8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC"], -["8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC"], -["2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC"], -["2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC"], -["549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC"], -["549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC"], -["9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC"], -["-1", "SIZE 1 EQUAL", "P2SH,STRICTENC"], -["-127", "SIZE 1 EQUAL", "P2SH,STRICTENC"], -["-128", "SIZE 2 EQUAL", "P2SH,STRICTENC"], -["-32767", "SIZE 2 EQUAL", "P2SH,STRICTENC"], -["-32768", "SIZE 3 EQUAL", "P2SH,STRICTENC"], -["-8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC"], -["-8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC"], -["-2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC"], -["-2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC"], -["-549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC"], -["-549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC"], -["-9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL", "P2SH,STRICTENC"], +["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "OK"], +["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "OK"], +["0x05 0x0100000000 IFDUP", "DEPTH 2 EQUALVERIFY 0x05 0x0100000000 EQUAL", "P2SH,STRICTENC", "OK", "IFDUP dups non ints"], +["0 DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "OK"], +["0 1", "NIP", "P2SH,STRICTENC", "OK"], +["1 0", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "OK"], +["22 21 20", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "ROT 22 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "ROT DROP 20 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "ROT DROP DROP 21 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "ROT ROT 21 EQUAL", "P2SH,STRICTENC", "OK"], +["22 21 20", "ROT ROT ROT 20 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 24 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT DROP 25 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2DROP 20 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2DROP DROP 21 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2DROP 2DROP 22 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2DROP 2DROP DROP 23 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2ROT 22 EQUAL", "P2SH,STRICTENC", "OK"], +["25 24 23 22 21 20", "2ROT 2ROT 2ROT 20 EQUAL", "P2SH,STRICTENC", "OK"], +["1 0", "SWAP 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "OK"], +["0 1", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "OK"], +["13 14", "2DUP ROT EQUALVERIFY EQUAL", "P2SH,STRICTENC", "OK"], +["-1 0 1 2", "3DUP DEPTH 7 EQUALVERIFY ADD ADD 3 EQUALVERIFY 2DROP 0 EQUALVERIFY", "P2SH,STRICTENC", "OK"], +["1 2 3 5", "2OVER ADD ADD 8 EQUALVERIFY ADD ADD 6 EQUAL", "P2SH,STRICTENC", "OK"], +["1 3 5 7", "2SWAP ADD 4 EQUALVERIFY ADD 12 EQUAL", "P2SH,STRICTENC", "OK"], +["0", "SIZE 0 EQUAL", "P2SH,STRICTENC", "OK"], +["1", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], +["127", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], +["128", "SIZE 2 EQUAL", "P2SH,STRICTENC", "OK"], +["32767", "SIZE 2 EQUAL", "P2SH,STRICTENC", "OK"], +["32768", "SIZE 3 EQUAL", "P2SH,STRICTENC", "OK"], +["8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC", "OK"], +["8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], +["2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], +["2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], +["9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], +["-1", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], +["-127", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], +["-128", "SIZE 2 EQUAL", "P2SH,STRICTENC", "OK"], +["-32767", "SIZE 2 EQUAL", "P2SH,STRICTENC", "OK"], +["-32768", "SIZE 3 EQUAL", "P2SH,STRICTENC", "OK"], +["-8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC", "OK"], +["-8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], +["-2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], +["-2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["-549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["-549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], +["-9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL", "P2SH,STRICTENC", "OK"], -["42", "SIZE 1 EQUALVERIFY 42 EQUAL", "P2SH,STRICTENC", "SIZE does not consume argument"], +["42", "SIZE 1 EQUALVERIFY 42 EQUAL", "P2SH,STRICTENC", "OK", "SIZE does not consume argument"], -["2 -2 ADD", "0 EQUAL", "P2SH,STRICTENC"], -["2147483647 -2147483647 ADD", "0 EQUAL", "P2SH,STRICTENC"], -["-1 -1 ADD", "-2 EQUAL", "P2SH,STRICTENC"], +["2 -2 ADD", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["2147483647 -2147483647 ADD", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["-1 -1 ADD", "-2 EQUAL", "P2SH,STRICTENC", "OK"], -["0 0","EQUAL", "P2SH,STRICTENC"], -["1 1 ADD", "2 EQUAL", "P2SH,STRICTENC"], -["1 1ADD", "2 EQUAL", "P2SH,STRICTENC"], -["111 1SUB", "110 EQUAL", "P2SH,STRICTENC"], -["111 1 ADD 12 SUB", "100 EQUAL", "P2SH,STRICTENC"], -["0 ABS", "0 EQUAL", "P2SH,STRICTENC"], -["16 ABS", "16 EQUAL", "P2SH,STRICTENC"], -["-16 ABS", "-16 NEGATE EQUAL", "P2SH,STRICTENC"], -["0 NOT", "NOP", "P2SH,STRICTENC"], -["1 NOT", "0 EQUAL", "P2SH,STRICTENC"], -["11 NOT", "0 EQUAL", "P2SH,STRICTENC"], -["0 0NOTEQUAL", "0 EQUAL", "P2SH,STRICTENC"], -["1 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"], -["111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"], -["-111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"], -["1 1 BOOLAND", "NOP", "P2SH,STRICTENC"], -["1 0 BOOLAND", "NOT", "P2SH,STRICTENC"], -["0 1 BOOLAND", "NOT", "P2SH,STRICTENC"], -["0 0 BOOLAND", "NOT", "P2SH,STRICTENC"], -["16 17 BOOLAND", "NOP", "P2SH,STRICTENC"], -["1 1 BOOLOR", "NOP", "P2SH,STRICTENC"], -["1 0 BOOLOR", "NOP", "P2SH,STRICTENC"], -["0 1 BOOLOR", "NOP", "P2SH,STRICTENC"], -["0 0 BOOLOR", "NOT", "P2SH,STRICTENC"], -["16 17 BOOLOR", "NOP", "P2SH,STRICTENC"], -["11 10 1 ADD", "NUMEQUAL", "P2SH,STRICTENC"], -["11 10 1 ADD", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"], -["11 10 1 ADD", "NUMNOTEQUAL NOT", "P2SH,STRICTENC"], -["111 10 1 ADD", "NUMNOTEQUAL", "P2SH,STRICTENC"], -["11 10", "LESSTHAN NOT", "P2SH,STRICTENC"], -["4 4", "LESSTHAN NOT", "P2SH,STRICTENC"], -["10 11", "LESSTHAN", "P2SH,STRICTENC"], -["-11 11", "LESSTHAN", "P2SH,STRICTENC"], -["-11 -10", "LESSTHAN", "P2SH,STRICTENC"], -["11 10", "GREATERTHAN", "P2SH,STRICTENC"], -["4 4", "GREATERTHAN NOT", "P2SH,STRICTENC"], -["10 11", "GREATERTHAN NOT", "P2SH,STRICTENC"], -["-11 11", "GREATERTHAN NOT", "P2SH,STRICTENC"], -["-11 -10", "GREATERTHAN NOT", "P2SH,STRICTENC"], -["11 10", "LESSTHANOREQUAL NOT", "P2SH,STRICTENC"], -["4 4", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["10 11", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["-11 11", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["-11 -10", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["11 10", "GREATERTHANOREQUAL", "P2SH,STRICTENC"], -["4 4", "GREATERTHANOREQUAL", "P2SH,STRICTENC"], -["10 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"], -["-11 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"], -["-11 -10", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"], -["1 0 MIN", "0 NUMEQUAL", "P2SH,STRICTENC"], -["0 1 MIN", "0 NUMEQUAL", "P2SH,STRICTENC"], -["-1 0 MIN", "-1 NUMEQUAL", "P2SH,STRICTENC"], -["0 -2147483647 MIN", "-2147483647 NUMEQUAL", "P2SH,STRICTENC"], -["2147483647 0 MAX", "2147483647 NUMEQUAL", "P2SH,STRICTENC"], -["0 100 MAX", "100 NUMEQUAL", "P2SH,STRICTENC"], -["-100 0 MAX", "0 NUMEQUAL", "P2SH,STRICTENC"], -["0 -2147483647 MAX", "0 NUMEQUAL", "P2SH,STRICTENC"], -["0 0 1", "WITHIN", "P2SH,STRICTENC"], -["1 0 1", "WITHIN NOT", "P2SH,STRICTENC"], -["0 -2147483647 2147483647", "WITHIN", "P2SH,STRICTENC"], -["-1 -100 100", "WITHIN", "P2SH,STRICTENC"], -["11 -100 100", "WITHIN", "P2SH,STRICTENC"], -["-2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC"], -["2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC"], +["0 0","EQUAL", "P2SH,STRICTENC", "OK"], +["1 1 ADD", "2 EQUAL", "P2SH,STRICTENC", "OK"], +["1 1ADD", "2 EQUAL", "P2SH,STRICTENC", "OK"], +["111 1SUB", "110 EQUAL", "P2SH,STRICTENC", "OK"], +["111 1 ADD 12 SUB", "100 EQUAL", "P2SH,STRICTENC", "OK"], +["0 ABS", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["16 ABS", "16 EQUAL", "P2SH,STRICTENC", "OK"], +["-16 ABS", "-16 NEGATE EQUAL", "P2SH,STRICTENC", "OK"], +["0 NOT", "NOP", "P2SH,STRICTENC", "OK"], +["1 NOT", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["11 NOT", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["0 0NOTEQUAL", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["1 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC", "OK"], +["111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC", "OK"], +["-111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC", "OK"], +["1 1 BOOLAND", "NOP", "P2SH,STRICTENC", "OK"], +["1 0 BOOLAND", "NOT", "P2SH,STRICTENC", "OK"], +["0 1 BOOLAND", "NOT", "P2SH,STRICTENC", "OK"], +["0 0 BOOLAND", "NOT", "P2SH,STRICTENC", "OK"], +["16 17 BOOLAND", "NOP", "P2SH,STRICTENC", "OK"], +["1 1 BOOLOR", "NOP", "P2SH,STRICTENC", "OK"], +["1 0 BOOLOR", "NOP", "P2SH,STRICTENC", "OK"], +["0 1 BOOLOR", "NOP", "P2SH,STRICTENC", "OK"], +["0 0 BOOLOR", "NOT", "P2SH,STRICTENC", "OK"], +["16 17 BOOLOR", "NOP", "P2SH,STRICTENC", "OK"], +["11 10 1 ADD", "NUMEQUAL", "P2SH,STRICTENC", "OK"], +["11 10 1 ADD", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "OK"], +["11 10 1 ADD", "NUMNOTEQUAL NOT", "P2SH,STRICTENC", "OK"], +["111 10 1 ADD", "NUMNOTEQUAL", "P2SH,STRICTENC", "OK"], +["11 10", "LESSTHAN NOT", "P2SH,STRICTENC", "OK"], +["4 4", "LESSTHAN NOT", "P2SH,STRICTENC", "OK"], +["10 11", "LESSTHAN", "P2SH,STRICTENC", "OK"], +["-11 11", "LESSTHAN", "P2SH,STRICTENC", "OK"], +["-11 -10", "LESSTHAN", "P2SH,STRICTENC", "OK"], +["11 10", "GREATERTHAN", "P2SH,STRICTENC", "OK"], +["4 4", "GREATERTHAN NOT", "P2SH,STRICTENC", "OK"], +["10 11", "GREATERTHAN NOT", "P2SH,STRICTENC", "OK"], +["-11 11", "GREATERTHAN NOT", "P2SH,STRICTENC", "OK"], +["-11 -10", "GREATERTHAN NOT", "P2SH,STRICTENC", "OK"], +["11 10", "LESSTHANOREQUAL NOT", "P2SH,STRICTENC", "OK"], +["4 4", "LESSTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["10 11", "LESSTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["-11 11", "LESSTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["-11 -10", "LESSTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["11 10", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["4 4", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["10 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC", "OK"], +["-11 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC", "OK"], +["-11 -10", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC", "OK"], +["1 0 MIN", "0 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 1 MIN", "0 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["-1 0 MIN", "-1 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 -2147483647 MIN", "-2147483647 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["2147483647 0 MAX", "2147483647 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 100 MAX", "100 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["-100 0 MAX", "0 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 -2147483647 MAX", "0 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 0 1", "WITHIN", "P2SH,STRICTENC", "OK"], +["1 0 1", "WITHIN NOT", "P2SH,STRICTENC", "OK"], +["0 -2147483647 2147483647", "WITHIN", "P2SH,STRICTENC", "OK"], +["-1 -100 100", "WITHIN", "P2SH,STRICTENC", "OK"], +["11 -100 100", "WITHIN", "P2SH,STRICTENC", "OK"], +["-2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC", "OK"], +["2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC", "OK"], -["2147483647 2147483647 SUB", "0 EQUAL", "P2SH,STRICTENC"], -["2147483647 DUP ADD", "4294967294 EQUAL", "P2SH,STRICTENC", ">32 bit EQUAL is valid"], -["2147483647 NEGATE DUP ADD", "-4294967294 EQUAL", "P2SH,STRICTENC"], +["2147483647 2147483647 SUB", "0 EQUAL", "P2SH,STRICTENC", "OK"], +["2147483647 DUP ADD", "4294967294 EQUAL", "P2SH,STRICTENC", "OK", ">32 bit EQUAL is valid"], +["2147483647 NEGATE DUP ADD", "-4294967294 EQUAL", "P2SH,STRICTENC", "OK"], -["''", "RIPEMD160 0x14 0x9c1185a5c5e9fc54612808977ee8f548b2258d31 EQUAL", "P2SH,STRICTENC"], -["'a'", "RIPEMD160 0x14 0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "RIPEMD160 0x14 0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc EQUAL", "P2SH,STRICTENC"], -["''", "SHA1 0x14 0xda39a3ee5e6b4b0d3255bfef95601890afd80709 EQUAL", "P2SH,STRICTENC"], -["'a'", "SHA1 0x14 0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "SHA1 0x14 0x32d10c7b8cf96570ca04ce37f2a19d84240d3a89 EQUAL", "P2SH,STRICTENC"], -["''", "SHA256 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EQUAL", "P2SH,STRICTENC"], -["'a'", "SHA256 0x20 0xca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "SHA256 0x20 0x71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 EQUAL", "P2SH,STRICTENC"], -["''", "DUP HASH160 SWAP SHA256 RIPEMD160 EQUAL", "P2SH,STRICTENC"], -["''", "DUP HASH256 SWAP SHA256 SHA256 EQUAL", "P2SH,STRICTENC"], -["''", "NOP HASH160 0x14 0xb472a266d0bd89c13706a4132ccfb16f7c3b9fcb EQUAL", "P2SH,STRICTENC"], -["'a'", "HASH160 NOP 0x14 0x994355199e516ff76c4fa4aab39337b9d84cf12b EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "HASH160 0x4c 0x14 0xc286a1af0947f58d1ad787385b1c2c4a976f9e71 EQUAL", "P2SH,STRICTENC"], -["''", "HASH256 0x20 0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456 EQUAL", "P2SH,STRICTENC"], -["'a'", "HASH256 0x20 0xbf5d3affb73efd2ec6c36ad3112dd933efed63c4e1cbffcfa88e2759c144f2d8 EQUAL", "P2SH,STRICTENC"], -["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"], +["''", "RIPEMD160 0x14 0x9c1185a5c5e9fc54612808977ee8f548b2258d31 EQUAL", "P2SH,STRICTENC", "OK"], +["'a'", "RIPEMD160 0x14 0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "RIPEMD160 0x14 0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc EQUAL", "P2SH,STRICTENC", "OK"], +["''", "SHA1 0x14 0xda39a3ee5e6b4b0d3255bfef95601890afd80709 EQUAL", "P2SH,STRICTENC", "OK"], +["'a'", "SHA1 0x14 0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA1 0x14 0x32d10c7b8cf96570ca04ce37f2a19d84240d3a89 EQUAL", "P2SH,STRICTENC", "OK"], +["''", "SHA256 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EQUAL", "P2SH,STRICTENC", "OK"], +["'a'", "SHA256 0x20 0xca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA256 0x20 0x71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 EQUAL", "P2SH,STRICTENC", "OK"], +["''", "DUP HASH160 SWAP SHA256 RIPEMD160 EQUAL", "P2SH,STRICTENC", "OK"], +["''", "DUP HASH256 SWAP SHA256 SHA256 EQUAL", "P2SH,STRICTENC", "OK"], +["''", "NOP HASH160 0x14 0xb472a266d0bd89c13706a4132ccfb16f7c3b9fcb EQUAL", "P2SH,STRICTENC", "OK"], +["'a'", "HASH160 NOP 0x14 0x994355199e516ff76c4fa4aab39337b9d84cf12b EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH160 0x4c 0x14 0xc286a1af0947f58d1ad787385b1c2c4a976f9e71 EQUAL", "P2SH,STRICTENC", "OK"], +["''", "HASH256 0x20 0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456 EQUAL", "P2SH,STRICTENC", "OK"], +["'a'", "HASH256 0x20 0xbf5d3affb73efd2ec6c36ad3112dd933efed63c4e1cbffcfa88e2759c144f2d8 EQUAL", "P2SH,STRICTENC", "OK"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], -["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], +["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], -["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", +["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discouraged NOPs are allowed if not executed"], -["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], -["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC"], -["0", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC"], +["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["NOP", "'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "520 byte push"], ["1", "0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "201 opcodes executed. 0x61 is NOP"], ["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "1,000 stack size (0x6f is 3DUP)"], ["1 TOALTSTACK 2 TOALTSTACK 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "1 2 3 4 5 6 7 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "1,000 stack size (altstack cleared between scriptSig/scriptPubKey)"], ["'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", "'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "Max-size (10,000-byte), max-push(520 bytes), max-opcodes(201), max stack size(1,000 items). 0x6f is 3DUP, 0x61 is NOP"], ["0", "IF 0x5050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050 ENDIF 1", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", ">201 opcodes, but RESERVED (0x50) doesn't count towards opcode limit."], -["NOP","1", "P2SH,STRICTENC"], +["NOP","1", "P2SH,STRICTENC", "OK"], -["1", "0x01 0x01 EQUAL", "P2SH,STRICTENC", "The following is useful for checking implementations of BN_bn2mpi"], -["127", "0x01 0x7F EQUAL", "P2SH,STRICTENC"], -["128", "0x02 0x8000 EQUAL", "P2SH,STRICTENC", "Leave room for the sign bit"], -["32767", "0x02 0xFF7F EQUAL", "P2SH,STRICTENC"], -["32768", "0x03 0x008000 EQUAL", "P2SH,STRICTENC"], -["8388607", "0x03 0xFFFF7F EQUAL", "P2SH,STRICTENC"], -["8388608", "0x04 0x00008000 EQUAL", "P2SH,STRICTENC"], -["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC"], -["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC"], -["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC"], -["549755813888", "0x06 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC"], -["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC"], -["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "Numbers are little-endian with the MSB being a sign bit"], -["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC"], -["-128", "0x02 0x8080 EQUAL", "P2SH,STRICTENC"], -["-32767", "0x02 0xFFFF EQUAL", "P2SH,STRICTENC"], -["-32768", "0x03 0x008080 EQUAL", "P2SH,STRICTENC"], -["-8388607", "0x03 0xFFFFFF EQUAL", "P2SH,STRICTENC"], -["-8388608", "0x04 0x00008080 EQUAL", "P2SH,STRICTENC"], -["-2147483647", "0x04 0xFFFFFFFF EQUAL", "P2SH,STRICTENC"], -["-2147483648", "0x05 0x0000008080 EQUAL", "P2SH,STRICTENC"], -["-4294967295", "0x05 0xFFFFFFFF80 EQUAL", "P2SH,STRICTENC"], -["-549755813887", "0x05 0xFFFFFFFFFF EQUAL", "P2SH,STRICTENC"], -["-549755813888", "0x06 0x000000008080 EQUAL", "P2SH,STRICTENC"], -["-9223372036854775807", "0x08 0xFFFFFFFFFFFFFFFF EQUAL", "P2SH,STRICTENC"], +["1", "0x01 0x01 EQUAL", "P2SH,STRICTENC", "OK", "The following is useful for checking implementations of BN_bn2mpi"], +["127", "0x01 0x7F EQUAL", "P2SH,STRICTENC", "OK"], +["128", "0x02 0x8000 EQUAL", "P2SH,STRICTENC", "OK", "Leave room for the sign bit"], +["32767", "0x02 0xFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["32768", "0x03 0x008000 EQUAL", "P2SH,STRICTENC", "OK"], +["8388607", "0x03 0xFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["8388608", "0x04 0x00008000 EQUAL", "P2SH,STRICTENC", "OK"], +["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC", "OK"], +["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["549755813888", "0x06 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "OK", "Numbers are little-endian with the MSB being a sign bit"], +["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC", "OK"], +["-128", "0x02 0x8080 EQUAL", "P2SH,STRICTENC", "OK"], +["-32767", "0x02 0xFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["-32768", "0x03 0x008080 EQUAL", "P2SH,STRICTENC", "OK"], +["-8388607", "0x03 0xFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["-8388608", "0x04 0x00008080 EQUAL", "P2SH,STRICTENC", "OK"], +["-2147483647", "0x04 0xFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["-2147483648", "0x05 0x0000008080 EQUAL", "P2SH,STRICTENC", "OK"], +["-4294967295", "0x05 0xFFFFFFFF80 EQUAL", "P2SH,STRICTENC", "OK"], +["-549755813887", "0x05 0xFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["-549755813888", "0x06 0x000000008080 EQUAL", "P2SH,STRICTENC", "OK"], +["-9223372036854775807", "0x08 0xFFFFFFFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], -["2147483647", "1ADD 2147483648 EQUAL", "P2SH,STRICTENC", "We can do math on 4-byte integers, and compare 5-byte ones"], -["2147483647", "1ADD 1", "P2SH,STRICTENC"], -["-2147483647", "1ADD 1", "P2SH,STRICTENC"], +["2147483647", "1ADD 2147483648 EQUAL", "P2SH,STRICTENC", "OK", "We can do math on 4-byte integers, and compare 5-byte ones"], +["2147483647", "1ADD 1", "P2SH,STRICTENC", "OK"], +["-2147483647", "1ADD 1", "P2SH,STRICTENC", "OK"], -["1", "0x02 0x0100 EQUAL NOT", "P2SH,STRICTENC", "Not the same byte array..."], -["1", "0x02 0x0100 NUMEQUAL", "P2SH,STRICTENC", "... but they are numerically equal"], -["11", "0x4c 0x03 0x0b0000 NUMEQUAL", "P2SH,STRICTENC"], -["0", "0x01 0x80 EQUAL NOT", "P2SH,STRICTENC"], -["0", "0x01 0x80 NUMEQUAL", "P2SH,STRICTENC", "Zero numerically equals negative zero"], -["0", "0x02 0x0080 NUMEQUAL", "P2SH,STRICTENC"], -["0x03 0x000080", "0x04 0x00000080 NUMEQUAL", "P2SH,STRICTENC"], -["0x03 0x100080", "0x04 0x10000080 NUMEQUAL", "P2SH,STRICTENC"], -["0x03 0x100000", "0x04 0x10000000 NUMEQUAL", "P2SH,STRICTENC"], +["1", "0x02 0x0100 EQUAL NOT", "P2SH,STRICTENC", "OK", "Not the same byte array..."], +["1", "0x02 0x0100 NUMEQUAL", "P2SH,STRICTENC", "OK", "... but they are numerically equal"], +["11", "0x4c 0x03 0x0b0000 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0", "0x01 0x80 EQUAL NOT", "P2SH,STRICTENC", "OK"], +["0", "0x01 0x80 NUMEQUAL", "P2SH,STRICTENC", "OK", "Zero numerically equals negative zero"], +["0", "0x02 0x0080 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0x03 0x000080", "0x04 0x00000080 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0x03 0x100080", "0x04 0x10000080 NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0x03 0x100000", "0x04 0x10000000 NUMEQUAL", "P2SH,STRICTENC", "OK"], -["NOP", "NOP 1", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode"], -["1", "IF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors"], -["0", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,"], -["1", "VERIFY 1", "P2SH,STRICTENC", "but, hey, more is always better, right?"], +["NOP", "NOP 1", "P2SH,STRICTENC", "OK", "The following tests check the if(stack.size() < N) tests in each opcode"], +["1", "IF 1 ENDIF", "P2SH,STRICTENC", "OK", "They are here to catch copy-and-paste errors"], +["0", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "OK", "Most of them are duplicated elsewhere,"], +["1", "VERIFY 1", "P2SH,STRICTENC", "OK", "but, hey, more is always better, right?"], -["0", "TOALTSTACK 1", "P2SH,STRICTENC"], -["1", "TOALTSTACK FROMALTSTACK", "P2SH,STRICTENC"], -["0 0", "2DROP 1", "P2SH,STRICTENC"], -["0 1", "2DUP", "P2SH,STRICTENC"], -["0 0 1", "3DUP", "P2SH,STRICTENC"], -["0 1 0 0", "2OVER", "P2SH,STRICTENC"], -["0 1 0 0 0 0", "2ROT", "P2SH,STRICTENC"], -["0 1 0 0", "2SWAP", "P2SH,STRICTENC"], -["1", "IFDUP", "P2SH,STRICTENC"], -["NOP", "DEPTH 1", "P2SH,STRICTENC"], -["0", "DROP 1", "P2SH,STRICTENC"], -["1", "DUP", "P2SH,STRICTENC"], -["0 1", "NIP", "P2SH,STRICTENC"], -["1 0", "OVER", "P2SH,STRICTENC"], -["1 0 0 0 3", "PICK", "P2SH,STRICTENC"], -["1 0", "PICK", "P2SH,STRICTENC"], -["1 0 0 0 3", "ROLL", "P2SH,STRICTENC"], -["1 0", "ROLL", "P2SH,STRICTENC"], -["1 0 0", "ROT", "P2SH,STRICTENC"], -["1 0", "SWAP", "P2SH,STRICTENC"], -["0 1", "TUCK", "P2SH,STRICTENC"], +["0", "TOALTSTACK 1", "P2SH,STRICTENC", "OK"], +["1", "TOALTSTACK FROMALTSTACK", "P2SH,STRICTENC", "OK"], +["0 0", "2DROP 1", "P2SH,STRICTENC", "OK"], +["0 1", "2DUP", "P2SH,STRICTENC", "OK"], +["0 0 1", "3DUP", "P2SH,STRICTENC", "OK"], +["0 1 0 0", "2OVER", "P2SH,STRICTENC", "OK"], +["0 1 0 0 0 0", "2ROT", "P2SH,STRICTENC", "OK"], +["0 1 0 0", "2SWAP", "P2SH,STRICTENC", "OK"], +["1", "IFDUP", "P2SH,STRICTENC", "OK"], +["NOP", "DEPTH 1", "P2SH,STRICTENC", "OK"], +["0", "DROP 1", "P2SH,STRICTENC", "OK"], +["1", "DUP", "P2SH,STRICTENC", "OK"], +["0 1", "NIP", "P2SH,STRICTENC", "OK"], +["1 0", "OVER", "P2SH,STRICTENC", "OK"], +["1 0 0 0 3", "PICK", "P2SH,STRICTENC", "OK"], +["1 0", "PICK", "P2SH,STRICTENC", "OK"], +["1 0 0 0 3", "ROLL", "P2SH,STRICTENC", "OK"], +["1 0", "ROLL", "P2SH,STRICTENC", "OK"], +["1 0 0", "ROT", "P2SH,STRICTENC", "OK"], +["1 0", "SWAP", "P2SH,STRICTENC", "OK"], +["0 1", "TUCK", "P2SH,STRICTENC", "OK"], -["1", "SIZE", "P2SH,STRICTENC"], +["1", "SIZE", "P2SH,STRICTENC", "OK"], -["0 0", "EQUAL", "P2SH,STRICTENC"], -["0 0", "EQUALVERIFY 1", "P2SH,STRICTENC"], -["0 0 1", "EQUAL EQUAL", "P2SH,STRICTENC", "OP_0 and bools must have identical byte representations"], +["0 0", "EQUAL", "P2SH,STRICTENC", "OK"], +["0 0", "EQUALVERIFY 1", "P2SH,STRICTENC", "OK"], +["0 0 1", "EQUAL EQUAL", "P2SH,STRICTENC", "OK", "OP_0 and bools must have identical byte representations"], -["0", "1ADD", "P2SH,STRICTENC"], -["2", "1SUB", "P2SH,STRICTENC"], -["-1", "NEGATE", "P2SH,STRICTENC"], -["-1", "ABS", "P2SH,STRICTENC"], -["0", "NOT", "P2SH,STRICTENC"], -["-1", "0NOTEQUAL", "P2SH,STRICTENC"], +["0", "1ADD", "P2SH,STRICTENC", "OK"], +["2", "1SUB", "P2SH,STRICTENC", "OK"], +["-1", "NEGATE", "P2SH,STRICTENC", "OK"], +["-1", "ABS", "P2SH,STRICTENC", "OK"], +["0", "NOT", "P2SH,STRICTENC", "OK"], +["-1", "0NOTEQUAL", "P2SH,STRICTENC", "OK"], -["1 0", "ADD", "P2SH,STRICTENC"], -["1 0", "SUB", "P2SH,STRICTENC"], -["-1 -1", "BOOLAND", "P2SH,STRICTENC"], -["-1 0", "BOOLOR", "P2SH,STRICTENC"], -["0 0", "NUMEQUAL", "P2SH,STRICTENC"], -["0 0", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"], -["-1 0", "NUMNOTEQUAL", "P2SH,STRICTENC"], -["-1 0", "LESSTHAN", "P2SH,STRICTENC"], -["1 0", "GREATERTHAN", "P2SH,STRICTENC"], -["0 0", "LESSTHANOREQUAL", "P2SH,STRICTENC"], -["0 0", "GREATERTHANOREQUAL", "P2SH,STRICTENC"], -["-1 0", "MIN", "P2SH,STRICTENC"], -["1 0", "MAX", "P2SH,STRICTENC"], -["-1 -1 0", "WITHIN", "P2SH,STRICTENC"], +["1 0", "ADD", "P2SH,STRICTENC", "OK"], +["1 0", "SUB", "P2SH,STRICTENC", "OK"], +["-1 -1", "BOOLAND", "P2SH,STRICTENC", "OK"], +["-1 0", "BOOLOR", "P2SH,STRICTENC", "OK"], +["0 0", "NUMEQUAL", "P2SH,STRICTENC", "OK"], +["0 0", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "OK"], +["-1 0", "NUMNOTEQUAL", "P2SH,STRICTENC", "OK"], +["-1 0", "LESSTHAN", "P2SH,STRICTENC", "OK"], +["1 0", "GREATERTHAN", "P2SH,STRICTENC", "OK"], +["0 0", "LESSTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["0 0", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "OK"], +["-1 0", "MIN", "P2SH,STRICTENC", "OK"], +["1 0", "MAX", "P2SH,STRICTENC", "OK"], +["-1 -1 0", "WITHIN", "P2SH,STRICTENC", "OK"], -["0", "RIPEMD160", "P2SH,STRICTENC"], -["0", "SHA1", "P2SH,STRICTENC"], -["0", "SHA256", "P2SH,STRICTENC"], -["0", "HASH160", "P2SH,STRICTENC"], -["0", "HASH256", "P2SH,STRICTENC"], -["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"], +["0", "RIPEMD160", "P2SH,STRICTENC", "OK"], +["0", "SHA1", "P2SH,STRICTENC", "OK"], +["0", "SHA256", "P2SH,STRICTENC", "OK"], +["0", "HASH160", "P2SH,STRICTENC", "OK"], +["0", "HASH256", "P2SH,STRICTENC", "OK"], +["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP1 1", "P2SH,STRICTENC"], -["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"], -["NOP", "NOP3 1", "P2SH,STRICTENC"], -["NOP", "NOP4 1", "P2SH,STRICTENC"], -["NOP", "NOP5 1", "P2SH,STRICTENC"], -["NOP", "NOP6 1", "P2SH,STRICTENC"], -["NOP", "NOP7 1", "P2SH,STRICTENC"], -["NOP", "NOP8 1", "P2SH,STRICTENC"], -["NOP", "NOP9 1", "P2SH,STRICTENC"], -["NOP", "NOP10 1", "P2SH,STRICTENC"], +["NOP", "NOP1 1", "P2SH,STRICTENC", "OK"], +["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP3 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP7 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP8 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP9 1", "P2SH,STRICTENC", "OK"], +["NOP", "NOP10 1", "P2SH,STRICTENC", "OK"], -["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "CHECKMULTISIG is allowed to have zero keys and/or sigs"], -["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Zero sigs means no sigs are checked"], -["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], +["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "CHECKMULTISIG is allowed to have zero keys and/or sigs"], +["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "Zero sigs means no sigs are checked"], +["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], -["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "CHECKMULTISIG is allowed to have zero keys and/or sigs"], -["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Zero sigs means no sigs are checked"], -["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], +["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "CHECKMULTISIG is allowed to have zero keys and/or sigs"], +["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "Zero sigs means no sigs are checked"], +["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], -["", "0 0 'a' 'b' 2 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test from up to 20 pubkeys, all not checked"], -["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 2 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], -["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"], +["", "0 0 'a' 'b' 2 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK", "Test from up to 20 pubkeys, all not checked"], +["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 2 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], +["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "OK"], ["", "0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "nOpCount is incremented by the number of keys evaluated in addition to the usual one op per op. In this case we have zero keys, so we can execute 201 CHECKMULTISIGS"], ["1", "0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC"], +"P2SH,STRICTENC", "OK"], ["", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "Even though there are no signatures being checked nOpCount is incremented by the number of keys."], ["1", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC"], +"P2SH,STRICTENC", "OK"], -["0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Very basic P2SH"], -["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"], +["0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "OK", "Very basic P2SH"], +["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "OK"], ["0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", "0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "Basic PUSH signedness check"], ["0x4c 0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", "0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL", -"P2SH,STRICTENC", +"P2SH,STRICTENC", "OK", "Basic PUSHDATA1 signedness check"], ["all PUSHDATA forms are equivalent"], -["0x4c 0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA1 of 75 bytes equals direct push of it"], -["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4c 0xFF 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA2 of 255 bytes equals PUSHDATA1 of it"], +["0x4c 0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "OK", "PUSHDATA1 of 75 bytes equals direct push of it"], +["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4c 0xFF 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "OK", "PUSHDATA2 of 255 bytes equals PUSHDATA1 of it"], -["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], +["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "OK", "Basic OP_0 execution"], ["Numeric pushes"], -["0x01 0x81", "0x4f EQUAL", "", "OP1_NEGATE pushes 0x81"], -["0x01 0x01", "0x51 EQUAL", "", "OP_1 pushes 0x01"], -["0x01 0x02", "0x52 EQUAL", "", "OP_2 pushes 0x02"], -["0x01 0x03", "0x53 EQUAL", "", "OP_3 pushes 0x03"], -["0x01 0x04", "0x54 EQUAL", "", "OP_4 pushes 0x04"], -["0x01 0x05", "0x55 EQUAL", "", "OP_5 pushes 0x05"], -["0x01 0x06", "0x56 EQUAL", "", "OP_6 pushes 0x06"], -["0x01 0x07", "0x57 EQUAL", "", "OP_7 pushes 0x07"], -["0x01 0x08", "0x58 EQUAL", "", "OP_8 pushes 0x08"], -["0x01 0x09", "0x59 EQUAL", "", "OP_9 pushes 0x09"], -["0x01 0x0a", "0x5a EQUAL", "", "OP_10 pushes 0x0a"], -["0x01 0x0b", "0x5b EQUAL", "", "OP_11 pushes 0x0b"], -["0x01 0x0c", "0x5c EQUAL", "", "OP_12 pushes 0x0c"], -["0x01 0x0d", "0x5d EQUAL", "", "OP_13 pushes 0x0d"], -["0x01 0x0e", "0x5e EQUAL", "", "OP_14 pushes 0x0e"], -["0x01 0x0f", "0x5f EQUAL", "", "OP_15 pushes 0x0f"], -["0x01 0x10", "0x60 EQUAL", "", "OP_16 pushes 0x10"], +["0x01 0x81", "0x4f EQUAL", "", "OK", "OP1_NEGATE pushes 0x81"], +["0x01 0x01", "0x51 EQUAL", "", "OK", "OP_1 pushes 0x01"], +["0x01 0x02", "0x52 EQUAL", "", "OK", "OP_2 pushes 0x02"], +["0x01 0x03", "0x53 EQUAL", "", "OK", "OP_3 pushes 0x03"], +["0x01 0x04", "0x54 EQUAL", "", "OK", "OP_4 pushes 0x04"], +["0x01 0x05", "0x55 EQUAL", "", "OK", "OP_5 pushes 0x05"], +["0x01 0x06", "0x56 EQUAL", "", "OK", "OP_6 pushes 0x06"], +["0x01 0x07", "0x57 EQUAL", "", "OK", "OP_7 pushes 0x07"], +["0x01 0x08", "0x58 EQUAL", "", "OK", "OP_8 pushes 0x08"], +["0x01 0x09", "0x59 EQUAL", "", "OK", "OP_9 pushes 0x09"], +["0x01 0x0a", "0x5a EQUAL", "", "OK", "OP_10 pushes 0x0a"], +["0x01 0x0b", "0x5b EQUAL", "", "OK", "OP_11 pushes 0x0b"], +["0x01 0x0c", "0x5c EQUAL", "", "OK", "OP_12 pushes 0x0c"], +["0x01 0x0d", "0x5d EQUAL", "", "OK", "OP_13 pushes 0x0d"], +["0x01 0x0e", "0x5e EQUAL", "", "OK", "OP_14 pushes 0x0e"], +["0x01 0x0f", "0x5f EQUAL", "", "OK", "OP_15 pushes 0x0f"], +["0x01 0x10", "0x60 EQUAL", "", "OK", "OP_16 pushes 0x10"], ["Equivalency of different numeric encodings"], -["0x02 0x8000", "128 NUMEQUAL", "", "0x8000 equals 128"], -["0x01 0x00", "0 NUMEQUAL", "", "0x00 numequals 0"], -["0x01 0x80", "0 NUMEQUAL", "", "0x80 (negative zero) numequals 0"], -["0x02 0x0080", "0 NUMEQUAL", "", "0x0080 numequals 0"], -["0x02 0x0500", "5 NUMEQUAL", "", "0x0500 numequals 5"], -["0x03 0xff7f80", "0x02 0xffff NUMEQUAL", "", ""], -["0x03 0xff7f00", "0x02 0xff7f NUMEQUAL", "", ""], -["0x04 0xffff7f80", "0x03 0xffffff NUMEQUAL", "", ""], -["0x04 0xffff7f00", "0x03 0xffff7f NUMEQUAL", "", ""], +["0x02 0x8000", "128 NUMEQUAL", "", "OK", "0x8000 equals 128"], +["0x01 0x00", "0 NUMEQUAL", "", "OK", "0x00 numequals 0"], +["0x01 0x80", "0 NUMEQUAL", "", "OK", "0x80 (negative zero) numequals 0"], +["0x02 0x0080", "0 NUMEQUAL", "", "OK", "0x0080 numequals 0"], +["0x02 0x0500", "5 NUMEQUAL", "", "OK", "0x0500 numequals 5"], +["0x03 0xff7f80", "0x02 0xffff NUMEQUAL", "", "OK", ""], +["0x03 0xff7f00", "0x02 0xff7f NUMEQUAL", "", "OK", ""], +["0x04 0xffff7f80", "0x03 0xffffff NUMEQUAL", "", "OK", ""], +["0x04 0xffff7f00", "0x03 0xffff7f NUMEQUAL", "", "OK", ""], ["Unevaluated non-minimal pushes are ignored"], -["0 IF 0x4c 0x00 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA1 ignored"], -["0 IF 0x4d 0x0000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA2 ignored"], -["0 IF 0x4c 0x00000000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA4 ignored"], -["0 IF 0x01 0x81 ENDIF 1", "", "MINIMALDATA", "1NEGATE equiv"], -["0 IF 0x01 0x01 ENDIF 1", "", "MINIMALDATA", "OP_1 equiv"], -["0 IF 0x01 0x02 ENDIF 1", "", "MINIMALDATA", "OP_2 equiv"], -["0 IF 0x01 0x03 ENDIF 1", "", "MINIMALDATA", "OP_3 equiv"], -["0 IF 0x01 0x04 ENDIF 1", "", "MINIMALDATA", "OP_4 equiv"], -["0 IF 0x01 0x05 ENDIF 1", "", "MINIMALDATA", "OP_5 equiv"], -["0 IF 0x01 0x06 ENDIF 1", "", "MINIMALDATA", "OP_6 equiv"], -["0 IF 0x01 0x07 ENDIF 1", "", "MINIMALDATA", "OP_7 equiv"], -["0 IF 0x01 0x08 ENDIF 1", "", "MINIMALDATA", "OP_8 equiv"], -["0 IF 0x01 0x09 ENDIF 1", "", "MINIMALDATA", "OP_9 equiv"], -["0 IF 0x01 0x0a ENDIF 1", "", "MINIMALDATA", "OP_10 equiv"], -["0 IF 0x01 0x0b ENDIF 1", "", "MINIMALDATA", "OP_11 equiv"], -["0 IF 0x01 0x0c ENDIF 1", "", "MINIMALDATA", "OP_12 equiv"], -["0 IF 0x01 0x0d ENDIF 1", "", "MINIMALDATA", "OP_13 equiv"], -["0 IF 0x01 0x0e ENDIF 1", "", "MINIMALDATA", "OP_14 equiv"], -["0 IF 0x01 0x0f ENDIF 1", "", "MINIMALDATA", "OP_15 equiv"], -["0 IF 0x01 0x10 ENDIF 1", "", "MINIMALDATA", "OP_16 equiv"], +["0 IF 0x4c 0x00 ENDIF 1", "", "MINIMALDATA", "OK", "non-minimal PUSHDATA1 ignored"], +["0 IF 0x4d 0x0000 ENDIF 1", "", "MINIMALDATA", "OK", "non-minimal PUSHDATA2 ignored"], +["0 IF 0x4c 0x00000000 ENDIF 1", "", "MINIMALDATA", "OK", "non-minimal PUSHDATA4 ignored"], +["0 IF 0x01 0x81 ENDIF 1", "", "MINIMALDATA", "OK", "1NEGATE equiv"], +["0 IF 0x01 0x01 ENDIF 1", "", "MINIMALDATA", "OK", "OP_1 equiv"], +["0 IF 0x01 0x02 ENDIF 1", "", "MINIMALDATA", "OK", "OP_2 equiv"], +["0 IF 0x01 0x03 ENDIF 1", "", "MINIMALDATA", "OK", "OP_3 equiv"], +["0 IF 0x01 0x04 ENDIF 1", "", "MINIMALDATA", "OK", "OP_4 equiv"], +["0 IF 0x01 0x05 ENDIF 1", "", "MINIMALDATA", "OK", "OP_5 equiv"], +["0 IF 0x01 0x06 ENDIF 1", "", "MINIMALDATA", "OK", "OP_6 equiv"], +["0 IF 0x01 0x07 ENDIF 1", "", "MINIMALDATA", "OK", "OP_7 equiv"], +["0 IF 0x01 0x08 ENDIF 1", "", "MINIMALDATA", "OK", "OP_8 equiv"], +["0 IF 0x01 0x09 ENDIF 1", "", "MINIMALDATA", "OK", "OP_9 equiv"], +["0 IF 0x01 0x0a ENDIF 1", "", "MINIMALDATA", "OK", "OP_10 equiv"], +["0 IF 0x01 0x0b ENDIF 1", "", "MINIMALDATA", "OK", "OP_11 equiv"], +["0 IF 0x01 0x0c ENDIF 1", "", "MINIMALDATA", "OK", "OP_12 equiv"], +["0 IF 0x01 0x0d ENDIF 1", "", "MINIMALDATA", "OK", "OP_13 equiv"], +["0 IF 0x01 0x0e ENDIF 1", "", "MINIMALDATA", "OK", "OP_14 equiv"], +["0 IF 0x01 0x0f ENDIF 1", "", "MINIMALDATA", "OK", "OP_15 equiv"], +["0 IF 0x01 0x10 ENDIF 1", "", "MINIMALDATA", "OK", "OP_16 equiv"], ["Numeric minimaldata rules are only applied when a stack item is numerically evaluated; the push itself is allowed"], -["0x01 0x00", "1", "MINIMALDATA"], -["0x01 0x80", "1", "MINIMALDATA"], -["0x02 0x0180", "1", "MINIMALDATA"], -["0x02 0x0100", "1", "MINIMALDATA"], -["0x02 0x0200", "1", "MINIMALDATA"], -["0x02 0x0300", "1", "MINIMALDATA"], -["0x02 0x0400", "1", "MINIMALDATA"], -["0x02 0x0500", "1", "MINIMALDATA"], -["0x02 0x0600", "1", "MINIMALDATA"], -["0x02 0x0700", "1", "MINIMALDATA"], -["0x02 0x0800", "1", "MINIMALDATA"], -["0x02 0x0900", "1", "MINIMALDATA"], -["0x02 0x0a00", "1", "MINIMALDATA"], -["0x02 0x0b00", "1", "MINIMALDATA"], -["0x02 0x0c00", "1", "MINIMALDATA"], -["0x02 0x0d00", "1", "MINIMALDATA"], -["0x02 0x0e00", "1", "MINIMALDATA"], -["0x02 0x0f00", "1", "MINIMALDATA"], -["0x02 0x1000", "1", "MINIMALDATA"], +["0x01 0x00", "1", "MINIMALDATA", "OK"], +["0x01 0x80", "1", "MINIMALDATA", "OK"], +["0x02 0x0180", "1", "MINIMALDATA", "OK"], +["0x02 0x0100", "1", "MINIMALDATA", "OK"], +["0x02 0x0200", "1", "MINIMALDATA", "OK"], +["0x02 0x0300", "1", "MINIMALDATA", "OK"], +["0x02 0x0400", "1", "MINIMALDATA", "OK"], +["0x02 0x0500", "1", "MINIMALDATA", "OK"], +["0x02 0x0600", "1", "MINIMALDATA", "OK"], +["0x02 0x0700", "1", "MINIMALDATA", "OK"], +["0x02 0x0800", "1", "MINIMALDATA", "OK"], +["0x02 0x0900", "1", "MINIMALDATA", "OK"], +["0x02 0x0a00", "1", "MINIMALDATA", "OK"], +["0x02 0x0b00", "1", "MINIMALDATA", "OK"], +["0x02 0x0c00", "1", "MINIMALDATA", "OK"], +["0x02 0x0d00", "1", "MINIMALDATA", "OK"], +["0x02 0x0e00", "1", "MINIMALDATA", "OK"], +["0x02 0x0f00", "1", "MINIMALDATA", "OK"], +["0x02 0x1000", "1", "MINIMALDATA", "OK"], ["Valid version of the 'Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule' script_invalid test"], -["1 0x02 0x0000", "PICK DROP", ""], -["1 0x02 0x0000", "ROLL DROP 1", ""], -["0x02 0x0000", "1ADD DROP 1", ""], -["0x02 0x0000", "1SUB DROP 1", ""], -["0x02 0x0000", "NEGATE DROP 1", ""], -["0x02 0x0000", "ABS DROP 1", ""], -["0x02 0x0000", "NOT DROP 1", ""], -["0x02 0x0000", "0NOTEQUAL DROP 1", ""], +["1 0x02 0x0000", "PICK DROP", "", "OK"], +["1 0x02 0x0000", "ROLL DROP 1", "", "OK"], +["0x02 0x0000", "1ADD DROP 1", "", "OK"], +["0x02 0x0000", "1SUB DROP 1", "", "OK"], +["0x02 0x0000", "NEGATE DROP 1", "", "OK"], +["0x02 0x0000", "ABS DROP 1", "", "OK"], +["0x02 0x0000", "NOT DROP 1", "", "OK"], +["0x02 0x0000", "0NOTEQUAL DROP 1", "", "OK"], -["0 0x02 0x0000", "ADD DROP 1", ""], -["0x02 0x0000 0", "ADD DROP 1", ""], -["0 0x02 0x0000", "SUB DROP 1", ""], -["0x02 0x0000 0", "SUB DROP 1", ""], -["0 0x02 0x0000", "BOOLAND DROP 1", ""], -["0x02 0x0000 0", "BOOLAND DROP 1", ""], -["0 0x02 0x0000", "BOOLOR DROP 1", ""], -["0x02 0x0000 0", "BOOLOR DROP 1", ""], -["0 0x02 0x0000", "NUMEQUAL DROP 1", ""], -["0x02 0x0000 1", "NUMEQUAL DROP 1", ""], -["0 0x02 0x0000", "NUMEQUALVERIFY 1", ""], -["0x02 0x0000 0", "NUMEQUALVERIFY 1", ""], -["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", ""], -["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", ""], -["0 0x02 0x0000", "LESSTHAN DROP 1", ""], -["0x02 0x0000 0", "LESSTHAN DROP 1", ""], -["0 0x02 0x0000", "GREATERTHAN DROP 1", ""], -["0x02 0x0000 0", "GREATERTHAN DROP 1", ""], -["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", ""], -["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", ""], -["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", ""], -["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", ""], -["0 0x02 0x0000", "MIN DROP 1", ""], -["0x02 0x0000 0", "MIN DROP 1", ""], -["0 0x02 0x0000", "MAX DROP 1", ""], -["0x02 0x0000 0", "MAX DROP 1", ""], +["0 0x02 0x0000", "ADD DROP 1", "", "OK"], +["0x02 0x0000 0", "ADD DROP 1", "", "OK"], +["0 0x02 0x0000", "SUB DROP 1", "", "OK"], +["0x02 0x0000 0", "SUB DROP 1", "", "OK"], +["0 0x02 0x0000", "BOOLAND DROP 1", "", "OK"], +["0x02 0x0000 0", "BOOLAND DROP 1", "", "OK"], +["0 0x02 0x0000", "BOOLOR DROP 1", "", "OK"], +["0x02 0x0000 0", "BOOLOR DROP 1", "", "OK"], +["0 0x02 0x0000", "NUMEQUAL DROP 1", "", "OK"], +["0x02 0x0000 1", "NUMEQUAL DROP 1", "", "OK"], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", "", "OK"], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", "", "OK"], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "", "OK"], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "", "OK"], +["0 0x02 0x0000", "LESSTHAN DROP 1", "", "OK"], +["0x02 0x0000 0", "LESSTHAN DROP 1", "", "OK"], +["0 0x02 0x0000", "GREATERTHAN DROP 1", "", "OK"], +["0x02 0x0000 0", "GREATERTHAN DROP 1", "", "OK"], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "", "OK"], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "", "OK"], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "", "OK"], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "", "OK"], +["0 0x02 0x0000", "MIN DROP 1", "", "OK"], +["0x02 0x0000 0", "MIN DROP 1", "", "OK"], +["0 0x02 0x0000", "MAX DROP 1", "", "OK"], +["0x02 0x0000 0", "MAX DROP 1", "", "OK"], -["0x02 0x0000 0 0", "WITHIN DROP 1", ""], -["0 0x02 0x0000 0", "WITHIN DROP 1", ""], -["0 0 0x02 0x0000", "WITHIN DROP 1", ""], +["0x02 0x0000 0 0", "WITHIN DROP 1", "", "OK"], +["0 0x02 0x0000 0", "WITHIN DROP 1", "", "OK"], +["0 0 0x02 0x0000", "WITHIN DROP 1", "", "OK"], -["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", ""], -["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", ""], -["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", ""], -["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""], -["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""], +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "", "OK"], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "", "OK"], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "", "OK"], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "", "OK"], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "", "OK"], ["While not really correctly DER encoded, the empty signature is allowed by"], ["STRICTENC to provide a compact way to provide a delibrately invalid signature."], -["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"], -["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"], +["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC", "OK"], +["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC", "OK"], ["CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and"], ["pubkeys in a specific order, and will exit early if the number of signatures"], @@ -681,241 +681,277 @@ [ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", "2 0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", - "STRICTENC", + "STRICTENC", "OK", "2-of-2 CHECKMULTISIG NOT with the second pubkey invalid, and both signatures validly encoded. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid pubkey." ], [ "0 0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", - "STRICTENC", + "STRICTENC", "OK", "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature." ], ["Increase test coverage for DERSIG"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "OK", "Overly long signature is correctly encoded"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "OK", "Missing S is correctly encoded"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "S with invalid S length is correctly encoded"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Non-integer R is correctly encoded"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Non-integer S is correctly encoded"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Zero-length R is correctly encoded"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"], ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", + "OK", "P2PK" ], [ "0x47 0x304402206e05a6fe23c59196ffe176c9ddc31e73a9885638f9d1328d47c0c703863b8876022076feb53811aa5b04e0e79f938eb19906cc5e67548bc555a8e8b8b0fc603d840c01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG", "", + "OK", "P2PKH" ], [ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", + "OK", "P2PK anyonecanpay" ], [ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", + "OK", "P2SH(P2PK)" ], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "", + "OK", "P2SH(P2PKH), bad sig but no VERIFY_P2SH" ], [ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", + "OK", "3-of-3" ], [ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x30440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", + "OK", "P2SH(2-of-3)" ], [ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", + "OK", "P2PK with too much R padding but no DERSIG" ], [ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", + "OK", "P2PK with too much S padding but no DERSIG" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", + "OK", "P2PK with too little R padding but no DERSIG" ], [ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", + "OK", "P2PK NOT with bad sig with too much R padding but no DERSIG" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", + "OK", "BIP66 example 1, without DERSIG" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", + "OK", "BIP66 example 4, without DERSIG" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "DERSIG", + "OK", "BIP66 example 4, with DERSIG" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", + "OK", "BIP66 example 6, without DERSIG" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", + "OK", "BIP66 example 7, without DERSIG" ], [ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", + "OK", "BIP66 example 10, without DERSIG" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", + "OK", "BIP66 example 12, without DERSIG" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "DERSIG", + "OK", "BIP66 example 12, with DERSIG" ], [ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", + "OK", "P2PK with multi-byte hashtype, without DERSIG" ], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", + "OK", "P2PK with high S but no LOW_S" ], [ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", + "OK", "P2PK with hybrid pubkey but no STRICTENC" ], [ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", + "OK", "P2PK NOT with invalid hybrid pubkey but no STRICTENC" ], [ "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401", "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "", + "OK", "1-of-2 with the second 1 hybrid pubkey and no STRICTENC" ], [ "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401", "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "STRICTENC", + "OK", "1-of-2 with the second 1 hybrid pubkey" ], [ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", + "OK", "P2PK with undefined hashtype but no STRICTENC" ], [ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", "", + "OK", "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC" ], [ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", + "OK", "3-of-3 with nonzero dummy but no NULLDUMMY" ], [ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", "", + "OK", "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY" ], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "", + "OK", "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" ], [ "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "", + "OK", "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY" ], [ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP8", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", + "OK", "P2PK with non-push scriptSig but with P2SH validation" ], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "SIGPUSHONLY", + "OK", "2-of-2 with two identical keys and sigs pushed" ], [ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH", + "OK", "P2PK with unnecessary input but no CLEANSTACK" ], [ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "P2SH", + "OK", "P2SH with unnecessary input but no CLEANSTACK" ], [ "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", "CLEANSTACK,P2SH", + "OK", "P2SH with CLEANSTACK" ], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4ecb56de8..006d8aa64 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -263,7 +263,7 @@ private: } public: - TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(-1) + TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK) { if (P2SH) { creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL); @@ -365,9 +365,8 @@ public: array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); + array.push_back(FormatScriptError((ScriptError_t)scriptError)); array.push_back(comment); - if (scriptError != -1) - array.push_back(FormatScriptError((ScriptError_t)scriptError)); return array; } @@ -715,7 +714,7 @@ BOOST_AUTO_TEST_CASE(script_valid) { // Read tests from test/data/script_valid.json // Format is an array of arrays - // Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ] + // Inner arrays are [ "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] // ... where scriptSig and scriptPubKey are stringified // scripts. UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); @@ -735,6 +734,7 @@ BOOST_AUTO_TEST_CASE(script_valid) string scriptPubKeyString = test[1].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); + BOOST_CHECK_EQUAL(test[3].get_str(), "OK"); DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest, SCRIPT_ERR_OK); } @@ -747,7 +747,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); - if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) + if (test.size() < 4) // Allow size > 2; extra stuff ignored (useful for comments) { if (test.size() != 1) { BOOST_ERROR("Bad test: " << strTest); @@ -759,10 +759,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) string scriptPubKeyString = test[1].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - int scriptError = -1; // Expected script error is optional, and follows comment - if (test.size() >= 5 && test[4].get_str() != "") { - scriptError = ParseScriptError(test[4].get_str()); - } + int scriptError = ParseScriptError(test[3].get_str()); DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest, scriptError); } From 009b503792737ab03aeb6e15060bc4f499500a96 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 15:50:17 +0200 Subject: [PATCH 0405/1223] Get rid of expect in script_tests as it's implied by scripterror --- src/test/script_tests.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 006d8aa64..6340af208 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -145,13 +145,14 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu return txSpend; } -void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message, int scriptError) +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, const std::string& message, int scriptError) { + bool expect = (scriptError == SCRIPT_ERR_OK); ScriptError err; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx2 = tx; BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); - BOOST_CHECK_MESSAGE(scriptError == -1 || err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); + BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << tx2; @@ -349,11 +350,11 @@ public: return *this; } - TestBuilder& Test(bool expect) + TestBuilder& Test() { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment, expect ? SCRIPT_ERR_OK : scriptError); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, comment, scriptError); *this = copy; return *this; } @@ -680,7 +681,7 @@ BOOST_AUTO_TEST_CASE(script_build) std::string strBad; BOOST_FOREACH(TestBuilder& test, good) { - test.Test(true); + test.Test(); std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { @@ -690,7 +691,7 @@ BOOST_AUTO_TEST_CASE(script_build) strGood += str + ",\n"; } BOOST_FOREACH(TestBuilder& test, bad) { - test.Test(false); + test.Test(); std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { @@ -736,7 +737,7 @@ BOOST_AUTO_TEST_CASE(script_valid) unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_EQUAL(test[3].get_str(), "OK"); - DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest, SCRIPT_ERR_OK); + DoTest(scriptPubKey, scriptSig, scriptflags, strTest, SCRIPT_ERR_OK); } } @@ -761,7 +762,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); int scriptError = ParseScriptError(test[3].get_str()); - DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest, scriptError); + DoTest(scriptPubKey, scriptSig, scriptflags, strTest, scriptError); } } From dde46d3ae1de18700e089bc1861cf1e18649dc5d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 16:11:47 +0200 Subject: [PATCH 0406/1223] Merge script_valid and script_invalid tests --- src/Makefile.test.include | 3 +- src/test/data/script_invalid.json | 877 ------------------ .../{script_valid.json => script_tests.json} | 865 +++++++++++++++++ src/test/script_tests.cpp | 569 ++++++------ 4 files changed, 1127 insertions(+), 1187 deletions(-) delete mode 100644 src/test/data/script_invalid.json rename src/test/data/{script_valid.json => script_tests.json} (54%) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index d806fb219..f025b18c7 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -20,11 +20,10 @@ EXTRA_DIST += \ test/data/txcreatesign.hex JSON_TEST_FILES = \ - test/data/script_valid.json \ + test/data/script_tests.json \ test/data/base58_keys_valid.json \ test/data/base58_encode_decode.json \ test/data/base58_keys_invalid.json \ - test/data/script_invalid.json \ test/data/tx_invalid.json \ test/data/tx_valid.json \ test/data/sighash.json diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json deleted file mode 100644 index 1427cb630..000000000 --- a/src/test/data/script_invalid.json +++ /dev/null @@ -1,877 +0,0 @@ -[ -["Format is: [scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], -["It is evaluated as if there was a crediting coinbase transaction with two 0"], -["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], -["followed by a spending transaction which spends this output as only input (and"], -["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], -["nSequences are max."], - -["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], -[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], -[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], -[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], - -["", "", "P2SH,STRICTENC","EVAL_FALSE"], -["", "NOP", "P2SH,STRICTENC","EVAL_FALSE"], -["", "NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP","NOP", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP","NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], - -["DEPTH", "", "P2SH,STRICTENC", "EVAL_FALSE"], - -["0x4c01","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA1 with not enough bytes"], -["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA2 with not enough bytes"], -["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA4 with not enough bytes"], - -["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC","BAD_OPCODE", "0x50 is reserved"], -["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC","EVAL_FALSE", "0x51 through 0x60 push 1 through 16 onto stack"], -["0","NOP", "P2SH,STRICTENC","EVAL_FALSE",""], -["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VER non-functional"], -["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], -["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], -["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], -["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], - -["1 IF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF/ENDIF can't span scriptSig/scriptPubKey"], -["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["0 NOTIF", "123", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], - -["0", "DUP IF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0", "IF 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], - -["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], - -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], -["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], - -["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "OP_RETURN", "Multiple ELSEs"], -["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], - -["1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "Malformed IF/ELSE/ENDIF sequence"], -["1", "ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], -["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], - -["1", "RETURN", "P2SH,STRICTENC", "OP_RETURN"], -["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], - -["1", "RETURN 'data'", "P2SH,STRICTENC", "OP_RETURN", "canonical prunable txout format"], -["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], - -["0", "VERIFY 1", "P2SH,STRICTENC", "VERIFY"], -["1", "VERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], -["1", "VERIFY 0", "P2SH,STRICTENC", "EVAL_FALSE"], - -["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION", "alt stack not shared between sig/pubkey"], - -["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1 NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1 0 NIP", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], -["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "0 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "-1 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["NOP", "0 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "-1 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], -["NOP", "ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "EQUALVERIFY"], -["NOP", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "EVAL_FALSE"], -["NOP", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 2", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "2 3 2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["'a' 'b'", "CAT", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], -["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], -["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], -["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], -["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "LEFT disabled"], -["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "RIGHT disabled"], - -["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "INVERT disabled"], -["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "AND disabled"], -["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "OR disabled"], -["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "XOR disabled"], -["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2MUL disabled"], -["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2DIV disabled"], -["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MUL disabled"], -["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "DIV disabled"], -["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MOD disabled"], -["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "LSHIFT disabled"], -["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "RSHIFT disabled"], - -["", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are no stack items"], -["0", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are not 2 stack items"], -["0 1","EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], - -["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], -["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], -["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NUMEQUAL must be in numeric range"], -["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NOT is an arithmetic operand"], - -["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], - -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], - -["Ensure 100% coverage of discouraged NOPS"], -["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], - -["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], - -["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", - "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], - -["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP10 invalid if executed"], -["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], - -["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "invalid because scriptSig and scriptPubKey are processed separately"], - -["NOP", "RIPEMD160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "SHA1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "SHA256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "HASH160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "HASH256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["NOP", -"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push"], -["0", -"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push in non-executed IF branch"], -["1", -"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", -"OP_COUNT", -">201 opcodes executed. 0x61 is NOP"], -["0", -"IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1", -"P2SH,STRICTENC", -"OP_COUNT", -">201 opcodes including non-executed IF branch. 0x61 is NOP"], -["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"P2SH,STRICTENC", -"STACK_SIZE", -">1,000 stack size (0x6f is 3DUP)"], -["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", -"P2SH,STRICTENC", -"STACK_SIZE", -">1,000 stack+altstack size"], -["NOP", -"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", -"SCRIPT_SIZE", -"10,001-byte scriptPubKey"], - -["NOP1","NOP10", "P2SH,STRICTENC", "EVAL_FALSE"], - -["1","VER", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER is reserved"], -["1","VERIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERIF is reserved"], -["1","VERNOTIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERNOTIF is reserved"], -["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"], -["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"], -["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"], -["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == OP_NOP10 + 1"], - -["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], -["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], -["-2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "Because we use a sign bit, -2147483648 is also 5 bytes"], -["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], -["2147483648", "1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], - -["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"], -["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLAND on 5-byte integers"], - -["1", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "ENDIF without IF"], -["1", "IF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF without ENDIF"], -["1 IF 1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IFs don't carry over"], - -["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "The following tests check the if(stack.size() < N) tests in each opcode"], -["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "They are here to catch copy-and-paste errors"], -["NOP", "VERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "Most of them are duplicated elsewhere,"], - -["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "but, hey, more is always better, right?"], -["1", "FROMALTSTACK", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION"], -["1", "2DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "2DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1", "3DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1 1", "2OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1 1", "2SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "IFDUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1 1 3", "PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["0", "PICK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1 1 3", "ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["0", "ROLL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1", "ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "TUCK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["1", "EQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["NOP", "1ADD 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "1SUB 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "NEGATE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "ABS 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "NOT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["1", "ADD", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "SUB", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "BOOLAND", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "BOOLOR", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "NUMEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "LESSTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "GREATERTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "MIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1", "MAX", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["1 1", "WITHIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "SHA1 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "SHA256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "HASH160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", "HASH256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - -["Increase CHECKSIG and CHECKMULTISIG negative test coverage"], -["", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are no stack items"], -["0", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are not 2 stack items"], -["", "CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are no stack items"], -["", "-1 CHECKMULTISIG NOT", "STRICTENC", "PUBKEY_COUNT", "CHECKMULTISIG must error when the specified number of pubkeys is negative"], -["", "1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"], -["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "SIG_COUNT", "CHECKMULTISIG must error when the specified number of signatures is negative"], -["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough signatures on the stack"], -["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "EVAL_FALSE", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"], - -["", -"0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG", -"P2SH,STRICTENC", -"OP_COUNT", -"202 CHECKMULTISIGS, fails due to 201 op limit"], - -["1", -"0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC", -"INVALID_STACK_OPERATION", -""], - -["", -"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", -"P2SH,STRICTENC", -"OP_COUNT", -"Fails due to 201 sig op limit"], - -["1", -"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", -"P2SH,STRICTENC", -"OP_COUNT", -""], - - -["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "PUBKEY_COUNT", "nPubKeys > 20"], -["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "SIG_COUNT", "nSigs > nPubKeys"], - - -["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY", "Tests for Script.IsPushOnly()"], -["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY"], - -["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED in P2SH should fail"], -["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER in P2SH should fail"], - -["0x00", "'00' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE", "Basic OP_0 execution"], - -["MINIMALDATA enforcement for PUSHDATAs"], - -["0x4c 0x00", "DROP 1", "MINIMALDATA", "MINIMALDATA", "Empty vector minimally represented by OP_0"], -["0x01 0x81", "DROP 1", "MINIMALDATA", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"], -["0x01 0x01", "DROP 1", "MINIMALDATA", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"], -["0x01 0x02", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x03", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x04", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x05", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x06", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x07", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x08", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x09", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0a", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0b", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0c", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0d", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0e", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x0f", "DROP 1", "MINIMALDATA", "MINIMALDATA"], -["0x01 0x10", "DROP 1", "MINIMALDATA", "MINIMALDATA"], - -["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "MINIMALDATA", - "PUSHDATA1 of 72 bytes minimally represented by direct push"], - -["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "MINIMALDATA", - "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"], - -["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", - "MINIMALDATA", - "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"], - -["MINIMALDATA enforcement for numeric arguments"], - -["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], -["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "0x80 (negative zero) numequals 0"], -["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], -["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], -["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], -["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], -["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], -["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff"], -["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xff7f"], -["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffffff"], -["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff7f"], - -["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"], - -["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "UNKNOWN_ERROR"], -["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], - -["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], - -["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], - -["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], -["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], - - -["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"], -["pubkeys/signatures so they fail due to the STRICTENC rules on validly encoded"], -["signatures and pubkeys."], -[ - "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", - "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", - "STRICTENC", - "PUBKEYTYPE", - "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." -], -[ - "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1", - "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", - "STRICTENC", - "SIG_DER", - "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." -], -[ - "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", - "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", - "P2SH,STRICTENC", - "SIG_DER", - "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" -], - -["Increase DERSIG test coverage"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Overly long signature is incorrectly encoded for DERSIG"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Missing S is incorrectly encoded for DERSIG"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "S with invalid S length is incorrectly encoded for DERSIG"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer R is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer S is incorrectly encoded for DERSIG"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length R is incorrectly encoded for DERSIG"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], - -["Automatically generated test cases"], -[ - "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", - "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", - "", - "EVAL_FALSE", - "P2PK, bad sig" -], -[ - "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", - "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", - "", - "EQUALVERIFY", - "P2PKH, bad pubkey" -], -[ - "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201", - "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", - "", - "EVAL_FALSE", - "P2PK anyonecanpay marked with normal hashtype" -], -[ - "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", - "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", - "P2SH", - "EVAL_FALSE", - "P2SH(P2PK), bad redeemscript" -], -[ - "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", - "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", - "P2SH", - "EQUALVERIFY", - "P2SH(P2PKH), bad sig" -], -[ - "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0", - "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", - "", - "EVAL_FALSE", - "3-of-3, 2 sigs" -], -[ - "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", - "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", - "P2SH", - "EVAL_FALSE", - "P2SH(2-of-3), 1 sig" -], -[ - "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "SIG_DER", - "P2PK with too much R padding" -], -[ - "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "SIG_DER", - "P2PK with too much S padding" -], -[ - "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "SIG_DER", - "P2PK with too little R padding" -], -[ - "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "DERSIG", - "SIG_DER", - "P2PK NOT with bad sig with too much R padding" -], -[ - "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "", - "EVAL_FALSE", - "P2PK NOT with too much R padding but no DERSIG" -], -[ - "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "DERSIG", - "SIG_DER", - "P2PK NOT with too much R padding" -], -[ - "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "SIG_DER", - "BIP66 example 1, with DERSIG" -], -[ - "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "", - "EVAL_FALSE", - "BIP66 example 2, without DERSIG" -], -[ - "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "SIG_DER", - "BIP66 example 2, with DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "EVAL_FALSE", - "BIP66 example 3, without DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "EVAL_FALSE", - "BIP66 example 3, with DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "EVAL_FALSE", - "BIP66 example 5, without DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "SIG_DER", - "BIP66 example 5, with DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "SIG_DER", - "BIP66 example 6, with DERSIG" -], -[ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "SIG_DER", - "BIP66 example 7, with DERSIG" -], -[ - "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "", - "EVAL_FALSE", - "BIP66 example 8, without DERSIG" -], -[ - "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "SIG_DER", - "BIP66 example 8, with DERSIG" -], -[ - "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "", - "EVAL_FALSE", - "BIP66 example 9, without DERSIG" -], -[ - "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "SIG_DER", - "BIP66 example 9, with DERSIG" -], -[ - "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "SIG_DER", - "BIP66 example 10, with DERSIG" -], -[ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "", - "EVAL_FALSE", - "BIP66 example 11, without DERSIG" -], -[ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "EVAL_FALSE", - "BIP66 example 11, with DERSIG" -], -[ - "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", - "DERSIG", - "SIG_DER", - "P2PK with multi-byte hashtype, with DERSIG" -], -[ - "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", - "LOW_S", - "SIG_HIGH_S", - "P2PK with high S" -], -[ - "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", - "STRICTENC", - "PUBKEYTYPE", - "P2PK with hybrid pubkey" -], -[ - "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", - "", - "EVAL_FALSE", - "P2PK NOT with hybrid pubkey but no STRICTENC" -], -[ - "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", - "STRICTENC", - "PUBKEYTYPE", - "P2PK NOT with hybrid pubkey" -], -[ - "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", - "STRICTENC", - "PUBKEYTYPE", - "P2PK NOT with invalid hybrid pubkey" -], -[ - "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201", - "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", - "STRICTENC", - "PUBKEYTYPE", - "1-of-2 with the first 1 hybrid pubkey" -], -[ - "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", - "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", - "STRICTENC", - "SIG_HASHTYPE", - "P2PK with undefined hashtype" -], -[ - "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", - "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", - "STRICTENC", - "SIG_HASHTYPE", - "P2PK NOT with invalid sig and undefined hashtype" -], -[ - "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", - "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", - "NULLDUMMY", - "SIG_NULLDUMMY", - "3-of-3 with nonzero dummy" -], -[ - "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", - "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", - "NULLDUMMY", - "SIG_NULLDUMMY", - "3-of-3 NOT with invalid sig with nonzero dummy" -], -[ - "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", - "SIGPUSHONLY", - "SIG_PUSHONLY", - "2-of-2 with two identical keys and sigs pushed using OP_DUP" -], -[ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", - "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", - "P2SH", - "SIG_PUSHONLY", - "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" -], -[ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", - "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", - "SIGPUSHONLY", - "SIG_PUSHONLY", - "P2SH(P2PK) with non-push scriptSig but not P2SH" -], -[ - "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", - "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", - "CLEANSTACK,P2SH", - "CLEANSTACK", - "P2PK with unnecessary input" -], -[ - "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", - "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", - "CLEANSTACK,P2SH", - "CLEANSTACK", - "P2SH with unnecessary input" -], - -["The End"] -] diff --git a/src/test/data/script_valid.json b/src/test/data/script_tests.json similarity index 54% rename from src/test/data/script_valid.json rename to src/test/data/script_tests.json index 4e86ee78b..e69cc9e41 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_tests.json @@ -701,6 +701,556 @@ ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"], +["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +[" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], + +["", "", "P2SH,STRICTENC","EVAL_FALSE"], +["", "NOP", "P2SH,STRICTENC","EVAL_FALSE"], +["", "NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP","NOP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP","NOP DEPTH", "P2SH,STRICTENC", "EVAL_FALSE"], + +["DEPTH", "", "P2SH,STRICTENC", "EVAL_FALSE"], + +["0x4c01","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA1 with not enough bytes"], +["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA2 with not enough bytes"], +["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC","BAD_OPCODE", "PUSHDATA4 with not enough bytes"], + +["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC","BAD_OPCODE", "0x50 is reserved"], +["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC","EVAL_FALSE", "0x51 through 0x60 push 1 through 16 onto stack"], +["0","NOP", "P2SH,STRICTENC","EVAL_FALSE",""], +["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VER non-functional"], +["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], +["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERIF illegal everywhere"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], +["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "VERNOTIF illegal everywhere"], + +["1 IF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF/ENDIF can't span scriptSig/scriptPubKey"], +["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["0 NOTIF", "123", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], + +["0", "DUP IF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "IF 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], + +["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], + +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "EVAL_FALSE"], + +["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "OP_RETURN", "Multiple ELSEs"], +["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], + +["1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "Malformed IF/ELSE/ENDIF sequence"], +["1", "ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], +["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL"], + +["1", "RETURN", "P2SH,STRICTENC", "OP_RETURN"], +["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "OP_RETURN"], + +["1", "RETURN 'data'", "P2SH,STRICTENC", "OP_RETURN", "canonical prunable txout format"], +["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], + +["0", "VERIFY 1", "P2SH,STRICTENC", "VERIFY"], +["1", "VERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "VERIFY 0", "P2SH,STRICTENC", "EVAL_FALSE"], + +["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION", "alt stack not shared between sig/pubkey"], + +["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 0 NIP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "EVAL_FALSE"], +["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "-1 PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "0 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "-1 ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "EQUALVERIFY"], +["NOP", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "TUCK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "EVAL_FALSE"], +["NOP", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 2", "3DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2 3 2OVER 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["'a' 'b'", "CAT", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], +["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], +["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], +["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], +["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "LEFT disabled"], +["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "RIGHT disabled"], + +["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "INVERT disabled"], +["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "AND disabled"], +["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "OR disabled"], +["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "XOR disabled"], +["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2MUL disabled"], +["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "2DIV disabled"], +["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MUL disabled"], +["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "DIV disabled"], +["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "MOD disabled"], +["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "LSHIFT disabled"], +["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "RSHIFT disabled"], + +["", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are no stack items"], +["0", "EQUAL NOT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "EQUAL must error when there are not 2 stack items"], +["0 1","EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], + +["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], +["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "], +["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NUMEQUAL must be in numeric range"], +["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NOT is an arithmetic operand"], + +["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], +["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], + +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], + +["Ensure 100% coverage of discouraged NOPS"], +["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], + +["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], + +["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", + "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], + +["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], +["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP10 invalid if executed"], +["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], + +["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "invalid because scriptSig and scriptPubKey are processed separately"], + +["NOP", "RIPEMD160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["NOP", +"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", +"P2SH,STRICTENC", +"PUSH_SIZE", +">520 byte push"], +["0", +"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", +"P2SH,STRICTENC", +"PUSH_SIZE", +">520 byte push in non-executed IF branch"], +["1", +"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"P2SH,STRICTENC", +"OP_COUNT", +">201 opcodes executed. 0x61 is NOP"], +["0", +"IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1", +"P2SH,STRICTENC", +"OP_COUNT", +">201 opcodes including non-executed IF branch. 0x61 is NOP"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"P2SH,STRICTENC", +"STACK_SIZE", +">1,000 stack size (0x6f is 3DUP)"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"P2SH,STRICTENC", +"STACK_SIZE", +">1,000 stack+altstack size"], +["NOP", +"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"P2SH,STRICTENC", +"SCRIPT_SIZE", +"10,001-byte scriptPubKey"], + +["NOP1","NOP10", "P2SH,STRICTENC", "EVAL_FALSE"], + +["1","VER", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER is reserved"], +["1","VERIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERIF is reserved"], +["1","VERNOTIF", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VERNOTIF is reserved"], +["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"], +["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"], +["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"], +["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == OP_NOP10 + 1"], + +["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], +["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], +["-2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "Because we use a sign bit, -2147483648 is also 5 bytes"], +["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], +["2147483648", "1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"], + +["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"], +["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLAND on 5-byte integers"], + +["1", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "ENDIF without IF"], +["1", "IF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF without ENDIF"], +["1 IF 1", "ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IFs don't carry over"], + +["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "The following tests check the if(stack.size() < N) tests in each opcode"], +["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "They are here to catch copy-and-paste errors"], +["NOP", "VERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "Most of them are duplicated elsewhere,"], + +["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION", "but, hey, more is always better, right?"], +["1", "FROMALTSTACK", "P2SH,STRICTENC", "INVALID_ALTSTACK_OPERATION"], +["1", "2DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "2DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "3DUP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1", "2OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1", "2SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "IFDUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "DROP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "DUP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NIP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "OVER", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 3", "PICK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0", "PICK 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1 1 3", "ROLL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["0", "ROLL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "ROT", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SWAP", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "TUCK", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["1", "EQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["NOP", "1ADD 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "1SUB 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "NEGATE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "ABS 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "NOT 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["1", "ADD", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "SUB", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "BOOLAND", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "BOOLOR", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "LESSTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "GREATERTHAN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "MIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1", "MAX", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["1 1", "WITHIN", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA1 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "SHA256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH160 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], +["NOP", "HASH256 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["Increase CHECKSIG and CHECKMULTISIG negative test coverage"], +["", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are no stack items"], +["0", "CHECKSIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKSIG must error when there are not 2 stack items"], +["", "CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are no stack items"], +["", "-1 CHECKMULTISIG NOT", "STRICTENC", "PUBKEY_COUNT", "CHECKMULTISIG must error when the specified number of pubkeys is negative"], +["", "1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"], +["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "SIG_COUNT", "CHECKMULTISIG must error when the specified number of signatures is negative"], +["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough signatures on the stack"], +["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "EVAL_FALSE", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"], + +["", +"0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG", +"P2SH,STRICTENC", +"OP_COUNT", +"202 CHECKMULTISIGS, fails due to 201 op limit"], + +["1", +"0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY", +"P2SH,STRICTENC", +"INVALID_STACK_OPERATION", +""], + +["", +"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", +"P2SH,STRICTENC", +"OP_COUNT", +"Fails due to 201 sig op limit"], + +["1", +"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", +"P2SH,STRICTENC", +"OP_COUNT", +""], + + +["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "PUBKEY_COUNT", "nPubKeys > 20"], +["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "SIG_COUNT", "nSigs > nPubKeys"], + + +["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY", "Tests for Script.IsPushOnly()"], +["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "SIG_PUSHONLY"], + +["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED in P2SH should fail"], +["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "BAD_OPCODE", "OP_VER in P2SH should fail"], + +["0x00", "'00' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE", "Basic OP_0 execution"], + +["MINIMALDATA enforcement for PUSHDATAs"], + +["0x4c 0x00", "DROP 1", "MINIMALDATA", "MINIMALDATA", "Empty vector minimally represented by OP_0"], +["0x01 0x81", "DROP 1", "MINIMALDATA", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"], +["0x01 0x01", "DROP 1", "MINIMALDATA", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"], +["0x01 0x02", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x03", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x04", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x05", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x06", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x07", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x08", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x09", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0a", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0b", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0c", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0d", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0e", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x0f", "DROP 1", "MINIMALDATA", "MINIMALDATA"], +["0x01 0x10", "DROP 1", "MINIMALDATA", "MINIMALDATA"], + +["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "MINIMALDATA", + "PUSHDATA1 of 72 bytes minimally represented by direct push"], + +["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "MINIMALDATA", + "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"], + +["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "MINIMALDATA", + "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"], + +["MINIMALDATA enforcement for numeric arguments"], + +["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "0x80 (negative zero) numequals 0"], +["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"], +["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], +["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"], +["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], +["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"], +["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff"], +["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xff7f"], +["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffffff"], +["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff7f"], + +["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"], + +["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "UNKNOWN_ERROR"], +["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], + +["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], + +["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], + +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"], + + +["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"], +["pubkeys/signatures so they fail due to the STRICTENC rules on validly encoded"], +["signatures and pubkeys."], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", + "STRICTENC", + "PUBKEYTYPE", + "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." +], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "SIG_DER", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." +], +[ + "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f", + "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG", + "P2SH,STRICTENC", + "SIG_DER", + "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs" +], + +["Increase DERSIG test coverage"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Overly long signature is incorrectly encoded for DERSIG"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Missing S is incorrectly encoded for DERSIG"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "S with invalid S length is incorrectly encoded for DERSIG"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer R is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer S is incorrectly encoded for DERSIG"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length R is incorrectly encoded for DERSIG"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], + ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", @@ -709,6 +1259,13 @@ "OK", "P2PK" ], +[ + "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "", + "EVAL_FALSE", + "P2PK, bad sig" +], [ "0x47 0x304402206e05a6fe23c59196ffe176c9ddc31e73a9885638f9d1328d47c0c703863b8876022076feb53811aa5b04e0e79f938eb19906cc5e67548bc555a8e8b8b0fc603d840c01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG", @@ -716,6 +1273,13 @@ "OK", "P2PKH" ], +[ + "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", + "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", + "", + "EQUALVERIFY", + "P2PKH, bad pubkey" +], [ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", @@ -723,6 +1287,13 @@ "OK", "P2PK anyonecanpay" ], +[ + "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "", + "EVAL_FALSE", + "P2PK anyonecanpay marked with normal hashtype" +], [ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", @@ -730,6 +1301,13 @@ "OK", "P2SH(P2PK)" ], +[ + "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", + "P2SH", + "EVAL_FALSE", + "P2SH(P2PK), bad redeemscript" +], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", @@ -737,6 +1315,13 @@ "OK", "P2SH(P2PKH), bad sig but no VERIFY_P2SH" ], +[ + "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", + "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", + "P2SH", + "EQUALVERIFY", + "P2SH(P2PKH), bad sig" +], [ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", @@ -744,6 +1329,13 @@ "OK", "3-of-3" ], +[ + "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "", + "EVAL_FALSE", + "3-of-3, 2 sigs" +], [ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x30440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", @@ -751,6 +1343,13 @@ "OK", "P2SH(2-of-3)" ], +[ + "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", + "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", + "P2SH", + "EVAL_FALSE", + "P2SH(2-of-3), 1 sig" +], [ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -758,6 +1357,13 @@ "OK", "P2PK with too much R padding but no DERSIG" ], +[ + "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "SIG_DER", + "P2PK with too much R padding" +], [ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -765,6 +1371,13 @@ "OK", "P2PK with too much S padding but no DERSIG" ], +[ + "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "SIG_DER", + "P2PK with too much S padding" +], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -772,6 +1385,13 @@ "OK", "P2PK with too little R padding but no DERSIG" ], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "SIG_DER", + "P2PK with too little R padding" +], [ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", @@ -779,6 +1399,27 @@ "OK", "P2PK NOT with bad sig with too much R padding but no DERSIG" ], +[ + "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "DERSIG", + "SIG_DER", + "P2PK NOT with bad sig with too much R padding" +], +[ + "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "", + "EVAL_FALSE", + "P2PK NOT with too much R padding but no DERSIG" +], +[ + "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "DERSIG", + "SIG_DER", + "P2PK NOT with too much R padding" +], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -786,6 +1427,41 @@ "OK", "BIP66 example 1, without DERSIG" ], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "SIG_DER", + "BIP66 example 1, with DERSIG" +], +[ + "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "", + "EVAL_FALSE", + "BIP66 example 2, without DERSIG" +], +[ + "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "SIG_DER", + "BIP66 example 2, with DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "EVAL_FALSE", + "BIP66 example 3, without DERSIG" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "EVAL_FALSE", + "BIP66 example 3, with DERSIG" +], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", @@ -800,6 +1476,20 @@ "OK", "BIP66 example 4, with DERSIG" ], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "EVAL_FALSE", + "BIP66 example 5, without DERSIG" +], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "SIG_DER", + "BIP66 example 5, with DERSIG" +], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", @@ -807,6 +1497,13 @@ "OK", "BIP66 example 6, without DERSIG" ], +[ + "1", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "SIG_DER", + "BIP66 example 6, with DERSIG" +], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", @@ -814,6 +1511,41 @@ "OK", "BIP66 example 7, without DERSIG" ], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "SIG_DER", + "BIP66 example 7, with DERSIG" +], +[ + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "", + "EVAL_FALSE", + "BIP66 example 8, without DERSIG" +], +[ + "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "DERSIG", + "SIG_DER", + "BIP66 example 8, with DERSIG" +], +[ + "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "", + "EVAL_FALSE", + "BIP66 example 9, without DERSIG" +], +[ + "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "SIG_DER", + "BIP66 example 9, with DERSIG" +], [ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", @@ -821,6 +1553,27 @@ "OK", "BIP66 example 10, without DERSIG" ], +[ + "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", + "DERSIG", + "SIG_DER", + "BIP66 example 10, with DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "", + "EVAL_FALSE", + "BIP66 example 11, without DERSIG" +], +[ + "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", + "DERSIG", + "EVAL_FALSE", + "BIP66 example 11, with DERSIG" +], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", @@ -842,6 +1595,13 @@ "OK", "P2PK with multi-byte hashtype, without DERSIG" ], +[ + "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "DERSIG", + "SIG_DER", + "P2PK with multi-byte hashtype, with DERSIG" +], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", @@ -849,6 +1609,13 @@ "OK", "P2PK with high S but no LOW_S" ], +[ + "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "LOW_S", + "SIG_HIGH_S", + "P2PK with high S" +], [ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", @@ -856,6 +1623,27 @@ "OK", "P2PK with hybrid pubkey but no STRICTENC" ], +[ + "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "STRICTENC", + "PUBKEYTYPE", + "P2PK with hybrid pubkey" +], +[ + "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "", + "EVAL_FALSE", + "P2PK NOT with hybrid pubkey but no STRICTENC" +], +[ + "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "PUBKEYTYPE", + "P2PK NOT with hybrid pubkey" +], [ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", @@ -863,6 +1651,13 @@ "OK", "P2PK NOT with invalid hybrid pubkey but no STRICTENC" ], +[ + "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "PUBKEYTYPE", + "P2PK NOT with invalid hybrid pubkey" +], [ "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401", "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", @@ -877,6 +1672,13 @@ "OK", "1-of-2 with the second 1 hybrid pubkey" ], +[ + "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201", + "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", + "STRICTENC", + "PUBKEYTYPE", + "1-of-2 with the first 1 hybrid pubkey" +], [ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", @@ -884,6 +1686,13 @@ "OK", "P2PK with undefined hashtype but no STRICTENC" ], +[ + "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "STRICTENC", + "SIG_HASHTYPE", + "P2PK with undefined hashtype" +], [ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", @@ -891,6 +1700,13 @@ "OK", "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC" ], +[ + "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", + "STRICTENC", + "SIG_HASHTYPE", + "P2PK NOT with invalid sig and undefined hashtype" +], [ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", @@ -898,6 +1714,13 @@ "OK", "3-of-3 with nonzero dummy but no NULLDUMMY" ], +[ + "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "NULLDUMMY", + "SIG_NULLDUMMY", + "3-of-3 with nonzero dummy" +], [ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", @@ -905,6 +1728,13 @@ "OK", "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY" ], +[ + "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NULLDUMMY", + "SIG_NULLDUMMY", + "3-of-3 NOT with invalid sig with nonzero dummy" +], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", @@ -912,6 +1742,13 @@ "OK", "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" ], +[ + "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "SIGPUSHONLY", + "SIG_PUSHONLY", + "2-of-2 with two identical keys and sigs pushed using OP_DUP" +], [ "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", @@ -926,6 +1763,20 @@ "OK", "P2PK with non-push scriptSig but with P2SH validation" ], +[ + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", + "P2SH", + "SIG_PUSHONLY", + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" +], +[ + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", + "SIGPUSHONLY", + "SIG_PUSHONLY", + "P2SH(P2PK) with non-push scriptSig but not P2SH" +], [ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", @@ -940,6 +1791,13 @@ "OK", "P2PK with unnecessary input but no CLEANSTACK" ], +[ + "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "CLEANSTACK,P2SH", + "CLEANSTACK", + "P2PK with unnecessary input" +], [ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", @@ -947,6 +1805,13 @@ "OK", "P2SH with unnecessary input but no CLEANSTACK" ], +[ + "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", + "CLEANSTACK,P2SH", + "CLEANSTACK", + "P2SH with unnecessary input" +], [ "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 6340af208..d42187f91 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -2,8 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "data/script_invalid.json.h" -#include "data/script_valid.json.h" +#include "data/script_tests.json.h" #include "core_io.h" #include "key.h" @@ -399,356 +398,310 @@ BOOST_AUTO_TEST_CASE(script_build) { const KeyData keys; - std::vector good; - std::vector bad; + std::vector tests; - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2PK", 0 - ).PushSig(keys.key0)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2PK, bad sig", 0 - ).PushSig(keys.key0).DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK", 0 + ).PushSig(keys.key0)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK, bad sig", 0 + ).PushSig(keys.key0).DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, - "P2PKH", 0 - ).PushSig(keys.key1).Push(keys.pubkey1C)); - bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, - "P2PKH, bad pubkey", 0 - ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5).ScriptError(SCRIPT_ERR_EQUALVERIFY)); + tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH", 0 + ).PushSig(keys.key1).Push(keys.pubkey1C)); + tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH, bad pubkey", 0 + ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5).ScriptError(SCRIPT_ERR_EQUALVERIFY)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, - "P2PK anyonecanpay", 0 - ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, - "P2PK anyonecanpay marked with normal hashtype", 0 - ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01").ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK anyonecanpay", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK anyonecanpay marked with normal hashtype", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01").ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, - "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).PushRedeem()); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, - "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, - "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true - ).PushSig(keys.key0).DamagePush(10).PushRedeem()); - bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, - "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).DamagePush(10).PushRedeem().ScriptError(SCRIPT_ERR_EQUALVERIFY)); + tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem().ScriptError(SCRIPT_ERR_EQUALVERIFY)); - good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "3-of-3", 0 - ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); - bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "3-of-3, 2 sigs", 0 - ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3, 2 sigs", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true - ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true - ).Num(0).PushSig(keys.key1).Num(0).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).Num(0).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much R padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much S padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too little R padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with bad sig with too much R padding but no DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10).ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with too much R padding but no DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much R padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much S padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too little R padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with bad sig with too much R padding but no DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10).ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with too much R padding but no DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 1, without DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 2, without DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 3, without DERSIG", 0 - ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 4, without DERSIG", 0 - ).Num(0)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 5, without DERSIG", 0 - ).Num(1).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 6, without DERSIG", 0 - ).Num(1)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 7, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 8, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 9, without DERSIG", 0 - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 10, without DERSIG", 0 - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 11, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 12, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with multi-byte hashtype, without DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG - ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 1, without DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 2, without DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 3, without DERSIG", 0 + ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 4, without DERSIG", 0 + ).Num(0)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 5, without DERSIG", 0 + ).Num(1).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 6, without DERSIG", 0 + ).Num(1)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, + "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 7, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 8, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 9, without DERSIG", 0 + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 10, without DERSIG", 0 + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 11, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, + "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 12, without DERSIG", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, + "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG + ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with multi-byte hashtype, without DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101").ScriptError(SCRIPT_ERR_SIG_DER)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with high S but no LOW_S", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with high S", SCRIPT_VERIFY_LOW_S - ).PushSig(keys.key2, SIGHASH_ALL, 32, 33).ScriptError(SCRIPT_ERR_SIG_HIGH_S)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with high S but no LOW_S", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with high S", SCRIPT_VERIFY_LOW_S + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33).ScriptError(SCRIPT_ERR_SIG_HIGH_S)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, - "P2PK with hybrid pubkey but no STRICTENC", 0 - ).PushSig(keys.key0, SIGHASH_ALL)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, - "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with hybrid pubkey but no STRICTENC", 0 - ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 - ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); - good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, - "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); - good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, - "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); - bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, - "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).Num(0).PushSig(keys.key1, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, + "P2PK with hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, + "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, - "P2PK with undefined hashtype but no STRICTENC", 0 - ).PushSig(keys.key1, 5)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, - "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key1, 5).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0 - ).PushSig(keys.key1, 5).DamagePush(10)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key1, 5).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK with undefined hashtype but no STRICTENC", 0 + ).PushSig(keys.key1, 5)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, 5).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0 + ).PushSig(keys.key1, 5).DamagePush(10)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, 5).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); - good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "3-of-3 with nonzero dummy but no NULLDUMMY", 0 - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); - bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); - good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, - "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0 - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); - bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, - "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY - ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy but no NULLDUMMY", 0 + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, + "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0 + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, + "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, - "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0 - ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, - "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY - ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0, true - ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem()); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with non-push scriptSig but with P2SH validation", 0 - ).PushSig(keys.key2).Add(CScript() << OP_NOP8)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2SH(P2PK) with non-push scriptSig but not P2SH", SCRIPT_VERIFY_SIGPUSHONLY, true - ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, - "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY - ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH - ).Num(11).PushSig(keys.key0)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH - ).Num(11).PushSig(keys.key0).ScriptError(SCRIPT_ERR_CLEANSTACK)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true - ).Num(11).PushSig(keys.key0).PushRedeem()); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true - ).Num(11).PushSig(keys.key0).PushRedeem().ScriptError(SCRIPT_ERR_CLEANSTACK)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true - ).PushSig(keys.key0).PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0 + ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY + ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with non-push scriptSig but with P2SH validation", 0 + ).PushSig(keys.key2).Add(CScript() << OP_NOP8)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig but not P2SH", SCRIPT_VERIFY_SIGPUSHONLY, true + ).PushSig(keys.key2).Add(CScript() << OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY + ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH + ).Num(11).PushSig(keys.key0)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH + ).Num(11).PushSig(keys.key0).ScriptError(SCRIPT_ERR_CLEANSTACK)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true + ).Num(11).PushSig(keys.key0).PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true + ).Num(11).PushSig(keys.key0).PushRedeem().ScriptError(SCRIPT_ERR_CLEANSTACK)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem()); - std::set tests_good; - std::set tests_bad; + std::set tests_set; { - UniValue json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue json_tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests))); - for (unsigned int idx = 0; idx < json_good.size(); idx++) { - const UniValue& tv = json_good[idx]; - tests_good.insert(JSONPrettyPrint(tv.get_array())); - } - for (unsigned int idx = 0; idx < json_bad.size(); idx++) { - const UniValue& tv = json_bad[idx]; - tests_bad.insert(JSONPrettyPrint(tv.get_array())); + for (unsigned int idx = 0; idx < json_tests.size(); idx++) { + const UniValue& tv = json_tests[idx]; + tests_set.insert(JSONPrettyPrint(tv.get_array())); } } - std::string strGood; - std::string strBad; + std::string strGen; - BOOST_FOREACH(TestBuilder& test, good) { + BOOST_FOREACH(TestBuilder& test, tests) { test.Test(); std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS - if (tests_good.count(str) == 0) { + if (tests_set.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); } #endif - strGood += str + ",\n"; - } - BOOST_FOREACH(TestBuilder& test, bad) { - test.Test(); - std::string str = JSONPrettyPrint(test.GetJSON()); -#ifndef UPDATE_JSON_TESTS - if (tests_bad.count(str) == 0) { - BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); - } -#endif - strBad += str + ",\n"; + strGen += str + ",\n"; } #ifdef UPDATE_JSON_TESTS - FILE* valid = fopen("script_valid.json.gen", "w"); - fputs(strGood.c_str(), valid); - fclose(valid); - FILE* invalid = fopen("script_invalid.json.gen", "w"); - fputs(strBad.c_str(), invalid); - fclose(invalid); + FILE* file = fopen("script_tests.json.gen", "w"); + fputs(strGen.c_str(), file); + fclose(file); #endif } -BOOST_AUTO_TEST_CASE(script_valid) +BOOST_AUTO_TEST_CASE(script_json_test) { - // Read tests from test/data/script_valid.json + // Read tests from test/data/script_tests.json // Format is an array of arrays // Inner arrays are [ "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] // ... where scriptSig and scriptPubKey are stringified // scripts. - UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + UniValue tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests))); for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); - if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) - { - if (test.size() != 1) { - BOOST_ERROR("Bad test: " << strTest); - } - continue; - } - string scriptSigString = test[0].get_str(); - CScript scriptSig = ParseScript(scriptSigString); - string scriptPubKeyString = test[1].get_str(); - CScript scriptPubKey = ParseScript(scriptPubKeyString); - unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - BOOST_CHECK_EQUAL(test[3].get_str(), "OK"); - - DoTest(scriptPubKey, scriptSig, scriptflags, strTest, SCRIPT_ERR_OK); - } -} - -BOOST_AUTO_TEST_CASE(script_invalid) -{ - // Scripts that should evaluate as invalid - UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { - UniValue test = tests[idx]; - string strTest = test.write(); - if (test.size() < 4) // Allow size > 2; extra stuff ignored (useful for comments) + if (test.size() < 4) // Allow size > 3; extra stuff ignored (useful for comments) { if (test.size() != 1) { BOOST_ERROR("Bad test: " << strTest); From f20d42ed2b1b8de9c41525f96c40b172ab82ec99 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 3 Apr 2016 12:08:14 +0200 Subject: [PATCH 0407/1223] UpdateTip: log only one line at most per block Avoid logging two or more lines per block in UpdateTip by adding the warning into the UpdateTip log message. --- src/main.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2c0b3bfee..1044c3556 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -2555,16 +2556,10 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utx)\n", __func__, - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nVersion, - log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); - cvBlockChange.notify_all(); - // Check the version of the last 100 blocks to see if we need to upgrade: static bool fWarned = false; + std::vector warningMessages; if (!IsInitialBlockDownload()) { int nUpgraded = 0; @@ -2580,10 +2575,11 @@ void static UpdateTip(CBlockIndex *pindexNew) { fWarned = true; } } else { - LogPrintf("%s: unknown new rules are about to activate (versionbit %i)\n", __func__, bit); + warningMessages.push_back(strprintf("unknown new rules are about to activate (versionbit %i)", bit)); } } } + // Check the version of the last 100 blocks to see if we need to upgrade: for (int i = 0; i < 100 && pindex != NULL; i++) { int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus()); @@ -2592,7 +2588,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { pindex = pindex->pprev; } if (nUpgraded > 0) - LogPrintf("%s: %d of last 100 blocks have unexpected version\n", __func__, nUpgraded); + warningMessages.push_back(strprintf("%d of last 100 blocks have unexpected version", nUpgraded)); if (nUpgraded > 100/2) { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: @@ -2603,6 +2599,15 @@ void static UpdateTip(CBlockIndex *pindexNew) { } } } + LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utx)", __func__, + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nVersion, + log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), + Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); + if (!warningMessages.empty()) + LogPrintf(" warning='%s'", boost::algorithm::join(warningMessages, ", ")); + LogPrintf("\n"); + } /** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ From eda3d9248971a1c3df6e6c4b23ba89be30508b51 Mon Sep 17 00:00:00 2001 From: mruddy Date: Tue, 5 Apr 2016 22:26:38 +0000 Subject: [PATCH 0408/1223] Net: Add IPv6 Link-Local Address Support --- src/netbase.cpp | 10 +++++++--- src/netbase.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 7f79dd02c..281c6bcb7 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -170,7 +170,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign if (aiTrav->ai_family == AF_INET6) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); - vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); + struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr; + vIP.push_back(CNetAddr(s6->sin6_addr, s6->sin6_scope_id)); } aiTrav = aiTrav->ai_next; @@ -629,6 +630,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest void CNetAddr::Init() { memset(ip, 0, sizeof(ip)); + scopeId = 0; } void CNetAddr::SetIP(const CNetAddr& ipIn) @@ -678,9 +680,10 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr); } -CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) +CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) { SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr); + scopeId = scope; } CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) @@ -1099,7 +1102,7 @@ CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), po assert(addr.sin_family == AF_INET); } -CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) +CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port)) { assert(addr.sin6_family == AF_INET6); } @@ -1192,6 +1195,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const memset(paddrin6, 0, *addrlen); if (!GetIn6Addr(&paddrin6->sin6_addr)) return false; + paddrin6->sin6_scope_id = scopeId; paddrin6->sin6_family = AF_INET6; paddrin6->sin6_port = htons(port); return true; diff --git a/src/netbase.h b/src/netbase.h index 1db66ac27..db736154f 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -44,6 +44,7 @@ class CNetAddr { protected: unsigned char ip[16]; // in network byte order + uint32_t scopeId; // for scoped/link-local ipv6 addresses public: CNetAddr(); @@ -89,7 +90,7 @@ class CNetAddr std::vector GetGroup() const; int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; - CNetAddr(const struct in6_addr& pipv6Addr); + CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); bool GetIn6Addr(struct in6_addr* pipv6Addr) const; friend bool operator==(const CNetAddr& a, const CNetAddr& b); From 07398e8e9d2ef807e63abd0978a6e98549bdf271 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 6 Apr 2016 10:27:51 +0200 Subject: [PATCH 0409/1223] init: allow shutdown during 'Activating best chain...' Two-line patch to make it possible to shut down bitcoind cleanly during the initial ActivateBestChain. Fixes #6459 (among other complaints). To reproduce: - shutdown bitcoind - copy chainstate - start bitcoind - let the chain sync a bit - shutdown bitcoind - copy back old chainstate - start bitcoind - bitcoind will catch up with all blocks during Init() (the `boost::this_thread::interruption_point` / `ShutdownRequested()` dance is ugly, this should be refactored all over bitcoind at some point when moving from boost::threads to c++11 threads, but it works...) --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index b68c6affa..c1137c9b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2877,6 +2877,8 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, CBlockIndex *pindexMostWork = NULL; do { boost::this_thread::interruption_point(); + if (ShutdownRequested()) + break; CBlockIndex *pindexNewTip = NULL; const CBlockIndex *pindexFork; From 4f7c959af1672f9f51122867dca48ac4fa454d75 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 5 Apr 2016 14:20:49 +0200 Subject: [PATCH 0410/1223] Refactor IsRBFOptIn, avoid exception --- src/policy/rbf.cpp | 15 ++++++++------- src/policy/rbf.h | 8 +++++++- src/wallet/rpcwallet.cpp | 12 ++++-------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp index 98b1a1ba4..133cff611 100644 --- a/src/policy/rbf.cpp +++ b/src/policy/rbf.cpp @@ -14,33 +14,34 @@ bool SignalsOptInRBF(const CTransaction &tx) return false; } -bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool) +RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool) { AssertLockHeld(pool.cs); CTxMemPool::setEntries setAncestors; // First check the transaction itself. - if (SignalsOptInRBF(entry.GetTx())) { - return true; + if (SignalsOptInRBF(tx)) { + return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125; } // If this transaction is not in our mempool, then we can't be sure // we will know about all its inputs. - if (!pool.exists(entry.GetTx().GetHash())) { - throw std::runtime_error("Cannot determine RBF opt-in signal for non-mempool transaction\n"); + if (!pool.exists(tx.GetHash())) { + return RBF_TRANSACTIONSTATE_UNKNOWN; } // If all the inputs have nSequence >= maxint-1, it still might be // signaled for RBF if any unconfirmed parents have signaled. uint64_t noLimit = std::numeric_limits::max(); std::string dummy; + CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash()); pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) { if (SignalsOptInRBF(it->GetTx())) { - return true; + return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125; } } - return false; + return RBF_TRANSACTIONSTATE_FINAL; } diff --git a/src/policy/rbf.h b/src/policy/rbf.h index 925ce0d9b..5a711dba0 100644 --- a/src/policy/rbf.h +++ b/src/policy/rbf.h @@ -7,6 +7,12 @@ #include "txmempool.h" +enum RBFTransactionState { + RBF_TRANSACTIONSTATE_UNKNOWN, + RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125, + RBF_TRANSACTIONSTATE_FINAL +}; + // Check whether the sequence numbers on this transaction are signaling // opt-in to replace-by-fee, according to BIP 125 bool SignalsOptInRBF(const CTransaction &tx); @@ -15,6 +21,6 @@ bool SignalsOptInRBF(const CTransaction &tx); // according to BIP 125 // This involves checking sequence numbers of the transaction, as well // as the sequence numbers of all in-mempool ancestors. -bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool); +RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool); #endif // BITCOIN_POLICY_RBF_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 61c9846e1..5511e9d3a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -82,15 +82,11 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) std::string rbfStatus = "no"; if (confirms <= 0) { LOCK(mempool.cs); - if (!mempool.exists(hash)) { - if (SignalsOptInRBF(wtx)) { - rbfStatus = "yes"; - } else { - rbfStatus = "unknown"; - } - } else if (IsRBFOptIn(*mempool.mapTx.find(hash), mempool)) { + RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool); + if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN) + rbfStatus = "unknown"; + else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125) rbfStatus = "yes"; - } } entry.push_back(Pair("bip125-replaceable", rbfStatus)); From 9f7336b4575b15193151dbf08b09562529a24363 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 5 Apr 2016 10:45:11 +0200 Subject: [PATCH 0411/1223] [Wallet] slightly refactor GetOldestKeyPoolTime() --- src/wallet/wallet.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e8c946671..15b9af852 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2611,12 +2611,19 @@ bool CWallet::GetKeyFromPool(CPubKey& result) int64_t CWallet::GetOldestKeyPoolTime() { - int64_t nIndex = 0; - CKeyPool keypool; - ReserveKeyFromKeyPool(nIndex, keypool); - if (nIndex == -1) + LOCK(cs_wallet); + + // if the keypool is empty, return + if (setKeyPool.empty()) return GetTime(); - ReturnKey(nIndex); + + // load oldest key from keypool, get time and return + CKeyPool keypool; + CWalletDB walletdb(strWalletFile); + int64_t nIndex = *(setKeyPool.begin()); + if (!walletdb.ReadPool(nIndex, keypool)) + throw runtime_error("GetOldestKeyPoolTime(): read oldest key in keypool failed"); + assert(keypool.vchPubKey.IsValid()); return keypool.nTime; } From bf477bcc794360c145156c9e8f155e0215f70dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 6 Apr 2016 16:00:25 +0200 Subject: [PATCH 0412/1223] Trivial: Globals: Explicitly pass const CChainParams& to ProcessMessage() --- src/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b68c6affa..4e94ab780 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4475,9 +4475,8 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } -bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived) +bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams) { - const CChainParams& chainparams = Params(); RandAddSeedPerfmon(); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) @@ -5487,7 +5486,7 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime); + fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams); boost::this_thread::interruption_point(); } catch (const std::ios_base::failure& e) From 2d1d6581eca4508838cd339cc19c72efc42d6ea0 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 3 Apr 2016 15:24:09 +0200 Subject: [PATCH 0413/1223] Track block download times per individual block Currently, we're keeping a timeout for each requested block, starting from when it is requested, with a correction factor for the number of blocks in the queue. That's unnecessarily complicated and inaccurate. As peers process block requests in order, we can make the timeout for each block start counting only when all previous ones have been received, and have a correction based on the number of peers, rather than the total number of blocks. --- src/main.cpp | 60 +++++++++++++++++++++++++--------------------------- src/main.h | 4 ++++ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b68c6affa..de74593bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -195,15 +195,10 @@ namespace { struct QueuedBlock { uint256 hash; CBlockIndex* pindex; //!< Optional. - int64_t nTime; //!< Time of "getdata" request in microseconds. bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. - int64_t nTimeDisconnect; //!< The timeout for this block request (for disconnecting a slow peer) }; map::iterator> > mapBlocksInFlight; - /** Number of blocks in flight with validated headers. */ - int nQueuedValidatedHeaders = 0; - /** Number of preferable block download peers. */ int nPreferredDownload = 0; @@ -212,6 +207,9 @@ namespace { /** Dirty block file entries. */ set setDirtyFileInfo; + + /** Number of peers from which we're downloading blocks. */ + int nPeersWithValidatedDownloads = 0; } // anon namespace ////////////////////////////////////////////////////////////////////////////// @@ -259,6 +257,8 @@ struct CNodeState { //! Since when we're stalling block download progress (in microseconds), or 0. int64_t nStallingSince; list vBlocksInFlight; + //! When the first entry in vBlocksInFlight started downloading. Don't care when vBlocksInFlight is empty. + int64_t nDownloadingSince; int nBlocksInFlight; int nBlocksInFlightValidHeaders; //! Whether we consider this a preferred download peer. @@ -276,6 +276,7 @@ struct CNodeState { pindexBestHeaderSent = NULL; fSyncStarted = false; nStallingSince = 0; + nDownloadingSince = 0; nBlocksInFlight = 0; nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; @@ -310,12 +311,6 @@ void UpdatePreferredDownload(CNode* node, CNodeState* state) nPreferredDownload += state->fPreferredDownload; } -// Returns time at which to timeout block request (nTime in microseconds) -int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams) -{ - return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore); -} - void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; @@ -335,11 +330,12 @@ void FinalizeNode(NodeId nodeid) { } BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) { - nQueuedValidatedHeaders -= entry.fValidatedHeaders; mapBlocksInFlight.erase(entry.hash); } EraseOrphansFor(nodeid); nPreferredDownload -= state->fPreferredDownload; + nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0); + assert(nPeersWithValidatedDownloads >= 0); mapNodeState.erase(nodeid); } @@ -350,8 +346,15 @@ bool MarkBlockAsReceived(const uint256& hash) { map::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end()) { CNodeState *state = State(itInFlight->second.first); - nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders; state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders; + if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) { + // Last validated block on the queue was received. + nPeersWithValidatedDownloads--; + } + if (state->vBlocksInFlight.begin() == itInFlight->second.second) { + // First block on the queue was received, update the start download time for the next one + state->nDownloadingSince = std::max(state->nDownloadingSince, GetTimeMicros()); + } state->vBlocksInFlight.erase(itInFlight->second.second); state->nBlocksInFlight--; state->nStallingSince = 0; @@ -369,12 +372,17 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - int64_t nNow = GetTimeMicros(); - QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)}; - nQueuedValidatedHeaders += newentry.fValidatedHeaders; + QueuedBlock newentry = {hash, pindex, pindex != NULL}; list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders; + if (state->nBlocksInFlight == 1) { + // We're starting a block download (batch) from this peer. + state->nDownloadingSince = GetTimeMicros(); + } + if (state->nBlocksInFlightValidHeaders == 1 && pindex != NULL) { + nPeersWithValidatedDownloads++; + } mapBlocksInFlight[hash] = std::make_pair(nodeid, it); } @@ -3894,7 +3902,6 @@ void UnloadBlockIndex() nBlockSequenceId = 1; mapBlockSource.clear(); mapBlocksInFlight.clear(); - nQueuedValidatedHeaders = 0; nPreferredDownload = 0; setDirtyBlockIndex.clear(); setDirtyFileInfo.clear(); @@ -5811,24 +5818,15 @@ bool SendMessages(CNode* pto) LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id); pto->fDisconnect = true; } - // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval - // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to - // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link + // In case there is a block that has been in flight from this peer for 2 + 0.5 * N times the block interval + // (with N the number of peers from which we're downloading validated blocks), disconnect due to timeout. + // We compensate for other peers to prevent killing off peers due to our own downstream link // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes // to unreasonably increase our timeout. - // We also compare the block download timeout originally calculated against the time at which we'd disconnect - // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're - // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a - // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing - // more quickly than once every 5 minutes, then we'll shorten the download window for this block). if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) { QueuedBlock &queuedBlock = state.vBlocksInFlight.front(); - int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams); - if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) { - LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow); - queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow; - } - if (queuedBlock.nTimeDisconnect < nNow) { + int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0); + if (nNow > state.nDownloadingSince + consensusParams.nPowTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) { LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id); pto->fDisconnect = true; } diff --git a/src/main.h b/src/main.h index 3ea9dc500..68fcf8e7c 100644 --- a/src/main.h +++ b/src/main.h @@ -106,6 +106,10 @@ static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60; /** Maximum feefilter broadcast delay after significant change. */ static const unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60; +/** Block download timeout base, expressed in millionths of the block interval (i.e. 20 min) */ +static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 2000000; +/** Additional block download timeout per parallel downloading peer (i.e. 5 min) */ +static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 500000; static const unsigned int DEFAULT_LIMITFREERELAY = 15; static const bool DEFAULT_RELAYPRIORITY = true; From 0e24bbf679c95784ed5514a6a1f2fbf99dd97725 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 4 Apr 2016 13:35:26 +0200 Subject: [PATCH 0414/1223] Self check after the last peer is removed --- src/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index de74593bb..87c727b28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -338,6 +338,13 @@ void FinalizeNode(NodeId nodeid) { assert(nPeersWithValidatedDownloads >= 0); mapNodeState.erase(nodeid); + + if (mapNodeState.empty()) { + // Do a consistency check after the last peer is removed. + assert(mapBlocksInFlight.empty()); + assert(nPreferredDownload == 0); + assert(nPeersWithValidatedDownloads == 0); + } } // Requires cs_main. From 62b9a557fca2aa55803c336ffcceccc50ccf0c3e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 7 Apr 2016 13:18:11 +0200 Subject: [PATCH 0415/1223] Reduce block timeout to 10 minutes Now that #7804 fixed the timeout handling, reduce the block timeout from 20 minutes to 10 minutes. 20 minutes is overkill. --- src/main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.h b/src/main.h index 68fcf8e7c..0962f44e9 100644 --- a/src/main.h +++ b/src/main.h @@ -106,8 +106,8 @@ static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60; /** Maximum feefilter broadcast delay after significant change. */ static const unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60; -/** Block download timeout base, expressed in millionths of the block interval (i.e. 20 min) */ -static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 2000000; +/** Block download timeout base, expressed in millionths of the block interval (i.e. 10 min) */ +static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000; /** Additional block download timeout per parallel downloading peer (i.e. 5 min) */ static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 500000; From 5078ca45438e8f8d8e7cd937659887fb8ec70038 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 7 Apr 2016 15:21:01 +0200 Subject: [PATCH 0416/1223] tests: Check Content-Type header returned from RPC server Check the Content-Type header that is returned from the RPC server. Only if it is `application/json` the data is supposed to be parsed as JSON. This gives better reporting if the HTTP server happens to return an error that is not JSON-formatted, which is the case if it happens at a lower level before JSON-RPC kicks in. Before: `Unexpected exception caught during testing: No JSON object could be decoded` After: `JSONRPC error: non-JSON HTTP response with '403 Forbidden' from server` --- qa/rpc-tests/test_framework/authproxy.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 1eb277259..e5f7ab365 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -154,6 +154,11 @@ class AuthServiceProxy(object): raise JSONRPCException({ 'code': -342, 'message': 'missing HTTP response from server'}) + content_type = http_response.getheader('Content-Type') + if content_type != 'application/json': + raise JSONRPCException({ + 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) + responsedata = http_response.read().decode('utf8') response = json.loads(responsedata, parse_float=decimal.Decimal) if "error" in response and response["error"] is None: From 617deeb06e99d4b5fb76235b6009ec72accb4970 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Mon, 4 Apr 2016 11:17:23 -0400 Subject: [PATCH 0417/1223] Gave miner test values constants for less error-prone values. --- src/test/miner_tests.cpp | 53 ++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index ab6485081..492bed145 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -124,6 +124,11 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; + const CAmount BLOCKSUBSIDY = 50*COIN; + const CAmount LOWFEE = CENT; + const CAmount HIGHFEE = COIN; + const CAmount HIGHERFEE = 4*COIN; + // block sigops > limit: 1000 CHECKMULTISIG + 1 tx.vin.resize(1); // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG @@ -131,28 +136,28 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].prevout.n = 0; tx.vout.resize(1); - tx.vout[0].nValue = 5000000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY; for (unsigned int i = 0; i < 1001; ++i) { - tx.vout[0].nValue -= 1000000; + tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails - mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); - tx.vout[0].nValue = 5000000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY; for (unsigned int i = 0; i < 1001; ++i) { - tx.vout[0].nValue -= 1000000; + tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes - mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); @@ -167,13 +172,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].scriptSig << vchData << OP_DROP; tx.vin[0].scriptSig << OP_1; tx.vin[0].prevout.hash = txFirst[0]->GetHash(); - tx.vout[0].nValue = 5000000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY; for (unsigned int i = 0; i < 128; ++i) { - tx.vout[0].nValue -= 10000000; + tx.vout[0].nValue -= 10*LOWFEE; hash = tx.GetHash(); bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase - mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); @@ -182,24 +187,24 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // orphan in mempool, template creation fails hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent tx.vin[0].scriptSig = CScript() << OP_1; tx.vin[0].prevout.hash = txFirst[1]->GetHash(); - tx.vout[0].nValue = 4900000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; tx.vin[1].prevout.hash = txFirst[0]->GetHash(); tx.vin[1].prevout.n = 0; - tx.vout[0].nValue = 5900000000LL; + tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -211,7 +216,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); // give it a fee so it'll get mined - mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE/10).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); @@ -219,29 +224,29 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].prevout.n = 0; tx.vin[0].scriptSig = CScript() << OP_1; - tx.vout[0].nValue = 4900000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY-LOWFEE; script = CScript() << OP_0; tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin[0].scriptSig = CScript() << std::vector(script.begin(), script.end()); - tx.vout[0].nValue -= 1000000; + tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // double spend txn pair in mempool, template creation fails tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].scriptSig = CScript() << OP_1; - tx.vout[0].nValue = 4900000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); @@ -298,11 +303,11 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = chainActive.Tip()->nHeight + 1; // txFirst[0] is the 2nd block prevheights[0] = baseheight + 1; tx.vout.resize(1); - tx.vout[0].nValue = 4900000000LL; + tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; tx.vout[0].scriptPubKey = CScript() << OP_1; tx.nLockTime = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 2))); // Sequence locks pass on 2nd block From f8536a62c318aeb1049479568aa8c4b6b03e87a6 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Wed, 6 Apr 2016 08:29:19 -0400 Subject: [PATCH 0418/1223] Corrected values --- src/test/miner_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 492bed145..469862518 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = BLOCKSUBSIDY; for (unsigned int i = 0; i < 128; ++i) { - tx.vout[0].nValue -= 10*LOWFEE; + tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); // give it a fee so it'll get mined - mempool.addUnchecked(hash, entry.Fee(LOWFEE/10).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); From e4ba9f6b0402cf7a2ad0d74f617c434a26c6e124 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Apr 2016 14:33:08 -0400 Subject: [PATCH 0419/1223] Version 2 transactions remain non-standard until CSV activates Before activation, such transactions might not be mined, so don't allow into the mempool. --- src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index a9f104c88..f5c7e11d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1025,6 +1025,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (fRequireStandard && !IsStandardTx(tx, reason)) return state.DoS(0, false, REJECT_NONSTANDARD, reason); + // Don't relay version 2 transactions until CSV is active, and we can be + // sure that such transactions will be mined (unless we're on + // -testnet/-regtest). + const CChainParams& chainparams = Params(); + if (fRequireStandard && tx.nVersion >= 2 && VersionBitsTipState(chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV) != THRESHOLD_ACTIVE) { + return state.DoS(0, false, REJECT_NONSTANDARD, "premature-version2-tx"); + } + // Only accept nLockTime-using transactions that can be mined in the next // block; we don't want our mempool filled up with transactions that can't // be mined yet. From 5cb1d8a2071d05beb9907a423178895fd8a5c359 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Apr 2016 14:54:50 -0400 Subject: [PATCH 0420/1223] Tests: move get_bip9_status to util.py --- qa/rpc-tests/bip68-112-113-p2p.py | 19 ++++++------------- qa/rpc-tests/test_framework/util.py | 7 +++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index f391cb0b7..35c831cb8 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -149,13 +149,6 @@ class BIP68_112_113Test(ComparisonTestFramework): block.solve() return block - def get_bip9_status(self, key): - info = self.nodes[0].getblockchaininfo() - for row in info['bip9_softforks']: - if row['id'] == key: - return row - raise IndexError ('key:"%s" not found' % key) - def create_bip68txs(self, bip68inputs, txversion, locktime_delta = 0): txs = [] assert(len(bip68inputs) >= 16) @@ -223,11 +216,11 @@ class BIP68_112_113Test(ComparisonTestFramework): self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - assert_equal(self.get_bip9_status('csv')['status'], 'defined') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'defined') test_blocks = self.generate_blocks(61, 4) yield TestInstance(test_blocks, sync_every_block=False) # 1 # Advanced from DEFINED to STARTED, height = 143 - assert_equal(self.get_bip9_status('csv')['status'], 'started') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started') # Fail to achieve LOCKED_IN 100 out of 144 signal bit 0 # using a variety of bits to simulate multiple parallel softforks @@ -237,7 +230,7 @@ class BIP68_112_113Test(ComparisonTestFramework): test_blocks = self.generate_blocks(24, 536936448, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) # 2 # Failed to advance past STARTED, height = 287 - assert_equal(self.get_bip9_status('csv')['status'], 'started') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started') # 108 out of 144 signal bit 0 to achieve lock-in # using a variety of bits to simulate multiple parallel softforks @@ -247,7 +240,7 @@ class BIP68_112_113Test(ComparisonTestFramework): test_blocks = self.generate_blocks(10, 536936448, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) # 3 # Advanced from STARTED to LOCKED_IN, height = 431 - assert_equal(self.get_bip9_status('csv')['status'], 'locked_in') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in') # 140 more version 4 blocks test_blocks = self.generate_blocks(140, 4) @@ -291,7 +284,7 @@ class BIP68_112_113Test(ComparisonTestFramework): test_blocks = self.generate_blocks(2, 4) yield TestInstance(test_blocks, sync_every_block=False) # 5 # Not yet advanced to ACTIVE, height = 574 (will activate for block 576, not 575) - assert_equal(self.get_bip9_status('csv')['status'], 'locked_in') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in') # Test both version 1 and version 2 transactions for all tests # BIP113 test transaction will be modified before each use to put in appropriate block time @@ -368,7 +361,7 @@ class BIP68_112_113Test(ComparisonTestFramework): # 1 more version 4 block to get us to height 575 so the fork should now be active for the next block test_blocks = self.generate_blocks(1, 4) yield TestInstance(test_blocks, sync_every_block=False) # 8 - assert_equal(self.get_bip9_status('csv')['status'], 'active') + assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'active') ################################# diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index f069c32a6..d9fe0f75f 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -545,3 +545,10 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee): txid = node.sendrawtransaction(signresult["hex"], True) txids.append(txid) return txids + +def get_bip9_status(node, key): + info = node.getblockchaininfo() + for row in info['bip9_softforks']: + if row['id'] == key: + return row + raise IndexError ('key:"%s" not found' % key) From da5fdbb3a2778523cce70d635c1aa2b31a693bc6 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Apr 2016 14:59:50 -0400 Subject: [PATCH 0421/1223] Test relay of version 2 transactions --- qa/rpc-tests/bip68-sequence.py | 46 +++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 377a35b68..33e05dfc5 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -# Test BIP68 implementation (mempool only) +# Test BIP68 implementation # from test_framework.test_framework import BitcoinTestFramework @@ -26,8 +26,10 @@ class BIP68Test(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"])) self.is_network_split = False self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] + connect_nodes(self.nodes[0], 1) def run_test(self): # Generate some coins @@ -42,10 +44,18 @@ class BIP68Test(BitcoinTestFramework): print "Running test sequence-lock-unconfirmed-inputs" self.test_sequence_lock_unconfirmed_inputs() - # This test needs to change when BIP68 becomes consensus - print "Running test BIP68 not consensus" + print "Running test BIP68 not consensus before versionbits activation" self.test_bip68_not_consensus() + print "Verifying nVersion=2 transactions aren't standard" + self.test_version2_relay(before_activation=True) + + print "Activating BIP68 (and 112/113)" + self.activateCSV() + + print "Verifying nVersion=2 transactions are now standard" + self.test_version2_relay(before_activation=False) + print "Passed\n" # Test that BIP68 is not in effect if tx version is 1, or if @@ -333,8 +343,12 @@ class BIP68Test(BitcoinTestFramework): self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1)) self.nodes[0].generate(10) - # Make sure that BIP68 isn't being used to validate blocks. + # Make sure that BIP68 isn't being used to validate blocks, prior to + # versionbits activation. If more blocks are mined prior to this test + # being run, then it's possible the test has activated the soft fork, and + # this test should be moved to run earlier, or deleted. def test_bip68_not_consensus(self): + assert(get_bip9_status(self.nodes[0], 'csv')['status'] != 'active') txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) @@ -381,6 +395,30 @@ class BIP68Test(BitcoinTestFramework): self.nodes[0].submitblock(ToHex(block)) assert_equal(self.nodes[0].getbestblockhash(), block.hash) + def activateCSV(self): + # activation should happen at block height 432 (3 periods) + min_activation_height = 432 + height = self.nodes[0].getblockcount() + assert(height < 432) + self.nodes[0].generate(432-height) + assert(get_bip9_status(self.nodes[0], 'csv')['status'] == 'active') + sync_blocks(self.nodes) + + # Use self.nodes[1] to test standardness relay policy + def test_version2_relay(self, before_activation): + inputs = [ ] + outputs = { self.nodes[1].getnewaddress() : 1.0 } + rawtx = self.nodes[1].createrawtransaction(inputs, outputs) + rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex'] + tx = FromHex(CTransaction(), rawtxfund) + tx.nVersion = 2 + tx_signed = self.nodes[1].signrawtransaction(ToHex(tx))["hex"] + try: + tx_id = self.nodes[1].sendrawtransaction(tx_signed) + assert(before_activation == False) + except: + assert(before_activation) + if __name__ == '__main__': BIP68Test().main() From 11114a69c86e9abf4dd7e88ac268f5d078f40913 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 13:18:31 +0200 Subject: [PATCH 0422/1223] [amount] test negative fee rates and full constructor --- src/test/amount_tests.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index 59dab2063..c65646474 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -27,6 +27,15 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 1e3); BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 9e3); + feeRate = CFeeRate(-1000); + // Must always just return -1 * arg + BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); + BOOST_CHECK_EQUAL(feeRate.GetFee(1), -1); + BOOST_CHECK_EQUAL(feeRate.GetFee(121), -121); + BOOST_CHECK_EQUAL(feeRate.GetFee(999), -999); + BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), -1e3); + BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), -9e3); + feeRate = CFeeRate(123); // Truncates the result, if not integer BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); @@ -37,6 +46,26 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK_EQUAL(feeRate.GetFee(999), 122); BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), 123); BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), 1107); + + feeRate = CFeeRate(-123); + // Truncates the result, if not integer + BOOST_CHECK_EQUAL(feeRate.GetFee(0), 0); + BOOST_CHECK_EQUAL(feeRate.GetFee(8), -1); // Special case: returns -1 instead of 0 + BOOST_CHECK_EQUAL(feeRate.GetFee(9), -1); + + // Check full constructor + // default value + BOOST_CHECK(CFeeRate(CAmount(-1), 1000) == CFeeRate(-1)); + BOOST_CHECK(CFeeRate(CAmount(0), 1000) == CFeeRate(0)); + BOOST_CHECK(CFeeRate(CAmount(1), 1000) == CFeeRate(1)); + // lost precision (can only resolve satoshis per kB) + BOOST_CHECK(CFeeRate(CAmount(1), 1001) == CFeeRate(0)); + BOOST_CHECK(CFeeRate(CAmount(2), 1001) == CFeeRate(1)); + // some more integer checks + BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); + BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); + // Maximum size in bytes, should not crash + CFeeRate(MAX_MONEY, (std::numeric_limits::max() >> 1) - 1).GetFeePerK(); } BOOST_AUTO_TEST_SUITE_END() From fa2da2cb607ba359231fccc9635abe7c8616de56 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 13:44:01 +0200 Subject: [PATCH 0423/1223] [amount] Add support for negative fee rates Currently negative fee rates are not supported on archs of 64-bit or more --- src/amount.cpp | 20 +++++++++++++++----- src/amount.h | 11 +++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/amount.cpp b/src/amount.cpp index 68806ff06..7b8618de3 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -9,20 +9,30 @@ const std::string CURRENCY_UNIT = "BTC"; -CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) +CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_) { + assert(nBytes_ <= uint64_t(std::numeric_limits::max())); + int64_t nSize = int64_t(nBytes_); + if (nSize > 0) - nSatoshisPerK = nFeePaid*1000/nSize; + nSatoshisPerK = nFeePaid * 1000 / nSize; else nSatoshisPerK = 0; } -CAmount CFeeRate::GetFee(size_t nSize) const +CAmount CFeeRate::GetFee(size_t nBytes_) const { + assert(nBytes_ <= uint64_t(std::numeric_limits::max())); + int64_t nSize = int64_t(nBytes_); + CAmount nFee = nSatoshisPerK * nSize / 1000; - if (nFee == 0 && nSize != 0 && nSatoshisPerK > 0) - nFee = CAmount(1); + if (nFee == 0 && nSize != 0) { + if (nSatoshisPerK > 0) + nFee = CAmount(1); + if (nSatoshisPerK < 0) + nFee = CAmount(-1); + } return nFee; } diff --git a/src/amount.h b/src/amount.h index 9aba6525c..5e52f37f2 100644 --- a/src/amount.h +++ b/src/amount.h @@ -11,6 +11,7 @@ #include #include +/** Amount in satoshis (Can be negative) */ typedef int64_t CAmount; static const CAmount COIN = 100000000; @@ -30,22 +31,24 @@ extern const std::string CURRENCY_UNIT; static const CAmount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } -/** Type-safe wrapper class for fee rates - * (how much to pay based on transaction size) +/** + * Fee rate in satoshis per kilobyte: CAmount / kB */ class CFeeRate { private: CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes public: + /** Fee rate of 0 satoshis per kB */ CFeeRate() : nSatoshisPerK(0) { } explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } - CFeeRate(const CAmount& nFeePaid, size_t nSize); + /** Constructor for a fee rate in satoshis per kB. The size in bytes must not exceed (2^63 - 1)*/ + CFeeRate(const CAmount& nFeePaid, size_t nBytes); CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } /** * Return the fee in satoshis for the given size in bytes. */ - CAmount GetFee(size_t size) const; + CAmount GetFee(size_t nBytes) const; /** * Return the fee in satoshis for a size of 1000 bytes */ From 03c77fdc143fb8d533011f23164daac560e381b2 Mon Sep 17 00:00:00 2001 From: Matthew English Date: Fri, 1 Apr 2016 23:44:26 +0200 Subject: [PATCH 0424/1223] Doc: Update isStandardTx comment --- src/policy/policy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index e3ed7be00..d1a15451d 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -73,12 +73,12 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) BOOST_FOREACH(const CTxIn& txin, tx.vin) { // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed - // keys. (remember the 520 byte limit on redeemScript size) That works + // keys (remember the 520 byte limit on redeemScript size). That works // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627 // bytes of scriptSig, which we round off to 1650 bytes for some minor // future-proofing. That's also enough to spend a 20-of-20 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not - // considered standard) + // considered standard. if (txin.scriptSig.size() > 1650) { reason = "scriptsig-size"; return false; From 4521f005a1e61969f21b91a7e8eef5a5cdfdd191 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 9 Apr 2016 06:52:43 +0200 Subject: [PATCH 0425/1223] tests: add varints_bitpatterns test The current tests for varint only check that serialization-deserialization is a roundtrip. That is a useful test, but it is also good to check for some exact bit patterns, to prevent a code change that changes the serialization format from going undetected. As the varint functions are templated, also check with different types. --- src/test/serialize_tests.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index c0fd99aca..bec2c7459 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -160,6 +160,27 @@ BOOST_AUTO_TEST_CASE(varints) } } +BOOST_AUTO_TEST_CASE(varints_bitpatterns) +{ + CDataStream ss(SER_DISK, 0); + ss << VARINT(0); BOOST_CHECK_EQUAL(HexStr(ss), "00"); ss.clear(); + ss << VARINT(0x7f); BOOST_CHECK_EQUAL(HexStr(ss), "7f"); ss.clear(); + ss << VARINT((int8_t)0x7f); BOOST_CHECK_EQUAL(HexStr(ss), "7f"); ss.clear(); + ss << VARINT(0x80); BOOST_CHECK_EQUAL(HexStr(ss), "8000"); ss.clear(); + ss << VARINT((uint8_t)0x80); BOOST_CHECK_EQUAL(HexStr(ss), "8000"); ss.clear(); + ss << VARINT(0x1234); BOOST_CHECK_EQUAL(HexStr(ss), "a334"); ss.clear(); + ss << VARINT((int16_t)0x1234); BOOST_CHECK_EQUAL(HexStr(ss), "a334"); ss.clear(); + ss << VARINT(0xffff); BOOST_CHECK_EQUAL(HexStr(ss), "82fe7f"); ss.clear(); + ss << VARINT((uint16_t)0xffff); BOOST_CHECK_EQUAL(HexStr(ss), "82fe7f"); ss.clear(); + ss << VARINT(0x123456); BOOST_CHECK_EQUAL(HexStr(ss), "c7e756"); ss.clear(); + ss << VARINT((int32_t)0x123456); BOOST_CHECK_EQUAL(HexStr(ss), "c7e756"); ss.clear(); + ss << VARINT(0x80123456U); BOOST_CHECK_EQUAL(HexStr(ss), "86ffc7e756"); ss.clear(); + ss << VARINT((uint32_t)0x80123456U); BOOST_CHECK_EQUAL(HexStr(ss), "86ffc7e756"); ss.clear(); + ss << VARINT(0xffffffff); BOOST_CHECK_EQUAL(HexStr(ss), "8efefefe7f"); ss.clear(); + ss << VARINT(0x7fffffffffffffffLL); BOOST_CHECK_EQUAL(HexStr(ss), "fefefefefefefefe7f"); ss.clear(); + ss << VARINT(0xffffffffffffffffULL); BOOST_CHECK_EQUAL(HexStr(ss), "80fefefefefefefefe7f"); ss.clear(); +} + BOOST_AUTO_TEST_CASE(compactsize) { CDataStream ss(SER_DISK, 0); From 62a64860580253d9c733f3b8826908bba40eab1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 8 Apr 2016 18:52:59 +0200 Subject: [PATCH 0426/1223] RPC: do not print ping info in getpeerinfo when no ping received yet, fix help --- src/rpc/net.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 017cd6ca3..ce14d034c 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -97,9 +97,9 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " \"bytesrecv\": n, (numeric) The total bytes received\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" - " \"pingtime\": n, (numeric) ping time\n" - " \"minping\": n, (numeric) minimum observed ping time\n" - " \"pingwait\": n, (numeric) ping wait\n" + " \"pingtime\": n, (numeric) ping time (if available)\n" + " \"minping\": n, (numeric) minimum observed ping time (if any at all)\n" + " \"pingwait\": n, (numeric) ping wait (if non-zero)\n" " \"version\": v, (numeric) The peer version, such as 7001\n" " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n" " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n" @@ -150,8 +150,10 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); obj.push_back(Pair("conntime", stats.nTimeConnected)); obj.push_back(Pair("timeoffset", stats.nTimeOffset)); - obj.push_back(Pair("pingtime", stats.dPingTime)); - obj.push_back(Pair("minping", stats.dPingMin)); + if (stats.dPingTime > 0.0) + obj.push_back(Pair("pingtime", stats.dPingTime)); + if (stats.dPingMin < std::numeric_limits::max()/1e6) + obj.push_back(Pair("minping", stats.dPingMin)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); From fe53a2af6f8dccd53116ae35f28ec3860cc72f19 Mon Sep 17 00:00:00 2001 From: mruddy Date: Fri, 8 Apr 2016 20:15:41 -0400 Subject: [PATCH 0427/1223] doc: add arch linux setup and build example [skip ci] --- doc/build-unix.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index c1e92d8d1..dc754fc73 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -250,6 +250,24 @@ A list of additional configure flags can be displayed with: ./configure --help +Setup and Build Example: Arch Linux +----------------------------------- +This example lists the steps necessary to setup and build a command line only, non-wallet distribution of the latest changes on Arch Linux: + + pacman -S git base-devel boost libevent python + git clone https://github.com/bitcoin/bitcoin.git + cd bitcoin/ + ./autogen.sh + ./configure --disable-wallet --without-gui --without-miniupnpc + make check + +Note: +Enabling wallet support requires either compiling against a Berkeley DB newer than 4.8 (package `db`) using `--with-incompatible-bdb`, +or building and depending on a local version of Berkeley DB 4.8. The readily available Arch Linux packages are currently built using +`--with-incompatible-bdb` according to the [PKGBUILD](https://projects.archlinux.org/svntogit/community.git/tree/bitcoin/trunk/PKGBUILD). +As mentioned above, when maintaining portability of the wallet between the standard Bitcoin Core distributions and independently built +node software is desired, Berkeley DB 4.8 must be used. + ARM Cross-compilation ------------------- @@ -270,4 +288,4 @@ To build executables for ARM: make -For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. \ No newline at end of file +For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. From facf5a494708df755a15d63d339412201512e13f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 9 Apr 2016 15:28:17 +0200 Subject: [PATCH 0428/1223] [amount] tests: Fix off-by-one mistake --- src/test/amount_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index c65646474..fd6f88b36 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); // Maximum size in bytes, should not crash - CFeeRate(MAX_MONEY, (std::numeric_limits::max() >> 1) - 1).GetFeePerK(); + CFeeRate(MAX_MONEY, std::numeric_limits::max() >> 1).GetFeePerK(); } BOOST_AUTO_TEST_SUITE_END() From fa05e22e919b7e2e816606f0c0d3dea1bd325bfd Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 9 Apr 2016 21:14:18 +0200 Subject: [PATCH 0429/1223] [qa] pull-tester: Don't mute zmq ImportError --- qa/pull-tester/rpc-tests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 6d3bda10e..17c0b3adf 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -45,10 +45,10 @@ if 'ENABLE_ZMQ' not in vars(): if ENABLE_ZMQ: try: import zmq - except ImportError: - print("WARNING: \"import zmq\" failed. Setting ENABLE_ZMQ=0. " \ - "To run zmq tests, see dependency info in /qa/README.md.") - ENABLE_ZMQ=0 + except ImportError as e: + print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ + "to run zmq tests, see dependency info in /qa/README.md.") + raise e ENABLE_COVERAGE=0 From faa4f22342b682a5ead1bbb8587facd761b4ac2d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 9 Apr 2016 22:17:52 +0200 Subject: [PATCH 0430/1223] [qa] pull-tester: Exit early when no tests are run --- qa/pull-tester/rpc-tests.py | 110 ++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 17c0b3adf..e159082a0 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -40,15 +40,6 @@ if 'ENABLE_UTILS' not in vars(): ENABLE_UTILS=0 if 'ENABLE_ZMQ' not in vars(): ENABLE_ZMQ=0 - -# python-zmq may not be installed. Handle this gracefully and with some helpful info -if ENABLE_ZMQ: - try: - import zmq - except ImportError as e: - print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ - "to run zmq tests, see dependency info in /qa/README.md.") - raise e ENABLE_COVERAGE=0 @@ -76,11 +67,24 @@ if "BITCOIND" not in os.environ: if "BITCOINCLI" not in os.environ: os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT -#Disable Windows tests by default if EXEEXT == ".exe" and "-win" not in opts: - print "Win tests currently disabled. Use -win option to enable" + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + print "Win tests currently disabled by default. Use -win option to enable" sys.exit(0) +if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): + print "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" + sys.exit(0) + +# python-zmq may not be installed. Handle this gracefully and with some helpful info +if ENABLE_ZMQ: + try: + import zmq + except ImportError as e: + print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ + "to run zmq tests, see dependency info in /qa/README.md.") + raise e + #Tests testScripts = [ 'bip68-112-113-p2p.py', @@ -119,6 +123,9 @@ testScripts = [ 'p2p-versionbits-warning.py', 'importprunedfunds.py', ] +if ENABLE_ZMQ: + testScripts.append('zmq_test.py') + testScriptsExt = [ 'bip9-softforks.py', 'bip65-cltv.py', @@ -143,11 +150,6 @@ testScriptsExt = [ 'pruning.py', # leave pruning last as it takes a REALLY long time ] -#Enable ZMQ tests -if ENABLE_ZMQ == 1: - testScripts.append('zmq_test.py') - - def runtests(): coverage = None @@ -155,53 +157,49 @@ def runtests(): coverage = RPCCoverage() print("Initializing coverage directory at %s\n" % coverage.dir) - if(ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): - rpcTestDir = buildDir + '/qa/rpc-tests/' - run_extended = '-extended' in opts - cov_flag = coverage.flag if coverage else '' - flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn) + rpcTestDir = buildDir + '/qa/rpc-tests/' + run_extended = '-extended' in opts + cov_flag = coverage.flag if coverage else '' + flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn) - #Run Tests - for i in range(len(testScripts)): - if (len(opts) == 0 - or (len(opts) == 1 and "-win" in opts ) - or run_extended - or testScripts[i] in opts - or re.sub(".py$", "", testScripts[i]) in opts ): + #Run Tests + for i in range(len(testScripts)): + if (len(opts) == 0 + or (len(opts) == 1 and "-win" in opts ) + or run_extended + or testScripts[i] in opts + or re.sub(".py$", "", testScripts[i]) in opts ): - print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0])) - time0 = time.time() - subprocess.check_call( - rpcTestDir + testScripts[i] + flags, shell=True) - print("Duration: %s s\n" % (int(time.time() - time0))) + print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0])) + time0 = time.time() + subprocess.check_call( + rpcTestDir + testScripts[i] + flags, shell=True) + print("Duration: %s s\n" % (int(time.time() - time0))) - # exit if help is called so we print just one set of - # instructions - p = re.compile(" -h| --help") - if p.match(passOn): - sys.exit(0) + # exit if help is called so we print just one set of + # instructions + p = re.compile(" -h| --help") + if p.match(passOn): + sys.exit(0) - # Run Extended Tests - for i in range(len(testScriptsExt)): - if (run_extended or testScriptsExt[i] in opts - or re.sub(".py$", "", testScriptsExt[i]) in opts): + # Run Extended Tests + for i in range(len(testScriptsExt)): + if (run_extended or testScriptsExt[i] in opts + or re.sub(".py$", "", testScriptsExt[i]) in opts): - print( - "Running 2nd level testscript " - + "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0])) - time0 = time.time() - subprocess.check_call( - rpcTestDir + testScriptsExt[i] + flags, shell=True) - print("Duration: %s s\n" % (int(time.time() - time0))) + print( + "Running 2nd level testscript " + + "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0])) + time0 = time.time() + subprocess.check_call( + rpcTestDir + testScriptsExt[i] + flags, shell=True) + print("Duration: %s s\n" % (int(time.time() - time0))) - if coverage: - coverage.report_rpc_coverage() + if coverage: + coverage.report_rpc_coverage() - print("Cleaning up coverage data") - coverage.cleanup() - - else: - print "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" + print("Cleaning up coverage data") + coverage.cleanup() class RPCCoverage(object): From 5eeb913d6cff9cfe9a6769d7efe4a7b9f23de0f4 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 8 Apr 2016 22:14:19 +0200 Subject: [PATCH 0431/1223] Clean up lockorder data of destroyed mutexes The lockorder potential deadlock detection works by remembering for each lock A that is acquired while holding another B the pair (A,B), and triggering a warning when (B,A) already exists in the table. A and B in the above text are represented by pointers to the CCriticalSection object that is acquired. This does mean however that we need to clean up the table entries that refer to any critical section which is destroyed, as it memory address can potentially be used for another unrelated lock in the future. Implement this clean up by remembering not only the pairs in forward direction, but also backward direction. This allows for fast iteration over all pairs that use a deleted CCriticalSection in either the first or the second position. --- src/sync.cpp | 55 +++++++++++++++++++++++++++++++++++++++++----------- src/sync.h | 33 +++++++++++++++++++------------ 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/sync.cpp b/src/sync.cpp index 8df8ae43f..641ed2c8c 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -56,11 +56,24 @@ private: }; typedef std::vector > LockStack; +typedef std::map, LockStack> LockOrders; +typedef std::set > InvLockOrders; -static boost::mutex dd_mutex; -static std::map, LockStack> lockorders; -static boost::thread_specific_ptr lockstack; +struct LockData { + // Very ugly hack: as the global constructs and destructors run single + // threaded, we use this boolean to know whether LockData still exists, + // as DeleteLock can get called by global CCriticalSection destructors + // after LockData disappears. + bool available; + LockData() : available(true) {} + ~LockData() { available = false; } + LockOrders lockorders; + InvLockOrders invlockorders; + boost::mutex dd_mutex; +} static lockdata; + +boost::thread_specific_ptr lockstack; static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) { @@ -117,7 +130,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) if (lockstack.get() == NULL) lockstack.reset(new LockStack); - dd_mutex.lock(); + boost::unique_lock lock(lockdata.dd_mutex); (*lockstack).push_back(std::make_pair(c, locklocation)); @@ -127,23 +140,21 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) break; std::pair p1 = std::make_pair(i.first, c); - if (lockorders.count(p1)) + if (lockdata.lockorders.count(p1)) continue; - lockorders[p1] = (*lockstack); + lockdata.lockorders[p1] = (*lockstack); std::pair p2 = std::make_pair(c, i.first); - if (lockorders.count(p2)) - potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); + lockdata.invlockorders.insert(p2); + if (lockdata.lockorders.count(p2)) + potential_deadlock_detected(p1, lockdata.lockorders[p2], lockdata.lockorders[p1]); } } - dd_mutex.unlock(); } static void pop_lock() { - dd_mutex.lock(); (*lockstack).pop_back(); - dd_mutex.unlock(); } void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry) @@ -173,4 +184,26 @@ void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, abort(); } +void DeleteLock(void* cs) +{ + if (!lockdata.available) { + // We're already shutting down. + return; + } + boost::unique_lock lock(lockdata.dd_mutex); + std::pair item = std::make_pair(cs, (void*)0); + LockOrders::iterator it = lockdata.lockorders.lower_bound(item); + while (it != lockdata.lockorders.end() && it->first.first == cs) { + std::pair invitem = std::make_pair(it->first.second, it->first.first); + lockdata.invlockorders.erase(invitem); + lockdata.lockorders.erase(it++); + } + InvLockOrders::iterator invit = lockdata.invlockorders.lower_bound(item); + while (invit != lockdata.invlockorders.end() && invit->first == cs) { + std::pair invinvitem = std::make_pair(invit->second, invit->first); + lockdata.lockorders.erase(invinvitem); + lockdata.invlockorders.erase(invit++); + } +} + #endif /* DEBUG_LOCKORDER */ diff --git a/src/sync.h b/src/sync.h index 34dd8c228..0c58fb6b4 100644 --- a/src/sync.h +++ b/src/sync.h @@ -71,30 +71,39 @@ public: } }; -/** - * Wrapped boost mutex: supports recursive locking, but no waiting - * TODO: We should move away from using the recursive lock by default. - */ -typedef AnnotatedMixin CCriticalSection; - -/** Wrapped boost mutex: supports waiting but not recursive locking */ -typedef AnnotatedMixin CWaitableCriticalSection; - -/** Just a typedef for boost::condition_variable, can be wrapped later if desired */ -typedef boost::condition_variable CConditionVariable; - #ifdef DEBUG_LOCKORDER void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); void LeaveCritical(); std::string LocksHeld(); void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs); +void DeleteLock(void* cs); #else void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} void static inline LeaveCritical() {} void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {} +void static inline DeleteLock(void* cs) {} #endif #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) +/** + * Wrapped boost mutex: supports recursive locking, but no waiting + * TODO: We should move away from using the recursive lock by default. + */ +class CCriticalSection : public AnnotatedMixin +{ +public: + ~CCriticalSection() { + DeleteLock((void*)this); + } +}; + +typedef CCriticalSection CDynamicCriticalSection; +/** Wrapped boost mutex: supports waiting but not recursive locking */ +typedef AnnotatedMixin CWaitableCriticalSection; + +/** Just a typedef for boost::condition_variable, can be wrapped later if desired */ +typedef boost::condition_variable CConditionVariable; + #ifdef DEBUG_LOCKCONTENTION void PrintLockContention(const char* pszName, const char* pszFile, int nLine); #endif From faa41ee204124da19dcf1e5b8a3aef1e216bf5e6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 10 Apr 2016 16:54:28 +0200 Subject: [PATCH 0432/1223] [qa] py2: Unfiddle strings into bytes explicitly --- qa/rpc-tests/bip65-cltv-p2p.py | 3 +- qa/rpc-tests/bip68-112-113-p2p.py | 5 +- qa/rpc-tests/bip9-softforks.py | 9 +- qa/rpc-tests/bipdersig-p2p.py | 5 +- qa/rpc-tests/decodescript.py | 22 ++- qa/rpc-tests/fundrawtransaction.py | 3 - qa/rpc-tests/getblocktemplate_proposals.py | 2 +- qa/rpc-tests/httpbasics.py | 11 +- qa/rpc-tests/invalidblockrequest.py | 10 +- qa/rpc-tests/invalidtxrequest.py | 6 +- qa/rpc-tests/listtransactions.py | 7 +- qa/rpc-tests/multi_rpc.py | 13 +- qa/rpc-tests/p2p-feefilter.py | 2 +- qa/rpc-tests/p2p-fullblocktest.py | 32 ++-- qa/rpc-tests/proxy_test.py | 8 +- qa/rpc-tests/pruning.py | 2 +- qa/rpc-tests/rawtransactions.py | 2 - qa/rpc-tests/replace-by-fee.py | 10 +- qa/rpc-tests/rest.py | 15 +- qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/comptool.py | 6 +- qa/rpc-tests/test_framework/mininode.py | 186 ++++++++++----------- qa/rpc-tests/test_framework/netutil.py | 11 +- qa/rpc-tests/test_framework/script.py | 4 +- qa/rpc-tests/test_framework/socks5.py | 2 +- qa/rpc-tests/test_framework/util.py | 15 +- qa/rpc-tests/zmq_test.py | 22 +-- src/test/bctest.py | 3 +- 28 files changed, 205 insertions(+), 213 deletions(-) diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 54559c354..99d74344a 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -10,7 +10,6 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP -from binascii import unhexlify from io import BytesIO import time @@ -60,7 +59,7 @@ class BIP65Test(ComparisonTestFramework): rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = BytesIO(unhexlify(signresult['hex'])) + f = BytesIO(hex_str_to_bytes(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 35c831cb8..3bcfdabe2 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -10,7 +10,6 @@ from test_framework.mininode import ToHex, CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import * -from binascii import unhexlify from io import BytesIO import time @@ -119,7 +118,7 @@ class BIP68_112_113Test(ComparisonTestFramework): outputs = { to_address : amount } rawtx = node.createrawtransaction(inputs, outputs) tx = CTransaction() - f = BytesIO(unhexlify(rawtx)) + f = BytesIO(hex_str_to_bytes(rawtx)) tx.deserialize(f) return tx @@ -127,7 +126,7 @@ class BIP68_112_113Test(ComparisonTestFramework): rawtx = ToHex(unsignedtx) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = BytesIO(unhexlify(signresult['hex'])) + f = BytesIO(hex_str_to_bytes(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 98975e719..d131eed92 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -10,7 +10,6 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP -from binascii import hexlify, unhexlify from io import BytesIO import time import itertools @@ -30,7 +29,6 @@ test that enforcement has triggered ''' - class BIP9SoftForksTest(ComparisonTestFramework): def __init__(self): @@ -53,15 +51,15 @@ class BIP9SoftForksTest(ComparisonTestFramework): outputs = { to_address : amount } rawtx = node.createrawtransaction(inputs, outputs) tx = CTransaction() - f = BytesIO(unhexlify(rawtx)) + f = BytesIO(hex_str_to_bytes(rawtx)) tx.deserialize(f) tx.nVersion = 2 return tx def sign_transaction(self, node, tx): - signresult = node.signrawtransaction(hexlify(tx.serialize())) + signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize())) tx = CTransaction() - f = BytesIO(unhexlify(signresult['hex'])) + f = BytesIO(hex_str_to_bytes(signresult['hex'])) tx.deserialize(f) return tx @@ -184,7 +182,6 @@ class BIP9SoftForksTest(ComparisonTestFramework): NetworkThread().start() # Start up network handling in another thread - def get_tests(self): for test in itertools.chain( self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing), diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 95be385d9..bba86a50c 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -10,7 +10,6 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript -from binascii import unhexlify from io import BytesIO import time @@ -25,7 +24,7 @@ def unDERify(tx): newscript = [] for i in scriptSig: if (len(newscript) == 0): - newscript.append(i[0:-1] + '\0' + i[-1]) + newscript.append(i[0:-1] + b'\0' + i[-1:]) else: newscript.append(i) tx.vin[0].scriptSig = CScript(newscript) @@ -68,7 +67,7 @@ class BIP66Test(ComparisonTestFramework): rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() - f = BytesIO(unhexlify(signresult['hex'])) + f = BytesIO(hex_str_to_bytes(signresult['hex'])) tx.deserialize(f) return tx diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 2dfafac2f..578844f2c 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -6,7 +6,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import * -from binascii import hexlify, unhexlify from io import BytesIO class DecodeScriptTest(BitcoinTestFramework): @@ -131,7 +130,7 @@ class DecodeScriptTest(BitcoinTestFramework): assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) txSave = CTransaction() - txSave.deserialize(BytesIO(unhexlify(tx))) + txSave.deserialize(BytesIO(hex_str_to_bytes(tx))) # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' @@ -147,7 +146,7 @@ class DecodeScriptTest(BitcoinTestFramework): # some more full transaction tests of varying specific scriptSigs. used instead of # tests in decodescript_script_sig because the decodescript RPC is specifically # for working on scriptPubKeys (argh!). - push_signature = hexlify(txSave.vin[0].scriptSig)[2:(0x48*2+4)] + push_signature = bytes_to_hex_str(txSave.vin[0].scriptSig)[2:(0x48*2+4)] signature = push_signature[2:] der_signature = signature[:-2] signature_sighash_decoded = der_signature + '[ALL]' @@ -156,25 +155,24 @@ class DecodeScriptTest(BitcoinTestFramework): signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]' # 1) P2PK scriptSig - txSave.vin[0].scriptSig = unhexlify(push_signature) - rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) # make sure that the sighash decodes come out correctly for a more complex / lesser used case. - txSave.vin[0].scriptSig = unhexlify(push_signature_2) - rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) # 2) multisig scriptSig - txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2) - rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature + push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) # 3) test a scriptSig that contains more than push operations. # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it. - txSave.vin[0].scriptSig = unhexlify('6a143011020701010101010101020601010101010101') - rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) - print(hexlify('636174')) + txSave.vin[0].scriptSig = hex_str_to_bytes('6a143011020701010101010101020601010101010101') + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm']) def run_test(self): diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 82c9e48a4..4492ea398 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -148,7 +148,6 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee - ##################################################################### # test a fundrawtransaction with which will not get a change output # ##################################################################### @@ -178,7 +177,6 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee - ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # ######################################################################### @@ -484,7 +482,6 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance()) - ############################################### # multiple (~19) inputs tx test | Compare fee # ############################################### diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index d2cb4ab8d..07bfe69c6 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -130,7 +130,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): # Test 5: Add an invalid tx to the end (non-duplicate) txlist.append(bytearray(txlist[0])) - txlist[-1][4+1] = b'\xff' + txlist[-1][4+1] = 0xff assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent') txlist.pop() diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index eff4c6e80..cf37976a4 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -9,7 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import base64 try: import http.client as httplib @@ -31,7 +30,7 @@ class HTTPBasicsTest (BitcoinTestFramework): ################################################# url = urlparse.urlparse(self.nodes[0].url) authpair = url.username + ':' + url.password - headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -48,7 +47,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.close() #same should be if we add keep-alive because this should be the std. behaviour - headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"} + headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection": "keep-alive"} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -65,7 +64,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.close() #now do the same with "Connection: close" - headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"} + headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection":"close"} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -77,7 +76,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #node1 (2nd node) is running with disabled keep-alive option urlNode1 = urlparse.urlparse(self.nodes[1].url) authpair = urlNode1.username + ':' + urlNode1.password - headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) conn.connect() @@ -88,7 +87,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on urlNode2 = urlparse.urlparse(self.nodes[2].url) authpair = urlNode2.username + ':' + urlNode2.password - headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn.connect() diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index daad312d3..de6be8d5b 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -77,9 +77,9 @@ class InvalidBlockRequestTest(ComparisonTestFramework): block2 = create_block(self.tip, create_coinbase(height), self.block_time) self.block_time += 1 - # chr(81) is OP_TRUE - tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50 * COIN) - tx2 = create_transaction(tx1, 0, chr(81), 50 * COIN) + # b'0x51' is OP_TRUE + tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN) + tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN) block2.vtx.extend([tx1, tx2]) block2.hashMerkleRoot = block2.calc_merkle_root() @@ -95,7 +95,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): assert(block2_orig.vtx != block2.vtx) self.tip = block2.sha256 - yield TestInstance([[block2, RejectResult(16,'bad-txns-duplicate')], [block2_orig, True]]) + yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]]) height += 1 ''' @@ -110,7 +110,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): block3.rehash() block3.solve() - yield TestInstance([[block3, RejectResult(16,'bad-cb-amount')]]) + yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]]) if __name__ == '__main__': diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index 8fe471ccd..7b8199bab 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -61,10 +61,10 @@ class InvalidTxRequestTest(ComparisonTestFramework): height += 1 yield test - # chr(100) is OP_NOTIF + # b'\x64' is OP_NOTIF # Transaction will be rejected with code 16 (REJECT_INVALID) - tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50 * COIN - 12000) - yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) + tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 50 * COIN - 12000) + yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]]) # TODO: test further transactions... diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 8fe72d95d..0783a1f3d 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -9,11 +9,10 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import CTransaction, COIN from io import BytesIO -import binascii def txFromHex(hexstring): tx = CTransaction() - f = BytesIO(binascii.unhexlify(hexstring)) + f = BytesIO(hex_str_to_bytes(hexstring)) tx.deserialize(f) return tx @@ -167,7 +166,7 @@ class ListTransactionsTest(BitcoinTestFramework): tx3 = self.nodes[0].createrawtransaction(inputs, outputs) tx3_modified = txFromHex(tx3) tx3_modified.vin[0].nSequence = 0 - tx3 = binascii.hexlify(tx3_modified.serialize()).decode('utf-8') + tx3 = bytes_to_hex_str(tx3_modified.serialize()) tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex'] txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) @@ -193,7 +192,7 @@ class ListTransactionsTest(BitcoinTestFramework): # Replace tx3, and check that tx4 becomes unknown tx3_b = tx3_modified tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee - tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') + tx3_b = bytes_to_hex_str(tx3_b.serialize()) tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) assert(is_opt_in(self.nodes[0], txid_3b)) diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 2452b7731..afb18cf3d 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -53,7 +53,7 @@ class HTTPBasicsTest (BitcoinTestFramework): password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI=" authpairnew = "rt:"+password - headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -63,7 +63,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.close() #Use new authpair to confirm both work - headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -74,7 +74,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Wrong login name with rt's password authpairnew = "rtwrong:"+password - headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -85,7 +85,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Wrong password for rt authpairnew = "rt:"+password+"wrong" - headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -96,7 +96,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Correct for rt2 authpairnew = "rt2:"+password2 - headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -107,7 +107,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Wrong password for rt2 authpairnew = "rt2:"+password2+"wrong" - headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() @@ -117,6 +117,5 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.close() - if __name__ == '__main__': HTTPBasicsTest ().main () diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index f85c18dcd..281b6ca37 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -14,7 +14,7 @@ FeeFilterTest -- test processing of feefilter messages ''' def hashToHex(hash): - return format(hash, '064x').decode('utf-8') + return format(hash, '064x') # Wait up to 60 secs to see if the testnode has received all the expected invs def allInvsMatch(invsExpected, testnode): diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index 131350c98..ae82d9dca 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -33,7 +33,7 @@ class FullBlockTest(ComparisonTestFramework): self.num_nodes = 1 self.block_heights = {} self.coinbase_key = CECKey() - self.coinbase_key.set_secretbytes(bytes("horsebattery")) + self.coinbase_key.set_secretbytes(b"horsebattery") self.coinbase_pubkey = self.coinbase_key.get_pubkey() self.block_time = int(time.time())+1 self.tip = None @@ -70,7 +70,7 @@ class FullBlockTest(ComparisonTestFramework): block = create_block(base_block_hash, coinbase, self.block_time) if (spend != None): tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), "", 0xffffffff)) # no signature yet + tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), b"", 0xffffffff)) # no signature yet # This copies the java comparison tool testing behavior: the first # txout has a garbage scriptPubKey, "to make sure we're not # pre-verifying too much" (?) @@ -80,7 +80,7 @@ class FullBlockTest(ComparisonTestFramework): else: tx.vout.append(CTxOut(1, script)) # Now sign it if necessary - scriptSig = "" + scriptSig = b"" scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey) if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend scriptSig = CScript([OP_TRUE]) @@ -225,7 +225,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) tip(6) block(9, spend=out4, additional_coinbase_value=1) - yield rejected(RejectResult(16, 'bad-cb-amount')) + yield rejected(RejectResult(16, b'bad-cb-amount')) # Create a fork that ends in a block with too much fee (the one that causes the reorg) @@ -237,7 +237,7 @@ class FullBlockTest(ComparisonTestFramework): yield rejected() block(11, spend=out4, additional_coinbase_value=1) - yield rejected(RejectResult(16, 'bad-cb-amount')) + yield rejected(RejectResult(16, b'bad-cb-amount')) # Try again, but with a valid fork first @@ -279,7 +279,7 @@ class FullBlockTest(ComparisonTestFramework): out6 = get_spendable_output() too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50)) block(16, spend=out6, script=too_many_checksigs) - yield rejected(RejectResult(16, 'bad-blk-sigops')) + yield rejected(RejectResult(16, b'bad-blk-sigops')) # Attempt to spend a transaction created on a different fork @@ -288,7 +288,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) tip(15) block(17, spend=txout_b3) - yield rejected(RejectResult(16, 'bad-txns-inputs-missingorspent')) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) # Attempt to spend a transaction created on a different fork (on a fork this time) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -309,7 +309,7 @@ class FullBlockTest(ComparisonTestFramework): tip(15) out7 = get_spendable_output() block(20, spend=out7) - yield rejected(RejectResult(16, 'bad-txns-premature-spend-of-coinbase')) + yield rejected(RejectResult(16, b'bad-txns-premature-spend-of-coinbase')) # Attempt to spend a coinbase at depth too low (on a fork this time) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -333,7 +333,7 @@ class FullBlockTest(ComparisonTestFramework): old_hash = b23.sha256 tx = CTransaction() script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69 - script_output = CScript([chr(0)*script_length]) + script_output = CScript([b'\x00' * script_length]) tx.vout.append(CTxOut(0, script_output)) tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1))) b23 = update_block(23, [tx]) @@ -345,11 +345,11 @@ class FullBlockTest(ComparisonTestFramework): tip(15) b24 = block(24, spend=out6) script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69 - script_output = CScript([chr(0)*(script_length+1)]) + script_output = CScript([b'\x00' * (script_length+1)]) tx.vout = [CTxOut(0, script_output)] b24 = update_block(24, [tx]) assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1) - yield rejected(RejectResult(16, 'bad-blk-length')) + yield rejected(RejectResult(16, b'bad-blk-length')) b25 = block(25, spend=out7) yield rejected() @@ -361,12 +361,12 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) tip(15) b26 = block(26, spend=out6) - b26.vtx[0].vin[0].scriptSig = chr(0) + b26.vtx[0].vin[0].scriptSig = b'\x00' b26.vtx[0].rehash() # update_block causes the merkle root to get updated, even with no new # transactions, and updates the required state. b26 = update_block(26, []) - yield rejected(RejectResult(16, 'bad-cb-length')) + yield rejected(RejectResult(16, b'bad-cb-length')) # Extend the b26 chain to make sure bitcoind isn't accepting b26 b27 = block(27, spend=out7) @@ -375,10 +375,10 @@ class FullBlockTest(ComparisonTestFramework): # Now try a too-large-coinbase script tip(15) b28 = block(28, spend=out6) - b28.vtx[0].vin[0].scriptSig = chr(0)*101 + b28.vtx[0].vin[0].scriptSig = b'\x00' * 101 b28.vtx[0].rehash() b28 = update_block(28, []) - yield rejected(RejectResult(16, 'bad-cb-length')) + yield rejected(RejectResult(16, b'bad-cb-length')) # Extend the b28 chain to make sure bitcoind isn't accepted b28 b29 = block(29, spend=out7) @@ -390,7 +390,7 @@ class FullBlockTest(ComparisonTestFramework): # b30 has a max-sized coinbase scriptSig. tip(23) b30 = block(30) - b30.vtx[0].vin[0].scriptSig = chr(0)*100 + b30.vtx[0].vin[0].scriptSig = b'\x00' * 100 b30.vtx[0].rehash() b30 = update_block(30, []) yield accepted() diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index b3c65573e..91c871ddc 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -86,7 +86,7 @@ class ProxyTest(BitcoinTestFramework): assert(isinstance(cmd, Socks5Command)) # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, "15.61.23.23") + assert_equal(cmd.addr, b"15.61.23.23") assert_equal(cmd.port, 1234) if not auth: assert_equal(cmd.username, None) @@ -100,7 +100,7 @@ class ProxyTest(BitcoinTestFramework): assert(isinstance(cmd, Socks5Command)) # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534") + assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534") assert_equal(cmd.port, 5443) if not auth: assert_equal(cmd.username, None) @@ -113,7 +113,7 @@ class ProxyTest(BitcoinTestFramework): cmd = proxies[2].queue.get() assert(isinstance(cmd, Socks5Command)) assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, "bitcoinostk4e4re.onion") + assert_equal(cmd.addr, b"bitcoinostk4e4re.onion") assert_equal(cmd.port, 8333) if not auth: assert_equal(cmd.username, None) @@ -125,7 +125,7 @@ class ProxyTest(BitcoinTestFramework): cmd = proxies[3].queue.get() assert(isinstance(cmd, Socks5Command)) assert_equal(cmd.atyp, AddressType.DOMAINNAME) - assert_equal(cmd.addr, "node.noumenon") + assert_equal(cmd.addr, b"node.noumenon") assert_equal(cmd.port, 8333) if not auth: assert_equal(cmd.username, None) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index dd2adea95..eccd157e5 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -311,7 +311,7 @@ class PruneTest(BitcoinTestFramework): # \ \ # ++...++(1044) .. # - # N0 ********************(1032) @@...@@@(1552) + # N0 ********************(1032) @@...@@@(1552) # \ # *...**(1320) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 762a6d6a3..e38ef6c8b 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -88,8 +88,6 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance - - # 2of3 test from different nodes bal = self.nodes[2].getbalance() addr1 = self.nodes[1].getnewaddress() diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index b951900c4..4c8ef6de2 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -11,15 +11,11 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.script import * from test_framework.mininode import * -import binascii MAX_REPLACEMENT_LIMIT = 100 -def satoshi_round(amount): - return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) - def txToHex(tx): - return binascii.hexlify(tx.serialize()).decode('utf-8') + return bytes_to_hex_str(tx.serialize()) def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): """Create a txout with a given amount and scriptPubKey @@ -53,9 +49,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): tx2.vout = [CTxOut(amount, scriptPubKey)] tx2.rehash() - binascii.hexlify(tx2.serialize()).decode('utf-8') - - signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8')) + signed_tx = node.signrawtransaction(txToHex(tx2)) txid = node.sendrawtransaction(signed_tx['hex'], True) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 3c8a405bd..359f9239f 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -39,7 +39,7 @@ def http_get_call(host, port, path, response_object = 0): if response_object: return conn.getresponse() - return conn.getresponse().read() + return conn.getresponse().read().decode('utf-8') #allows simple http post calls with a request body def http_post_call(host, port, path, requestdata = '', response_object = 0): @@ -141,9 +141,9 @@ class RESTTest (BitcoinTestFramework): bb_hash = self.nodes[0].getbestblockhash() binaryRequest = b'\x01\x02' - binaryRequest += binascii.unhexlify(txid) + binaryRequest += hex_str_to_bytes(txid) binaryRequest += pack("i", n) - binaryRequest += binascii.unhexlify(vintx) + binaryRequest += hex_str_to_bytes(vintx) binaryRequest += pack("i", 0) bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) @@ -234,7 +234,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(response_hex.status, 200) assert_greater_than(int(response_hex.getheader('content-length')), 160) response_hex_str = response_hex.read() - assert_equal(encode(response_str, "hex")[0:160], response_hex_str[0:160]) + assert_equal(encode(response_str, "hex_codec")[0:160], response_hex_str[0:160]) # compare with hex block header response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) @@ -242,7 +242,7 @@ class RESTTest (BitcoinTestFramework): assert_greater_than(int(response_header_hex.getheader('content-length')), 160) response_header_hex_str = response_header_hex.read() assert_equal(response_hex_str[0:160], response_header_hex_str[0:160]) - assert_equal(encode(response_header_str, "hex")[0:160], response_header_hex_str[0:160]) + assert_equal(encode(response_header_str, "hex_codec")[0:160], response_header_hex_str[0:160]) # check json format block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json') @@ -252,7 +252,7 @@ class RESTTest (BitcoinTestFramework): # compare with json block header response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) - response_header_json_str = response_header_json.read() + response_header_json_str = response_header_json.read().decode('utf-8') json_obj = json.loads(response_header_json_str, parse_float=Decimal) assert_equal(len(json_obj), 1) #ensure that there is one header in the json response assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same @@ -276,7 +276,7 @@ class RESTTest (BitcoinTestFramework): self.sync_all() response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) - response_header_json_str = response_header_json.read() + response_header_json_str = response_header_json.read().decode('utf-8') json_obj = json.loads(response_header_json_str) assert_equal(len(json_obj), 5) #now we should have 5 header objects @@ -292,7 +292,6 @@ class RESTTest (BitcoinTestFramework): assert_greater_than(int(response.getheader('content-length')), 10) - # check block tx details # let's make 3 tx and mine them on node 1 txs = [] diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index afa0f5f9b..384f40e62 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -62,6 +62,6 @@ def create_transaction(prevtx, n, sig, value): tx = CTransaction() assert(n < len(prevtx.vout)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) - tx.vout.append(CTxOut(value, "")) + tx.vout.append(CTxOut(value, b"")) tx.calc_sha256() return tx diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 6279070fb..17626cf8d 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -31,7 +31,7 @@ class RejectResult(object): ''' Outcome that expects rejection of a transaction or block. ''' - def __init__(self, code, reason=''): + def __init__(self, code, reason=b''): self.code = code self.reason = reason def match(self, other): @@ -97,9 +97,9 @@ class TestNode(NodeConnCB): raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) def on_reject(self, conn, message): - if message.message == 'tx': + if message.message == b'tx': self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) - if message.message == 'block': + if message.message == b'block': self.block_reject_map[message.data] = RejectResult(message.code, message.reason) def send_inv(self, obj): diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 53f5e8805..5ee5b1327 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -20,10 +20,10 @@ import struct import socket import asyncore -import binascii import time import sys import random +from binascii import hexlify, unhexlify from io import BytesIO from codecs import encode import hashlib @@ -34,7 +34,7 @@ import copy BIP0031_VERSION = 60000 MY_VERSION = 60001 # past bip-31 for ping/pong -MY_SUBVERSION = "/python-mininode-tester:0.0.1/" +MY_SUBVERSION = b"/python-mininode-tester:0.0.2/" MAX_INV_SZ = 50000 MAX_BLOCK_SIZE = 1000000 @@ -131,7 +131,7 @@ def deser_vector(f, c): def ser_vector(l): - r = "" + r = b"" if len(l) < 253: r = struct.pack("B", len(l)) elif len(l) < 0x10000: @@ -161,7 +161,7 @@ def deser_uint256_vector(f): def ser_uint256_vector(l): - r = "" + r = b"" if len(l) < 253: r = struct.pack("B", len(l)) elif len(l) < 0x10000: @@ -221,7 +221,7 @@ def deser_int_vector(f): def ser_int_vector(l): - r = "" + r = b"" if len(l) < 253: r = struct.pack("B", len(l)) elif len(l) < 0x10000: @@ -236,19 +236,19 @@ def ser_int_vector(l): # Deserialize from a hex string representation (eg from RPC) def FromHex(obj, hex_string): - obj.deserialize(BytesIO(binascii.unhexlify(hex_string))) + obj.deserialize(BytesIO(unhexlify(hex_string.encode('ascii')))) return obj # Convert a binary-serializable object to hex (eg for submission via RPC) def ToHex(obj): - return binascii.hexlify(obj.serialize()).decode('utf-8') + return hexlify(obj.serialize()).decode('ascii') # Objects that map to bitcoind objects, which can be serialized/deserialized class CAddress(object): def __init__(self): self.nServices = 1 - self.pchReserved = "\x00" * 10 + "\xff" * 2 + self.pchReserved = b"\x00" * 10 + b"\xff" * 2 self.ip = "0.0.0.0" self.port = 0 @@ -259,7 +259,7 @@ class CAddress(object): self.port = struct.unpack(">H", f.read(2))[0] def serialize(self): - r = "" + r = b"" r += struct.pack(" class msg_headers(object): - command = "headers" + command = b"headers" def __init__(self): self.headers = [] @@ -982,10 +982,10 @@ class msg_headers(object): class msg_reject(object): - command = "reject" + command = b"reject" def __init__(self): - self.message = "" + self.message = b"" self.code = 0 self.reason = "" self.data = 0L @@ -1025,7 +1025,7 @@ def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): return False class msg_feefilter(object): - command = "feefilter" + command = b"feefilter" def __init__(self, feerate=0L): self.feerate = feerate @@ -1034,7 +1034,7 @@ class msg_feefilter(object): self.feerate = struct.unpack("= 209: th = sha256(data) @@ -1313,11 +1313,11 @@ class NodeConn(asyncore.dispatcher): self.last_sent = time.time() def got_message(self, message): - if message.command == "version": + if message.command == b"version": if message.nVersion <= BIP0031_VERSION: - self.messagemap['ping'] = msg_ping_prebip31 + self.messagemap[b'ping'] = msg_ping_prebip31 if self.last_sent + 30 * 60 < time.time(): - self.send_message(self.messagemap['ping']()) + self.send_message(self.messagemap[b'ping']()) self.show_debug_msg("Recv %s" % repr(message)) self.cb.deliver(self, message) diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index bbc58a14e..52a7ab748 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -4,13 +4,14 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # Linux network utilities + import sys import socket import fcntl import struct import array import os -import binascii +from binascii import unhexlify, hexlify # Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal STATE_ESTABLISHED = '01' @@ -43,7 +44,7 @@ def _remove_empty(array): def _convert_ip_port(array): host,port = array.split(':') # convert host from mangled-per-four-bytes form as used by kernel - host = binascii.unhexlify(host) + host = unhexlify(host) host_out = '' for x in range(0, len(host) // 4): (val,) = struct.unpack('=I', host[x*4:(x+1)*4]) @@ -94,7 +95,7 @@ def all_interfaces(): max_possible = 8 # initial value while True: bytes = max_possible * struct_size - names = array.array('B', '\0' * bytes) + names = array.array('B', b'\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl( s.fileno(), 0x8912, # SIOCGIFCONF @@ -105,7 +106,7 @@ def all_interfaces(): else: break namestr = names.tostring() - return [(namestr[i:i+16].split('\0', 1)[0], + return [(namestr[i:i+16].split(b'\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) for i in range(0, outbytes, struct_size)] @@ -136,7 +137,7 @@ def addr_to_hex(addr): addr = sub[0] + ([0] * nullbytes) + sub[1] else: raise ValueError('Could not parse address %s' % addr) - return binascii.hexlify(bytearray(addr)) + return hexlify(bytearray(addr)).decode('ascii') def test_ipv6_local(): ''' diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index bf5e25fb2..5fb5758f8 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -629,7 +629,7 @@ class CScriptNum(object): neg = obj.value < 0 absvalue = -obj.value if neg else obj.value while (absvalue): - r.append(chr(absvalue & 0xff)) + r.append(absvalue & 0xff) absvalue >>= 8 if r[-1] & 0x80: r.append(0x80 if neg else 0) @@ -777,7 +777,7 @@ class CScript(bytes): # need to change def _repr(o): if isinstance(o, bytes): - return "x('%s')" % hexlify(o).decode('utf8') + return b"x('%s')" % hexlify(o).decode('ascii') else: return repr(o) diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py index 12327a6c5..f725d9770 100644 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/qa/rpc-tests/test_framework/socks5.py @@ -102,7 +102,7 @@ class Socks5Connection(object): addr = recvall(self.conn, 4) elif atyp == AddressType.DOMAINNAME: n = recvall(self.conn, 1)[0] - addr = str(recvall(self.conn, n)) + addr = recvall(self.conn, n) elif atyp == AddressType.IPV6: addr = recvall(self.conn, 16) else: diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index d9fe0f75f..42541b416 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,6 +1,8 @@ # Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. + + # # Helpful routines for regression testing # @@ -9,6 +11,8 @@ import os import sys +from binascii import hexlify, unhexlify +from base64 import b64encode from decimal import Decimal, ROUND_DOWN import json import random @@ -91,6 +95,15 @@ def check_json_precision(): def count_bytes(hex_string): return len(bytearray.fromhex(hex_string)) +def bytes_to_hex_str(byte_str): + return hexlify(byte_str).decode('ascii') + +def hex_str_to_bytes(hex_str): + return unhexlify(hex_str.encode('ascii')) + +def str_to_b64str(string): + return b64encode(string.encode('utf-8')).decode('ascii') + def sync_blocks(rpc_connections, wait=1): """ Wait until everybody has the same block count @@ -466,7 +479,7 @@ def assert_is_hash_string(string, length=64): "String %r contains invalid characters for a hash." % string) def satoshi_round(amount): - return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) # Helper to create at least "count" utxos # Pass in a fee that is sufficient for relay and mining new transactions. diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index 88532541a..3a8d62ef2 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -28,8 +28,8 @@ class ZMQTest (BitcoinTestFramework): def setup_nodes(self): self.zmqContext = zmq.Context() self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) - self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") - self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx") self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) return start_nodes(4, self.options.tmpdir, extra_args=[ ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], @@ -46,13 +46,13 @@ class ZMQTest (BitcoinTestFramework): print "listen..." msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] - blkhash = binascii.hexlify(body) + blkhash = bytes_to_hex_str(body) assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq @@ -63,10 +63,10 @@ class ZMQTest (BitcoinTestFramework): zmqHashes = [] for x in range(0,n*2): msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] - if topic == "hashblock": - zmqHashes.append(binascii.hexlify(body)) + if topic == b"hashblock": + zmqHashes.append(bytes_to_hex_str(body)) for x in range(0,n): assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq @@ -77,11 +77,11 @@ class ZMQTest (BitcoinTestFramework): # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() - topic = str(msg[0]) + topic = msg[0] body = msg[1] hashZMQ = "" - if topic == "hashtx": - hashZMQ = binascii.hexlify(body) + if topic == b"hashtx": + hashZMQ = bytes_to_hex_str(body) assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq diff --git a/src/test/bctest.py b/src/test/bctest.py index 8105b87ff..fc59152ba 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -2,6 +2,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. from __future__ import division,print_function,unicode_literals +from io import open import subprocess import os import json @@ -16,7 +17,7 @@ def bctest(testDir, testObj, exeext): inputData = None if "input" in testObj: filename = testDir + "/" + testObj['input'] - inputData = open(filename).read() + inputData = open(filename, 'rb').read() stdinCfg = subprocess.PIPE outputFn = None From fa6399d918fdaa8844c4c767b2012e0b2ca60ee9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 10 Apr 2016 20:49:07 +0200 Subject: [PATCH 0433/1223] [doc] gitian: Replace precise with trusty --- doc/gitian-building.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 69d79b3c6..e1f46cd82 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -363,7 +363,7 @@ Output from `gbuild` will look something like Resolving deltas: 100% (41590/41590), done. From https://github.com/bitcoin/bitcoin ... (new tags, new branch etc) - --- Building for precise amd64 --- + --- Building for trusty amd64 --- Stopping target if it is up Making a new image copy stdin: is not a tty @@ -412,14 +412,14 @@ So, if you use LXC: export PATH="$PATH":/path/to/gitian-builder/libexec export USE_LXC=1 cd /path/to/gitian-builder -./libexec/make-clean-vm --suite precise --arch amd64 +./libexec/make-clean-vm --suite trusty --arch amd64 -LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root apt-get update -LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root \ +LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root apt-get update +LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root \ -e DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -y install \ $( sed -ne '/^packages:/,/[^-] .*/ {/^- .*/{s/"//g;s/- //;p}}' ../bitcoin/contrib/gitian-descriptors/*|sort|uniq ) -LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root apt-get -q -y purge grub -LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root -e DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade +LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root apt-get -q -y purge grub +LXC_ARCH=amd64 LXC_SUITE=trusty on-target -u root -e DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade ``` And then set offline mode for apt-cacher-ng: From fa42a675c08ba738a47bf37056ef090441ec5a83 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 5 Apr 2016 13:29:04 +0200 Subject: [PATCH 0434/1223] [gitian] hardcode datetime for depends --- contrib/gitian-descriptors/gitian-linux.yml | 19 ++++++++++++---- contrib/gitian-descriptors/gitian-osx.yml | 19 ++++++++++++---- contrib/gitian-descriptors/gitian-win.yml | 25 ++++++++++++++++----- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 8b2ab4ebf..045643e29 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -41,29 +41,36 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi - # Create global faketime wrappers + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done + } - # Create per-host faketime wrappers + function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done + } + export PATH=${WRAP_DIR}:${PATH} + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + cd bitcoin BASEPREFIX=`pwd`/depends # Build dependencies for each host @@ -71,6 +78,10 @@ script: | make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + # Create the release tarball using (arbitrarily) the first host ./autogen.sh ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 74fc2e93a..dbd0cedaf 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -53,29 +53,36 @@ script: | export ZERO_AR_DATE=1 - # Create global faketime wrappers + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done + } - # Create per-host faketime wrappers + function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done + } + export PATH=${WRAP_DIR}:${PATH} + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + cd bitcoin BASEPREFIX=`pwd`/depends @@ -87,6 +94,10 @@ script: | make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + # Create the release tarball using (arbitrarily) the first host ./autogen.sh ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 719ca9c23..2c035db17 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -44,29 +44,31 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi - # Create global faketime wrappers + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} done + } - # Create per-host faketime wrappers + function create_per-host_faketime_wrappers { for i in $HOSTS; do for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done + } - # Create per-host linker wrapper + function create_per-host_linker_wrapper { # This is only needed for trusty, as the mingw linker leaks a few bytes of # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900 for i in $HOSTS; do @@ -82,15 +84,21 @@ script: | echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} - echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} done done + } export PATH=${WRAP_DIR}:${PATH} + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_linker_wrapper "2000-01-01 12:00:00" + cd bitcoin BASEPREFIX=`pwd`/depends # Build dependencies for each host @@ -98,6 +106,11 @@ script: | make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + # Create the release tarball using (arbitrarily) the first host ./autogen.sh ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` From 66b07247a7a9e48e082502338176cc06edf61474 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 11 Apr 2016 01:09:34 +0000 Subject: [PATCH 0435/1223] Only send one GetAddr response per connection. This conserves resources from abusive peers that just send getaddr in a loop. Also makes correlating addr messages against INVs less effective. --- src/main.cpp | 8 ++++++++ src/net.cpp | 1 + src/net.h | 1 + 3 files changed, 10 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f5c7e11d6..df494b226 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5214,6 +5214,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } + // Only send one GetAddr response per connection to reduce resource waste + // and discourage addr stamping of INV announcements. + if (pfrom->fSentAddr) { + LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id); + return true; + } + pfrom->fSentAddr = true; + pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); BOOST_FOREACH(const CAddress &addr, vAddr) diff --git a/src/net.cpp b/src/net.cpp index e8cc753a4..77310fb16 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2384,6 +2384,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nNextAddrSend = 0; nNextInvSend = 0; fRelayTxes = false; + fSentAddr = false; pfilter = new CBloomFilter(); nPingNonceSent = 0; nPingUsecStart = 0; diff --git a/src/net.h b/src/net.h index ab9eb68d8..230fd5bf4 100644 --- a/src/net.h +++ b/src/net.h @@ -358,6 +358,7 @@ public: // b) the peer may tell us in its version message that we should not relay tx invs // unless it loads a bloom filter. bool fRelayTxes; + bool fSentAddr; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; CBloomFilter* pfilter; From 0dbf6e4b409648a27324bf230d7feec973984da4 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 1 Apr 2016 12:19:28 -0400 Subject: [PATCH 0436/1223] build: define base filenames for use elsewhere in the buildsystem Unfortunately, the target namees defined at the Makefile.am level can't be used for *.in substitution. So these new defines will have to stay synced up with those targets. Using the new variables for the deploy targets in the main Makefile.am will ensure that they stay in sync, otherwise build tests will fail. --- Makefile.am | 6 +++--- configure.ac | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0929a59ed..5783c1fdd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,9 +10,9 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libbitcoinconsensus.pc endif -BITCOIND_BIN=$(top_builddir)/src/bitcoind$(EXEEXT) -BITCOIN_QT_BIN=$(top_builddir)/src/qt/bitcoin-qt$(EXEEXT) -BITCOIN_CLI_BIN=$(top_builddir)/src/bitcoin-cli$(EXEEXT) +BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT) +BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT) +BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) empty := diff --git a/configure.ac b/configure.ac index ec5656814..6e463dfc5 100644 --- a/configure.ac +++ b/configure.ac @@ -14,6 +14,11 @@ AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) +BITCOIN_DAEMON_NAME=bitcoind +BITCOIN_GUI_NAME=bitcoin-qt +BITCOIN_CLI_NAME=bitcoin-cli +BITCOIN_TX_NAME=bitcoin-tx + AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_CONFIG_H]) @@ -1019,6 +1024,10 @@ AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(COPYRIGHT_HOLDERS, "_COPYRIGHT_HOLDERS") AC_SUBST(COPYRIGHT_HOLDERS_SUBSTITUTION, "_COPYRIGHT_HOLDERS_SUBSTITUTION") AC_SUBST(COPYRIGHT_HOLDERS_FINAL, "_COPYRIGHT_HOLDERS_FINAL") +AC_SUBST(BITCOIN_DAEMON_NAME) +AC_SUBST(BITCOIN_GUI_NAME) +AC_SUBST(BITCOIN_CLI_NAME) +AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(HARDENED_CXXFLAGS) From 26880c34cd3e0837724487f6b14cc3cdd7bc8a4f Mon Sep 17 00:00:00 2001 From: JeremyRand Date: Fri, 26 Feb 2016 00:04:48 +0000 Subject: [PATCH 0437/1223] build: Use PACKAGE_TARNAME and new bin names in NSIS script. Replaces the hardcoded string "bitcoin" with the autoconf variable PACKAGE_TARNAME; fixes #7265. Places where I chose not to replace: 1. bitcoin.ico wasn't replaced because it doesn't seem to be relevant to the build system and its filename never affects the end user. 2. InstallDir wasn't replaced because the current text has an uppercase B, and I'm not sure of a good way to capitalize the result of PACKAGE_TARNAME. 3. A comment in the Main Installer section wasn't replaced because comments don't ever face the end user. 4. The registry value "URL:Bitcoin" wasn't replaced for the same reason as InstallDir. 5. Startup shortcut wasn't replaced for the same reason as InstallDir. All other appearances of "bitcoin" were replaced with PACKAGE_TARNAME, except for the bin names, which were instead replaced with the new bin name autoconf variables. --- share/setup.nsi.in | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index e553a5ae8..ebffb3b85 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -20,7 +20,7 @@ SetCompressor /SOLID lzma !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup !define MUI_STARTMENUPAGE_DEFAULTFOLDER "@PACKAGE_NAME@" -!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin-qt.exe +!define MUI_FINISHPAGE_RUN $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE @@ -48,7 +48,7 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile @abs_top_srcdir@/bitcoin-${VERSION}-win@WINDOWS_BITS@-setup.exe +OutFile @abs_top_srcdir@/@PACKAGE_TARNAME@-${VERSION}-win@WINDOWS_BITS@-setup.exe !if "@WINDOWS_BITS@" == "64" InstallDir $PROGRAMFILES64\Bitcoin !else @@ -73,19 +73,19 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_srcdir@/release/bitcoin-qt.exe + File @abs_top_srcdir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ File /oname=COPYING.txt @abs_top_srcdir@/COPYING File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt SetOutPath $INSTDIR\daemon - File @abs_top_srcdir@/release/bitcoind.exe - File @abs_top_srcdir@/release/bitcoin-cli.exe + File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ + File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ SetOutPath $INSTDIR\doc File /r @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 # Remove old wxwidgets-based-bitcoin executable and locales: - Delete /REBOOTOK $INSTDIR\bitcoin.exe + Delete /REBOOTOK $INSTDIR\@PACKAGE_TARNAME@.exe RMDir /r /REBOOTOK $INSTDIR\locale SectionEnd @@ -95,7 +95,7 @@ Section -post SEC0001 WriteUninstaller $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\bitcoin-qt.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" @@ -106,10 +106,10 @@ Section -post SEC0001 WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 - WriteRegStr HKCR "bitcoin" "URL Protocol" "" - WriteRegStr HKCR "bitcoin" "" "URL:Bitcoin" - WriteRegStr HKCR "bitcoin\DefaultIcon" "" $INSTDIR\bitcoin-qt.exe - WriteRegStr HKCR "bitcoin\shell\open\command" "" '"$INSTDIR\bitcoin-qt.exe" "%1"' + WriteRegStr HKCR "@PACKAGE_TARNAME@" "URL Protocol" "" + WriteRegStr HKCR "@PACKAGE_TARNAME@" "" "URL:Bitcoin" + WriteRegStr HKCR "@PACKAGE_TARNAME@\DefaultIcon" "" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ + WriteRegStr HKCR "@PACKAGE_TARNAME@\shell\open\command" "" '"$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "%1"' SectionEnd # Macro for selecting uninstaller sections @@ -127,7 +127,7 @@ done${UNSECTION_ID}: # Uninstaller sections Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\bitcoin-qt.exe + Delete /REBOOTOK $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ Delete /REBOOTOK $INSTDIR\COPYING.txt Delete /REBOOTOK $INSTDIR\readme.txt RMDir /r /REBOOTOK $INSTDIR\daemon @@ -147,7 +147,7 @@ Section -un.post UNSEC0001 DeleteRegValue HKCU "${REGKEY}" Path DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" DeleteRegKey /IfEmpty HKCU "${REGKEY}" - DeleteRegKey HKCR "bitcoin" + DeleteRegKey HKCR "@PACKAGE_TARNAME@" RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup RmDir /REBOOTOK $INSTDIR Push $R0 From 0528e30a4551d1437e049103624fd461229aced1 Mon Sep 17 00:00:00 2001 From: JeremyRand Date: Sat, 19 Mar 2016 11:19:06 +0000 Subject: [PATCH 0438/1223] Remove wxwidgets references from NSIS script. The NSIS script tried to delete wxwidgets-based executables/locales. These files are ancient, and presumably no users have them anymore, so we can simplify the NSIS script by removing those lines. --- share/setup.nsi.in | 4 ---- 1 file changed, 4 deletions(-) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index ebffb3b85..c062f96a3 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -83,10 +83,6 @@ Section -Main SEC0000 File /r @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 - - # Remove old wxwidgets-based-bitcoin executable and locales: - Delete /REBOOTOK $INSTDIR\@PACKAGE_TARNAME@.exe - RMDir /r /REBOOTOK $INSTDIR\locale SectionEnd Section -post SEC0001 From 4a1d5c19ee86b924705e66a8bc31567a35f9e53d Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 8 Apr 2016 16:00:40 +0800 Subject: [PATCH 0439/1223] [Doc] Update gitian build guide to debian 8.4.0 --- doc/gitian-building.md | 20 +++++++++++------- .../all_files_in_one_partition.png | Bin 0 -> 3350 bytes .../create_vm_file_location_size.png | Bin 71743 -> 111942 bytes doc/gitian-building/select_startup_disk.png | Bin 130324 -> 72785 bytes 4 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 doc/gitian-building/all_files_in_one_partition.png diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 69d79b3c6..151b9d8f9 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -47,7 +47,7 @@ You can also install Gitian on actual hardware instead of using virtualization. Create a new VirtualBox VM --------------------------- -In the VirtualBox GUI click "Create" and choose the following parameters in the wizard: +In the VirtualBox GUI click "New" and choose the following parameters in the wizard: ![](gitian-building/create_new_vm.png) @@ -74,13 +74,6 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - File location and size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Click `Create` -Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/debian-8.3.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). -This DVD image can be validated using a SHA256 hashing tool, for example on -Unixy OSes by entering the following in a terminal: - - echo "dd25bcdde3c6ea5703cc0f313cde621b13d42ff7d252e2538a11663c93bf8654 debian-8.3.0-amd64-netinst.iso" | sha256sum -c - # (must return OK) - After creating the VM, we need to configure it. - Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`. @@ -102,6 +95,13 @@ After creating the VM, we need to configure it. - Click `Ok` twice to save. +Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.4.0/amd64/iso-cd/debian-8.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +This DVD image can be validated using a SHA256 hashing tool, for example on +Unixy OSes by entering the following in a terminal: + + echo "7a6b418e6a4ee3ca75dda04d79ed96c9e2c33bb0c703ca7e40c6374ab4590748 debian-8.4.0-amd64-netinst.iso" | sha256sum -c + # (must return OK) + Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded iso. ![](gitian-building/select_startup_disk.png) @@ -160,6 +160,10 @@ To select a different button, press `Tab`. ![](gitian-building/debian_install_12_choose_disk.png) + - Partition Disks -> *All files in one partition* + +![](gitian-building/all_files_in_one_partition.png) + - Finish partitioning and write changes to disk -> *Yes* (`Tab`, `Enter` to select the `Yes` button) ![](gitian-building/debian_install_14_finish.png) diff --git a/doc/gitian-building/all_files_in_one_partition.png b/doc/gitian-building/all_files_in_one_partition.png new file mode 100644 index 0000000000000000000000000000000000000000..8cbb0d8adc1deda1c7c4023611b65521e054ff69 GIT binary patch literal 3350 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∾;f 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

5}ss6hBz2 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

Yv36);|zQ7@X|zmOcox3QHk-s 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 literal 130324 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%0Ak59s=zJ0NHtF`o_dye&c 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 TE= Date: Mon, 11 Apr 2016 17:31:25 +0800 Subject: [PATCH 0440/1223] Add jl2012 public key for gitian build --- contrib/gitian-downloader/jl2012-key.pgp | 105 +++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 contrib/gitian-downloader/jl2012-key.pgp diff --git a/contrib/gitian-downloader/jl2012-key.pgp b/contrib/gitian-downloader/jl2012-key.pgp new file mode 100644 index 000000000..b8aad7fd8 --- /dev/null +++ b/contrib/gitian-downloader/jl2012-key.pgp @@ -0,0 +1,105 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: GPGTools - https://gpgtools.org + +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 +=1irw +-----END PGP PUBLIC KEY BLOCK----- From 7e91f632c70ff1848a152f24ee67a06796803943 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 11 Apr 2016 12:52:29 -0400 Subject: [PATCH 0441/1223] Use txid as key in mapAlreadyAskedFor Previously we used the CInv that would be sent to the peer announcing the transaction as the key, but using the txid instead allows us to decouple the p2p layer from the application logic (which relies on this map to avoid duplicate tx requests). --- src/main.cpp | 2 +- src/net.cpp | 6 +++--- src/net.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f5c7e11d6..5c1af9ecc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4956,7 +4956,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CValidationState state; pfrom->setAskFor.erase(inv.hash); - mapAlreadyAskedFor.erase(inv); + mapAlreadyAskedFor.erase(inv.hash); CFeeRate txFeeRate = CFeeRate(0); if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, &txFeeRate)) { diff --git a/src/net.cpp b/src/net.cpp index e8cc753a4..3bf8c165d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -93,7 +93,7 @@ CCriticalSection cs_vNodes; map mapRelay; deque > vRelayExpiration; CCriticalSection cs_mapRelay; -limitedmap mapAlreadyAskedFor(MAX_INV_SZ); +limitedmap mapAlreadyAskedFor(MAX_INV_SZ); static deque vOneShots; CCriticalSection cs_vOneShots; @@ -2436,7 +2436,7 @@ void CNode::AskFor(const CInv& inv) // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64_t nRequestTime; - limitedmap::const_iterator it = mapAlreadyAskedFor.find(inv); + limitedmap::const_iterator it = mapAlreadyAskedFor.find(inv.hash); if (it != mapAlreadyAskedFor.end()) nRequestTime = it->second; else @@ -2455,7 +2455,7 @@ void CNode::AskFor(const CInv& inv) if (it != mapAlreadyAskedFor.end()) mapAlreadyAskedFor.update(it, nRequestTime); else - mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime)); + mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime)); mapAskFor.insert(std::make_pair(nRequestTime, inv)); } diff --git a/src/net.h b/src/net.h index ab9eb68d8..1892c963f 100644 --- a/src/net.h +++ b/src/net.h @@ -164,7 +164,7 @@ extern CCriticalSection cs_vNodes; extern std::map mapRelay; extern std::deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; -extern limitedmap mapAlreadyAskedFor; +extern limitedmap mapAlreadyAskedFor; extern std::vector vAddedNodes; extern CCriticalSection cs_vAddedNodes; From 41dbc4849e0bf14eef98962b0f0bddcde0bb3014 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 9 Apr 2016 14:30:07 +0100 Subject: [PATCH 0442/1223] Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp`. See https://github.com/bitcoin/bitcoin/issues/7845#issuecomment-207684728. Also refactored `GetDefaultDataDir` function to return path for Mac in one expression. --- src/util.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 59f58f2c5..00b75fbdb 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -471,9 +471,7 @@ boost::filesystem::path GetDefaultDataDir() pathRet = fs::path(pszHome); #ifdef MAC_OSX // Mac - pathRet /= "Library/Application Support"; - TryCreateDirectory(pathRet); - return pathRet / "Bitcoin"; + return pathRet / "Library/Application Support/Bitcoin"; #else // Unix return pathRet / ".bitcoin"; From 85c807c9ead3215021503348e75851900dfa08db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 12 Apr 2016 15:44:18 +0930 Subject: [PATCH 0443/1223] getblockchaininfo: make bip9_softforks an object, not an array. We can't change "softforks", but it seems far more logical to use tags in an object rather than using an "id" field in an array. For example, to get the csv status before, you need to iterate the array to find the entry with 'id' field equal to "csv": jq '.bip9_softforks | map(select(.id == "csv"))[] | .status' Now: jq '.bip9_softforks.csv.status' There is no issue with fork names being incompatible with JSON tags, since we're selecting them ourselves. Signed-off-by: Rusty Russell --- qa/rpc-tests/bip9-softforks.py | 6 +----- qa/rpc-tests/test_framework/util.py | 5 +---- src/rpc/blockchain.cpp | 14 ++++++-------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 98975e719..e63343d35 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -79,11 +79,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): def get_bip9_status(self, key): info = self.nodes[0].getblockchaininfo() - for row in info['bip9_softforks']: - if row['id'] == key: - return row - raise IndexError ('key:"%s" not found' % key) - + return info['bip9_softforks'][key] def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature): # generate some coins for later diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index d9fe0f75f..acb7f8a6b 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -548,7 +548,4 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee): def get_bip9_status(node, key): info = node.getblockchaininfo() - for row in info['bip9_softforks']: - if row['id'] == key: - return row - raise IndexError ('key:"%s" not found' % key) + return info['bip9_softforks'][key] diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..7a01a10b7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -608,10 +608,9 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } -static UniValue BIP9SoftForkDesc(const std::string& name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id) { UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); switch (thresholdState) { case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; @@ -660,15 +659,14 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" " ],\n" - " \"bip9_softforks\": [ (array) status of BIP9 softforks in progress\n" - " {\n" - " \"id\": \"xxxx\", (string) name of the softfork\n" + " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" + " \"xxxx\" : { (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" - " ]\n" + " }\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") @@ -691,11 +689,11 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); - UniValue bip9_softforks(UniValue::VARR); + UniValue bip9_softforks(UniValue::VOBJ); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV)); + bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); From d12760b16ac30734b5e3b047df8aaf6564e927db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Apr 2016 16:54:07 +0930 Subject: [PATCH 0444/1223] rpc-tests: handle KeyError nicely in test_framework.py btcdrak wrote this for me. Signed-off-by: Rusty Russell --- qa/rpc-tests/test_framework/test_framework.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 19ee47260..3b08cd138 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -142,6 +142,9 @@ class BitcoinTestFramework(object): except AssertionError as e: print("Assertion failed: "+ str(e)) traceback.print_tb(sys.exc_info()[2]) + except KeyError as e: + print("key not found: "+ str(e)) + traceback.print_tb(sys.exc_info()[2]) except Exception as e: print("Unexpected exception caught during testing: "+str(e)) traceback.print_tb(sys.exc_info()[2]) From c6cb6f7d4c4bbfe96256c66b3aef4e7e3ff6285f Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Wed, 13 Apr 2016 16:02:46 -0400 Subject: [PATCH 0445/1223] Avoid unnecessary database access for unknown transactions --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9b164c799..f5baf3559 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4344,10 +4344,12 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) recentRejects->reset(); } + // Use pcoinsTip->HaveCoinsInCache as a quick approximation to exclude + // requesting or processing some txs which have already been included in a block return recentRejects->contains(inv.hash) || mempool.exists(inv.hash) || mapOrphanTransactions.count(inv.hash) || - pcoinsTip->HaveCoins(inv.hash); + pcoinsTip->HaveCoinsInCache(inv.hash); } case MSG_BLOCK: return mapBlockIndex.count(inv.hash); From 38c310299cfef419d42744362b90c1700b598953 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 14 Apr 2016 16:04:50 +0200 Subject: [PATCH 0446/1223] Change mapRelay to store CTransactions --- src/main.cpp | 7 ++----- src/net.cpp | 17 ++++------------- src/net.h | 5 ++--- 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fff1cc346..f84fb8dd5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4456,7 +4456,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam bool pushed = false; { LOCK(cs_mapRelay); - map::iterator mi = mapRelay.find(inv); + map::iterator mi = mapRelay.find(inv.hash); if (mi != mapRelay.end()) { pfrom->PushMessage(inv.GetCommand(), (*mi).second); pushed = true; @@ -4465,10 +4465,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam if (!pushed && inv.type == MSG_TX) { CTransaction tx; if (mempool.lookup(inv.hash, tx)) { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss.reserve(1000); - ss << tx; - pfrom->PushMessage(NetMsgType::TX, ss); + pfrom->PushMessage(NetMsgType::TX, tx); pushed = true; } } diff --git a/src/net.cpp b/src/net.cpp index 3bf8c165d..e64cb4ef9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -90,8 +90,8 @@ std::string strSubVersion; vector vNodes; CCriticalSection cs_vNodes; -map mapRelay; -deque > vRelayExpiration; +map mapRelay; +deque > vRelayExpiration; CCriticalSection cs_mapRelay; limitedmap mapAlreadyAskedFor(MAX_INV_SZ); @@ -2054,14 +2054,6 @@ instance_of_cnetcleanup; void RelayTransaction(const CTransaction& tx, CFeeRate feerate) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss.reserve(10000); - ss << tx; - RelayTransaction(tx, feerate, ss); -} - -void RelayTransaction(const CTransaction& tx, CFeeRate feerate, const CDataStream& ss) { CInv inv(MSG_TX, tx.GetHash()); { @@ -2073,9 +2065,8 @@ void RelayTransaction(const CTransaction& tx, CFeeRate feerate, const CDataStrea vRelayExpiration.pop_front(); } - // Save original serialized message so newer versions are preserved - mapRelay.insert(std::make_pair(inv, ss)); - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); + mapRelay.insert(std::make_pair(inv.hash, tx)); + vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv.hash)); } LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) diff --git a/src/net.h b/src/net.h index 1892c963f..7f905002a 100644 --- a/src/net.h +++ b/src/net.h @@ -161,8 +161,8 @@ extern int nMaxConnections; extern std::vector vNodes; extern CCriticalSection cs_vNodes; -extern std::map mapRelay; -extern std::deque > vRelayExpiration; +extern std::map mapRelay; +extern std::deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; extern limitedmap mapAlreadyAskedFor; @@ -773,7 +773,6 @@ public: class CTransaction; void RelayTransaction(const CTransaction& tx, CFeeRate feerate); -void RelayTransaction(const CTransaction& tx, CFeeRate feerate, const CDataStream& ss); /** Access to the (IP) address database (peers.dat) */ class CAddrDB From fa7abe0a00464e6aa88d55c63dba40878bbe5b79 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 14 Apr 2016 19:39:49 +0200 Subject: [PATCH 0447/1223] [test] bctest.py: Revert faa41ee --- src/test/bctest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/bctest.py b/src/test/bctest.py index fc59152ba..8105b87ff 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -2,7 +2,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. from __future__ import division,print_function,unicode_literals -from io import open import subprocess import os import json @@ -17,7 +16,7 @@ def bctest(testDir, testObj, exeext): inputData = None if "input" in testObj: filename = testDir + "/" + testObj['input'] - inputData = open(filename, 'rb').read() + inputData = open(filename).read() stdinCfg = subprocess.PIPE outputFn = None From 90604f16af63ec066d6561337f476ccd8acec326 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 1 Jun 2015 16:35:19 +0200 Subject: [PATCH 0448/1223] add bip32 pubkey serialization CExtPubKey should be serializable like CPubKey --- src/base58.h | 4 ++-- src/key.cpp | 6 +++--- src/key.h | 21 +++++++++++++++++++-- src/pubkey.cpp | 6 +++--- src/pubkey.h | 30 ++++++++++++++++++++++++++++-- src/test/bip32_tests.cpp | 16 ++++++++++++++++ 6 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/base58.h b/src/base58.h index a3980118a..cccebc9e0 100644 --- a/src/base58.h +++ b/src/base58.h @@ -164,7 +164,7 @@ public: CBitcoinExtKeyBase() {} }; -typedef CBitcoinExtKeyBase CBitcoinExtKey; -typedef CBitcoinExtKeyBase CBitcoinExtPubKey; +typedef CBitcoinExtKeyBase CBitcoinExtKey; +typedef CBitcoinExtKeyBase CBitcoinExtPubKey; #endif // BITCOIN_BASE58_H diff --git a/src/key.cpp b/src/key.cpp index 28ba5144e..6a3d9aa14 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -275,7 +275,7 @@ CExtPubKey CExtKey::Neuter() const { return ret; } -void CExtKey::Encode(unsigned char code[74]) const { +void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const { code[0] = nDepth; memcpy(code+1, vchFingerprint, 4); code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; @@ -286,12 +286,12 @@ void CExtKey::Encode(unsigned char code[74]) const { memcpy(code+42, key.begin(), 32); } -void CExtKey::Decode(const unsigned char code[74]) { +void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { nDepth = code[0]; memcpy(vchFingerprint, code+1, 4); nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8]; memcpy(chaincode.begin(), code+9, 32); - key.Set(code+42, code+74, true); + key.Set(code+42, code+BIP32_EXTKEY_SIZE, true); } bool ECC_InitSanityCheck() { diff --git a/src/key.h b/src/key.h index 6c820d49c..b4f48d59f 100644 --- a/src/key.h +++ b/src/key.h @@ -164,11 +164,28 @@ struct CExtKey { a.chaincode == b.chaincode && a.key == b.key; } - void Encode(unsigned char code[74]) const; - void Decode(const unsigned char code[74]); + void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; + void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); bool Derive(CExtKey& out, unsigned int nChild) const; CExtPubKey Neuter() const; void SetMaster(const unsigned char* seed, unsigned int nSeedLen); + template + void Serialize(Stream& s, int nType, int nVersion) const + { + unsigned int len = BIP32_EXTKEY_SIZE; + ::WriteCompactSize(s, len); + unsigned char code[BIP32_EXTKEY_SIZE]; + Encode(code); + s.write((const char *)&code[0], len); + } + template + void Unserialize(Stream& s, int nType, int nVersion) + { + unsigned int len = ::ReadCompactSize(s); + unsigned char code[BIP32_EXTKEY_SIZE]; + s.read((char *)&code[0], len); + Decode(code); + } }; /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ diff --git a/src/pubkey.cpp b/src/pubkey.cpp index db06a8928..be4ee27cd 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -246,7 +246,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi return true; } -void CExtPubKey::Encode(unsigned char code[74]) const { +void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const { code[0] = nDepth; memcpy(code+1, vchFingerprint, 4); code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; @@ -256,12 +256,12 @@ void CExtPubKey::Encode(unsigned char code[74]) const { memcpy(code+41, pubkey.begin(), 33); } -void CExtPubKey::Decode(const unsigned char code[74]) { +void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { nDepth = code[0]; memcpy(vchFingerprint, code+1, 4); nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8]; memcpy(chaincode.begin(), code+9, 32); - pubkey.Set(code+41, code+74); + pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE); } bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { diff --git a/src/pubkey.h b/src/pubkey.h index e1a17b658..db5444ea9 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -23,6 +23,8 @@ * script supports up to 75 for single byte push */ +const unsigned int BIP32_EXTKEY_SIZE = 74; + /** A reference to a CKey: the Hash160 of its serialized public key */ class CKeyID : public uint160 { @@ -205,9 +207,33 @@ struct CExtPubKey { a.chaincode == b.chaincode && a.pubkey == b.pubkey; } - void Encode(unsigned char code[74]) const; - void Decode(const unsigned char code[74]); + void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; + void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); bool Derive(CExtPubKey& out, unsigned int nChild) const; + + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return BIP32_EXTKEY_SIZE+1; //add one byte for the size (compact int) + } + template + void Serialize(Stream& s, int nType, int nVersion) const + { + unsigned int len = BIP32_EXTKEY_SIZE; + ::WriteCompactSize(s, len); + unsigned char code[BIP32_EXTKEY_SIZE]; + Encode(code); + s.write((const char *)&code[0], len); + } + template + void Unserialize(Stream& s, int nType, int nVersion) + { + unsigned int len = ::ReadCompactSize(s); + unsigned char code[BIP32_EXTKEY_SIZE]; + if (len != BIP32_EXTKEY_SIZE) + throw std::runtime_error("Invalid extended key size\n"); + s.read((char *)&code[0], len); + Decode(code); + } }; /** Users of this module must hold an ECCVerifyHandle. The constructor and diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index ce29e692d..7f1c2a32d 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -117,6 +117,22 @@ void RunTest(const TestVector &test) { } key = keyNew; pubkey = pubkeyNew; + + CDataStream ssPub(SER_DISK, CLIENT_VERSION); + ssPub << pubkeyNew; + BOOST_CHECK(ssPub.size() == 75); + + CDataStream ssPriv(SER_DISK, CLIENT_VERSION); + ssPriv << keyNew; + BOOST_CHECK(ssPriv.size() == 75); + + CExtPubKey pubCheck; + CExtKey privCheck; + ssPub >> pubCheck; + ssPriv >> privCheck; + + BOOST_CHECK(pubCheck == pubkeyNew); + BOOST_CHECK(privCheck == keyNew); } } From fa939366910ee11e9c307d0d57eb21cdec8a362b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 13 Apr 2016 12:10:04 +0200 Subject: [PATCH 0449/1223] [gitian] Add marcofalke-key.pgp --- contrib/gitian-downloader/marcofalke-key.pgp | 69 ++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 contrib/gitian-downloader/marcofalke-key.pgp diff --git a/contrib/gitian-downloader/marcofalke-key.pgp b/contrib/gitian-downloader/marcofalke-key.pgp new file mode 100644 index 000000000..ee626500a --- /dev/null +++ b/contrib/gitian-downloader/marcofalke-key.pgp @@ -0,0 +1,69 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +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 +=GC3s +-----END PGP PUBLIC KEY BLOCK----- From faf4c837fba119437ddbb36d6a799dc5fd79db37 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 13 Apr 2016 12:34:32 +0200 Subject: [PATCH 0450/1223] [gitian] Move keys to contrib/gitian-keys --- contrib/README.md | 6 +++--- .../achow101-key.pgp | 0 .../aschildbach-key.pgp | Bin .../bluematt-key.pgp | Bin .../btcdrak-key.pgp | 0 .../cdecker-key.pgp | Bin .../centaur1-key.pgp | 0 .../cfields-key.pgp | 0 .../devrandom-key.pgp | Bin .../{gitian-downloader => gitian-keys}/erkmos.pgp | Bin .../fanquake-key.pgp | 0 .../gavinandresen-key.pgp | Bin .../jl2012-key.pgp | 0 .../jonasschnelli-key.pgp | 0 .../laanwj-key.pgp | 0 .../luke-jr-key.pgp | Bin .../marcofalke-key.pgp | 0 .../michagogo-key.pgp | 0 .../petertodd-key.pgp | 0 .../{gitian-downloader => gitian-keys}/prab-key.pgp | 0 .../{gitian-downloader => gitian-keys}/sipa-key.pgp | Bin .../tcatm-key.pgp | Bin .../wtogami-key.pgp | 0 doc/release-process.md | 2 +- 24 files changed, 4 insertions(+), 4 deletions(-) rename contrib/{gitian-downloader => gitian-keys}/achow101-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/aschildbach-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/bluematt-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/btcdrak-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/cdecker-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/centaur1-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/cfields-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/devrandom-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/erkmos.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/fanquake-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/gavinandresen-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/jl2012-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/jonasschnelli-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/laanwj-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/luke-jr-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/marcofalke-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/michagogo-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/petertodd-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/prab-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/sipa-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/tcatm-key.pgp (100%) rename contrib/{gitian-downloader => gitian-keys}/wtogami-key.pgp (100%) diff --git a/contrib/README.md b/contrib/README.md index 946153916..32b3a170a 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -34,10 +34,10 @@ Contains files used to package bitcoind/bitcoin-qt for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here. ### [Gitian-descriptors](/contrib/gitian-descriptors) ### -Gavin's notes on getting gitian builds up and running using KVM. +Notes on getting Gitian builds up and running using KVM. -### [Gitian-downloader](/contrib/gitian-downloader) -Various PGP files of core developers. +### [Gitian-keys](/contrib/gitian-keys) +PGP keys used for signing Bitcoin Core [Gitian release](/doc/release-process.md) results. ### [MacDeploy](/contrib/macdeploy) ### Scripts and notes for Mac builds. diff --git a/contrib/gitian-downloader/achow101-key.pgp b/contrib/gitian-keys/achow101-key.pgp similarity index 100% rename from contrib/gitian-downloader/achow101-key.pgp rename to contrib/gitian-keys/achow101-key.pgp diff --git a/contrib/gitian-downloader/aschildbach-key.pgp b/contrib/gitian-keys/aschildbach-key.pgp similarity index 100% rename from contrib/gitian-downloader/aschildbach-key.pgp rename to contrib/gitian-keys/aschildbach-key.pgp diff --git a/contrib/gitian-downloader/bluematt-key.pgp b/contrib/gitian-keys/bluematt-key.pgp similarity index 100% rename from contrib/gitian-downloader/bluematt-key.pgp rename to contrib/gitian-keys/bluematt-key.pgp diff --git a/contrib/gitian-downloader/btcdrak-key.pgp b/contrib/gitian-keys/btcdrak-key.pgp similarity index 100% rename from contrib/gitian-downloader/btcdrak-key.pgp rename to contrib/gitian-keys/btcdrak-key.pgp diff --git a/contrib/gitian-downloader/cdecker-key.pgp b/contrib/gitian-keys/cdecker-key.pgp similarity index 100% rename from contrib/gitian-downloader/cdecker-key.pgp rename to contrib/gitian-keys/cdecker-key.pgp diff --git a/contrib/gitian-downloader/centaur1-key.pgp b/contrib/gitian-keys/centaur1-key.pgp similarity index 100% rename from contrib/gitian-downloader/centaur1-key.pgp rename to contrib/gitian-keys/centaur1-key.pgp diff --git a/contrib/gitian-downloader/cfields-key.pgp b/contrib/gitian-keys/cfields-key.pgp similarity index 100% rename from contrib/gitian-downloader/cfields-key.pgp rename to contrib/gitian-keys/cfields-key.pgp diff --git a/contrib/gitian-downloader/devrandom-key.pgp b/contrib/gitian-keys/devrandom-key.pgp similarity index 100% rename from contrib/gitian-downloader/devrandom-key.pgp rename to contrib/gitian-keys/devrandom-key.pgp diff --git a/contrib/gitian-downloader/erkmos.pgp b/contrib/gitian-keys/erkmos.pgp similarity index 100% rename from contrib/gitian-downloader/erkmos.pgp rename to contrib/gitian-keys/erkmos.pgp diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-keys/fanquake-key.pgp similarity index 100% rename from contrib/gitian-downloader/fanquake-key.pgp rename to contrib/gitian-keys/fanquake-key.pgp diff --git a/contrib/gitian-downloader/gavinandresen-key.pgp b/contrib/gitian-keys/gavinandresen-key.pgp similarity index 100% rename from contrib/gitian-downloader/gavinandresen-key.pgp rename to contrib/gitian-keys/gavinandresen-key.pgp diff --git a/contrib/gitian-downloader/jl2012-key.pgp b/contrib/gitian-keys/jl2012-key.pgp similarity index 100% rename from contrib/gitian-downloader/jl2012-key.pgp rename to contrib/gitian-keys/jl2012-key.pgp diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-keys/jonasschnelli-key.pgp similarity index 100% rename from contrib/gitian-downloader/jonasschnelli-key.pgp rename to contrib/gitian-keys/jonasschnelli-key.pgp diff --git a/contrib/gitian-downloader/laanwj-key.pgp b/contrib/gitian-keys/laanwj-key.pgp similarity index 100% rename from contrib/gitian-downloader/laanwj-key.pgp rename to contrib/gitian-keys/laanwj-key.pgp diff --git a/contrib/gitian-downloader/luke-jr-key.pgp b/contrib/gitian-keys/luke-jr-key.pgp similarity index 100% rename from contrib/gitian-downloader/luke-jr-key.pgp rename to contrib/gitian-keys/luke-jr-key.pgp diff --git a/contrib/gitian-downloader/marcofalke-key.pgp b/contrib/gitian-keys/marcofalke-key.pgp similarity index 100% rename from contrib/gitian-downloader/marcofalke-key.pgp rename to contrib/gitian-keys/marcofalke-key.pgp diff --git a/contrib/gitian-downloader/michagogo-key.pgp b/contrib/gitian-keys/michagogo-key.pgp similarity index 100% rename from contrib/gitian-downloader/michagogo-key.pgp rename to contrib/gitian-keys/michagogo-key.pgp diff --git a/contrib/gitian-downloader/petertodd-key.pgp b/contrib/gitian-keys/petertodd-key.pgp similarity index 100% rename from contrib/gitian-downloader/petertodd-key.pgp rename to contrib/gitian-keys/petertodd-key.pgp diff --git a/contrib/gitian-downloader/prab-key.pgp b/contrib/gitian-keys/prab-key.pgp similarity index 100% rename from contrib/gitian-downloader/prab-key.pgp rename to contrib/gitian-keys/prab-key.pgp diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-keys/sipa-key.pgp similarity index 100% rename from contrib/gitian-downloader/sipa-key.pgp rename to contrib/gitian-keys/sipa-key.pgp diff --git a/contrib/gitian-downloader/tcatm-key.pgp b/contrib/gitian-keys/tcatm-key.pgp similarity index 100% rename from contrib/gitian-downloader/tcatm-key.pgp rename to contrib/gitian-keys/tcatm-key.pgp diff --git a/contrib/gitian-downloader/wtogami-key.pgp b/contrib/gitian-keys/wtogami-key.pgp similarity index 100% rename from contrib/gitian-downloader/wtogami-key.pgp rename to contrib/gitian-keys/wtogami-key.pgp diff --git a/doc/release-process.md b/doc/release-process.md index 2c83896c2..5a6ac8482 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -115,7 +115,7 @@ The gbuild invocations below DO NOT DO THIS by default. Add other gitian builders keys to your gpg keyring - gpg --import ../bitcoin/contrib/gitian-downloader/*.pgp + gpg --import ../bitcoin/contrib/gitian-keys/*.pgp Verify the signatures From de821d56e1f458fbe580520c77ac066107f4d77c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 29 Mar 2016 11:34:25 +0200 Subject: [PATCH 0451/1223] [ZMQ] refactor message string --- src/zmq/zmqpublishnotifier.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index f5839620f..a9ce9c48c 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -9,6 +9,11 @@ static std::multimap mapPublishNotifiers; +static const char *MSG_HASHBLOCK = "hashblock"; +static const char *MSG_HASHTX = "hashtx"; +static const char *MSG_RAWBLOCK = "rawblock"; +static const char *MSG_RAWTX = "rawtx"; + // Internal function to send multipart message static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) { @@ -125,7 +130,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0); + int rc = zmq_send_multipart(psocket, MSG_HASHBLOCK, 9, data, 32, 0); return rc == 0; } @@ -136,7 +141,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0); + int rc = zmq_send_multipart(psocket, MSG_HASHTX, 6, data, 32, 0); return rc == 0; } @@ -158,7 +163,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) ss << block; } - int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); + int rc = zmq_send_multipart(psocket, MSG_RAWBLOCK, 8, &(*ss.begin()), ss.size(), 0); return rc == 0; } @@ -168,6 +173,6 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; - int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); + int rc = zmq_send_multipart(psocket, MSG_RAWTX, 5, &(*ss.begin()), ss.size(), 0); return rc == 0; } From 41e835dd50d358c127bab17a1f2872471dbdfe9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 30 Mar 2016 00:59:29 +0100 Subject: [PATCH 0452/1223] Add strict flag to RPCTypeCheckObj Strict flag forces type check on all object keys. --- src/rpc/server.cpp | 15 ++++++++++++++- src/rpc/server.h | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 8326fe14d..d06a9142b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -89,7 +89,8 @@ void RPCTypeCheck(const UniValue& params, void RPCTypeCheckObj(const UniValue& o, const map& typesExpected, - bool fAllowNull) + bool fAllowNull, + bool fStrict) { BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) { @@ -104,6 +105,18 @@ void RPCTypeCheckObj(const UniValue& o, throw JSONRPCError(RPC_TYPE_ERROR, err); } } + + if (fStrict) + { + BOOST_FOREACH(const string& k, o.getKeys()) + { + if (typesExpected.count(k) == 0) + { + string err = strprintf("Unexpected key %s", k); + throw JSONRPCError(RPC_TYPE_ERROR, err); + } + } + } } CAmount AmountFromValue(const UniValue& value) diff --git a/src/rpc/server.h b/src/rpc/server.h index a7ed710ce..b47133661 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -70,7 +70,7 @@ void RPCTypeCheck(const UniValue& params, Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type)); */ void RPCTypeCheckObj(const UniValue& o, - const std::map& typesExpected, bool fAllowNull=false); + const std::map& typesExpected, bool fAllowNull=false, bool fStrict=false); /** Opaque base class for timers returned by NewTimerFunc. * This provides no methods at the moment, but makes sure that delete From af4fe7fd126eff2dd1942276ea91c8ab9dd717c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 30 Mar 2016 02:04:22 +0100 Subject: [PATCH 0453/1223] Add change options to fundrawtransaction --- qa/rpc-tests/fundrawtransaction.py | 80 +++++++++++++++++++++++++++++- src/wallet/rpcwallet.cpp | 58 ++++++++++++++++++---- src/wallet/wallet.cpp | 34 +++++++++---- src/wallet/wallet.h | 5 +- 4 files changed, 153 insertions(+), 24 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 4492ea398..496c7fe8b 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -177,6 +177,83 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee + #################################################### + # test a fundrawtransaction with an invalid option # + #################################################### + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 5.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] + outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + try: + self.nodes[2].fundrawtransaction(rawtx, {'foo': 'bar'}) + raise AssertionError("Accepted invalid option foo") + except JSONRPCException,e: + assert("Unexpected key foo" in e.error['message']) + + + ############################################################ + # test a fundrawtransaction with an invalid change address # + ############################################################ + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 5.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] + outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + try: + self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': 'foobar'}) + raise AssertionError("Accepted invalid bitcoin address") + except JSONRPCException,e: + assert("changeAddress must be a valid bitcoin address" in e.error['message']) + + + + ############################################################ + # test a fundrawtransaction with a provided change address # + ############################################################ + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 5.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] + outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + change = self.nodes[2].getnewaddress() + rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + out = dec_tx['vout'][0]; + assert_equal(change, out['scriptPubKey']['addresses'][0]) + + + ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # ######################################################################### @@ -568,7 +645,7 @@ class RawTransactionsTest(BitcoinTestFramework): outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = self.nodes[3].fundrawtransaction(rawtx, True) + result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True }) res_dec = self.nodes[0].decoderawtransaction(result["hex"]) assert_equal(len(res_dec["vin"]), 1) assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) @@ -584,6 +661,7 @@ class RawTransactionsTest(BitcoinTestFramework): outputs = {self.nodes[2].getnewaddress() : watchonly_amount} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + # Backward compatibility test (2nd param is includeWatching) result = self.nodes[3].fundrawtransaction(rawtx, True) res_dec = self.nodes[0].decoderawtransaction(result["hex"]) assert_equal(len(res_dec["vin"]), 2) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5511e9d3a..5cd57fc38 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2437,7 +2437,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "fundrawtransaction \"hexstring\" includeWatching\n" + "fundrawtransaction \"hexstring\" ( options )\n" "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" "This will not modify existing inputs, and will add one change output to the outputs.\n" "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" @@ -2447,8 +2447,14 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" - "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" - "2. includeWatching (boolean, optional, default false) Also select inputs which are watch only\n" + "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" + "2. options (object, optional)\n" + " {\n" + " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n" + " \"changePosition\" (numeric, optional, default random) The index of the change output\n" + " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" + " }\n" + " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" @@ -2467,7 +2473,40 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + + CTxDestination changeAddress = CNoDestination(); + int changePosition = -1; + bool includeWatching = false; + + if (params.size() > 1) { + if (params[1].type() == UniValue::VBOOL) { + // backward compatibility bool only fallback + includeWatching = params[1].get_bool(); + } + else { + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); + + UniValue options = params[1]; + + RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL), true, true); + + if (options.exists("changeAddress")) { + CBitcoinAddress address(options["changeAddress"].get_str()); + + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "changeAddress must be a valid bitcoin address"); + + changeAddress = address.Get(); + } + + if (options.exists("changePosition")) + changePosition = options["changePosition"].get_int(); + + if (options.exists("includeWatching")) + includeWatching = options["includeWatching"].get_bool(); + } + } // parse hex string from parameter CTransaction origTx; @@ -2477,20 +2516,19 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (origTx.vout.size() == 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); - bool includeWatching = false; - if (params.size() > 1) - includeWatching = params[1].get_bool(); + if (changePosition != -1 && (changePosition < 0 || changePosition > origTx.vout.size())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); CMutableTransaction tx(origTx); CAmount nFee; string strFailReason; - int nChangePos = -1; - if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason, includeWatching)) + + if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(tx))); - result.push_back(Pair("changepos", nChangePos)); + result.push_back(Pair("changepos", changePosition)); result.push_back(Pair("fee", ValueFromAmount(nFee))); return result; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e8c946671..ee9255216 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1932,7 +1932,7 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange) { vector vecSend; @@ -1944,6 +1944,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC } CCoinControl coinControl; + coinControl.destChange = destChange; coinControl.fAllowOtherInputs = true; coinControl.fAllowWatchOnly = includeWatching; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -1951,11 +1952,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC CReserveKey reservekey(this); CWalletTx wtx; - if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false)) + if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, &coinControl, false)) return false; - if (nChangePosRet != -1) - tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]); + if (nChangePosInOut != -1) + tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.vout[nChangePosInOut]); // Add new txins (keeping original txin scriptSig/order) BOOST_FOREACH(const CTxIn& txin, wtx.vin) @@ -1968,9 +1969,10 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC } bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, - int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign) + int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign) { CAmount nValue = 0; + int nChangePosRequest = nChangePosInOut; unsigned int nSubtractFeeFromAmount = 0; BOOST_FOREACH (const CRecipient& recipient, vecSend) { @@ -2036,10 +2038,10 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Start with no fee and loop until there is enough fee while (true) { + nChangePosInOut = nChangePosRequest; txNew.vin.clear(); txNew.vout.clear(); wtxNew.fFromMe = true; - nChangePosRet = -1; bool fFirst = true; CAmount nValueToSelect = nValue; @@ -2159,14 +2161,24 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // add the dust to the fee. if (newTxOut.IsDust(::minRelayTxFee)) { + nChangePosInOut = -1; nFeeRet += nChange; reservekey.ReturnKey(); } else { - // Insert change txn at random position: - nChangePosRet = GetRandInt(txNew.vout.size()+1); - vector::iterator position = txNew.vout.begin()+nChangePosRet; + if (nChangePosInOut == -1) + { + // Insert change txn at random position: + nChangePosInOut = GetRandInt(txNew.vout.size()+1); + } + else if (nChangePosInOut > txNew.vout.size()) + { + strFailReason = _("Change index out of range"); + return false; + } + + vector::iterator position = txNew.vout.begin()+nChangePosInOut; txNew.vout.insert(position, newTxOut); } } @@ -2842,13 +2854,13 @@ void CWallet::GetScriptForMining(boost::shared_ptr &script) script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; } -void CWallet::LockCoin(COutPoint& output) +void CWallet::LockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.insert(output); } -void CWallet::UnlockCoin(COutPoint& output) +void CWallet::UnlockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.erase(output); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 96d5d4e1e..b0781e917 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -739,13 +739,14 @@ public: * Insert additional inputs into the transaction by * calling CreateTransaction(); */ - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange = CNoDestination()); /** * Create a new transaction paying the recipients with a set of coins * selected by SelectCoins(); Also create the change output, when needed + * @note passing nChangePosInOut as -1 will result in setting a random position */ - bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, + bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); From f2d0944eb372838e05c666ce9b3df119d7da5594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 6 Apr 2016 15:56:14 +0100 Subject: [PATCH 0454/1223] Add lockUnspents option to fundrawtransaction --- src/wallet/rpcwallet.cpp | 9 +++++++-- src/wallet/wallet.cpp | 10 +++++++++- src/wallet/wallet.h | 6 +++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5cd57fc38..3078cebd4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2453,6 +2453,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n" " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" + " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " }\n" " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" @@ -2478,6 +2479,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CTxDestination changeAddress = CNoDestination(); int changePosition = -1; bool includeWatching = false; + bool lockUnspents = false; if (params.size() > 1) { if (params[1].type() == UniValue::VBOOL) { @@ -2489,7 +2491,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) UniValue options = params[1]; - RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL), true, true); + RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true); if (options.exists("changeAddress")) { CBitcoinAddress address(options["changeAddress"].get_str()); @@ -2505,6 +2507,9 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (options.exists("includeWatching")) includeWatching = options["includeWatching"].get_bool(); + + if (options.exists("lockUnspents")) + lockUnspents = options["lockUnspents"].get_bool(); } } @@ -2523,7 +2528,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CAmount nFee; string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, changeAddress)) + if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ee9255216..8161c659a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1932,7 +1932,7 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) { vector vecSend; @@ -1962,7 +1962,15 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC BOOST_FOREACH(const CTxIn& txin, wtx.vin) { if (!coinControl.IsSelected(txin.prevout)) + { tx.vin.push_back(txin); + + if (lockUnspents) + { + LOCK2(cs_main, cs_wallet); + LockCoin(txin.prevout); + } + } } return true; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b0781e917..aab4b217c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -667,8 +667,8 @@ public: bool IsSpent(const uint256& hash, unsigned int n) const; bool IsLockedCoin(uint256 hash, unsigned int n) const; - void LockCoin(COutPoint& output); - void UnlockCoin(COutPoint& output); + void LockCoin(const COutPoint& output); + void UnlockCoin(const COutPoint& output); void UnlockAllCoins(); void ListLockedCoins(std::vector& vOutpts); @@ -739,7 +739,7 @@ public: * Insert additional inputs into the transaction by * calling CreateTransaction(); */ - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange = CNoDestination()); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); /** * Create a new transaction paying the recipients with a set of coins From 509cb006d514cece5ab7680094f033c8dc8a2318 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 28 Mar 2016 18:18:30 +0200 Subject: [PATCH 0455/1223] txdb: Add Cursor() method to CCoinsView to iterate over UTXO set Add a method Cursor() to CCoinsView that returns a cursor which can be used to iterate over the whole UTXO set. - rpc: Change gettxoutsetinfo to use new Cursor method - txdb: Remove GetStats method - Now that GetStats is implemented in terms of Cursor, remove it. --- src/coins.cpp | 8 +++-- src/coins.h | 33 ++++++++++------- src/rpc/blockchain.cpp | 58 +++++++++++++++++++++++++++++- src/test/coins_tests.cpp | 2 -- src/txdb.cpp | 78 ++++++++++++++++++++-------------------- src/txdb.h | 26 +++++++++++++- 6 files changed, 148 insertions(+), 57 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 877fb8b26..1c329740b 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -45,7 +45,7 @@ bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return fal bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } uint256 CCoinsView::GetBestBlock() const { return uint256(); } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } -bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } +CCoinsViewCursor *CCoinsView::Cursor() const { return 0; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } @@ -54,7 +54,7 @@ bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveC uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } -bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } +CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} @@ -300,3 +300,7 @@ CCoinsModifier::~CCoinsModifier() cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage(); } } + +CCoinsViewCursor::~CCoinsViewCursor() +{ +} diff --git a/src/coins.h b/src/coins.h index d297cae1a..d72f88547 100644 --- a/src/coins.h +++ b/src/coins.h @@ -297,20 +297,27 @@ struct CCoinsCacheEntry typedef boost::unordered_map CCoinsMap; -struct CCoinsStats +/** Cursor for iterating over CoinsView state */ +class CCoinsViewCursor { - int nHeight; +public: + CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {} + virtual ~CCoinsViewCursor(); + + virtual bool GetKey(uint256 &key) const = 0; + virtual bool GetValue(CCoins &coins) const = 0; + /* Don't care about GetKeySize here */ + virtual unsigned int GetValueSize() const = 0; + + virtual bool Valid() const = 0; + virtual void Next() = 0; + + //! Get best block at the time this cursor was created + const uint256 &GetBestBlock() const { return hashBlock; } +private: uint256 hashBlock; - uint64_t nTransactions; - uint64_t nTransactionOutputs; - uint64_t nSerializedSize; - uint256 hashSerialized; - CAmount nTotalAmount; - - CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} }; - /** Abstract view on the open txout dataset. */ class CCoinsView { @@ -329,8 +336,8 @@ public: //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - //! Calculate statistics about the unspent transaction output set - virtual bool GetStats(CCoinsStats &stats) const; + //! Get a cursor to iterate over the whole state + virtual CCoinsViewCursor *Cursor() const; //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} @@ -350,7 +357,7 @@ public: uint256 GetBestBlock() const; void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - bool GetStats(CCoinsStats &stats) const; + CCoinsViewCursor *Cursor() const; }; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..8dbfbd5ff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -18,11 +18,14 @@ #include "txmempool.h" #include "util.h" #include "utilstrencodings.h" +#include "hash.h" #include #include +#include // boost::thread::interrupt + using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); @@ -432,6 +435,59 @@ UniValue getblock(const UniValue& params, bool fHelp) return blockToJSON(block, pblockindex); } +struct CCoinsStats +{ + int nHeight; + uint256 hashBlock; + uint64_t nTransactions; + uint64_t nTransactionOutputs; + uint64_t nSerializedSize; + uint256 hashSerialized; + CAmount nTotalAmount; + + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} +}; + +//! Calculate statistics about the unspent transaction output set +static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) +{ + boost::scoped_ptr pcursor(view->Cursor()); + + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + stats.hashBlock = pcursor->GetBestBlock(); + { + LOCK(cs_main); + stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + } + ss << stats.hashBlock; + CAmount nTotalAmount = 0; + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + uint256 key; + CCoins coins; + if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { + stats.nTransactions++; + for (unsigned int i=0; iGetValueSize(); + ss << VARINT(0); + } else { + return error("%s: unable to read value", __func__); + } + pcursor->Next(); + } + stats.hashSerialized = ss.GetHash(); + stats.nTotalAmount = nTotalAmount; + return true; +} + UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -458,7 +514,7 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) CCoinsStats stats; FlushStateToDisk(); - if (pcoinsTip->GetStats(stats)) { + if (GetUTXOStats(pcoinsTip, stats)) { ret.push_back(Pair("height", (int64_t)stats.nHeight)); ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 3fe536f91..48e3c8ed8 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -61,8 +61,6 @@ public: hashBestBlock_ = hashBlock; return true; } - - bool GetStats(CCoinsStats& stats) const { return false; } }; class CCoinsViewCacheTest : public CCoinsViewCache diff --git a/src/txdb.cpp b/src/txdb.cpp index f99e11f26..be86cceeb 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -94,50 +94,52 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { return Read(DB_LAST_BLOCK, nFile); } -bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { +CCoinsViewCursor *CCoinsViewDB::Cursor() const +{ + CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast(&db)->NewIterator(), GetBestBlock()); /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ - boost::scoped_ptr pcursor(const_cast(&db)->NewIterator()); - pcursor->Seek(DB_COINS); + i->pcursor->Seek(DB_COINS); + // Cache key of first record + i->pcursor->GetKey(i->keyTmp); + return i; +} - CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); - stats.hashBlock = GetBestBlock(); - ss << stats.hashBlock; - CAmount nTotalAmount = 0; - while (pcursor->Valid()) { - boost::this_thread::interruption_point(); - std::pair key; - CCoins coins; - if (pcursor->GetKey(key) && key.first == DB_COINS) { - if (pcursor->GetValue(coins)) { - stats.nTransactions++; - for (unsigned int i=0; iGetValueSize(); - ss << VARINT(0); - } else { - return error("CCoinsViewDB::GetStats() : unable to read value"); - } - } else { - break; - } - pcursor->Next(); +bool CCoinsViewDBCursor::GetKey(uint256 &key) const +{ + // Return cached key + if (keyTmp.first == DB_COINS) { + key = keyTmp.second; + return true; } - { - LOCK(cs_main); - stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + return false; +} + +bool CCoinsViewDBCursor::GetValue(CCoins &coins) const +{ + return pcursor->GetValue(coins); +} + +unsigned int CCoinsViewDBCursor::GetValueSize() const +{ + return pcursor->GetValueSize(); +} + +bool CCoinsViewDBCursor::Valid() const +{ + return keyTmp.first == DB_COINS; +} + +void CCoinsViewDBCursor::Next() +{ + pcursor->Next(); + if (pcursor->Valid()) { + bool ok = pcursor->GetKey(keyTmp); + assert(ok); // If GetKey fails here something must be wrong with underlying database, we cannot handle that here + } else { + keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false } - stats.hashSerialized = ss.GetHash(); - stats.nTotalAmount = nTotalAmount; - return true; } bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { diff --git a/src/txdb.h b/src/txdb.h index 22e0c5704..749802f0e 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -26,6 +26,8 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; +class CCoinsViewDBCursor; + /** CCoinsView backed by the coin database (chainstate/) */ class CCoinsViewDB : public CCoinsView { @@ -38,7 +40,29 @@ public: bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - bool GetStats(CCoinsStats &stats) const; + CCoinsViewCursor *Cursor() const; +}; + +/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */ +class CCoinsViewDBCursor: public CCoinsViewCursor +{ +public: + ~CCoinsViewDBCursor() {} + + bool GetKey(uint256 &key) const; + bool GetValue(CCoins &coins) const; + unsigned int GetValueSize() const; + + bool Valid() const; + void Next(); + +private: + CCoinsViewDBCursor(CDBIterator* pcursorIn, const uint256 &hashBlockIn): + CCoinsViewCursor(hashBlockIn), pcursor(pcursorIn) {} + boost::scoped_ptr pcursor; + std::pair keyTmp; + + friend class CCoinsViewDB; }; /** Access to the block database (blocks/index/) */ From 9ad1a518574b9afed3e66a1e1658ead1d3d7ce54 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 9 Apr 2016 07:39:35 +0200 Subject: [PATCH 0456/1223] crypto: bytes counts are 64 bit Byte counts for SHA256, SHA512, SHA1 and RIPEMD160 must be 64 bits. `size_t` has a different size per platform, causing divergent results when hashing more than 4GB of data. --- src/crypto/ripemd160.h | 2 +- src/crypto/sha1.h | 2 +- src/crypto/sha256.h | 2 +- src/crypto/sha512.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index 687204fda..bd41f0250 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -14,7 +14,7 @@ class CRIPEMD160 private: uint32_t s[5]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index 7b2a21bc6..8fb20810b 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -14,7 +14,7 @@ class CSHA1 private: uint32_t s[5]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index 85cf33739..5b15b6a23 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -14,7 +14,7 @@ class CSHA256 private: uint32_t s[8]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 32; diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index f1f17caf9..614681fae 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -14,7 +14,7 @@ class CSHA512 private: uint64_t s[8]; unsigned char buf[128]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 64; From 99e70751f23aa59ac297f6746dd8f09a140d48ae Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 5 Apr 2016 15:14:48 +0200 Subject: [PATCH 0457/1223] =?UTF-8?q?Break=20circular=20dependency=20main?= =?UTF-8?q?=20=E2=86=94=20txdb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Break the circular dependency between main and txdb by: - Moving `CBlockFileInfo` from `main.h` to `chain.h`. I think this makes sense, as the other block-file stuff is there too. - Moving `CDiskTxPos` from `main.h` to `txdb.h`. This type seems specific to txdb. - Pass a functor `insertBlockIndex` to `LoadBlockIndexGuts`. This leaves it up to the caller how to insert block indices. --- src/chain.h | 54 +++++++++++++++++++++++++++++++++++ src/main.cpp | 2 +- src/main.h | 79 ---------------------------------------------------- src/txdb.cpp | 8 ++---- src/txdb.h | 33 +++++++++++++++++++--- 5 files changed, 87 insertions(+), 89 deletions(-) diff --git a/src/chain.h b/src/chain.h index 5b9605a80..e9da407e9 100644 --- a/src/chain.h +++ b/src/chain.h @@ -14,6 +14,60 @@ #include +class CBlockFileInfo +{ +public: + unsigned int nBlocks; //!< number of blocks stored in file + unsigned int nSize; //!< number of used bytes of block file + unsigned int nUndoSize; //!< number of used bytes in the undo file + unsigned int nHeightFirst; //!< lowest height of block in file + unsigned int nHeightLast; //!< highest height of block in file + uint64_t nTimeFirst; //!< earliest time of block in file + uint64_t nTimeLast; //!< latest time of block in file + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(VARINT(nBlocks)); + READWRITE(VARINT(nSize)); + READWRITE(VARINT(nUndoSize)); + READWRITE(VARINT(nHeightFirst)); + READWRITE(VARINT(nHeightLast)); + READWRITE(VARINT(nTimeFirst)); + READWRITE(VARINT(nTimeLast)); + } + + void SetNull() { + nBlocks = 0; + nSize = 0; + nUndoSize = 0; + nHeightFirst = 0; + nHeightLast = 0; + nTimeFirst = 0; + nTimeLast = 0; + } + + CBlockFileInfo() { + SetNull(); + } + + std::string ToString() const; + + /** update statistics (does not update nSize) */ + void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { + if (nBlocks==0 || nHeightFirst > nHeightIn) + nHeightFirst = nHeightIn; + if (nBlocks==0 || nTimeFirst > nTimeIn) + nTimeFirst = nTimeIn; + nBlocks++; + if (nHeightIn > nHeightLast) + nHeightLast = nHeightIn; + if (nTimeIn > nTimeLast) + nTimeLast = nTimeIn; + } +}; + struct CDiskBlockPos { int nFile; diff --git a/src/main.cpp b/src/main.cpp index a94d52f89..2db726cb4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3706,7 +3706,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) bool static LoadBlockIndexDB() { const CChainParams& chainparams = Params(); - if (!pblocktree->LoadBlockIndexGuts()) + if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex)) return false; boost::this_thread::interruption_point(); diff --git a/src/main.h b/src/main.h index 0962f44e9..cd2009e28 100644 --- a/src/main.h +++ b/src/main.h @@ -307,30 +307,6 @@ struct CNodeStateStats { std::vector vHeightInFlight; }; -struct CDiskTxPos : public CDiskBlockPos -{ - unsigned int nTxOffset; // after header - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*(CDiskBlockPos*)this); - READWRITE(VARINT(nTxOffset)); - } - - CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { - } - - CDiskTxPos() { - SetNull(); - } - - void SetNull() { - CDiskBlockPos::SetNull(); - nTxOffset = 0; - } -}; /** @@ -469,61 +445,6 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); - -class CBlockFileInfo -{ -public: - unsigned int nBlocks; //!< number of blocks stored in file - unsigned int nSize; //!< number of used bytes of block file - unsigned int nUndoSize; //!< number of used bytes in the undo file - unsigned int nHeightFirst; //!< lowest height of block in file - unsigned int nHeightLast; //!< highest height of block in file - uint64_t nTimeFirst; //!< earliest time of block in file - uint64_t nTimeLast; //!< latest time of block in file - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(VARINT(nBlocks)); - READWRITE(VARINT(nSize)); - READWRITE(VARINT(nUndoSize)); - READWRITE(VARINT(nHeightFirst)); - READWRITE(VARINT(nHeightLast)); - READWRITE(VARINT(nTimeFirst)); - READWRITE(VARINT(nTimeLast)); - } - - void SetNull() { - nBlocks = 0; - nSize = 0; - nUndoSize = 0; - nHeightFirst = 0; - nHeightLast = 0; - nTimeFirst = 0; - nTimeLast = 0; - } - - CBlockFileInfo() { - SetNull(); - } - - std::string ToString() const; - - /** update statistics (does not update nSize) */ - void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { - if (nBlocks==0 || nHeightFirst > nHeightIn) - nHeightFirst = nHeightIn; - if (nBlocks==0 || nTimeFirst > nTimeIn) - nTimeFirst = nTimeIn; - nBlocks++; - if (nHeightIn > nHeightLast) - nHeightLast = nHeightIn; - if (nTimeIn > nTimeLast) - nTimeLast = nTimeIn; - } -}; - /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: diff --git a/src/txdb.cpp b/src/txdb.cpp index be86cceeb..caa6bde38 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,10 +5,8 @@ #include "txdb.h" -#include "chain.h" #include "chainparams.h" #include "hash.h" -#include "main.h" #include "pow.h" #include "uint256.h" @@ -177,7 +175,7 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -bool CBlockTreeDB::LoadBlockIndexGuts() +bool CBlockTreeDB::LoadBlockIndexGuts(boost::function insertBlockIndex) { boost::scoped_ptr pcursor(NewIterator()); @@ -191,8 +189,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts() CDiskBlockIndex diskindex; if (pcursor->GetValue(diskindex)) { // Construct block index object - CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); - pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = insertBlockIndex(diskindex.hashPrev); pindexNew->nHeight = diskindex.nHeight; pindexNew->nFile = diskindex.nFile; pindexNew->nDataPos = diskindex.nDataPos; diff --git a/src/txdb.h b/src/txdb.h index 749802f0e..ce3c39d7f 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -8,15 +8,17 @@ #include "coins.h" #include "dbwrapper.h" +#include "chain.h" #include #include #include #include -class CBlockFileInfo; +#include + class CBlockIndex; -struct CDiskTxPos; +class CCoinsViewDBCursor; class uint256; //! -dbcache default (MiB) @@ -26,7 +28,30 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; -class CCoinsViewDBCursor; +struct CDiskTxPos : public CDiskBlockPos +{ + unsigned int nTxOffset; // after header + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*(CDiskBlockPos*)this); + READWRITE(VARINT(nTxOffset)); + } + + CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { + } + + CDiskTxPos() { + SetNull(); + } + + void SetNull() { + CDiskBlockPos::SetNull(); + nTxOffset = 0; + } +}; /** CCoinsView backed by the coin database (chainstate/) */ class CCoinsViewDB : public CCoinsView @@ -83,7 +108,7 @@ public: bool WriteTxIndex(const std::vector > &list); bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); - bool LoadBlockIndexGuts(); + bool LoadBlockIndexGuts(boost::function insertBlockIndex); }; #endif // BITCOIN_TXDB_H From 76212bbc6a13298d7154ac16c0b989aca5471de8 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 9 Apr 2016 07:59:49 +0200 Subject: [PATCH 0458/1223] rpc: make sure `gettxoutsetinfo` hash has txids The key (transaction id for the following outputs) should be serialized to the HashWriter. This is a problem as it means different transactions in the same position with the same outputs will potentially result in the same hash. Fixes primary concern of #7758. --- src/rpc/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b85b2f6b5..88f6278b2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -467,6 +467,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) CCoins coins; if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { stats.nTransactions++; + ss << key; for (unsigned int i=0; i Date: Fri, 15 Apr 2016 17:54:45 +0200 Subject: [PATCH 0459/1223] doc: update release-notes for `gettxoutsetinfo` change --- doc/release-notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 806d174eb..8360cc481 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -21,6 +21,13 @@ It is recommended to use this for sensitive information such as wallet passphrases, as command-line arguments can usually be read from the process table by any user on the system. +RPC low-level changes +---------------------- + +- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between + 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been + fixed, but this means that the output will be different than from previous versions. + 0.13.0 Change log ================= From 1e2c29f2632c378843c5a3c9ad401a7bcacc4de0 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Wed, 13 Apr 2016 10:09:16 -0700 Subject: [PATCH 0460/1223] prevector: destroy elements only via erase() Fixes a bug in which pop_back did not call the deleted item's destructor. Using the most general erase() implementation to implement all the others prevents similar bugs because the coupling between deallocation and destructor invocation only needs to be maintained in one place. Also reduces duplication of complex memmove logic. --- src/prevector.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/prevector.h b/src/prevector.h index 1da459bcf..16b2f8dca 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -298,9 +298,8 @@ public: } void resize(size_type new_size) { - while (size() > new_size) { - item_ptr(size() - 1)->~T(); - _size--; + if (size() > new_size) { + erase(item_ptr(new_size), end()); } if (new_size > capacity()) { change_capacity(new_size); @@ -368,10 +367,7 @@ public: } iterator erase(iterator pos) { - (*pos).~T(); - memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos)))); - _size--; - return pos; + return erase(pos, pos + 1); } iterator erase(iterator first, iterator last) { @@ -396,7 +392,7 @@ public: } void pop_back() { - _size--; + erase(end() - 1, end()); } T& front() { From 4ed41a2b611dfd328fe6f72312d6c596650f03f8 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Sat, 16 Apr 2016 06:49:38 -0700 Subject: [PATCH 0461/1223] test prevector::swap - add a swap operation to prevector tests (fails due to broken prevector::swap) - fix 2 prevector test operation conditions that were impossible --- src/test/prevector_tests.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 01a45b540..b39b90353 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -19,9 +19,11 @@ template class prevector_tester { typedef std::vector realtype; realtype real_vector; + realtype real_vector_alt; typedef prevector pretype; pretype pre_vector; + pretype pre_vector_alt; typedef typename pretype::size_type Size; @@ -149,6 +151,12 @@ public: pre_vector.shrink_to_fit(); test(); } + + void swap() { + real_vector.swap(real_vector_alt); + pre_vector.swap(pre_vector_alt); + test(); + } }; BOOST_AUTO_TEST_CASE(PrevectorTestInt) @@ -204,12 +212,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (test.size() > 0) { test.update(insecure_rand() % test.size(), insecure_rand()); } - if (((r >> 11) & 1024) == 11) { + if (((r >> 11) % 1024) == 11) { test.clear(); } - if (((r >> 21) & 512) == 12) { + if (((r >> 21) % 512) == 12) { test.assign(insecure_rand() % 32, insecure_rand()); } + if (((r >> 15) % 64) == 3) { + test.swap(); + } } } } From a7af72a697a8decab364792230153f114be3919c Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Thu, 14 Apr 2016 09:26:32 -0700 Subject: [PATCH 0462/1223] prevector::swap: fix (unreached) data corruption swap was using an incorrect condition to determine when to apply an optimization (not swapping the full direct[] when swapping two indirect prevectors). Rather than correct the optimization I'm removing it for simplicity. Removing this optimization minutely improves performance in the typical (currently only) usage of member swap(), which is swapping with a freshly value-initialized object. --- src/prevector.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/prevector.h b/src/prevector.h index 16b2f8dca..a0e1e140b 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -412,12 +412,7 @@ public: } void swap(prevector& other) { - if (_size & other._size & 1) { - std::swap(_union.capacity, other._union.capacity); - std::swap(_union.indirect, other._union.indirect); - } else { - std::swap(_union, other._union); - } + std::swap(_union, other._union); std::swap(_size, other._size); } From fc95f6ecb6ee09c4a5832247f2c8759cb88c2fa1 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Sat, 16 Apr 2016 13:35:42 -0700 Subject: [PATCH 0463/1223] fix typo in help text 'in which the transaction is included in' --- src/rpc/rawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index de8cd68f6..4e1b1576a 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -211,7 +211,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) "\nNOTE: By default this function only works sometimes. This is when there is an\n" "unspent output in the utxo for this transaction. To make it always work,\n" "you need to maintain a transaction index, using the -txindex command line option or\n" - "specify the block in which the transaction is included in manually (by blockhash).\n" + "specify the block in which the transaction is included manually (by blockhash).\n" "\nReturn the raw transaction data.\n" "\nArguments:\n" "1. \"txids\" (string) A json array of txids to filter\n" From dc0693f6379cc63fcea4cb979526b1ba8e0461f3 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Sat, 16 Apr 2016 13:42:28 -0700 Subject: [PATCH 0464/1223] add missing newline Without the newline I see "bein" where the two lines are concatenated: Note that all inputs selected must be of standard form and P2SH scripts must *bein* the wallet using importaddress or addmultisigaddress (to calculate fees). --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3078cebd4..096206f5d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2443,7 +2443,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" "The inputs added will not be signed, use signrawtransaction for that.\n" "Note that all existing inputs must have their previous output transaction be in the wallet.\n" - "Note that all inputs selected must be of standard form and P2SH scripts must be" + "Note that all inputs selected must be of standard form and P2SH scripts must be\n" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" From 3107c475a70042c1aad8b3bbb7d63234b1bbed8d Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Sun, 17 Apr 2016 00:01:49 -0700 Subject: [PATCH 0465/1223] fix spelling mistake --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3078cebd4..21192a58b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2455,7 +2455,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " }\n" - " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" + " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" From e9fc71e5fa6f0d7991bac616b9fed6a80e77a8d7 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:23:16 -0400 Subject: [PATCH 0466/1223] net: require lookup functions to specify all arguments To make it clear where DNS resolves are happening --- src/net.cpp | 4 ++-- src/netbase.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index f294e4c66..6ab6ef819 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1443,7 +1443,7 @@ void ThreadDNSAddressSeed() } else { vector vIPs; vector vAdd; - if (LookupHost(seed.host.c_str(), vIPs)) + if (LookupHost(seed.host.c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { @@ -1884,7 +1884,7 @@ void static Discover(boost::thread_group& threadGroup) if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { vector vaddr; - if (LookupHost(pszHostName, vaddr)) + if (LookupHost(pszHostName, vaddr, 0, true)) { BOOST_FOREACH (const CNetAddr &addr, vaddr) { diff --git a/src/netbase.h b/src/netbase.h index db736154f..4529f9822 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -206,9 +206,9 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut); bool IsProxy(const CNetAddr &addr); bool SetNameProxy(const proxyType &addrProxy); bool HaveNameProxy(); -bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); -bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); -bool Lookup(const char *pszName, std::vector& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0); +bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup); +bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup); +bool Lookup(const char *pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0); bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0); From a3310b4d485b1510c240f1db882530590b6fd7c9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Apr 2016 12:05:32 +0200 Subject: [PATCH 0467/1223] txdb: Fix assert crash in new UTXO set cursor Remove the mistaken assumption that GetKey returning false signifies an internal database issue. It will return false when the key cannot be deserialized into the (char,uint256) stanza, which indicates that the cursor has reached a different kind of key. Fixes bug #7890 introduced in #7756. --- src/txdb.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index be86cceeb..19ca17865 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -134,12 +134,8 @@ bool CCoinsViewDBCursor::Valid() const void CCoinsViewDBCursor::Next() { pcursor->Next(); - if (pcursor->Valid()) { - bool ok = pcursor->GetKey(keyTmp); - assert(ok); // If GetKey fails here something must be wrong with underlying database, we cannot handle that here - } else { + if (!pcursor->Valid() || !pcursor->GetKey(keyTmp)) keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false - } } bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { From de39c95c2468cc643a5d5bed9e5dd8cea6a40747 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Apr 2016 14:03:53 +0200 Subject: [PATCH 0468/1223] test: move accounting_tests and rpc_wallet_tests to wallet/test Move the two other wallet tests to where they belong. --- src/Makefile.test.include | 4 ++-- src/{ => wallet}/test/accounting_tests.cpp | 0 src/{ => wallet}/test/rpc_wallet_tests.cpp | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{ => wallet}/test/accounting_tests.cpp (100%) rename src/{ => wallet}/test/rpc_wallet_tests.cpp (100%) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f025b18c7..989718554 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -90,9 +90,9 @@ BITCOIN_TESTS =\ if ENABLE_WALLET BITCOIN_TESTS += \ - test/accounting_tests.cpp \ + wallet/test/accounting_tests.cpp \ wallet/test/wallet_tests.cpp \ - test/rpc_wallet_tests.cpp + wallet/test/rpc_wallet_tests.cpp endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) diff --git a/src/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp similarity index 100% rename from src/test/accounting_tests.cpp rename to src/wallet/test/accounting_tests.cpp diff --git a/src/test/rpc_wallet_tests.cpp b/src/wallet/test/rpc_wallet_tests.cpp similarity index 100% rename from src/test/rpc_wallet_tests.cpp rename to src/wallet/test/rpc_wallet_tests.cpp From fae1f4ebfe6be4426685b22166f5367c92ba0833 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 15 Apr 2016 11:25:19 +0200 Subject: [PATCH 0469/1223] [qa] rpc-tests: Fix link in comment and label error msg --- qa/pull-tester/rpc-tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index e159082a0..c0637209e 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -69,6 +69,7 @@ if "BITCOINCLI" not in os.environ: if EXEEXT == ".exe" and "-win" not in opts: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 print "Win tests currently disabled by default. Use -win option to enable" sys.exit(0) @@ -81,7 +82,7 @@ if ENABLE_ZMQ: try: import zmq except ImportError as e: - print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ + print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ "to run zmq tests, see dependency info in /qa/README.md.") raise e From f4eae2d910d9edb3750efec4facbeab161cce593 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Apr 2016 14:54:57 +0200 Subject: [PATCH 0470/1223] test: Create test fixture for wallet Removes all the `#ifdef ENABLE_WALLET` from `test_bitcoin` by making the wallet tests use their own fixture. --- src/Makefile.test.include | 2 ++ src/test/test_bitcoin.cpp | 23 -------------------- src/test/test_bitcoin.h | 3 +-- src/wallet/test/accounting_tests.cpp | 4 ++-- src/wallet/test/rpc_wallet_tests.cpp | 4 ++-- src/wallet/test/wallet_test_fixture.cpp | 28 +++++++++++++++++++++++++ src/wallet/test/wallet_test_fixture.h | 18 ++++++++++++++++ src/wallet/test/wallet_tests.cpp | 4 ++-- 8 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 src/wallet/test/wallet_test_fixture.cpp create mode 100644 src/wallet/test/wallet_test_fixture.h diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 989718554..08e2f6af4 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -90,6 +90,8 @@ BITCOIN_TESTS =\ if ENABLE_WALLET BITCOIN_TESTS += \ + wallet/test/wallet_test_fixture.cpp \ + wallet/test/wallet_test_fixture.h \ wallet/test/accounting_tests.cpp \ wallet/test/wallet_tests.cpp \ wallet/test/rpc_wallet_tests.cpp diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 97b999625..eb8ac01e8 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -19,10 +19,6 @@ #include "ui_interface.h" #include "rpc/server.h" #include "rpc/register.h" -#ifdef ENABLE_WALLET -#include "wallet/db.h" -#include "wallet/wallet.h" -#endif #include "test/testutil.h" @@ -57,10 +53,6 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); -#ifdef ENABLE_WALLET - bitdb.MakeMock(); - RegisterWalletRPCCommands(tableRPC); -#endif ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); @@ -69,12 +61,6 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(chainparams); -#ifdef ENABLE_WALLET - bool fFirstRun; - pwalletMain = new CWallet("wallet.dat"); - pwalletMain->LoadWallet(fFirstRun); - RegisterValidationInterface(pwalletMain); -#endif nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); @@ -86,19 +72,10 @@ TestingSetup::~TestingSetup() UnregisterNodeSignals(GetNodeSignals()); threadGroup.interrupt_all(); threadGroup.join_all(); -#ifdef ENABLE_WALLET - UnregisterValidationInterface(pwalletMain); - delete pwalletMain; - pwalletMain = NULL; -#endif UnloadBlockIndex(); delete pcoinsTip; delete pcoinsdbview; delete pblocktree; -#ifdef ENABLE_WALLET - bitdb.Flush(true); - bitdb.Reset(); -#endif boost::filesystem::remove_all(pathTemp); } diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 769ae5a13..57f66f6c6 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -25,8 +25,7 @@ struct BasicTestingSetup { }; /** Testing setup that configures a complete environment. - * Included are data directory, coins database, script check threads - * and wallet (if enabled) setup. + * Included are data directory, coins database, script check threads setup. */ struct TestingSetup: public BasicTestingSetup { CCoinsViewDB *pcoinsdbview; diff --git a/src/wallet/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp index dad191c68..d075b2b64 100644 --- a/src/wallet/test/accounting_tests.cpp +++ b/src/wallet/test/accounting_tests.cpp @@ -5,7 +5,7 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include @@ -14,7 +14,7 @@ extern CWallet* pwalletMain; -BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(accounting_tests, WalletTestingSetup) static void GetResults(CWalletDB& walletdb, std::map& results) diff --git a/src/wallet/test/rpc_wallet_tests.cpp b/src/wallet/test/rpc_wallet_tests.cpp index 3443be209..4e7d177f5 100644 --- a/src/wallet/test/rpc_wallet_tests.cpp +++ b/src/wallet/test/rpc_wallet_tests.cpp @@ -9,7 +9,7 @@ #include "main.h" #include "wallet/wallet.h" -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include #include @@ -23,7 +23,7 @@ extern UniValue CallRPC(string args); extern CWallet* pwalletMain; -BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, WalletTestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) { diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp new file mode 100644 index 000000000..837030096 --- /dev/null +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -0,0 +1,28 @@ +#include "wallet/test/wallet_test_fixture.h" + +#include "rpc/server.h" +#include "wallet/db.h" +#include "wallet/wallet.h" + +WalletTestingSetup::WalletTestingSetup(const std::string& chainName): + TestingSetup(chainName) +{ + bitdb.MakeMock(); + + bool fFirstRun; + pwalletMain = new CWallet("wallet.dat"); + pwalletMain->LoadWallet(fFirstRun); + RegisterValidationInterface(pwalletMain); + + RegisterWalletRPCCommands(tableRPC); +} + +WalletTestingSetup::~WalletTestingSetup() +{ + UnregisterValidationInterface(pwalletMain); + delete pwalletMain; + pwalletMain = NULL; + + bitdb.Flush(true); + bitdb.Reset(); +} diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h new file mode 100644 index 000000000..97a6d9839 --- /dev/null +++ b/src/wallet/test/wallet_test_fixture.h @@ -0,0 +1,18 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_TEST_FIXTURE_H +#define BITCOIN_WALLET_TEST_FIXTURE_H + +#include "test/test_bitcoin.h" + +/** Testing setup and teardown for wallet. + */ +struct WalletTestingSetup: public TestingSetup { + WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + ~WalletTestingSetup(); +}; + +#endif + diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index e84d58802..b759a6b2e 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -9,7 +9,7 @@ #include #include -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include #include @@ -25,7 +25,7 @@ using namespace std; typedef set > CoinSet; -BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) static CWallet wallet; static vector vCoins; From a25a4f5b04c3e045557e9e7e807b2af74ad75128 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Apr 2016 15:12:46 +0200 Subject: [PATCH 0471/1223] =?UTF-8?q?wallet=5Fismine.h=20=E2=86=92=20scrip?= =?UTF-8?q?t/ismine.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes conditional dependency of `src/test` on wallet. Makes multisig and P2SH tests complete without wallet built-in. --- src/Makefile.am | 4 ++-- src/{wallet/wallet_ismine.cpp => script/ismine.cpp} | 2 +- src/{wallet/wallet_ismine.h => script/ismine.h} | 6 +++--- src/test/multisig_tests.cpp | 12 +----------- src/test/script_P2SH_tests.cpp | 9 +-------- src/wallet/wallet.h | 2 +- 6 files changed, 9 insertions(+), 26 deletions(-) rename src/{wallet/wallet_ismine.cpp => script/ismine.cpp} (99%) rename src/{wallet/wallet_ismine.h => script/ismine.h} (90%) diff --git a/src/Makefile.am b/src/Makefile.am index d91e959cf..24744835f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,6 +135,7 @@ BITCOIN_CORE_H = \ script/sigcache.h \ script/sign.h \ script/standard.h \ + script/ismine.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ @@ -157,7 +158,6 @@ BITCOIN_CORE_H = \ wallet/db.h \ wallet/rpcwallet.h \ wallet/wallet.h \ - wallet/wallet_ismine.h \ wallet/walletdb.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ @@ -199,6 +199,7 @@ libbitcoin_server_a_SOURCES = \ rpc/rawtransaction.cpp \ rpc/server.cpp \ script/sigcache.cpp \ + script/ismine.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ @@ -229,7 +230,6 @@ libbitcoin_wallet_a_SOURCES = \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ - wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ policy/rbf.cpp \ $(BITCOIN_CORE_H) diff --git a/src/wallet/wallet_ismine.cpp b/src/script/ismine.cpp similarity index 99% rename from src/wallet/wallet_ismine.cpp rename to src/script/ismine.cpp index ebda5cc53..535c56b57 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/script/ismine.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "wallet_ismine.h" +#include "ismine.h" #include "key.h" #include "keystore.h" diff --git a/src/wallet/wallet_ismine.h b/src/script/ismine.h similarity index 90% rename from src/wallet/wallet_ismine.h rename to src/script/ismine.h index 51afd1b14..4b7db8802 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/script/ismine.h @@ -3,8 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_WALLET_WALLET_ISMINE_H -#define BITCOIN_WALLET_WALLET_ISMINE_H +#ifndef BITCOIN_SCRIPT_ISMINE_H +#define BITCOIN_SCRIPT_ISMINE_H #include "script/standard.h" @@ -31,4 +31,4 @@ typedef uint8_t isminefilter; isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); -#endif // BITCOIN_WALLET_WALLET_ISMINE_H +#endif // BITCOIN_SCRIPT_ISMINE_H diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index edf1650ca..d48a68ba5 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -9,12 +9,10 @@ #include "script/script_error.h" #include "script/interpreter.h" #include "script/sign.h" +#include "script/ismine.h" #include "uint256.h" #include "test/test_bitcoin.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet_ismine.h" -#endif #include #include @@ -210,10 +208,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); -#endif } { vector solutions; @@ -225,10 +221,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); -#endif } { vector solutions; @@ -239,11 +233,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK_EQUAL(solutions.size(), 4U); CTxDestination addr; BOOST_CHECK(!ExtractDestination(s, addr)); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); -#endif } { vector solutions; @@ -258,11 +250,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(addrs[0] == keyaddr[0]); BOOST_CHECK(addrs[1] == keyaddr[1]); BOOST_CHECK(nRequired == 1); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); -#endif } { vector solutions; diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 28b85e8d2..d10284fe9 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -9,12 +9,9 @@ #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" +#include "script/ismine.h" #include "test/test_bitcoin.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet_ismine.h" -#endif - #include #include @@ -101,9 +98,7 @@ BOOST_AUTO_TEST_CASE(sign) txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1; -#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); -#endif } for (int i = 0; i < 8; i++) { @@ -198,9 +193,7 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].scriptPubKey = inner[i]; -#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); -#endif } for (int i = 0; i < 4; i++) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index aab4b217c..fa8740eb7 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -12,8 +12,8 @@ #include "ui_interface.h" #include "utilstrencodings.h" #include "validationinterface.h" +#include "script/ismine.h" #include "wallet/crypter.h" -#include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" #include "wallet/rpcwallet.h" From b30fb42e499beee5899b7e0e6c7581101b14ee83 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Apr 2016 15:15:57 +0200 Subject: [PATCH 0472/1223] test: Rename wallet.dat to wallet_test.dat Indicate that the file name is not hardcoded, and a little bit of safety so that it never nukes the main wallet. Suggestion by Marco Falke. --- src/wallet/test/wallet_test_fixture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 837030096..9036ee26d 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -10,7 +10,7 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName): bitdb.MakeMock(); bool fFirstRun; - pwalletMain = new CWallet("wallet.dat"); + pwalletMain = new CWallet("wallet_test.dat"); pwalletMain->LoadWallet(fFirstRun); RegisterValidationInterface(pwalletMain); From 87049e832d97d4f2808c0b479b21fc7b16c86934 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Mon, 18 Apr 2016 12:10:47 -0400 Subject: [PATCH 0473/1223] Speed up getchaintips. --- src/rpc/blockchain.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 34637b9f7..3db827d9a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -760,17 +760,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp) LOCK(cs_main); - /* Build up a list of chain tips. We start with the list of all - known blocks, and successively remove blocks that appear as pprev - of another block. */ + /* + * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add chainActive.Tip() + */ std::set setTips; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - setTips.insert(item.second); + std::set setOrphans; + std::set setPrevs; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) { - const CBlockIndex* pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } } // Always report the currently active tip. From fa942c755ab513829dcab27487ba1e7ab5a806ee Mon Sep 17 00:00:00 2001 From: Joao Fonseca Date: Tue, 19 Apr 2016 12:22:11 +0100 Subject: [PATCH 0474/1223] Move method to check matches within arrays on util.py --- qa/rpc-tests/getblocktemplate_longpoll.py | 22 ------- qa/rpc-tests/getblocktemplate_proposals.py | 22 ------- qa/rpc-tests/keypool.py | 22 ------- qa/rpc-tests/listtransactions.py | 71 ++++++++-------------- qa/rpc-tests/receivedby.py | 40 +++--------- qa/rpc-tests/test_framework/util.py | 29 +++++++++ 6 files changed, 61 insertions(+), 145 deletions(-) diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 3e85957ae..e2a839f71 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -6,28 +6,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * - -def check_array_result(object_array, to_match, expected): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - """ - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) - import threading class LongpollThread(threading.Thread): diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 07bfe69c6..be119031b 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -10,28 +10,6 @@ from binascii import a2b_hex, b2a_hex from hashlib import sha256 from struct import pack - -def check_array_result(object_array, to_match, expected): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - """ - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) - def b2x(b): return b2a_hex(b).decode('ascii') diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 5253d49c3..b86c085e0 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -10,28 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * - -def check_array_result(object_array, to_match, expected): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - """ - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) - class KeyPoolTest(BitcoinTestFramework): def run_test(self): diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 0783a1f3d..4e5809f4a 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -16,27 +16,6 @@ def txFromHex(hexstring): tx.deserialize(f) return tx -def check_array_result(object_array, to_match, expected): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - """ - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) - class ListTransactionsTest(BitcoinTestFramework): def setup_nodes(self): @@ -48,28 +27,28 @@ class ListTransactionsTest(BitcoinTestFramework): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) self.sync_all() - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"txid":txid}, {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) # mine a block, confirmations should change: self.nodes[0].generate(1) self.sync_all() - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"txid":txid}, {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) # send-to-self: txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"send"}, {"amount":Decimal("-0.2")}) - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"receive"}, {"amount":Decimal("0.2")}) @@ -80,28 +59,28 @@ class ListTransactionsTest(BitcoinTestFramework): self.nodes[1].getaccountaddress("toself") : 0.44 } txid = self.nodes[1].sendmany("", send_to) self.sync_all() - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"send","amount":Decimal("-0.11")}, {"txid":txid} ) - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.11")}, {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"send","amount":Decimal("-0.22")}, {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.22")}, {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"send","amount":Decimal("-0.33")}, {"txid":txid} ) - check_array_result(self.nodes[0].listtransactions(), + assert_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.33")}, {"txid":txid, "account" : "from1"} ) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"send","amount":Decimal("-0.44")}, {"txid":txid, "account" : ""} ) - check_array_result(self.nodes[1].listtransactions(), + assert_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : "toself"} ) @@ -111,7 +90,7 @@ class ListTransactionsTest(BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0) - check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True), + assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True), {"category":"receive","amount":Decimal("0.1")}, {"txid":txid, "account" : "watchonly"} ) @@ -139,9 +118,9 @@ class ListTransactionsTest(BitcoinTestFramework): # 1. Chain a few transactions that don't opt-in. txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) assert(not is_opt_in(self.nodes[0], txid_1)) - check_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) sync_mempools(self.nodes) - check_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) # Tx2 will build off txid_1, still not opting in to RBF. utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1) @@ -155,9 +134,9 @@ class ListTransactionsTest(BitcoinTestFramework): # ...and check the result assert(not is_opt_in(self.nodes[1], txid_2)) - check_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) sync_mempools(self.nodes) - check_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) # Tx3 will opt-in to RBF utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2) @@ -171,9 +150,9 @@ class ListTransactionsTest(BitcoinTestFramework): txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) assert(is_opt_in(self.nodes[0], txid_3)) - check_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) sync_mempools(self.nodes) - check_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) # Tx4 will chain off tx3. Doesn't signal itself, but depends on one # that does. @@ -185,9 +164,9 @@ class ListTransactionsTest(BitcoinTestFramework): txid_4 = self.nodes[1].sendrawtransaction(tx4_signed) assert(not is_opt_in(self.nodes[1], txid_4)) - check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) sync_mempools(self.nodes) - check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) # Replace tx3, and check that tx4 becomes unknown tx3_b = tx3_modified @@ -197,9 +176,9 @@ class ListTransactionsTest(BitcoinTestFramework): txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) assert(is_opt_in(self.nodes[0], txid_3b)) - check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) sync_mempools(self.nodes) - check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) # Check gettransaction as well: for n in self.nodes[0:2]: diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 606426b39..7d8231f5e 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -25,32 +25,6 @@ def get_sub_array_from_array(object_array, to_match): return item return [] -def check_array_result(object_array, to_match, expected, should_not_find = False): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - If the should_not_find flag is true, to_match should not be found in object_array - """ - if should_not_find == True: - expected = { } - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0 and should_not_find != True: - raise AssertionError("No objects matched %s"%(str(to_match))) - if num_matched > 0 and should_not_find == True: - raise AssertionError("Objects was matched %s"%(str(to_match))) - class ReceivedByTest(BitcoinTestFramework): def setup_nodes(self): @@ -68,26 +42,26 @@ class ReceivedByTest(BitcoinTestFramework): self.sync_all() #Check not listed in listreceivedbyaddress because has 0 confirmations - check_array_result(self.nodes[1].listreceivedbyaddress(), + assert_array_result(self.nodes[1].listreceivedbyaddress(), {"address":addr}, { }, True) #Bury Tx under 10 block so it will be returned by listreceivedbyaddress self.nodes[1].generate(10) self.sync_all() - check_array_result(self.nodes[1].listreceivedbyaddress(), + assert_array_result(self.nodes[1].listreceivedbyaddress(), {"address":addr}, {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) #With min confidence < 10 - check_array_result(self.nodes[1].listreceivedbyaddress(5), + assert_array_result(self.nodes[1].listreceivedbyaddress(5), {"address":addr}, {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) #With min confidence > 10, should not find Tx - check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True) + assert_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True) #Empty Tx addr = self.nodes[1].getnewaddress() - check_array_result(self.nodes[1].listreceivedbyaddress(0,True), + assert_array_result(self.nodes[1].listreceivedbyaddress(0,True), {"address":addr}, {"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]}) @@ -131,7 +105,7 @@ class ReceivedByTest(BitcoinTestFramework): self.sync_all() # listreceivedbyaccount should return received_by_account_json because of 0 confirmations - check_array_result(self.nodes[1].listreceivedbyaccount(), + assert_array_result(self.nodes[1].listreceivedbyaccount(), {"account":account}, received_by_account_json) @@ -143,7 +117,7 @@ class ReceivedByTest(BitcoinTestFramework): self.nodes[1].generate(10) self.sync_all() # listreceivedbyaccount should return updated account balance - check_array_result(self.nodes[1].listreceivedbyaccount(), + assert_array_result(self.nodes[1].listreceivedbyaccount(), {"account":account}, {"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))}) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 8b720b54a..27891f7f4 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -478,6 +478,35 @@ def assert_is_hash_string(string, length=64): raise AssertionError( "String %r contains invalid characters for a hash." % string) +def assert_array_result(object_array, to_match, expected, should_not_find = False): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + If the should_not_find flag is true, to_match should not be found + in object_array + """ + if should_not_find == True: + expected = { } + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + elif should_not_find == True: + num_matched = num_matched+1 + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0 and should_not_find != True: + raise AssertionError("No objects matched %s"%(str(to_match))) + if num_matched > 0 and should_not_find == True: + raise AssertionError("Objects were found %s"%(str(to_match))) + def satoshi_round(amount): return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) From 5d217decc1145823a3c126658c82c60cf7dbfec8 Mon Sep 17 00:00:00 2001 From: Joao Fonseca Date: Tue, 19 Apr 2016 12:28:37 +0100 Subject: [PATCH 0475/1223] Add test to check spendable and unspendable UTXO on RPC listunspent --- qa/rpc-tests/wallet.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 8fdcea50b..555f83648 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -32,6 +32,12 @@ class WalletTest (BitcoinTestFramework): self.sync_all() def run_test (self): + + # Check that there's no UTXO on none of the nodes + assert_equal(len(self.nodes[0].listunspent()), 0) + assert_equal(len(self.nodes[1].listunspent()), 0) + assert_equal(len(self.nodes[2].listunspent()), 0) + print "Mining blocks..." self.nodes[0].generate(1) @@ -48,6 +54,11 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[1].getbalance(), 50) assert_equal(self.nodes[2].getbalance(), 0) + # Check that only first and second nodes have UTXOs + assert_equal(len(self.nodes[0].listunspent()), 1) + assert_equal(len(self.nodes[1].listunspent()), 1) + assert_equal(len(self.nodes[2].listunspent()), 0) + # Send 21 BTC from 0 to 2 using sendtoaddress call. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) @@ -259,6 +270,32 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException as e: assert("not an integer" in e.error['message']) + # Import address and private key to check correct behavior of spendable unspents + # 1. Send some coins to generate new UTXO + address_to_import = self.nodes[2].getnewaddress() + txid = self.nodes[0].sendtoaddress(address_to_import, 1) + self.nodes[0].generate(1) + self.sync_all() + + # 2. Import address from node2 to node1 + self.nodes[1].importaddress(address_to_import) + + # 3. Validate that the imported address is watch-only on node1 + assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"]) + + # 4. Check that the unspents after import are not spendable + assert_array_result(self.nodes[1].listunspent(), + {"address": address_to_import}, + {"spendable": False}) + + # 5. Import private key of the previously imported address on node1 + priv_key = self.nodes[2].dumpprivkey(address_to_import) + self.nodes[1].importprivkey(priv_key) + + # 6. Check that the unspents are now spendable on node1 + assert_array_result(self.nodes[1].listunspent(), + {"address": address_to_import}, + {"spendable": True}) # Mine a block from node0 to an address from node1 cbAddr = self.nodes[1].getnewaddress() From 0b25a9fb42d5df54ea35ddb2bb4837e1e29355fd Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 29 Mar 2016 14:30:02 +0200 Subject: [PATCH 0476/1223] [ZMQ] append a message sequence number to every ZMQ notification --- contrib/zmq/zmq_sub.py | 14 +++++++++----- doc/release-notes.md | 9 +++++++++ doc/zmq.md | 5 +++++ qa/rpc-tests/zmq_test.py | 13 +++++++++++++ src/zmq/zmqpublishnotifier.cpp | 29 +++++++++++++++++++++-------- src/zmq/zmqpublishnotifier.h | 12 ++++++++++++ 6 files changed, 69 insertions(+), 13 deletions(-) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index decf29d42..6268123dd 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -3,6 +3,7 @@ import array import binascii import zmq +import struct port = 28332 @@ -19,18 +20,21 @@ try: msg = zmqSubSocket.recv_multipart() topic = str(msg[0]) body = msg[1] - + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack('GetBlockHash(); @@ -130,8 +147,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, MSG_HASHBLOCK, 9, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHBLOCK, data, 32); } bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -141,8 +157,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, MSG_HASHTX, 6, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHTX, data, 32); } bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) @@ -163,8 +178,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) ss << block; } - int rc = zmq_send_multipart(psocket, MSG_RAWBLOCK, 8, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size()); } bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -173,6 +187,5 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; - int rc = zmq_send_multipart(psocket, MSG_RAWTX, 5, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 44d5cbea6..22f02a3d0 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -11,7 +11,19 @@ class CBlockIndex; class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { +private: + uint32_t nSequence; //! upcounting per message sequence number + public: + + /* send zmq multipart message + parts: + * command + * data + * message sequence number + */ + bool SendMessage(const char *command, const void* data, size_t size); + bool Initialize(void *pcontext); void Shutdown(); }; From fa10ce6a6dd0a6f00f6528e12f1de7a7fcb08928 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 19 Apr 2016 16:10:19 +0200 Subject: [PATCH 0477/1223] Move ui_interface.cpp to libbitcoin_server_a_SOURCES It is only needed by bitcoind and bitcoin-qt --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 10aa550a0..585463fc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -203,6 +203,7 @@ libbitcoin_server_a_SOURCES = \ torcontrol.cpp \ txdb.cpp \ txmempool.cpp \ + ui_interface.cpp \ validationinterface.cpp \ versionbits.cpp \ $(BITCOIN_CORE_H) @@ -323,7 +324,6 @@ libbitcoin_util_a_SOURCES = \ rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ - ui_interface.cpp \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ From 764d2377727c8945d648a018492a61add4fcf042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 6 Apr 2016 16:36:32 +0200 Subject: [PATCH 0478/1223] Globals: Explicitly pass const CChainParams& to UpdateTip() --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a94d52f89..aaf5f9ae6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2570,8 +2570,7 @@ void PruneAndFlush() { } /** Update chainActive and related internal data structures. */ -void static UpdateTip(CBlockIndex *pindexNew) { - const CChainParams& chainParams = Params(); +void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { chainActive.SetTip(pindexNew); // New best block @@ -2631,6 +2630,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { /** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams) { + const CChainParams& chainparams = Params(); // TODO replace consensusParams parameter CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); // Read block from disk. @@ -2668,7 +2668,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons // block that were added back and cleans up the mempool state. mempool.UpdateTransactionsFromBlock(vHashUpdate); // Update chainActive and related variables. - UpdateTip(pindexDelete->pprev); + UpdateTip(pindexDelete->pprev, chainparams); // Let wallets know transactions went from 1-confirmed to // 0-confirmed or conflicted: BOOST_FOREACH(const CTransaction &tx, block.vtx) { @@ -2727,7 +2727,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, list txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); // Update chainActive & related variables. - UpdateTip(pindexNew); + UpdateTip(pindexNew, chainparams); // Tell wallet about transactions that went from mempool // to conflicted: BOOST_FOREACH(const CTransaction &tx, txConflicted) { From d0a6353dec48f365c38de3c76b42f67eda737ed5 Mon Sep 17 00:00:00 2001 From: face Date: Sun, 17 Apr 2016 10:58:50 +0300 Subject: [PATCH 0479/1223] Pass CChainParams to DisconnectTip() --- src/main.cpp | 11 +++++------ src/main.h | 2 +- src/rpc/blockchain.cpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index aaf5f9ae6..518393000 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2628,14 +2628,13 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { } /** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ -bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams) +bool static DisconnectTip(CValidationState& state, const CChainParams& chainparams) { - const CChainParams& chainparams = Params(); // TODO replace consensusParams parameter CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) + if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus())) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); @@ -2828,7 +2827,7 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c // Disconnect active blocks which are no longer in the best chain. bool fBlocksDisconnected = false; while (chainActive.Tip() && chainActive.Tip() != pindexFork) { - if (!DisconnectTip(state, chainparams.GetConsensus())) + if (!DisconnectTip(state, chainparams)) return false; fBlocksDisconnected = true; } @@ -2973,7 +2972,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, return true; } -bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex) +bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex) { AssertLockHeld(cs_main); @@ -2989,7 +2988,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus setBlockIndexCandidates.erase(pindexWalk); // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. - if (!DisconnectTip(state, consensusParams)) { + if (!DisconnectTip(state, chainparams)) { mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); return false; } diff --git a/src/main.h b/src/main.h index 0962f44e9..e4c98a969 100644 --- a/src/main.h +++ b/src/main.h @@ -536,7 +536,7 @@ public: CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); /** Mark a block as invalid. */ -bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex); +bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b85b2f6b5..2670a85c4 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -928,7 +928,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, Params().GetConsensus(), pblockindex); + InvalidateBlock(state, Params(), pblockindex); } if (state.IsValid()) { From a4625acbf8afbe3f698e8dc7936312c9d2b65d22 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 17 Feb 2016 14:35:35 -0500 Subject: [PATCH 0480/1223] leveldb: integrate leveldb into our buildsystem leveldb's buildsystem causes us a few problems: - breaks out-of-tree builds - forces flags used for some tools - limits cross builds Rather than continuing to add wrappers around it, simply integrate it into our build. --- configure.ac | 22 ++++++++-- src/Makefile.am | 22 +++------- src/Makefile.leveldb.include | 81 ++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 src/Makefile.leveldb.include diff --git a/configure.ac b/configure.ac index 6e463dfc5..03b905210 100644 --- a/configure.ac +++ b/configure.ac @@ -267,7 +267,7 @@ case $host in fi CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" - LEVELDB_TARGET_FLAGS="TARGET_OS=OS_WINDOWS_CROSSCOMPILE" + LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" fi @@ -289,7 +289,7 @@ case $host in ;; *darwin*) TARGET_OS=darwin - LEVELDB_TARGET_FLAGS="TARGET_OS=Darwin" + LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin AC_CHECK_PROG([PORT],port, port) @@ -354,9 +354,11 @@ case $host in OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) - TARGET_OS=linux + LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; *) + OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` + LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac @@ -541,6 +543,18 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi +dnl This can go away when we require c++11 +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS -std=c++0x" +AC_MSG_CHECKING(for c++11 atomics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[]])], + [ AC_MSG_RESULT(yes); LEVELDB_ATOMIC_CPPFLAGS="-DLEVELDB_ATOMIC_PRESENT"; LEVELDB_ATOMIC_CXXFLAGS="-std=c++0x"], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= @@ -1043,6 +1057,8 @@ AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(LEVELDB_ATOMIC_CPPFLAGS) +AC_SUBST(LEVELDB_ATOMIC_CXXFLAGS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) diff --git a/src/Makefile.am b/src/Makefile.am index c1912dafc..3c056386f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,6 +3,7 @@ DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(HARDENED_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) +EXTRA_LIBRARIES = if EMBEDDED_UNIVALUE LIBUNIVALUE = univalue/libunivalue.la @@ -13,21 +14,6 @@ else LIBUNIVALUE = $(UNIVALUE_LIBS) endif -if EMBEDDED_LEVELDB -LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include -LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv -LIBLEVELDB += $(builddir)/leveldb/libleveldb.a -LIBMEMENV += $(builddir)/leveldb/libmemenv.a - -# NOTE: This dependency is not strictly necessary, but without it make may try to build both in parallel, which breaks the LevelDB build system in a race -$(LIBLEVELDB): $(LIBMEMENV) - -$(LIBLEVELDB) $(LIBMEMENV): - @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \ - CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \ - OPT="$(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" -endif - BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) @@ -49,7 +35,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: -EXTRA_LIBRARIES = \ +EXTRA_LIBRARIES += \ crypto/libbitcoin_crypto.a \ libbitcoin_util.a \ libbitcoin_common.a \ @@ -482,6 +468,10 @@ endif @test -f $(PROTOC) $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$( Date: Tue, 19 Apr 2016 13:07:16 -0700 Subject: [PATCH 0481/1223] Replace memcmp with std::equal in CScript::FindAndDelete Function is stl; std::equal just makes more sense. --- src/script/script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/script.h b/src/script/script.h index d2a68a07b..ef3af21d6 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -574,7 +574,7 @@ public: opcodetype opcode; do { - while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + while (end() - pc >= (long)b.size() && std::equal(b.begin(), b.end(), pc)) { pc = erase(pc, pc + b.size()); ++nFound; From c0f660c3a39e3b6d75d9a6bf8a9824c347c321b8 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Tue, 19 Apr 2016 13:13:46 -0700 Subject: [PATCH 0482/1223] Replace c-style cast with c++ style static_cast. --- src/script/script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/script.h b/src/script/script.h index ef3af21d6..0503b39a7 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -574,7 +574,7 @@ public: opcodetype opcode; do { - while (end() - pc >= (long)b.size() && std::equal(b.begin(), b.end(), pc)) + while (static_cast(end() - pc) >= b.size() && std::equal(b.begin(), b.end(), pc)) { pc = erase(pc, pc + b.size()); ++nFound; From e2a30bc9a9f7d2969e52632f8e8942a4e72f4ba6 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 3 Feb 2016 16:15:18 -0500 Subject: [PATCH 0483/1223] Unit test for CScript::FindAndDelete --- src/test/script_tests.cpp | 117 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index d42187f91..5e9711a4a 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1051,4 +1051,121 @@ BOOST_AUTO_TEST_CASE(script_GetScriptAsm) BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey)); } +static CScript +ScriptFromHex(const char* hex) +{ + std::vector data = ParseHex(hex); + return CScript(data.begin(), data.end()); +} + + +BOOST_AUTO_TEST_CASE(script_FindAndDelete) +{ + // Exercise the FindAndDelete functionality + CScript s; + CScript d; + CScript expect; + + s = CScript() << OP_1 << OP_2; + d = CScript(); // delete nothing should be a no-op + expect = s; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0); + BOOST_CHECK(s == expect); + + s = CScript() << OP_1 << OP_2 << OP_3; + d = CScript() << OP_2; + expect = CScript() << OP_1 << OP_3; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = CScript() << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3; + d = CScript() << OP_3; + expect = CScript() << OP_1 << OP_4; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 4); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("0302ff03"); // PUSH 0x02ff03 onto stack + d = ScriptFromHex("0302ff03"); + expect = CScript(); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("0302ff030302ff03"); // PUSH 0x2ff03 PUSH 0x2ff03 + d = ScriptFromHex("0302ff03"); + expect = CScript(); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("0302ff030302ff03"); + d = ScriptFromHex("02"); + expect = s; // FindAndDelete matches entire opcodes + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("0302ff030302ff03"); + d = ScriptFromHex("ff"); + expect = s; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0); + BOOST_CHECK(s == expect); + + // This is an odd edge case: strip of the push-three-bytes + // prefix, leaving 02ff03 which is push-two-bytes: + s = ScriptFromHex("0302ff030302ff03"); + d = ScriptFromHex("03"); + expect = CScript() << ParseHex("ff03") << ParseHex("ff03"); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2); + BOOST_CHECK(s == expect); + + // Byte sequence that spans multiple opcodes: + s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY + d = ScriptFromHex("feed51"); + expect = s; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0); // doesn't match 'inside' opcodes + BOOST_CHECK(s == expect); + + s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY + d = ScriptFromHex("02feed51"); + expect = ScriptFromHex("69"); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("516902feed5169"); + d = ScriptFromHex("feed51"); + expect = s; + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 0); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("516902feed5169"); + d = ScriptFromHex("02feed51"); + expect = ScriptFromHex("516969"); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = CScript() << OP_0 << OP_0 << OP_1 << OP_1; + d = CScript() << OP_0 << OP_1; + expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = CScript() << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1; + d = CScript() << OP_0 << OP_1; + expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 2); + BOOST_CHECK(s == expect); + + // Another weird edge case: + // End with invalid push (not enough data)... + s = ScriptFromHex("0003feed"); + d = ScriptFromHex("03feed"); // ... can remove the invalid push + expect = ScriptFromHex("00"); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); + + s = ScriptFromHex("0003feed"); + d = ScriptFromHex("00"); + expect = ScriptFromHex("03feed"); + BOOST_CHECK_EQUAL(s.FindAndDelete(d), 1); + BOOST_CHECK(s == expect); +} + BOOST_AUTO_TEST_SUITE_END() From f2d3ba73860e875972738d1da1507124d0971ae5 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 4 Apr 2016 02:36:47 +0000 Subject: [PATCH 0484/1223] Eliminate TX trickle bypass, sort TX invs for privacy and priority. Previously Bitcoin would send 1/4 of transactions out to all peers instantly. This causes high overhead because it makes >80% of INVs size 1. Doing so harms privacy, because it limits the amount of source obscurity a transaction can receive. These randomized broadcasts also disobeyed transaction dependencies and required use of the orphan pool. Because the orphan pool is so small this leads to poor propagation for dependent transactions. When the bypass wasn't in effect, transactions were sent in the order they were received. This avoided creating orphans but undermines privacy fairly significantly. This commit: Eliminates the bypass. The bypass is replaced by halving the average delay for outbound peers. Sorts candidate transactions for INV by their topological depth then by their feerate (then hash); removing the information leakage and providing priority service to higher fee transactions. Limits the amount of transactions sent in a single INV to 7tx/sec (and twice that for outbound); this limits the harm of low fee transaction floods, gives faster relay service to higher fee transactions. The 7 sounds lower than it really is because received advertisements need not be sent, and because the aggregate rate is multipled by the number of peers. --- src/main.cpp | 60 ++++++++++++++++++++++++++++------------------- src/main.h | 9 ++++--- src/txmempool.cpp | 15 ++++++++++++ src/txmempool.h | 1 + 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a94d52f89..4a28bbb00 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5560,6 +5560,29 @@ bool ProcessMessages(CNode* pfrom) return fOk; } +class CompareInvMempoolOrder +{ + CTxMemPool *mp; +public: + CompareInvMempoolOrder(CTxMemPool *mempool) + { + mp = mempool; + } + + bool operator()(const CInv &a, const CInv &b) + { + if (a.type != MSG_TX && b.type != MSG_TX) { + return false; + } else { + if (a.type != MSG_TX) { + return true; + } else if (b.type != MSG_TX) { + return false; + } + return mp->CompareDepthAndScore(a.hash, b.hash); + } + } +}; bool SendMessages(CNode* pto) { @@ -5790,42 +5813,31 @@ bool SendMessages(CNode* pto) bool fSendTrickle = pto->fWhitelisted; if (pto->nNextInvSend < nNow) { fSendTrickle = true; - pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL); + // Use half the delay for outbound peers, as their is less privacy concern for them. + pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound); } LOCK(pto->cs_inventory); - vInv.reserve(std::min(1000, pto->vInventoryToSend.size())); + if (fSendTrickle && pto->vInventoryToSend.size() > 1) { + // Topologically and fee-rate sort the inventory we send for privacy and priority reasons. + CompareInvMempoolOrder compareInvMempoolOrder(&mempool); + std::stable_sort(pto->vInventoryToSend.begin(), pto->vInventoryToSend.end(), compareInvMempoolOrder); + } + vInv.reserve(std::min(INVENTORY_BROADCAST_MAX, pto->vInventoryToSend.size())); vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { if (inv.type == MSG_TX && pto->filterInventoryKnown.contains(inv.hash)) continue; - - // trickle out tx inv to protect privacy - if (inv.type == MSG_TX && !fSendTrickle) - { - // 1/4 of tx invs blast to all immediately - static uint256 hashSalt; - if (hashSalt.IsNull()) - hashSalt = GetRandHash(); - uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt)); - hashRand = Hash(BEGIN(hashRand), END(hashRand)); - bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0); - - if (fTrickleWait) - { - vInvWait.push_back(inv); - continue; - } + // No reason to drain out at many times the network's capacity, + // especially since we have many peers and some will draw much shorter delays. + if (vInv.size() >= INVENTORY_BROADCAST_MAX || (inv.type == MSG_TX && !fSendTrickle)) { + vInvWait.push_back(inv); + continue; } pto->filterInventoryKnown.insert(inv.hash); vInv.push_back(inv); - if (vInv.size() >= 1000) - { - pto->PushMessage(NetMsgType::INV, vInv); - vInv.clear(); - } } pto->vInventoryToSend = vInvWait; } diff --git a/src/main.h b/src/main.h index 0962f44e9..4372c16a4 100644 --- a/src/main.h +++ b/src/main.h @@ -99,9 +99,12 @@ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60; /** Average delay between peer address broadcasts in seconds. */ static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30; -/** Average delay between trickled inventory broadcasts in seconds. - * Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */ -static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; +/** Average delay between trickled inventory transmissions in seconds. + * Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */ +static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5; +/** Maximum number of inventory items to send per transmission. + * Limits the impact of low-fee transaction floods. */ +static const unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL; /** Average delay between feefilter broadcasts in seconds. */ static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60; /** Maximum feefilter broadcast delay after significant change. */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52c779311..3aba578fa 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -752,6 +752,21 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(innerUsage == cachedInnerUsage); } +bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb) +{ + LOCK(cs); + indexed_transaction_set::const_iterator i = mapTx.find(hasha); + if (i == mapTx.end()) return false; + indexed_transaction_set::const_iterator j = mapTx.find(hashb); + if (j == mapTx.end()) return true; + uint64_t counta = i->GetCountWithAncestors(); + uint64_t countb = j->GetCountWithAncestors(); + if (counta == countb) { + return CompareTxMemPoolEntryByScore()(*i, *j); + } + return counta < countb; +} + void CTxMemPool::queryHashes(vector& vtxid) { vtxid.clear(); diff --git a/src/txmempool.h b/src/txmempool.h index de4ba0b37..e4934336c 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -511,6 +511,7 @@ public: std::list& conflicts, bool fCurrentEstimate = true); void clear(); void _clear(); //lock free + bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb); void queryHashes(std::vector& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); unsigned int GetTransactionsUpdated() const; From 220f950ab1302f8f8c0bb5b9c818f3d6569796bd Mon Sep 17 00:00:00 2001 From: Yuri Zhykin Date: Wed, 20 Apr 2016 00:03:42 +0300 Subject: [PATCH 0485/1223] Fix for incorrect locking in GetPubKey() (keystore.cpp) --- src/keystore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keystore.cpp b/src/keystore.cpp index cc8a57336..d568a7435 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -19,6 +19,7 @@ bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) con { CKey key; if (!GetKey(address, key)) { + LOCK(cs_KeyStore); WatchKeyMap::const_iterator it = mapWatchKeys.find(address); if (it != mapWatchKeys.end()) { vchPubKeyOut = it->second; From 807fa47a1e5c9f072d7dbf549bf17f66c47dbf46 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 19 Apr 2016 16:18:38 -0400 Subject: [PATCH 0486/1223] Tests: Fix deserialization of reject messages Assume that reject messages for blocks or transactions due to reason REJECT_MALFORMED will not include the hash of the block or tx being rejected. --- qa/rpc-tests/test_framework/mininode.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 5ee5b1327..af3356411 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -983,6 +983,7 @@ class msg_headers(object): class msg_reject(object): command = b"reject" + REJECT_MALFORMED = 1 def __init__(self): self.message = b"" @@ -994,14 +995,16 @@ class msg_reject(object): self.message = deser_string(f) self.code = struct.unpack(" Date: Tue, 19 Apr 2016 16:16:39 +0300 Subject: [PATCH 0487/1223] Explicitly pass CChainParams to ConnectBlock --- src/main.cpp | 10 +++++----- src/main.h | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 518393000..1015e538d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2221,9 +2221,9 @@ static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, + CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); int64_t nTimeStart = GetTimeMicros(); @@ -2703,7 +2703,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { CCoinsViewCache view(pcoinsTip); - bool rv = ConnectBlock(*pblock, state, pindexNew, view); + bool rv = ConnectBlock(*pblock, state, pindexNew, view, chainparams); GetMainSignals().BlockChecked(*pblock, state); if (!rv) { if (state.IsInvalid()) @@ -3523,7 +3523,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); if (!ContextualCheckBlock(block, state, pindexPrev)) return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); - if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) + if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true)) return false; assert(state.IsValid()); @@ -3891,7 +3891,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, CBlock block; if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); - if (!ConnectBlock(block, state, pindex, coins)) + if (!ConnectBlock(block, state, pindex, coins, chainparams)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); } } diff --git a/src/main.h b/src/main.h index e4c98a969..2c9635bcf 100644 --- a/src/main.h +++ b/src/main.h @@ -458,7 +458,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn /** Apply the effects of this block (with given index) on the UTXO set represented by coins. * Validity checks that depend on the UTXO set are also done; ConnectBlock() * can fail if those validity checks fail (among other reasons). */ -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, + const CChainParams& chainparams, bool fJustCheck = false); /** Undo the effects of this block (with given index) on the UTXO set represented by coins. * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean From a98cd1fc86eac1e5e5a09830028233dbce1dae70 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:38:06 -0400 Subject: [PATCH 0488/1223] net: manually resolve dns seed sources Note: Some seeds aren't actually returning an IP for their name entries, so they're being added to addrman with a source of [::]. This commit shouldn't change that behavior, for better or worse. --- src/net.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 6ab6ef819..7dec8fc1c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1454,7 +1454,15 @@ void ThreadDNSAddressSeed() found++; } } - addrman.Add(vAdd, CNetAddr(seed.name, true)); + // TODO: The seed name resolve may fail, yielding an IP of [::], which results in + // addrman assigning the same source to results from different seeds. + // This should switch to a hard-coded stable dummy IP for each seed name, so that the + // resolve is not required at all. + if (!vIPs.empty()) { + CService seedSource; + Lookup(seed.name.c_str(), seedSource, 0, true); + addrman.Add(vAdd, seedSource); + } } } From 367569926a9b15c05ba8d56c554880b8f5614f71 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:41:39 -0400 Subject: [PATCH 0489/1223] net: resolve outside of storage structures Rather than allowing CNetAddr/CService/CSubNet to launch DNS queries, require that addresses are already resolved. This greatly simplifies async resolve logic, and makes it harder to accidentally leak DNS queries. --- src/init.cpp | 7 ++++--- src/netbase.cpp | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 3667820a2..80527b782 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1156,10 +1156,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-externalip")) { BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { - CService addrLocal(strAddr, GetListenPort(), fNameLookup); - if (!addrLocal.IsValid()) + CService addrLocal; + if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) + AddLocal(addrLocal, LOCAL_MANUAL); + else return InitError(ResolveErrMsg("externalip", strAddr)); - AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } diff --git a/src/netbase.cpp b/src/netbase.cpp index 281c6bcb7..1855d0a2e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -614,10 +614,12 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest proxyType nameProxy; GetNameProxy(nameProxy); - CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port); - if (addrResolved.IsValid()) { - addr = addrResolved; - return ConnectSocket(addr, hSocketRet, nTimeout); + CService addrResolved; + if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy())) { + if (addrResolved.IsValid()) { + addr = addrResolved; + return ConnectSocket(addr, hSocketRet, nTimeout); + } } addr = CService("0.0.0.0:0"); From d39f5b425d8fc1bf3b7f33d35625ffd8d7a3cd77 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 12 Apr 2016 20:48:29 -0400 Subject: [PATCH 0490/1223] net: disable resolving from storage structures CNetAddr/CService/CSubnet can no longer resolve DNS. --- src/netbase.cpp | 28 ++++++++++++++-------------- src/netbase.h | 14 +++++++------- src/torcontrol.cpp | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 1855d0a2e..b44a8b16e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -688,19 +688,19 @@ CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) scopeId = scope; } -CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) +CNetAddr::CNetAddr(const char *pszIp) { Init(); std::vector vIP; - if (LookupHost(pszIp, vIP, 1, fAllowLookup)) + if (LookupHost(pszIp, vIP, 1, false)) *this = vIP[0]; } -CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) +CNetAddr::CNetAddr(const std::string &strIp) { Init(); std::vector vIP; - if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strIp.c_str(), vIP, 1, false)) *this = vIP[0]; } @@ -1123,35 +1123,35 @@ bool CService::SetSockAddr(const struct sockaddr *paddr) } } -CService::CService(const char *pszIpPort, bool fAllowLookup) +CService::CService(const char *pszIpPort) { Init(); CService ip; - if (Lookup(pszIpPort, ip, 0, fAllowLookup)) + if (Lookup(pszIpPort, ip, 0, false)) *this = ip; } -CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) +CService::CService(const char *pszIpPort, int portDefault) { Init(); CService ip; - if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + if (Lookup(pszIpPort, ip, portDefault, false)) *this = ip; } -CService::CService(const std::string &strIpPort, bool fAllowLookup) +CService::CService(const std::string &strIpPort) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, 0, false)) *this = ip; } -CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) +CService::CService(const std::string &strIpPort, int portDefault) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, portDefault, false)) *this = ip; } @@ -1245,7 +1245,7 @@ CSubNet::CSubNet(): memset(netmask, 0, sizeof(netmask)); } -CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) +CSubNet::CSubNet(const std::string &strSubnet) { size_t slash = strSubnet.find_last_of('/'); std::vector vIP; @@ -1255,7 +1255,7 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) memset(netmask, 255, sizeof(netmask)); std::string strAddress = strSubnet.substr(0, slash); - if (LookupHost(strAddress.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strAddress.c_str(), vIP, 1, false)) { network = vIP[0]; if (slash != strSubnet.npos) diff --git a/src/netbase.h b/src/netbase.h index 4529f9822..65187a17c 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -49,8 +49,8 @@ class CNetAddr public: CNetAddr(); CNetAddr(const struct in_addr& ipv4Addr); - explicit CNetAddr(const char *pszIp, bool fAllowLookup = false); - explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false); + explicit CNetAddr(const char *pszIp); + explicit CNetAddr(const std::string &strIp); void Init(); void SetIP(const CNetAddr& ip); @@ -119,7 +119,7 @@ class CSubNet public: CSubNet(); - explicit CSubNet(const std::string &strSubnet, bool fAllowLookup = false); + explicit CSubNet(const std::string &strSubnet); //constructor for single ip subnet (/32 or /128) explicit CSubNet(const CNetAddr &addr); @@ -154,10 +154,10 @@ class CService : public CNetAddr CService(const CNetAddr& ip, unsigned short port); CService(const struct in_addr& ipv4Addr, unsigned short port); CService(const struct sockaddr_in& addr); - explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false); - explicit CService(const char *pszIpPort, bool fAllowLookup = false); - explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false); - explicit CService(const std::string& strIpPort, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, int portDefault); + explicit CService(const char *pszIpPort); + explicit CService(const std::string& strIpPort, int portDefault); + explicit CService(const std::string& strIpPort); void Init(); void SetPort(unsigned short portIn); unsigned short GetPort() const; diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 1c7bc2dbe..47d834c7b 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -438,7 +438,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep private_key = i->second; } - service = CService(service_id+".onion", GetListenPort(), false); + service = CService(service_id+".onion", GetListenPort()); LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString()); if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile()); From 3a99fb2cb14955f5e029d315041a093e957e6c3e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 20 Apr 2016 13:49:55 -0400 Subject: [PATCH 0491/1223] Fix headers announcements edge case Previously we would assert that if every block in vBlockHashesToAnnounce is in chainActive, then the blocks to be announced must connect. However, there are edge cases where this assumption could be violated (eg using invalidateblock / reconsiderblock), so just check for this case and revert to inv-announcement instead. --- src/main.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index a94d52f89..e2fbfcf12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5718,7 +5718,21 @@ bool SendMessages(CNode* pto) fRevertToInv = true; break; } - assert(pBestIndex == NULL || pindex->pprev == pBestIndex); + if (pBestIndex != NULL && pindex->pprev != pBestIndex) { + // This means that the list of blocks to announce don't + // connect to each other. + // This shouldn't really be possible to hit during + // regular operation (because reorgs should take us to + // a chain that has some block not on the prior chain, + // which should be caught by the prior check), but one + // way this could happen is by using invalidateblock / + // reconsiderblock repeatedly on the tip, causing it to + // be added multiple times to vBlockHashesToAnnounce. + // Robustly deal with this rare situation by reverting + // to an inv. + fRevertToInv = true; + break; + } pBestIndex = pindex; if (fFoundStartingHeader) { // add this to the headers message From dc13dcd2bec2613a1cd5e0395b09b449d176146f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 7 Apr 2016 13:57:36 +0200 Subject: [PATCH 0492/1223] Split up and optimize transaction and block inv queues --- src/main.cpp | 76 +++++++++++++++++++++++++++++++--------------------- src/net.h | 20 +++++++++----- 2 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4a28bbb00..61d9301f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5569,18 +5569,11 @@ public: mp = mempool; } - bool operator()(const CInv &a, const CInv &b) + bool operator()(std::set::iterator a, std::set::iterator b) { - if (a.type != MSG_TX && b.type != MSG_TX) { - return false; - } else { - if (a.type != MSG_TX) { - return true; - } else if (b.type != MSG_TX) { - return false; - } - return mp->CompareDepthAndScore(a.hash, b.hash); - } + /* As std::make_heap produces a max-heap, we want the entries with the + * fewest ancestors/highest fee to sort later. */ + return mp->CompareDepthAndScore(*b, *a); } }; @@ -5808,38 +5801,59 @@ bool SendMessages(CNode* pto) // Message: inventory // vector vInv; - vector vInvWait; { + LOCK(pto->cs_inventory); + vInv.reserve(std::max(pto->vInventoryBlockToSend.size(), INVENTORY_BROADCAST_MAX)); + + // Add blocks + BOOST_FOREACH(const uint256& hash, pto->vInventoryBlockToSend) { + vInv.push_back(CInv(MSG_BLOCK, hash)); + if (vInv.size() == MAX_INV_SZ) { + pto->PushMessage(NetMsgType::INV, vInv); + vInv.clear(); + } + } + pto->vInventoryBlockToSend.clear(); + + // Determine transactions to relay bool fSendTrickle = pto->fWhitelisted; if (pto->nNextInvSend < nNow) { fSendTrickle = true; - // Use half the delay for outbound peers, as their is less privacy concern for them. + // Use half the delay for outbound peers, as there is less privacy concern for them. pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound); } - LOCK(pto->cs_inventory); - if (fSendTrickle && pto->vInventoryToSend.size() > 1) { + if (fSendTrickle) { + // Produce a vector with all candidates for sending + vector::iterator> vInvTx; + vInvTx.reserve(pto->setInventoryTxToSend.size()); + for (std::set::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) { + vInvTx.push_back(it); + } // Topologically and fee-rate sort the inventory we send for privacy and priority reasons. + // A heap is used so that not all items need sorting if only a few are being sent. CompareInvMempoolOrder compareInvMempoolOrder(&mempool); - std::stable_sort(pto->vInventoryToSend.begin(), pto->vInventoryToSend.end(), compareInvMempoolOrder); - } - vInv.reserve(std::min(INVENTORY_BROADCAST_MAX, pto->vInventoryToSend.size())); - vInvWait.reserve(pto->vInventoryToSend.size()); - BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) - { - if (inv.type == MSG_TX && pto->filterInventoryKnown.contains(inv.hash)) - continue; + std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder); // No reason to drain out at many times the network's capacity, // especially since we have many peers and some will draw much shorter delays. - if (vInv.size() >= INVENTORY_BROADCAST_MAX || (inv.type == MSG_TX && !fSendTrickle)) { - vInvWait.push_back(inv); - continue; + unsigned int nRelayedTransactions = 0; + while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) { + // Fetch the top element from the heap + std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder); + std::set::iterator it = vInvTx.back(); + vInvTx.pop_back(); + uint256 hash = *it; + // Remove it from the to-be-sent set + pto->setInventoryTxToSend.erase(it); + // Check if not in the filter already + if (pto->filterInventoryKnown.contains(hash)) { + continue; + } + // Send + vInv.push_back(CInv(MSG_TX, hash)); + nRelayedTransactions++; + pto->filterInventoryKnown.insert(hash); } - - pto->filterInventoryKnown.insert(inv.hash); - - vInv.push_back(inv); } - pto->vInventoryToSend = vInvWait; } if (!vInv.empty()) pto->PushMessage(NetMsgType::INV, vInv); diff --git a/src/net.h b/src/net.h index bf367684f..a95fa79e7 100644 --- a/src/net.h +++ b/src/net.h @@ -397,7 +397,13 @@ public: // inventory based relay CRollingBloomFilter filterInventoryKnown; - std::vector vInventoryToSend; + // Set of transaction ids we still have to announce. + // They are sorted by the mempool before relay, so the order is not important. + std::set setInventoryTxToSend; + // List of block ids we still have announce. + // There is no final sorting before sending, as they are always sent immediately + // and in the order requested. + std::vector vInventoryBlockToSend; CCriticalSection cs_inventory; std::set setAskFor; std::multimap mapAskFor; @@ -517,11 +523,13 @@ public: void PushInventory(const CInv& inv) { - { - LOCK(cs_inventory); - if (inv.type == MSG_TX && filterInventoryKnown.contains(inv.hash)) - return; - vInventoryToSend.push_back(inv); + LOCK(cs_inventory); + if (inv.type == MSG_TX) { + if (!filterInventoryKnown.contains(inv.hash)) { + setInventoryTxToSend.insert(inv.hash); + } + } else if (inv.type == MSG_BLOCK) { + vInventoryBlockToSend.push_back(inv.hash); } } From ed7068302c7490e8061cb3a558a0f83a465beeea Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 8 Apr 2016 16:26:41 +0200 Subject: [PATCH 0493/1223] Handle mempool requests in send loop, subject to trickle By eliminating queued entries from the mempool response and responding only at trickle time, this makes the mempool no longer leak transaction arrival order information (as the mempool itself is also sorted)-- at least no more than relay itself leaks it. --- src/main.cpp | 74 ++++++++++++++++++++++++++++++++-------------------- src/net.cpp | 1 + src/net.h | 2 ++ 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 61d9301f8..282c8cdb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5235,34 +5235,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fDisconnect = true; return true; } - LOCK2(cs_main, pfrom->cs_filter); - std::vector vtxid; - mempool.queryHashes(vtxid); - vector vInv; - BOOST_FOREACH(uint256& hash, vtxid) { - CInv inv(MSG_TX, hash); - if (pfrom->pfilter) { - CTransaction tx; - bool fInMemPool = mempool.lookup(hash, tx); - if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... - if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue; - } - if (pfrom->minFeeFilter) { - CFeeRate feeRate; - mempool.lookupFeeRate(hash, feeRate); - LOCK(pfrom->cs_feeFilter); - if (feeRate.GetFeePerK() < pfrom->minFeeFilter) - continue; - } - vInv.push_back(inv); - if (vInv.size() == MAX_INV_SZ) { - pfrom->PushMessage(NetMsgType::INV, vInv); - vInv.clear(); - } - } - if (vInv.size() > 0) - pfrom->PushMessage(NetMsgType::INV, vInv); + LOCK(pfrom->cs_inventory); + pfrom->fSendMempool = true; } @@ -5815,13 +5790,52 @@ bool SendMessages(CNode* pto) } pto->vInventoryBlockToSend.clear(); - // Determine transactions to relay + // Check whether periodic sends should happen bool fSendTrickle = pto->fWhitelisted; if (pto->nNextInvSend < nNow) { fSendTrickle = true; // Use half the delay for outbound peers, as there is less privacy concern for them. pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound); } + + // Respond to BIP35 mempool requests + if (fSendTrickle && pto->fSendMempool) { + std::vector vtxid; + mempool.queryHashes(vtxid); + pto->fSendMempool = false; + CAmount filterrate = 0; + { + LOCK(pto->cs_feeFilter); + filterrate = pto->minFeeFilter; + } + + LOCK(pto->cs_filter); + + BOOST_FOREACH(const uint256& hash, vtxid) { + CInv inv(MSG_TX, hash); + pto->setInventoryTxToSend.erase(hash); + if (filterrate) { + CFeeRate feeRate; + mempool.lookupFeeRate(hash, feeRate); + if (feeRate.GetFeePerK() < filterrate) + continue; + } + if (pto->pfilter) { + CTransaction tx; + bool fInMemPool = mempool.lookup(hash, tx); + if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... + if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue; + } + pto->filterInventoryKnown.insert(hash); + vInv.push_back(inv); + if (vInv.size() == MAX_INV_SZ) { + pto->PushMessage(NetMsgType::INV, vInv); + vInv.clear(); + } + } + } + + // Determine transactions to relay if (fSendTrickle) { // Produce a vector with all candidates for sending vector::iterator> vInvTx; @@ -5851,6 +5865,10 @@ bool SendMessages(CNode* pto) // Send vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; + if (vInv.size() == MAX_INV_SZ) { + pto->PushMessage(NetMsgType::INV, vInv); + vInv.clear(); + } pto->filterInventoryKnown.insert(hash); } } diff --git a/src/net.cpp b/src/net.cpp index f294e4c66..6b305ebae 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2370,6 +2370,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa hashContinue = uint256(); nStartingHeight = -1; filterInventoryKnown.reset(); + fSendMempool = false; fGetAddr = false; nNextLocalAddrSend = 0; nNextAddrSend = 0; diff --git a/src/net.h b/src/net.h index a95fa79e7..26acf59e6 100644 --- a/src/net.h +++ b/src/net.h @@ -411,6 +411,8 @@ public: // Used for headers announcements - unfiltered blocks to relay // Also protected by cs_inventory std::vector vBlockHashesToAnnounce; + // Used for BIP35 mempool sending, also protected by cs_inventory + bool fSendMempool; // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. From 4578215e7f787968c1d6478e6df75499bd36dd8d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 10 Apr 2016 15:33:05 +0200 Subject: [PATCH 0494/1223] Return mempool queries in dependency order --- src/txmempool.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 3aba578fa..0d9fcc982 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -767,6 +767,16 @@ bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb return counta < countb; } +namespace { +class DepthAndScoreComparator +{ + CTxMemPool *mp; +public: + DepthAndScoreComparator(CTxMemPool *mempool) : mp(mempool) {} + bool operator()(const uint256& a, const uint256& b) { return mp->CompareDepthAndScore(a, b); } +}; +} + void CTxMemPool::queryHashes(vector& vtxid) { vtxid.clear(); @@ -775,6 +785,8 @@ void CTxMemPool::queryHashes(vector& vtxid) vtxid.reserve(mapTx.size()); for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) vtxid.push_back(mi->GetTx().GetHash()); + + std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this)); } bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const From b5599147533103efea896a1fc4ff51f2d3ad5808 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 20 Apr 2016 07:05:23 +0000 Subject: [PATCH 0495/1223] Move bloom and feerate filtering to just prior to tx sending. This will avoid sending more pointless INVs around updates, and prevents using filter updates to timetag transactions. Also adds locking for fRelayTxes. --- src/main.cpp | 42 ++++++++++++++++++++++++++++++++++++------ src/net.cpp | 15 +-------------- src/net.h | 2 +- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 282c8cdb6..b707de2e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4557,12 +4557,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH); pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); } - if (!vRecv.empty()) + if (!vRecv.empty()) { vRecv >> pfrom->nStartingHeight; - if (!vRecv.empty()) - vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message - else - pfrom->fRelayTxes = true; + } + { + LOCK(pfrom->cs_filter); + if (!vRecv.empty()) + vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message + else + pfrom->fRelayTxes = true; + } // Disconnect if we connected to ourself if (nNonce == nLocalHostNonce && nNonce > 1) @@ -5325,12 +5329,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBloomFilter filter; vRecv >> filter; + LOCK(pfrom->cs_filter); + if (!filter.IsWithinSizeConstraints()) // There is no excuse for sending a too-large filter Misbehaving(pfrom->GetId(), 100); else { - LOCK(pfrom->cs_filter); delete pfrom->pfilter; pfrom->pfilter = new CBloomFilter(filter); pfrom->pfilter->UpdateEmptyFull(); @@ -5798,6 +5803,12 @@ bool SendMessages(CNode* pto) pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound); } + // Time to send but the peer has requested we not relay transactions. + if (fSendTrickle) { + LOCK(pto->cs_filter); + if (!pto->fRelayTxes) pto->setInventoryTxToSend.clear(); + } + // Respond to BIP35 mempool requests if (fSendTrickle && pto->fSendMempool) { std::vector vtxid; @@ -5843,6 +5854,11 @@ bool SendMessages(CNode* pto) for (std::set::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) { vInvTx.push_back(it); } + CAmount filterrate = 0; + { + LOCK(pto->cs_feeFilter); + filterrate = pto->minFeeFilter; + } // Topologically and fee-rate sort the inventory we send for privacy and priority reasons. // A heap is used so that not all items need sorting if only a few are being sent. CompareInvMempoolOrder compareInvMempoolOrder(&mempool); @@ -5850,6 +5866,7 @@ bool SendMessages(CNode* pto) // No reason to drain out at many times the network's capacity, // especially since we have many peers and some will draw much shorter delays. unsigned int nRelayedTransactions = 0; + LOCK(pto->cs_filter); while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) { // Fetch the top element from the heap std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder); @@ -5862,6 +5879,19 @@ bool SendMessages(CNode* pto) if (pto->filterInventoryKnown.contains(hash)) { continue; } + // Not in the mempool anymore? don't bother sending it. + CFeeRate feeRate; + if (!mempool.lookupFeeRate(hash, feeRate)) { + continue; + } + if (filterrate && feeRate.GetFeePerK() < filterrate) { + continue; + } + if (pto->pfilter) { + CTransaction tx; + if (!mempool.lookup(hash, tx)) continue; + if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue; + } // Send vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; diff --git a/src/net.cpp b/src/net.cpp index 6b305ebae..ccc430f5c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2071,20 +2071,7 @@ void RelayTransaction(const CTransaction& tx, CFeeRate feerate) LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { - if(!pnode->fRelayTxes) - continue; - { - LOCK(pnode->cs_feeFilter); - if (feerate.GetFeePerK() < pnode->minFeeFilter) - continue; - } - LOCK(pnode->cs_filter); - if (pnode->pfilter) - { - if (pnode->pfilter->IsRelevantAndUpdate(tx)) - pnode->PushInventory(inv); - } else - pnode->PushInventory(inv); + pnode->PushInventory(inv); } } diff --git a/src/net.h b/src/net.h index 26acf59e6..b6ec7bf3e 100644 --- a/src/net.h +++ b/src/net.h @@ -357,7 +357,7 @@ public: // a) it allows us to not relay tx invs before receiving the peer's version message // b) the peer may tell us in its version message that we should not relay tx invs // unless it loads a bloom filter. - bool fRelayTxes; + bool fRelayTxes; //protected by cs_filter bool fSentAddr; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; From fa243293343eb964bfee5b91cc52b91f16232ab6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 21 Apr 2016 15:28:53 +0200 Subject: [PATCH 0496/1223] [contrib] verify-commits: Add MarcoFalke fingerprint --- contrib/verify-commits/trusted-keys | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index a0d0f82db..ad1b28be0 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -5,3 +5,4 @@ AF8BE07C7049F3A26B239D5325B3083201782B2F 81291FA67D2C379A006A053FEAB5AF94D9E9ABE7 3F1888C6DCA92A6499C4911FDBA1A67379A1A931 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC +FE09B823E6D83A3BC7983EAA2D7F2372E50FE137 From a6666b25c7fa196d3829f0df38104e0384408412 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 2 Apr 2016 16:45:26 +0200 Subject: [PATCH 0497/1223] depends: mac deploy Py3 compatibility This fixes the gitian MacOSX build, it was broken in #7723. The patch to `native_mac_alias` should probably make it upstream. --- contrib/macdeploy/macdeployqtplus | 6 +- depends/packages/native_mac_alias.mk | 5 ++ .../patches/native_mac_alias/python3.patch | 72 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 depends/patches/native_mac_alias/python3.patch diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 685ed8e5b..f8201e72c 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -210,8 +210,8 @@ def getFrameworks(binaryPath, verbose): sys.stderr.write(o_stderr) sys.stderr.flush() raise RuntimeError("otool failed with return code %d" % otool.returncode) - - otoolLines = o_stdout.split("\n") + + otoolLines = o_stdout.decode().split("\n") otoolLines.pop(0) # First line is the inspected binary if ".framework" in binaryPath or binaryPath.endswith(".dylib"): otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency. @@ -676,7 +676,7 @@ if verbose >= 2: print("+ Installing qt.conf +") f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") -f.write(qt_conf) +f.write(qt_conf.encode()) f.close() # ------------------------------------------------ diff --git a/depends/packages/native_mac_alias.mk b/depends/packages/native_mac_alias.mk index d117c1c9a..85a8a402b 100644 --- a/depends/packages/native_mac_alias.mk +++ b/depends/packages/native_mac_alias.mk @@ -5,6 +5,11 @@ $(package)_download_file=v$($(package)_version).tar.bz2 $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=87ad827e66790028361e43fc754f68ed041a9bdb214cca03c853f079b04fb120 $(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_patches=python3.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/python3.patch +endef define $(package)_build_cmds python setup.py build diff --git a/depends/patches/native_mac_alias/python3.patch b/depends/patches/native_mac_alias/python3.patch new file mode 100644 index 000000000..1a32340be --- /dev/null +++ b/depends/patches/native_mac_alias/python3.patch @@ -0,0 +1,72 @@ +diff -dur a/mac_alias/alias.py b/mac_alias/alias.py +--- a/mac_alias/alias.py 2015-10-19 12:12:48.000000000 +0200 ++++ b/mac_alias/alias.py 2016-04-03 12:13:12.037159417 +0200 +@@ -243,10 +243,10 @@ + alias = Alias() + alias.appinfo = appinfo + +- alias.volume = VolumeInfo (volname.replace('/',':'), ++ alias.volume = VolumeInfo (volname.decode().replace('/',':'), + voldate, fstype, disktype, + volattrs, volfsid) +- alias.target = TargetInfo (kind, filename.replace('/',':'), ++ alias.target = TargetInfo (kind, filename.decode().replace('/',':'), + folder_cnid, cnid, + crdate, creator_code, type_code) + alias.target.levels_from = levels_from +@@ -261,9 +261,9 @@ + b.read(1) + + if tag == TAG_CARBON_FOLDER_NAME: +- alias.target.folder_name = value.replace('/',':') ++ alias.target.folder_name = value.decode().replace('/',':') + elif tag == TAG_CNID_PATH: +- alias.target.cnid_path = struct.unpack(b'>%uI' % (length // 4), ++ alias.target.cnid_path = struct.unpack('>%uI' % (length // 4), + value) + elif tag == TAG_CARBON_PATH: + alias.target.carbon_path = value +@@ -298,9 +298,9 @@ + alias.target.creation_date \ + = mac_epoch + datetime.timedelta(seconds=seconds) + elif tag == TAG_POSIX_PATH: +- alias.target.posix_path = value ++ alias.target.posix_path = value.decode() + elif tag == TAG_POSIX_PATH_TO_MOUNTPOINT: +- alias.volume.posix_path = value ++ alias.volume.posix_path = value.decode() + elif tag == TAG_RECURSIVE_ALIAS_OF_DISK_IMAGE: + alias.volume.disk_image_alias = Alias.from_bytes(value) + elif tag == TAG_USER_HOME_LENGTH_PREFIX: +@@ -422,13 +422,13 @@ + # (so doing so is ridiculous, and nothing could rely on it). + b.write(struct.pack(b'>h28pI2shI64pII4s4shhI2s10s', + self.target.kind, +- carbon_volname, voldate, ++ carbon_volname, int(voldate), + self.volume.fs_type, + self.volume.disk_type, + self.target.folder_cnid, + carbon_filename, + self.target.cnid, +- crdate, ++ int(crdate), + self.target.creator_code, + self.target.type_code, + self.target.levels_from, +@@ -449,12 +449,12 @@ + + b.write(struct.pack(b'>hhQhhQ', + TAG_HIGH_RES_VOLUME_CREATION_DATE, +- 8, long(voldate * 65536), ++ 8, int(voldate * 65536), + TAG_HIGH_RES_CREATION_DATE, +- 8, long(crdate * 65536))) ++ 8, int(crdate * 65536))) + + if self.target.cnid_path: +- cnid_path = struct.pack(b'>%uI' % len(self.target.cnid_path), ++ cnid_path = struct.pack('>%uI' % len(self.target.cnid_path), + *self.target.cnid_path) + b.write(struct.pack(b'>hh', TAG_CNID_PATH, + len(cnid_path))) From 06fdffd222ba0a00add4abe9fab9ad2c3e220d8f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 20 Apr 2016 16:36:52 -0400 Subject: [PATCH 0498/1223] travis: switch to Trusty --- .travis.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 95ef36bf0..0c9ac71c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,7 @@ # IPv6 support sudo: required -dist: precise -group: legacy +dist: trusty os: linux language: cpp @@ -38,22 +37,25 @@ matrix: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" PPA="ppa:chris-lea/zeromq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" PPA="ppa:chris-lea/zeromq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" exclude: - compiler: gcc +before_install: + - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") install: - - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi + - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/google-chrome.list; fi - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi + - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: From d1d7775587473410a107e7079616b9ecaae8dd06 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Tue, 19 Apr 2016 13:17:38 -0700 Subject: [PATCH 0499/1223] Improve worst-case behavior of CScript::FindAndDelete Thanks to Sergio Lerner for identifying this issue and suggesting this kind of solution. --- src/script/script.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/script/script.h b/src/script/script.h index 0503b39a7..bdbd340bc 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -570,17 +570,26 @@ public: int nFound = 0; if (b.empty()) return nFound; - iterator pc = begin(); + CScript result; + iterator pc = begin(), pc2 = begin(); opcodetype opcode; do { + result.insert(result.end(), pc2, pc); while (static_cast(end() - pc) >= b.size() && std::equal(b.begin(), b.end(), pc)) { - pc = erase(pc, pc + b.size()); + pc = pc + b.size(); ++nFound; } + pc2 = pc; } while (GetOp(pc, opcode)); + + if (nFound > 0) { + result.insert(result.end(), pc2, end()); + *this = result; + } + return nFound; } int Find(opcodetype op) const From 57704499be948c640c789c7fc11ed1abf8a681bd Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Mon, 18 Apr 2016 14:56:02 -0700 Subject: [PATCH 0500/1223] CBase58Data::SetString: cleanse the full vector SetString seems to be passing the length of the wrong variable to memory_cleanse, resulting in the last byte of the temporary buffer not being securely erased. --- src/base58.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base58.cpp b/src/base58.cpp index d81c26092..d1d60a6f1 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -177,7 +177,7 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) vchData.resize(vchTemp.size() - nVersionBytes); if (!vchData.empty()) memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size()); - memory_cleanse(&vchTemp[0], vchData.size()); + memory_cleanse(&vchTemp[0], vchTemp.size()); return true; } From f59dceb44f9bcfe1447b2dcca7483ed806cab22a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 22 Apr 2016 09:21:09 +0200 Subject: [PATCH 0501/1223] qt: Fix out-of-tree GUI builds Without this patch: - When I compile the GUI from the bitcoin directory itself, it works as expected. - When I build the GUI in an out-of-tree build, I cannot get it to select tabs. When I click, say the "Receive" tab nothing happens, the button selects but it doesn't switch the page. The rest - even the debug window - seems to work. See full discussion here: https://github.com/bitcoin/bitcoin/pull/7911#issuecomment-212413442 This turned out to be caused by a mismatch in the arguments to moc, preventing it from finding `bitcoin-config.h`. Fix this by passing `$(DEFAULT_INCLUDES)` to it, which gets set to the appropriate path by autoconf itself. --- src/Makefile.qt.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 8443fe697..3b3991944 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -424,11 +424,11 @@ ui_%.h: %.ui $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false) %.moc: %.cpp - $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \ + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ moc_%.cpp: %.h - $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \ + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ %.qm: %.ts From 9c0bcb617b7358006842900ad8a9b333b30f5031 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 22 Apr 2016 11:20:06 -0700 Subject: [PATCH 0502/1223] push back getaddednodeinfo dead value --- src/rpc/net.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ce14d034c..320091b9c 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -347,6 +347,7 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("connected", false)); UniValue addresses(UniValue::VARR); obj.push_back(Pair("addresses", addresses)); + ret.push_back(obj); } } From 74f7b1273c41892058fb2ff99aab878ccd22082a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 20 Apr 2016 09:05:12 +0200 Subject: [PATCH 0503/1223] dbwrapper: Remove throw keywords in function signatures Using throw() specifications in function signatures is not only not required in C++, it is considered deprecated for [various reasons](https://stackoverflow.com/questions/1055387/throw-keyword-in-functions-signature). It is not implemented by any of the common C++ compilers. The usage is also inconsistent with the rest of the source code. --- src/dbwrapper.cpp | 4 ++-- src/dbwrapper.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 1907e2fa7..16f85a3e6 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -15,7 +15,7 @@ #include #include -void HandleError(const leveldb::Status& status) throw(dbwrapper_error) +void HandleError(const leveldb::Status& status) { if (status.ok()) return; @@ -102,7 +102,7 @@ CDBWrapper::~CDBWrapper() options.env = NULL; } -bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) throw(dbwrapper_error) +bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) { leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); HandleError(status); diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 5e7313f7e..96fb42429 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -23,7 +23,7 @@ public: dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} }; -void HandleError(const leveldb::Status& status) throw(dbwrapper_error); +void HandleError(const leveldb::Status& status); /** Batch of changes queued to be written to a CDBWrapper */ class CDBBatch @@ -180,7 +180,7 @@ public: ~CDBWrapper(); template - bool Read(const K& key, V& value) const throw(dbwrapper_error) + bool Read(const K& key, V& value) const { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); @@ -206,7 +206,7 @@ public: } template - bool Write(const K& key, const V& value, bool fSync = false) throw(dbwrapper_error) + bool Write(const K& key, const V& value, bool fSync = false) { CDBBatch batch(&obfuscate_key); batch.Write(key, value); @@ -214,7 +214,7 @@ public: } template - bool Exists(const K& key) const throw(dbwrapper_error) + bool Exists(const K& key) const { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); @@ -233,14 +233,14 @@ public: } template - bool Erase(const K& key, bool fSync = false) throw(dbwrapper_error) + bool Erase(const K& key, bool fSync = false) { CDBBatch batch(&obfuscate_key); batch.Erase(key); return WriteBatch(batch, fSync); } - bool WriteBatch(CDBBatch& batch, bool fSync = false) throw(dbwrapper_error); + bool WriteBatch(CDBBatch& batch, bool fSync = false); // not available for LevelDB; provide for compatibility with BDB bool Flush() @@ -248,7 +248,7 @@ public: return true; } - bool Sync() throw(dbwrapper_error) + bool Sync() { CDBBatch batch(&obfuscate_key); return WriteBatch(batch, true); From 878bf480a3875181712a53a1156754faa19e579b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 20 Apr 2016 09:08:45 +0200 Subject: [PATCH 0504/1223] dbwrapper: Remove CDBWrapper::GetObfuscateKeyHex It is an unnecessary method as it is used only two times and only internally, and the whole implementation is HexStr(obfuscate_key). --- src/dbwrapper.cpp | 9 ++------- src/dbwrapper.h | 6 ------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 16f85a3e6..9eae7c7c8 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -84,10 +84,10 @@ CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, b Write(OBFUSCATE_KEY_KEY, new_key); obfuscate_key = new_key; - LogPrintf("Wrote new obfuscate key for %s: %s\n", path.string(), GetObfuscateKeyHex()); + LogPrintf("Wrote new obfuscate key for %s: %s\n", path.string(), HexStr(obfuscate_key)); } - LogPrintf("Using obfuscation key for %s: %s\n", path.string(), GetObfuscateKeyHex()); + LogPrintf("Using obfuscation key for %s: %s\n", path.string(), HexStr(obfuscate_key)); } CDBWrapper::~CDBWrapper() @@ -141,11 +141,6 @@ const std::vector& CDBWrapper::GetObfuscateKey() const return obfuscate_key; } -std::string CDBWrapper::GetObfuscateKeyHex() const -{ - return HexStr(obfuscate_key); -} - CDBIterator::~CDBIterator() { delete piter; } bool CDBIterator::Valid() { return piter->Valid(); } void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 96fb42429..153c0fd1b 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -268,12 +268,6 @@ public: * Accessor for obfuscate_key. */ const std::vector& GetObfuscateKey() const; - - /** - * Return the obfuscate_key as a hex-formatted string. - */ - std::string GetObfuscateKeyHex() const; - }; #endif // BITCOIN_DBWRAPPER_H From b69836d6ff2bd7dc9568ad4af8235662bb4f1826 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 20 Apr 2016 11:46:01 +0200 Subject: [PATCH 0505/1223] dbwrapper: Pass parent CDBWrapper into CDBBatch and CDBIterator Pass parent wrapper directly instead of obfuscation key. This makes it possible for other databases which re-use this code to use other properties from the database. Add a namespace dbwrapper_private for private functions to be used only in dbwrapper.h/cpp and dbwrapper_tests. --- src/dbwrapper.cpp | 14 +++++++---- src/dbwrapper.h | 46 ++++++++++++++++++++++-------------- src/test/dbwrapper_tests.cpp | 8 +++---- src/txdb.cpp | 6 ++--- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 9eae7c7c8..42f57676a 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -136,12 +136,16 @@ bool CDBWrapper::IsEmpty() return !(it->Valid()); } -const std::vector& CDBWrapper::GetObfuscateKey() const -{ - return obfuscate_key; -} - CDBIterator::~CDBIterator() { delete piter; } bool CDBIterator::Valid() { return piter->Valid(); } void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } void CDBIterator::Next() { piter->Next(); } + +namespace dbwrapper_private { + +const std::vector& GetObfuscateKey(const CDBWrapper &w) +{ + return w.obfuscate_key; +} + +}; diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 153c0fd1b..9eca2edf6 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -25,20 +25,34 @@ public: void HandleError(const leveldb::Status& status); +class CDBWrapper; + +/** These should be considered an implementation detail of the specific database. + */ +namespace dbwrapper_private { + +/** Work around circular dependency, as well as for testing in dbwrapper_tests. + * Database obfuscation should be considered an implementation detail of the + * specific database. + */ +const std::vector& GetObfuscateKey(const CDBWrapper &w); + +}; + /** Batch of changes queued to be written to a CDBWrapper */ class CDBBatch { friend class CDBWrapper; private: + const CDBWrapper &parent; leveldb::WriteBatch batch; - const std::vector *obfuscate_key; public: /** - * @param[in] obfuscate_key If passed, XOR data with this key. + * @param[in] parent CDBWrapper that this batch is to be submitted to */ - CDBBatch(const std::vector *obfuscate_key) : obfuscate_key(obfuscate_key) { }; + CDBBatch(const CDBWrapper &parent) : parent(parent) { }; template void Write(const K& key, const V& value) @@ -51,7 +65,7 @@ public: CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.reserve(ssValue.GetSerializeSize(value)); ssValue << value; - ssValue.Xor(*obfuscate_key); + ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); leveldb::Slice slValue(&ssValue[0], ssValue.size()); batch.Put(slKey, slValue); @@ -72,17 +86,17 @@ public: class CDBIterator { private: + const CDBWrapper &parent; leveldb::Iterator *piter; - const std::vector *obfuscate_key; public: /** + * @param[in] parent Parent CDBWrapper instance. * @param[in] piterIn The original leveldb iterator. - * @param[in] obfuscate_key If passed, XOR data with this key. */ - CDBIterator(leveldb::Iterator *piterIn, const std::vector* obfuscate_key) : - piter(piterIn), obfuscate_key(obfuscate_key) { }; + CDBIterator(const CDBWrapper &parent, leveldb::Iterator *piterIn) : + parent(parent), piter(piterIn) { }; ~CDBIterator(); bool Valid(); @@ -118,7 +132,7 @@ public: leveldb::Slice slValue = piter->value(); try { CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); - ssValue.Xor(*obfuscate_key); + ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); ssValue >> value; } catch (const std::exception&) { return false; @@ -134,6 +148,7 @@ public: class CDBWrapper { + friend const std::vector& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w); private: //! custom environment this database is using (may be NULL in case of default environment) leveldb::Env* penv; @@ -208,7 +223,7 @@ public: template bool Write(const K& key, const V& value, bool fSync = false) { - CDBBatch batch(&obfuscate_key); + CDBBatch batch(*this); batch.Write(key, value); return WriteBatch(batch, fSync); } @@ -235,7 +250,7 @@ public: template bool Erase(const K& key, bool fSync = false) { - CDBBatch batch(&obfuscate_key); + CDBBatch batch(*this); batch.Erase(key); return WriteBatch(batch, fSync); } @@ -250,24 +265,19 @@ public: bool Sync() { - CDBBatch batch(&obfuscate_key); + CDBBatch batch(*this); return WriteBatch(batch, true); } CDBIterator *NewIterator() { - return new CDBIterator(pdb->NewIterator(iteroptions), &obfuscate_key); + return new CDBIterator(*this, pdb->NewIterator(iteroptions)); } /** * Return true if the database managed by this class contains no entries. */ bool IsEmpty(); - - /** - * Accessor for obfuscate_key. - */ - const std::vector& GetObfuscateKey() const; }; #endif // BITCOIN_DBWRAPPER_H diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index e39931587..081d57831 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) uint256 res; // Ensure that we're doing real obfuscation when obfuscate=true - BOOST_CHECK(obfuscate != is_null_key(dbw.GetObfuscateKey())); + BOOST_CHECK(obfuscate != is_null_key(dbwrapper_private::GetObfuscateKey(dbw))); BOOST_CHECK(dbw.Write(key, in)); BOOST_CHECK(dbw.Read(key, res)); @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) uint256 in3 = GetRandHash(); uint256 res; - CDBBatch batch(&dbw.GetObfuscateKey()); + CDBBatch batch(dbw); batch.Write(key, in); batch.Write(key2, in2); @@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) BOOST_CHECK_EQUAL(res2.ToString(), in.ToString()); BOOST_CHECK(!odbw.IsEmpty()); // There should be existing data - BOOST_CHECK(is_null_key(odbw.GetObfuscateKey())); // The key should be an empty string + BOOST_CHECK(is_null_key(dbwrapper_private::GetObfuscateKey(odbw))); // The key should be an empty string uint256 in2 = GetRandHash(); uint256 res3; @@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) // Check that the key/val we wrote with unobfuscated wrapper doesn't exist uint256 res2; BOOST_CHECK(!odbw.Read(key, res2)); - BOOST_CHECK(!is_null_key(odbw.GetObfuscateKey())); + BOOST_CHECK(!is_null_key(dbwrapper_private::GetObfuscateKey(odbw))); uint256 in2 = GetRandHash(); uint256 res3; diff --git a/src/txdb.cpp b/src/txdb.cpp index 19ca17865..5fbaeb608 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -49,7 +49,7 @@ uint256 CCoinsViewDB::GetBestBlock() const { } bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { - CDBBatch batch(&db.GetObfuscateKey()); + CDBBatch batch(db); size_t count = 0; size_t changed = 0; for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { @@ -139,7 +139,7 @@ void CCoinsViewDBCursor::Next() } bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { - CDBBatch batch(&GetObfuscateKey()); + CDBBatch batch(*this); for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); } @@ -155,7 +155,7 @@ bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { } bool CBlockTreeDB::WriteTxIndex(const std::vector >&vect) { - CDBBatch batch(&GetObfuscateKey()); + CDBBatch batch(*this); for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Write(make_pair(DB_TXINDEX, it->first), it->second); return WriteBatch(batch); From 869cf1234a915808fda6fd663dead5580fbd046e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 20 Apr 2016 11:48:57 +0200 Subject: [PATCH 0506/1223] dbwrapper: Move `HandleError` to `dbwrapper_private` HandleError is implementation-specific. --- src/dbwrapper.cpp | 34 +++++++++++++++++----------------- src/dbwrapper.h | 10 ++++++---- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 42f57676a..09c68fbe5 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -15,20 +15,6 @@ #include #include -void HandleError(const leveldb::Status& status) -{ - if (status.ok()) - return; - LogPrintf("%s\n", status.ToString()); - if (status.IsCorruption()) - throw dbwrapper_error("Database corrupted"); - if (status.IsIOError()) - throw dbwrapper_error("Database I/O error"); - if (status.IsNotFound()) - throw dbwrapper_error("Database entry missing"); - throw dbwrapper_error("Unknown database error"); -} - static leveldb::Options GetOptions(size_t nCacheSize) { leveldb::Options options; @@ -61,13 +47,13 @@ CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, b if (fWipe) { LogPrintf("Wiping LevelDB in %s\n", path.string()); leveldb::Status result = leveldb::DestroyDB(path.string(), options); - HandleError(result); + dbwrapper_private::HandleError(result); } TryCreateDirectory(path); LogPrintf("Opening LevelDB in %s\n", path.string()); } leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); - HandleError(status); + dbwrapper_private::HandleError(status); LogPrintf("Opened LevelDB successfully\n"); // The base-case obfuscation key, which is a noop. @@ -105,7 +91,7 @@ CDBWrapper::~CDBWrapper() bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) { leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); - HandleError(status); + dbwrapper_private::HandleError(status); return true; } @@ -143,6 +129,20 @@ void CDBIterator::Next() { piter->Next(); } namespace dbwrapper_private { +void HandleError(const leveldb::Status& status) +{ + if (status.ok()) + return; + LogPrintf("%s\n", status.ToString()); + if (status.IsCorruption()) + throw dbwrapper_error("Database corrupted"); + if (status.IsIOError()) + throw dbwrapper_error("Database I/O error"); + if (status.IsNotFound()) + throw dbwrapper_error("Database entry missing"); + throw dbwrapper_error("Unknown database error"); +} + const std::vector& GetObfuscateKey(const CDBWrapper &w) { return w.obfuscate_key; diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 9eca2edf6..a0779d3ab 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -23,14 +23,16 @@ public: dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} }; -void HandleError(const leveldb::Status& status); - class CDBWrapper; /** These should be considered an implementation detail of the specific database. */ namespace dbwrapper_private { +/** Handle database error by throwing dbwrapper_error exception. + */ +void HandleError(const leveldb::Status& status); + /** Work around circular dependency, as well as for testing in dbwrapper_tests. * Database obfuscation should be considered an implementation detail of the * specific database. @@ -208,7 +210,7 @@ public: if (status.IsNotFound()) return false; LogPrintf("LevelDB read failure: %s\n", status.ToString()); - HandleError(status); + dbwrapper_private::HandleError(status); } try { CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); @@ -242,7 +244,7 @@ public: if (status.IsNotFound()) return false; LogPrintf("LevelDB read failure: %s\n", status.ToString()); - HandleError(status); + dbwrapper_private::HandleError(status); } return true; } From 5555528b47b7d33a5b963c076e6bb09ee25931b5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 23 Apr 2016 14:35:52 +0200 Subject: [PATCH 0507/1223] [qa] mininode: Unfiddle strings into bytes --- qa/rpc-tests/test_framework/mininode.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index af3356411..30aecfd44 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -93,7 +93,7 @@ def deser_uint256(f): def ser_uint256(u): - rs = "" + rs = b"" for i in xrange(8): rs += struct.pack(">= 32 @@ -191,7 +191,7 @@ def deser_string_vector(f): def ser_string_vector(l): - r = "" + r = b"" if len(l) < 253: r = struct.pack("B", len(l)) elif len(l) < 0x10000: @@ -624,7 +624,7 @@ class CAlert(object): self.vchSig = deser_string(f) def serialize(self): - r = "" + r = b"" r += ser_string(self.vchMsg) r += ser_string(self.vchSig) return r @@ -988,7 +988,7 @@ class msg_reject(object): def __init__(self): self.message = b"" self.code = 0 - self.reason = "" + self.reason = b"" self.data = 0L def deserialize(self, f): From fb26bf0ea3822638b10a783f054c280fc053a2b5 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Sat, 23 Apr 2016 22:21:52 -0700 Subject: [PATCH 0508/1223] CAddrMan::Deserialize handle corrupt serializations better. --- src/addrman.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/addrman.h b/src/addrman.h index 4f3de8d7c..308545045 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -350,6 +350,14 @@ public: nUBuckets ^= (1 << 30); } + if (nNew > ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) { + throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit."); + } + + if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) { + throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit."); + } + // Deserialize entries from the new table. for (int n = 0; n < nNew; n++) { CAddrInfo &info = mapInfo[n]; From c907f4d56b0a27ecd002a6d7d89a38cfc6d45ee3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 15 Apr 2016 13:21:16 +0200 Subject: [PATCH 0509/1223] doc: Update release process The actual release process quite diverged from what was written here, also clarify things a bit. --- doc/release-notes.md | 15 +++ doc/release-process.md | 284 +++++++++++++++++++++++++---------------- 2 files changed, 186 insertions(+), 113 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 806d174eb..4e318ef29 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,21 @@ (note: this is a temporary file, to be added-to by anybody, and moved to release-notes at release time) +Bitcoin Core version *version* is now available from: + + + +This is a new major version release, including new features, various bugfixes +and performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + Notable changes =============== diff --git a/doc/release-process.md b/doc/release-process.md index 5a6ac8482..34dead86b 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -1,181 +1,228 @@ Release Process ==================== -* Update translations (ping wumpus, Diapolo or tcatm on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex) +Before every release candidate: + +* Update translations (ping wumpus on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex) + +Before every minor and major release: + * Update [bips.md](bips.md) to account for changes since the last release. -* Update hardcoded [seeds](/contrib/seeds) +* Update version in sources (see below) +* Write release notes (see below) -* * * +Before every major release: + +* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example. + +### First time / New builders -###First time / New builders Check out the source code in the following directory hierarchy. - cd /path/to/your/toplevel/build - git clone https://github.com/bitcoin/gitian.sigs.git - git clone https://github.com/bitcoin/bitcoin-detached-sigs.git - git clone https://github.com/devrandom/gitian-builder.git - git clone https://github.com/bitcoin/bitcoin.git + cd /path/to/your/toplevel/build + git clone https://github.com/bitcoin/gitian.sigs.git + git clone https://github.com/bitcoin/bitcoin-detached-sigs.git + git clone https://github.com/devrandom/gitian-builder.git + git clone https://github.com/bitcoin/bitcoin.git -###Bitcoin maintainers/release engineers, update (commit) version in sources +### Bitcoin maintainers/release engineers, update version in sources - pushd ./bitcoin - contrib/verifysfbinaries/verify.sh - configure.ac - doc/README* - doc/Doxyfile - contrib/gitian-descriptors/*.yml - src/clientversion.h (change CLIENT_VERSION_IS_RELEASE to true) +Update the following: - # tag version in git +- `configure.ac`: + - `_CLIENT_VERSION_MAJOR` + - `_CLIENT_VERSION_MINOR` + - `_CLIENT_VERSION_REVISION` + - Don't forget to set `_CLIENT_VERSION_IS_RELEASE` to `true` +- `src/clientversion.h`: (this mirrors `configure.ac` - see issue #3539) + - `CLIENT_VERSION_MAJOR` + - `CLIENT_VERSION_MINOR` + - `CLIENT_VERSION_REVISION` + - Don't forget to set `CLIENT_VERSION_IS_RELEASE` to `true` +- `doc/README.md` and `doc/README_windows.txt` +- `doc/Doxyfile`: `PROJECT_NUMBER` contains the full version +- `contrib/gitian-descriptors/*.yml`: usually one'd want to do this on master after branching off the release - but be sure to at least do it before a new major release - git tag -s v(new version, e.g. 0.8.0) +Write release notes. git shortlog helps a lot, for example: - # write release notes. git shortlog helps a lot, for example: + git shortlog --no-merges v(current version, e.g. 0.7.2)..v(new version, e.g. 0.8.0) - git shortlog --no-merges v(current version, e.g. 0.7.2)..v(new version, e.g. 0.8.0) - popd +(or ping @wumpus on IRC, he has specific tooling to generate the list of merged pulls +and sort them into categories based on labels) -* * * +Generate list of authors: -###Setup and perform Gitian builds + git log --format='%aN' "$*" | sort -ui | sed -e 's/^/- /' - Setup Gitian descriptors: +Tag version (or release candidate) in git - pushd ./bitcoin - export SIGNER=(your Gitian key, ie bluematt, sipa, etc) - export VERSION=(new version, e.g. 0.8.0) - git fetch - git checkout v${VERSION} - popd + git tag -s v(new version, e.g. 0.8.0) - Ensure your gitian.sigs are up-to-date if you wish to gverify your builds against other Gitian signatures. +### Setup and perform Gitian builds - pushd ./gitian.sigs - git pull - popd +Setup Gitian descriptors: - Ensure gitian-builder is up-to-date to take advantage of new caching features (`e9741525c` or later is recommended). + pushd ./bitcoin + export SIGNER=(your Gitian key, ie bluematt, sipa, etc) + export VERSION=(new version, e.g. 0.8.0) + git fetch + git checkout v${VERSION} + popd - pushd ./gitian-builder - git pull +Ensure your gitian.sigs are up-to-date if you wish to gverify your builds against other Gitian signatures. -###Fetch and create inputs: (first time, or when dependency versions change) + pushd ./gitian.sigs + git pull + popd - mkdir -p inputs - wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch - wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz +Ensure gitian-builder is up-to-date to take advantage of new caching features (`e9741525c` or later is recommended). - Register and download the Apple SDK: see [OS X readme](README_osx.txt) for details. + pushd ./gitian-builder + git pull + popd - https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg +### Fetch and create inputs: (first time, or when dependency versions change) - Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: + pushd ./gitian-builder + mkdir -p inputs + wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch + wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz + popd - tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk +Register and download the Apple SDK: see [OS X readme](README_osx.txt) for details. -###Optional: Seed the Gitian sources cache and offline git repositories +https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg + +Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: + + tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk + +### Optional: Seed the Gitian sources cache and offline git repositories By default, Gitian will fetch source files as needed. To cache them ahead of time: - make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common + pushd ./gitian-builder + make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common + popd Only missing files will be fetched, so this is safe to re-run for each build. NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from local URLs. For example: -``` -./bin/gbuild --url bitcoin=/path/to/bitcoin,signature=/path/to/sigs {rest of arguments} -``` + + pushd ./gitian-builder + ./bin/gbuild --url bitcoin=/path/to/bitcoin,signature=/path/to/sigs {rest of arguments} + popd + The gbuild invocations below DO NOT DO THIS by default. -###Build and sign Bitcoin Core for Linux, Windows, and OS X: +### Build and sign Bitcoin Core for Linux, Windows, and OS X: - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + pushd ./gitian-builder + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ + popd - Build output expected: +Build output expected: - 1. source tarball (bitcoin-${VERSION}.tar.gz) - 2. linux 32-bit and 64-bit dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz) - 3. windows 32-bit and 64-bit unsigned installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe, bitcoin-${VERSION}-win[32|64].zip) - 4. OS X unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz) - 5. Gitian signatures (in gitian.sigs/${VERSION}-/(your Gitian key)/ + 1. source tarball (`bitcoin-${VERSION}.tar.gz`) + 2. linux 32-bit and 64-bit dist tarballs (`bitcoin-${VERSION}-linux[32|64].tar.gz`) + 3. windows 32-bit and 64-bit unsigned installers and dist zips (`bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe`, `bitcoin-${VERSION}-win[32|64].zip`) + 4. OS X unsigned installer and dist tarball (`bitcoin-${VERSION}-osx-unsigned.dmg`, `bitcoin-${VERSION}-osx64.tar.gz`) + 5. Gitian signatures (in `gitian.sigs/${VERSION}-/(your Gitian key)/`) -###Verify other gitian builders signatures to your own. (Optional) +### Verify other gitian builders signatures to your own. (Optional) - Add other gitian builders keys to your gpg keyring +Add other gitian builders keys to your gpg keyring - gpg --import ../bitcoin/contrib/gitian-keys/*.pgp + gpg --import bitcoin/contrib/gitian-keys/*.pgp - Verify the signatures +Verify the signatures - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + pushd ./gitian-builder + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + popd - popd - -###Next steps: +### Next steps: Commit your signature to gitian.sigs: - pushd gitian.sigs - git add ${VERSION}-linux/${SIGNER} - git add ${VERSION}-win-unsigned/${SIGNER} - git add ${VERSION}-osx-unsigned/${SIGNER} - git commit -a - git push # Assuming you can push to the gitian.sigs tree - popd + pushd gitian.sigs + git add ${VERSION}-linux/${SIGNER} + git add ${VERSION}-win-unsigned/${SIGNER} + git add ${VERSION}-osx-unsigned/${SIGNER} + git commit -a + git push # Assuming you can push to the gitian.sigs tree + popd - Wait for Windows/OS X detached signatures: - Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys. - Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries. +Wait for Windows/OS X detached signatures: - Create (and optionally verify) the signed OS X binary: +- Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys. +- Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries. - pushd ./gitian-builder - ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml - mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg - popd +Create (and optionally verify) the signed OS X binary: - Create (and optionally verify) the signed Windows binaries: + pushd ./gitian-builder + ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml + mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg + popd - pushd ./gitian-builder - ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-signed ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml - mv build/out/bitcoin-*win64-setup.exe ../bitcoin-${VERSION}-win64-setup.exe - mv build/out/bitcoin-*win32-setup.exe ../bitcoin-${VERSION}-win32-setup.exe - popd +Create (and optionally verify) the signed Windows binaries: + + pushd ./gitian-builder + ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-signed ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml + mv build/out/bitcoin-*win64-setup.exe ../bitcoin-${VERSION}-win64-setup.exe + mv build/out/bitcoin-*win32-setup.exe ../bitcoin-${VERSION}-win32-setup.exe + popd Commit your signature for the signed OS X/Windows binaries: - pushd gitian.sigs - git add ${VERSION}-osx-signed/${SIGNER} - git add ${VERSION}-win-signed/${SIGNER} - git commit -a - git push # Assuming you can push to the gitian.sigs tree - popd - -------------------------------------------------------------------------- + pushd gitian.sigs + git add ${VERSION}-osx-signed/${SIGNER} + git add ${VERSION}-win-signed/${SIGNER} + git commit -a + git push # Assuming you can push to the gitian.sigs tree + popd ### After 3 or more people have gitian-built and their results match: - Create `SHA256SUMS.asc` for the builds, and GPG-sign it: + ```bash sha256sum * > SHA256SUMS +``` + +The list of files should be: +``` +bitcoin-${VERSION}-linux32.tar.gz +bitcoin-${VERSION}-linux64.tar.gz +bitcoin-${VERSION}-osx64.tar.gz +bitcoin-${VERSION}-osx.dmg +bitcoin-${VERSION}.tar.gz +bitcoin-${VERSION}-win32-setup.exe +bitcoin-${VERSION}-win32.zip +bitcoin-${VERSION}-win64-setup.exe +bitcoin-${VERSION}-win64.zip +``` + +- GPG-sign it, delete the unsigned file: +``` gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc rm SHA256SUMS ``` @@ -185,6 +232,15 @@ Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spur - Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server into `/var/www/bin/bitcoin-core-${VERSION}` +- A `.torrent` will appear in the directory after a few minutes. Optionally help seed this torrent. To get the `magnet:` URI use: +```bash +transmission-show -m +``` +Insert the magnet URI into the announcement sent to mailing lists. This permits +people without access to `bitcoin.org` to download the binary distribution. +Also put it into the `optional_magnetlink:` slot in the YAML file for +bitcoin.org (see below for bitcoin.org update instructions). + - Update bitcoin.org version - First, check to see if the Bitcoin.org maintainers have prepared a @@ -202,16 +258,18 @@ Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spur - Announce the release: - - Release sticky on bitcointalk: https://bitcointalk.org/index.php?board=1.0 + - bitcoin-dev and bitcoin-core-dev mailing list - - Bitcoin-development mailing list + - Bitcoin Core announcements list https://bitcoincore.org/en/list/announcements/join/ + + - bitcoincore.org blog post - Update title of #bitcoin on Freenode IRC - - Optionally reddit /r/Bitcoin, ... but this will usually sort out itself + - Optionally twitter, reddit /r/Bitcoin, ... but this will usually sort out itself -- Notify BlueMatt so that he can start building [the PPAs](https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin) + - Notify BlueMatt so that he can start building [the PPAs](https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin) -- Add release notes for the new version to the directory `doc/release-notes` in git master + - Add release notes for the new version to the directory `doc/release-notes` in git master -- Celebrate + - Celebrate From 182bec427946d4ce951e8572130c903f0131447e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 15 Apr 2016 13:21:51 +0200 Subject: [PATCH 0510/1223] contrib: remove hardcoded version from verify.sh Closes #7595 as by removing the hardcoded version number from `verify.sh`. --- contrib/verifysfbinaries/verify.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contrib/verifysfbinaries/verify.sh b/contrib/verifysfbinaries/verify.sh index 847c50755..657c3bd33 100755 --- a/contrib/verifysfbinaries/verify.sh +++ b/contrib/verifysfbinaries/verify.sh @@ -23,9 +23,6 @@ BASEDIR="https://bitcoin.org/bin/" VERSIONPREFIX="bitcoin-core-" RCVERSIONSTRING="rc" -#this URL is used if a version number is not specified as an argument to the script -SIGNATUREFILE="$BASEDIR""$VERSIONPREFIX""0.10.4/""$RCSUBDIR""$SIGNATUREFILENAME" - if [ ! -d "$WORKINGDIR" ]; then mkdir "$WORKINGDIR" fi @@ -53,7 +50,8 @@ if [ -n "$1" ]; then SIGNATUREFILE="$BASEDIR$SIGNATUREFILENAME" else - BASEDIR="${SIGNATUREFILE%/*}/" + echo "Error: need to specify a version on the command line" + exit 2 fi #first we fetch the file containing the signature From f1544700703a442191ac1dfaae7f31b04ba7b12b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 15 Apr 2016 12:18:12 +0200 Subject: [PATCH 0511/1223] [contrib] Remove reference to sf and add doc to verify.sh --- contrib/README.md | 4 ++-- contrib/{verifysfbinaries => verifybinaries}/README.md | 9 ++++++++- contrib/{verifysfbinaries => verifybinaries}/verify.sh | 0 3 files changed, 10 insertions(+), 3 deletions(-) rename contrib/{verifysfbinaries => verifybinaries}/README.md (81%) rename contrib/{verifysfbinaries => verifybinaries}/verify.sh (100%) diff --git a/contrib/README.md b/contrib/README.md index 32b3a170a..a23b197cc 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -51,5 +51,5 @@ Test and Verify Tools ### [TestGen](/contrib/testgen) ### Utilities to generate test vectors for the data-driven Bitcoin tests. -### [Verify SF Binaries](/contrib/verifysfbinaries) ### -This script attempts to download and verify the signature file SHA256SUMS.asc from SourceForge. +### [Verify Binaries](/contrib/verifybinaries) ### +This script attempts to download and verify the signature file SHA256SUMS.asc from bitcoin.org. diff --git a/contrib/verifysfbinaries/README.md b/contrib/verifybinaries/README.md similarity index 81% rename from contrib/verifysfbinaries/README.md rename to contrib/verifybinaries/README.md index 1db3fe52f..8970f3daa 100644 --- a/contrib/verifysfbinaries/README.md +++ b/contrib/verifybinaries/README.md @@ -1,6 +1,13 @@ -### Verify Binaries ### +### Verify Binaries This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org. It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file. The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2. + +Usage: + +```sh +./verify.sh bitcoin-core-0.11.2 +./verify.sh bitcoin-core-0.12.0 +``` diff --git a/contrib/verifysfbinaries/verify.sh b/contrib/verifybinaries/verify.sh similarity index 100% rename from contrib/verifysfbinaries/verify.sh rename to contrib/verifybinaries/verify.sh From f8e6fb1800fbac87e76cdddc074d8f4af585f050 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 25 Apr 2016 12:31:45 +0200 Subject: [PATCH 0512/1223] Introduce constant for maximum CScript length --- src/script/interpreter.cpp | 2 +- src/script/script.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 9c47f7c6c..fd4a5674c 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -247,7 +247,7 @@ bool EvalScript(vector >& stack, const CScript& script, un vector vfExec; vector altstack; set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); - if (script.size() > 10000) + if (script.size() > MAX_SCRIPT_SIZE) return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE); int nOpCount = 0; bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; diff --git a/src/script/script.h b/src/script/script.h index d2a68a07b..68cde03e3 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -27,6 +27,9 @@ static const int MAX_OPS_PER_SCRIPT = 201; // Maximum number of public keys per multisig static const int MAX_PUBKEYS_PER_MULTISIG = 20; +// Maximum script length in bytes +static const int MAX_SCRIPT_SIZE = 10000; + // Threshold for nLockTime: below this value it is interpreted as block number, // otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC From 4f87af6fc7580912726f9bf833c21e6e1b478e1d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 25 Apr 2016 12:32:01 +0200 Subject: [PATCH 0513/1223] Treat overly long scriptPubKeys as unspendable --- src/script/script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/script.h b/src/script/script.h index 68cde03e3..2a338d6f5 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -624,7 +624,7 @@ public: */ bool IsUnspendable() const { - return (size() > 0 && *begin() == OP_RETURN); + return (size() > 0 && *begin() == OP_RETURN) || (size() > MAX_SCRIPT_SIZE); } void clear() From 4bf631e5e48cd4c14c825cdaf7a1bee81e15493d Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Sun, 24 Apr 2016 21:59:46 -0700 Subject: [PATCH 0514/1223] CDataStream::ignore Throw exception instead of assert on negative nSize. Previously disk corruption would cause an assert instead of an exception. --- src/streams.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/streams.h b/src/streams.h index 0fc6135a6..a50fe4e85 100644 --- a/src/streams.h +++ b/src/streams.h @@ -240,7 +240,9 @@ public: CDataStream& ignore(int nSize) { // Ignore from the beginning of the buffer - assert(nSize >= 0); + if (nSize < 0) { + throw std::ios_base::failure("CDataStream::ignore(): nSize negative"); + } unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { From 5d0434d13d0145a110c0c93e59edfd7d062f8531 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 24 Apr 2016 16:21:44 +0200 Subject: [PATCH 0515/1223] Fix OOM bug: UTXO entries with invalid script length --- src/compressor.h | 10 ++++++++-- src/streams.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/compressor.h b/src/compressor.h index 4a7209083..fa702f0df 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -86,8 +86,14 @@ public: return; } nSize -= nSpecialScripts; - script.resize(nSize); - s >> REF(CFlatData(script)); + if (nSize > MAX_SCRIPT_SIZE) { + // Overly long script, replace with a short invalid one + script << OP_RETURN; + s.ignore(nSize); + } else { + script.resize(nSize); + s >> REF(CFlatData(script)); + } } }; diff --git a/src/streams.h b/src/streams.h index a50fe4e85..ed14f3f41 100644 --- a/src/streams.h +++ b/src/streams.h @@ -406,6 +406,20 @@ public: return (*this); } + CAutoFile& ignore(size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::ignore: file handle is NULL"); + unsigned char data[4096]; + while (nSize > 0) { + size_t nNow = std::min(nSize, sizeof(data)); + if (fread(data, 1, nNow, file) != nNow) + throw std::ios_base::failure(feof(file) ? "CAutoFile::ignore: end of file" : "CAutoFile::read: fread failed"); + nSize -= nNow; + } + return (*this); + } + CAutoFile& write(const char* pch, size_t nSize) { if (!file) From 1e44169f0e0c334a86b14a22ebc8fec45cec7354 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 25 Apr 2016 14:05:36 +0200 Subject: [PATCH 0516/1223] Add tests for CCoins deserialization --- src/test/coins_tests.cpp | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 48e3c8ed8..129ce04e0 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -4,7 +4,9 @@ #include "coins.h" #include "random.h" +#include "script/standard.h" #include "uint256.h" +#include "utilstrencodings.h" #include "test/test_bitcoin.h" #include "main.h" #include "consensus/validation.h" @@ -345,4 +347,73 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) BOOST_CHECK(spent_a_duplicate_coinbase); } +BOOST_AUTO_TEST_CASE(ccoins_serialization) +{ + // Good example + CDataStream ss1(ParseHex("0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e"), SER_DISK, CLIENT_VERSION); + CCoins cc1; + ss1 >> cc1; + BOOST_CHECK_EQUAL(cc1.nVersion, 1); + BOOST_CHECK_EQUAL(cc1.fCoinBase, false); + BOOST_CHECK_EQUAL(cc1.nHeight, 203998); + BOOST_CHECK_EQUAL(cc1.vout.size(), 2); + BOOST_CHECK_EQUAL(cc1.IsAvailable(0), false); + BOOST_CHECK_EQUAL(cc1.IsAvailable(1), true); + BOOST_CHECK_EQUAL(cc1.vout[1].nValue, 60000000000ULL); + BOOST_CHECK_EQUAL(HexStr(cc1.vout[1].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35")))))); + + // Good example + CDataStream ss2(ParseHex("0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b"), SER_DISK, CLIENT_VERSION); + CCoins cc2; + ss2 >> cc2; + BOOST_CHECK_EQUAL(cc2.nVersion, 1); + BOOST_CHECK_EQUAL(cc2.fCoinBase, true); + BOOST_CHECK_EQUAL(cc2.nHeight, 120891); + BOOST_CHECK_EQUAL(cc2.vout.size(), 17); + for (int i = 0; i < 17; i++) { + BOOST_CHECK_EQUAL(cc2.IsAvailable(i), i == 4 || i == 16); + } + BOOST_CHECK_EQUAL(cc2.vout[4].nValue, 234925952); + BOOST_CHECK_EQUAL(HexStr(cc2.vout[4].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("61b01caab50f1b8e9c50a5057eb43c2d9563a4ee")))))); + BOOST_CHECK_EQUAL(cc2.vout[16].nValue, 110397); + BOOST_CHECK_EQUAL(HexStr(cc2.vout[16].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4")))))); + + // Smallest possible example + CDataStream ssx(SER_DISK, CLIENT_VERSION); + BOOST_CHECK_EQUAL(HexStr(ssx.begin(), ssx.end()), ""); + + CDataStream ss3(ParseHex("0002000600"), SER_DISK, CLIENT_VERSION); + CCoins cc3; + ss3 >> cc3; + BOOST_CHECK_EQUAL(cc3.nVersion, 0); + BOOST_CHECK_EQUAL(cc3.fCoinBase, false); + BOOST_CHECK_EQUAL(cc3.nHeight, 0); + BOOST_CHECK_EQUAL(cc3.vout.size(), 1); + BOOST_CHECK_EQUAL(cc3.IsAvailable(0), true); + BOOST_CHECK_EQUAL(cc3.vout[0].nValue, 0); + BOOST_CHECK_EQUAL(cc3.vout[0].scriptPubKey.size(), 0); + + // scriptPubKey that ends beyond the end of the stream + CDataStream ss4(ParseHex("0002000800"), SER_DISK, CLIENT_VERSION); + try { + CCoins cc4; + ss4 >> cc4; + BOOST_CHECK_MESSAGE(false, "We should have thrown"); + } catch (const std::ios_base::failure& e) { + } + + // Very large scriptPubKey (3*10^9 bytes) past the end of the stream + CDataStream tmp(SER_DISK, CLIENT_VERSION); + uint64_t x = 3000000000ULL; + tmp << VARINT(x); + BOOST_CHECK_EQUAL(HexStr(tmp.begin(), tmp.end()), "8a95c0bb00"); + CDataStream ss5(ParseHex("0002008a95c0bb0000"), SER_DISK, CLIENT_VERSION); + try { + CCoins cc5; + ss5 >> cc5; + BOOST_CHECK_MESSAGE(false, "We should have thrown"); + } catch (const std::ios_base::failure& e) { + } +} + BOOST_AUTO_TEST_SUITE_END() From 17a6a217867603f349de676739f072c789c3918f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 25 Apr 2016 16:01:28 +0200 Subject: [PATCH 0517/1223] qt: Make it possible to show details for multiple transactions A small GUI annoyance for me has always been that it's impossible to have multiple transaction detail windows open, for example to compare transactions. This patch makes the window non-modal so that it is possible to open transaction details at will. --- src/qt/transactionview.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index a352228c3..eb6111e68 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -478,8 +478,9 @@ void TransactionView::showDetails() QModelIndexList selection = transactionView->selectionModel()->selectedRows(); if(!selection.isEmpty()) { - TransactionDescDialog dlg(selection.at(0)); - dlg.exec(); + TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0)); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); } } From 62a9abd12b27d94cddae2b38f94bb44fead34235 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Mon, 25 Apr 2016 11:08:10 -0500 Subject: [PATCH 0518/1223] Fixing comment in script_test.json test case --- src/test/data/script_tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index e69cc9e41..e75b7825e 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1098,7 +1098,7 @@ "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", "P2SH,STRICTENC", "OP_COUNT", -"Fails due to 201 sig op limit"], +"Fails due to 201 script operation limit"], ["1", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", From efb54ba065e41e0d36383bcabfcc01bbca7b2340 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Mon, 25 Apr 2016 13:13:52 -0700 Subject: [PATCH 0519/1223] lock cs_main for State/Misbehaving ProcessMessage calls State(...) and Misbehaving(...) without holding the required lock; add LOCK(cs_main) blocks. --- src/main.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f6a89fa2e..a85ee46d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4514,6 +4514,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, strCommand == NetMsgType::FILTERCLEAR)) { if (pfrom->nVersion >= NO_BLOOM_VERSION) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); return false; } else { @@ -4529,6 +4530,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pfrom->nVersion != 0) { pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message")); + LOCK(cs_main); Misbehaving(pfrom->GetId(), 1); return false; } @@ -4584,7 +4586,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); // Potentially mark this peer as a preferred download peer. + { + LOCK(cs_main); UpdatePreferredDownload(pfrom, State(pfrom->GetId())); + } // Change version pfrom->PushMessage(NetMsgType::VERACK); @@ -4642,6 +4647,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (pfrom->nVersion == 0) { // Must have a version message before anything else + LOCK(cs_main); Misbehaving(pfrom->GetId(), 1); return false; } @@ -4677,6 +4683,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; if (vAddr.size() > 1000) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 20); return error("message addr size() = %u", vAddr.size()); } @@ -4746,6 +4753,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 20); return error("message inv size() = %u", vInv.size()); } @@ -4821,6 +4829,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 20); return error("message getdata size() = %u", vInv.size()); } @@ -5074,6 +5083,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks. unsigned int nCount = ReadCompactSize(vRecv); if (nCount > MAX_HEADERS_RESULTS) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 20); return error("headers message size = %u", nCount); } @@ -5350,8 +5360,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> filter; if (!filter.IsWithinSizeConstraints()) + { // There is no excuse for sending a too-large filter + LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); + } else { LOCK(pfrom->cs_filter); @@ -5372,13 +5385,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // and thus, the maximum size any matched object can have) in a filteradd message if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); } else { LOCK(pfrom->cs_filter); if (pfrom->pfilter) pfrom->pfilter->insert(vData); else + { + LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); + } } } From 719de56ab2c8e5bc6ce9f67c7bf159adc242d49b Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Mon, 25 Apr 2016 12:31:32 -0700 Subject: [PATCH 0520/1223] lock cs_main for chainActive ActivateBestChain uses chainActive after releasing the lock; reorder operations to move all access to synchronized object into existing LOCK(cs_main) block. --- src/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a85ee46d5..83fc4d6bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2897,14 +2897,15 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c */ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { CBlockIndex *pindexMostWork = NULL; + CBlockIndex *pindexNewTip = NULL; do { boost::this_thread::interruption_point(); if (ShutdownRequested()) break; - CBlockIndex *pindexNewTip = NULL; const CBlockIndex *pindexFork; bool fInitialDownload; + int nNewHeight; { LOCK(cs_main); CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2920,6 +2921,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, pindexNewTip = chainActive.Tip(); pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload(); + nNewHeight = chainActive.Height(); } // When we reach this point, we switched to a new tip (stored in pindexNewTip). @@ -2948,7 +2950,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { + if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { pnode->PushBlockHash(hash); } @@ -2961,7 +2963,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, } } } - } while(pindexMostWork != chainActive.Tip()); + } while (pindexNewTip != pindexMostWork); CheckBlockIndex(chainparams.GetConsensus()); // Write changes periodically to disk, after relay. From 9267a47d86d0673eae9e504ee566aa4e0410d923 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 25 Apr 2016 22:27:59 -0400 Subject: [PATCH 0521/1223] depends: enable pre-compiled headers for qt All trusty compilers work ok with this now, and it shaves a few minutes off of build time --- depends/packages/qt.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 77df77b73..e5ac0c965 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -31,7 +31,7 @@ $(package)_config_opts += -no-iconv $(package)_config_opts += -no-gif $(package)_config_opts += -no-freetype $(package)_config_opts += -no-nis -$(package)_config_opts += -no-pch +$(package)_config_opts += -pch $(package)_config_opts += -no-qml-debug $(package)_config_opts += -nomake examples $(package)_config_opts += -nomake tests From cf77fcdb1fe525b63b004ef729173f04bdb48882 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 25 Apr 2016 22:29:23 -0400 Subject: [PATCH 0522/1223] travis: drop MAKEJOBS=2 for windows compilers These were only in place because of the old precice mingw toolchain --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0c9ac71c0..804686a34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,11 +37,11 @@ matrix: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" - compiler: ": 32-bit + dash" env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" - compiler: ": bitcoind" env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" From 174023c9b008fc02316bce972b0c1031de3feee3 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Apr 2016 01:17:46 -0400 Subject: [PATCH 0523/1223] travis: Don't disable writing ccache for pull-requests This was doing more harm than good. The original intention was to speed up builds, since a PR's ccache results will be thrown away anyway. However, each PR maintains its own cache, so disabling writes means that subsequent pushes don't benefit from the fresh cache. This is significant when (for example) many headers are touched in a PR, then the PR is updated. With this change, the updated PR will take advantage of the cache generated during the PR's previous build. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 804686a34..25e9cc1e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,7 +71,6 @@ script: - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir PACKAGE=bitcoin VERSION=$HOST From a33b7c9cb545985771d074748c0e368ca2d06702 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 26 Apr 2016 00:54:57 -0400 Subject: [PATCH 0524/1223] travis: temporarily disable qt to avoid timeouts These builds take longer than they did on precise. Disable them now to keep things working, we can re-enable them after experimentation --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25e9cc1e0..2f3ea4e76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,11 +37,11 @@ matrix: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" + env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" + env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - compiler: ": bitcoind" env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" From 89c844df14046a114bebec959bd9e188bf8ba21b Mon Sep 17 00:00:00 2001 From: randy-waterhouse Date: Tue, 26 Apr 2016 19:43:14 +1200 Subject: [PATCH 0525/1223] Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 03b905210..100bb79e1 100644 --- a/configure.ac +++ b/configure.ac @@ -354,6 +354,7 @@ case $host in OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) + TARGET_OS=linux LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; *) From f135e3c943a19096485b0979918f8878f7fa1c8d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 26 Apr 2016 16:01:45 +0200 Subject: [PATCH 0526/1223] qt: Add transaction hash to details window title --- src/qt/forms/transactiondescdialog.ui | 2 +- src/qt/transactiondescdialog.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui index 5ae1e1285..3a698cfd1 100644 --- a/src/qt/forms/transactiondescdialog.ui +++ b/src/qt/forms/transactiondescdialog.ui @@ -11,7 +11,7 @@ - Transaction details + Transaction details diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index f7b6995b2..65adcc4f0 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -14,6 +14,7 @@ TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *pa ui(new Ui::TransactionDescDialog) { ui->setupUi(this); + setWindowTitle(tr("Details for %1").arg(idx.data(TransactionTableModel::TxIDRole).toString())); QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString(); ui->detailText->setHtml(desc); } From 67969af09f4729d041589da5f31ac40c07d2f4be Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 3 Dec 2015 14:44:57 +0100 Subject: [PATCH 0527/1223] build: Enable C++11 build, require C++11 compiler Implements #6211. --- build-aux/m4/ax_cxx_compile_stdcxx.m4 | 558 ++++++++++++++++++++++++++ configure.ac | 2 + 2 files changed, 560 insertions(+) create mode 100644 build-aux/m4/ax_cxx_compile_stdcxx.m4 diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000..079e17d2a --- /dev/null +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,558 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXXFLAGS to +# enable support. VERSION may be '11' (for the C++11 standard) or '14' +# (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + + AC_SUBST(HAVE_CXX$1) + fi +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) diff --git a/configure.ac b/configure.ac index 100bb79e1..713ea59ed 100644 --- a/configure.ac +++ b/configure.ac @@ -55,6 +55,8 @@ case $host in lt_cv_deplibs_check_method="pass_all" ;; esac +dnl Require C++11 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) dnl Libtool init checks. LT_INIT([pic-only]) From fada064f67302502f6b51d9d22927381c2707cbb Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 26 Apr 2016 18:11:42 +0200 Subject: [PATCH 0528/1223] [qa] test_framework: Properly print exceptions and assert empty dict --- qa/rpc-tests/test_framework/test_framework.py | 2 +- qa/rpc-tests/test_framework/util.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 3b08cd138..18ecf64b0 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -146,7 +146,7 @@ class BitcoinTestFramework(object): print("key not found: "+ str(e)) traceback.print_tb(sys.exc_info()[2]) except Exception as e: - print("Unexpected exception caught during testing: "+str(e)) + print("Unexpected exception caught during testing: " + repr(e)) traceback.print_tb(sys.exc_info()[2]) if not self.options.noshutdown: diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 27891f7f4..baa1ed679 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -487,7 +487,7 @@ def assert_array_result(object_array, to_match, expected, should_not_find = Fals in object_array """ if should_not_find == True: - expected = { } + assert_equal(expected, { }) num_matched = 0 for item in object_array: all_match = True From 61c01706cd1d38023facea7f25bc1d84980f8c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Tue, 26 Apr 2016 22:22:59 +0200 Subject: [PATCH 0529/1223] Log invalid block hash to make debugging easier. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index f6a89fa2e..a8f8e6fa5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3371,7 +3371,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state if (ppindex) *ppindex = pindex; if (pindex->nStatus & BLOCK_FAILED_MASK) - return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate"); + return state.Invalid(error("%s: block %s is marked invalid", __func__, hash.ToString()), 0, "duplicate"); return true; } From 63b3111f84daa421abc2889a550e86c17bf9609d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 9 Mar 2016 16:45:58 -0500 Subject: [PATCH 0530/1223] build: quiet annoying warnings without adding new ones Disabling warnings can be tricky, because doing so can cause a different compiler to create new warnings about unsupported disable flags. Also, some warnings don't surface until they're paired with another warning (gcc). For example, adding "-Wno-foo" won't cause any trouble, but if there's a legitimate warning emitted, the "unknown option -Wno-foo" will show up as well. Work around this in 2 ways: 1. When checking to see if -Wno-foo is supported, check for "-Wfoo" instead. 2. Enable -Werror while checking 1. If "-Werror -Wfoo" compiles, "-Wno-foo" is almost guaranteed to be supported. -Werror itself is also checked. If that fails to compile by itself, it likely means that the user added a flag that adds a warning. In that case, -Werror won't be used while checking, and the build may be extra noisy. The user would need to fix the bad input flag. Also, silence 2 more additional warnings that can show up post-c++11. --- configure.ac | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 100bb79e1..e73f7e086 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,9 @@ AC_ARG_ENABLE([debug], [enable_debug=$enableval], [enable_debug=no]) +AC_LANG_PUSH([C++]) +AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) + if test "x$enable_debug" = xyes; then CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER" if test "x$GCC" = xyes; then @@ -196,11 +199,19 @@ if test "x$enable_debug" = xyes; then fi fi -## TODO: Remove these hard-coded paths and flags. They are here for the sake of -## compatibility with the legacy buildsystem. -## if test "x$CXXFLAGS_overridden" = "xno"; then - CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wno-self-assign" + AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) + + ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all + ## unknown options if any other warning is produced. Test the -Wfoo case, and + ## set the -Wno-foo case if it works. + AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wself-assign],[CXXFLAGS="$CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[CXXFLAGS="$CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[CXXFLAGS="$CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) fi CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" @@ -222,8 +233,6 @@ AC_ARG_WITH([daemon], [build_bitcoind=$withval], [build_bitcoind=yes]) -AC_LANG_PUSH([C++]) - use_pkgconfig=yes case $host in *mingw*) From 84c13e759dbb0de282e2c8ce43d77f4d52fda6d9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 26 Apr 2016 14:34:40 +0200 Subject: [PATCH 0531/1223] chain: Add assertion in case of missing records in index db --- src/chain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chain.cpp b/src/chain.cpp index 32f6480f8..77e924e70 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -93,6 +93,7 @@ CBlockIndex* CBlockIndex::GetAncestor(int height) pindexWalk = pindexWalk->pskip; heightWalk = heightSkip; } else { + assert(pindexWalk->pprev); pindexWalk = pindexWalk->pprev; heightWalk--; } From 6030625631c62b0ffab2ac545c8351fa59dca483 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 27 Apr 2016 11:07:43 +0200 Subject: [PATCH 0532/1223] test: Add more thorough test for dbwrapper iterators I made a silly mistake in a database wrapper where keys were sorted by char instead of uint8_t. As x86 char is signed the sorting for the block index database was messed up, resulting in a segfault due to missing records. Add a test to catch: - Wrong sorting - Seeking errors - Iteration result not complete --- src/test/dbwrapper_tests.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 081d57831..8745d1439 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -203,5 +203,39 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_CHECK(odbw.Read(key, res3)); BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString()); } - + +BOOST_AUTO_TEST_CASE(iterator_ordering) +{ + path ph = temp_directory_path() / unique_path(); + CDBWrapper dbw(ph, (1 << 20), true, false, false); + for (int x=0x00; x<256; ++x) { + uint8_t key = x; + uint32_t value = x*x; + BOOST_CHECK(dbw.Write(key, value)); + } + + boost::scoped_ptr it(const_cast(&dbw)->NewIterator()); + for (int c=0; c<2; ++c) { + int seek_start; + if (c == 0) + seek_start = 0x00; + else + seek_start = 0x80; + it->Seek((uint8_t)seek_start); + for (int x=seek_start; x<256; ++x) { + uint8_t key; + uint32_t value; + BOOST_CHECK(it->Valid()); + if (!it->Valid()) // Avoid spurious errors about invalid iterator's key and value in case of failure + break; + BOOST_CHECK(it->GetKey(key)); + BOOST_CHECK(it->GetValue(value)); + BOOST_CHECK_EQUAL(key, x); + BOOST_CHECK_EQUAL(value, x*x); + it->Next(); + } + BOOST_CHECK(!it->Valid()); + } +} + BOOST_AUTO_TEST_SUITE_END() From f90efbfeef9cd733aa7590fdf581ff82b999c4b5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Apr 2016 13:17:00 -0400 Subject: [PATCH 0533/1223] Create signmessagewithprivkey rpc New rpc 'signmessagewithprivkey' which takes a private key to sign a message without using the wallet. --- src/rpc/misc.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index e8a099b44..09f518578 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -366,6 +366,48 @@ UniValue verifymessage(const UniValue& params, bool fHelp) return (pubkey.GetID() == keyID); } +UniValue signmessagewithprivkey(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "signmessagewithprivkey \"privkey\" \"message\"\n" + "\nSign a message with the private key of an address\n" + "\nArguments:\n" + "1. \"privkey\" (string, required) The private key to sign the message with.\n" + "2. \"message\" (string, required) The message to create a signature of.\n" + "\nResult:\n" + "\"signature\" (string) The signature of the message encoded in base 64\n" + "\nExamples:\n" + "\nCreate the signature\n" + + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + + "\nVerify the signature\n" + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + "\nAs json rpc\n" + + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") + ); + + string strPrivkey = params[0].get_str(); + string strMessage = params[1].get_str(); + + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strPrivkey); + if (!fGood) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); + CKey key = vchSecret.GetKey(); + if (!key.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + + CHashWriter ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + vector vchSig; + if (!key.SignCompact(ss.GetHash(), vchSig)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + UniValue setmocktime(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -404,6 +446,7 @@ static const CRPCCommand commands[] = { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, { "util", "verifymessage", &verifymessage, true }, + { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, From a398549b3bfc976f1b6408f41af7dac3514e2553 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 21 Apr 2016 16:23:40 -0400 Subject: [PATCH 0534/1223] depends: use c++11 --- depends/hosts/darwin.mk | 2 +- depends/packages/bdb.mk | 1 + depends/packages/boost.mk | 2 +- depends/packages/protobuf.mk | 1 + depends/packages/qt.mk | 2 +- depends/packages/zeromq.mk | 1 + 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 2958dc50c..dbe6d0079 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -3,7 +3,7 @@ OSX_SDK_VERSION=10.9 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk LD64_VERSION=241.9 darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index e2f85ad4f..200d57314 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -9,6 +9,7 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_cxxflags=-std=c++11 endef define $(package)_preprocess_cmds diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 215c694b6..ef1307c24 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -20,7 +20,7 @@ $(package)_archiver_$(host_os)=$($(package)_ar) $(package)_toolset_darwin=darwin $(package)_archiver_darwin=$($(package)_libtool) $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags=-fvisibility=hidden +$(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC endef diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk index 5affad283..54d3fd924 100644 --- a/depends/packages/protobuf.mk +++ b/depends/packages/protobuf.mk @@ -4,6 +4,7 @@ $(package)_download_path=$(native_$(package)_download_path) $(package)_file_name=$(native_$(package)_file_name) $(package)_sha256_hash=$(native_$(package)_sha256_hash) $(package)_dependencies=native_$(package) +$(package)_cxxflags=-std=c++11 define $(package)_set_vars $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index e5ac0c965..c1fc8e305 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -49,7 +49,7 @@ $(package)_config_opts += -no-sql-sqlite2 $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -hostprefix $(build_prefix) $(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -no-c++11 +$(package)_config_opts += -c++11 $(package)_config_opts += -openssl-linked $(package)_config_opts += -v $(package)_config_opts += -static diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 7b866e9c0..b3f18db05 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -7,6 +7,7 @@ $(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61 define $(package)_set_vars $(package)_config_opts=--without-documentation --disable-shared $(package)_config_opts_linux=--with-pic + $(package)_cxxflags=-std=c++11 endef define $(package)_config_cmds From a946bb6b182ee169934ffb97940434f38d1ae9e8 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 22 Dec 2015 13:52:57 +0100 Subject: [PATCH 0535/1223] [RPC] createrawtransaction: add option to set the sequence number per input --- qa/rpc-tests/rawtransactions.py | 6 ++++++ src/rpc/rawtransaction.cpp | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index e38ef6c8b..ef545273c 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -137,5 +137,11 @@ class RawTransactionsTest(BitcoinTestFramework): self.sync_all() assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}] + outputs = { self.nodes[0].getnewaddress() : 1 } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['vin'][0]['sequence'], 1000) + if __name__ == '__main__': RawTransactionsTest().main() diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index de8cd68f6..b475f9a22 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -334,6 +334,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) " {\n" " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n (numeric, required) The output number\n" + " \"sequence\":n (numeric, optional) The sequence number\n" " }\n" " ,...\n" " ]\n" @@ -384,6 +385,12 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits::max() - 1 : std::numeric_limits::max()); + + // set the sequence number if passed in the parameters object + const UniValue& sequenceObj = find_value(o, "sequence"); + if (sequenceObj.isNum()) + nSequence = sequenceObj.get_int(); + CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); rawTx.vin.push_back(in); From e59336fbf9b906bf05d50a732036613216898bd1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 3 Dec 2015 16:29:45 +0100 Subject: [PATCH 0536/1223] [bitcoin-tx] allow to set nSequence number over the in= command --- src/bitcoin-tx.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 95d7a085a..d5e2fc279 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -71,7 +71,7 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage = HelpMessageGroup(_("Commands:")); strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX")); strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX")); - strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX")); + strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX")); strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N")); strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N")); strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX")); @@ -181,15 +181,15 @@ static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal) static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) { + std::vector vStrInputParts; + boost::split(vStrInputParts, strInput, boost::is_any_of(":")); + // separate TXID:VOUT in string - size_t pos = strInput.find(':'); - if ((pos == string::npos) || - (pos == 0) || - (pos == (strInput.size() - 1))) + if (vStrInputParts.size()<2) throw runtime_error("TX input missing separator"); // extract and validate TXID - string strTxid = strInput.substr(0, pos); + string strTxid = vStrInputParts[0]; if ((strTxid.size() != 64) || !IsHex(strTxid)) throw runtime_error("invalid TX input txid"); uint256 txid(uint256S(strTxid)); @@ -198,13 +198,18 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; // extract and validate vout - string strVout = strInput.substr(pos + 1, string::npos); + string strVout = vStrInputParts[1]; int vout = atoi(strVout); if ((vout < 0) || (vout > (int)maxVout)) throw runtime_error("invalid TX input vout"); + // extract the optional sequence number + uint32_t nSequenceIn=std::numeric_limits::max(); + if (vStrInputParts.size() > 2) + nSequenceIn = atoi(vStrInputParts[2]); + // append to transaction input list - CTxIn txin(txid, vout); + CTxIn txin(txid, vout, CScript(), nSequenceIn); tx.vin.push_back(txin); } From 383fc10ebb8e9ffe88c1b9e2ea706c76e5a6343e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 27 Apr 2016 09:57:02 -0400 Subject: [PATCH 0537/1223] Only use AddInventoryKnown for transactions filterInventoryKnown is only used when relaying transactions, so stop adding block hashes to the filter. --- src/main.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f6a89fa2e..90db9de14 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4765,7 +4765,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, const CInv &inv = vInv[nInv]; boost::this_thread::interruption_point(); - pfrom->AddInventoryKnown(inv); bool fAlreadyHave = AlreadyHave(inv); LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id); @@ -4795,6 +4794,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else { + pfrom->AddInventoryKnown(inv); if (fBlocksOnly) LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) @@ -5173,10 +5173,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlock block; vRecv >> block; - CInv inv(MSG_BLOCK, block.GetHash()); - LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id); - - pfrom->AddInventoryKnown(inv); + LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id); CValidationState state; // Process all blocks from whitelisted peers, even if not requested, @@ -5189,7 +5186,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash()); if (nDoS > 0) { LOCK(cs_main); Misbehaving(pfrom->GetId(), nDoS); @@ -5769,9 +5766,7 @@ bool SendMessages(CNode* pto) hashToAnnounce.ToString(), chainActive.Tip()->GetBlockHash().ToString()); } - // If the peer announced this block to us, don't inv it back. - // (Since block announcements may not be via inv's, we can't solely rely on - // setInventoryKnown to track this.) + // If the peer's chain has this block, don't inv it back. if (!PeerHasHeader(&state, pindex)) { pto->PushInventory(CInv(MSG_BLOCK, hashToAnnounce)); LogPrint("net", "%s: sending inv peer=%d hash=%s\n", __func__, From b02119e4634f2453260bb1b195e39bdc0a3b5691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Wed, 27 Apr 2016 18:04:02 +0200 Subject: [PATCH 0538/1223] Remove useless argument to AlertNotify. It is always 'true', so useless. --- src/main.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f6a89fa2e..418ef704b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1593,7 +1593,7 @@ bool fLargeWorkForkFound = false; bool fLargeWorkInvalidChainFound = false; CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL; -static void AlertNotify(const std::string& strMessage, bool fThread) +static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); std::string strCmd = GetArg("-alertnotify", ""); @@ -1607,10 +1607,7 @@ static void AlertNotify(const std::string& strMessage, bool fThread) safeStatus = singleQuote+safeStatus+singleQuote; boost::replace_all(strCmd, "%s", safeStatus); - if (fThread) - boost::thread t(runCommand, strCmd); // thread runs free - else - runCommand(strCmd); + boost::thread t(runCommand, strCmd); // thread runs free } void CheckForkWarningConditions() @@ -1632,7 +1629,7 @@ void CheckForkWarningConditions() { std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") + pindexBestForkBase->phashBlock->ToString() + std::string("'"); - AlertNotify(warning, true); + AlertNotify(warning); } if (pindexBestForkTip && pindexBestForkBase) { @@ -2163,7 +2160,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const if (!strWarning.empty()) { strMiscWarning = strWarning; - AlertNotify(strWarning, true); + AlertNotify(strWarning); lastAlertTime = now; } } @@ -2598,7 +2595,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { if (state == THRESHOLD_ACTIVE) { strMiscWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit); if (!fWarned) { - AlertNotify(strMiscWarning, true); + AlertNotify(strMiscWarning); fWarned = true; } } else { @@ -2620,7 +2617,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: strMiscWarning = _("Warning: Unknown block versions being mined! It's possible unknown rules are in effect"); if (!fWarned) { - AlertNotify(strMiscWarning, true); + AlertNotify(strMiscWarning); fWarned = true; } } From f4ac02ee7c6530c273503d8575a492e9b2ac1f13 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Wed, 27 Apr 2016 09:26:33 -0700 Subject: [PATCH 0539/1223] fix race that could fail to persist a ban DumpBanList currently does this: - with lock: take a copy of the banmap - perform I/O (write out the banmap) - with lock: mark the banmap non-dirty If a new ban is added during the I/O operation, it may never be persisted to disk. Reorder operations so that the data to be persisted cannot be older than the time at which the banmap was marked non-dirty. --- src/net.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 7dec8fc1c..f566af24c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2634,9 +2634,10 @@ void DumpBanlist() CBanDB bandb; banmap_t banmap; + CNode::SetBannedSetDirty(false); CNode::GetBanned(banmap); - if (bandb.Write(banmap)) - CNode::SetBannedSetDirty(false); + if (!bandb.Write(banmap)) + CNode::SetBannedSetDirty(true); LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); From c7aac2d557fe3d3aa5bcdd3301a9b87eb110d8ed Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Wed, 27 Apr 2016 22:36:45 -0400 Subject: [PATCH 0540/1223] Deprecating the remaining LogPrintf dependencies that were made obsolete in PR #7459. --- src/pow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pow.cpp b/src/pow.cpp index 058404f35..1db3b6929 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -64,9 +64,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); arith_uint256 bnNew; - arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); - bnOld = bnNew; bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespan; From 2aacc72727b891aa6f42e97d16e8954fba014703 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 10:18:06 +0200 Subject: [PATCH 0541/1223] build: update ax_cxx_compile_stdcxx to serial 4 --- build-aux/m4/ax_cxx_compile_stdcxx.m4 | 50 +++++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index 079e17d2a..2c18e49c5 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -9,9 +9,9 @@ # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified -# version of the C++ standard. If necessary, add switches to CXXFLAGS to -# enable support. VERSION may be '11' (for the C++11 standard) or '14' -# (for the C++14 standard). +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. @@ -39,7 +39,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 1 +#serial 4 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). @@ -74,14 +74,17 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" + [ac_save_CXX="$CXX" + CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) + CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi ac_success=yes break fi @@ -97,14 +100,17 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" + [ac_save_CXX="$CXX" + CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) + CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi ac_success=yes break fi @@ -115,18 +121,16 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi - else - if test x$ac_success = xno; then - HAVE_CXX$1=0 - AC_MSG_NOTICE([No compiler with C++$1 support was found]) - else - HAVE_CXX$1=1 - AC_DEFINE(HAVE_CXX$1,1, - [define if the compiler supports basic C++$1 syntax]) - fi - - AC_SUBST(HAVE_CXX$1) fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) ]) From 7df92242a99db68962048aad34532e6c0e7a42fa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 10:43:39 +0200 Subject: [PATCH 0542/1223] doc: Add note about new build/test requirements to release notes [skip ci] --- doc/release-notes.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 7a673cc35..7d44b8cda 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -43,6 +43,19 @@ RPC low-level changes 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been fixed, but this means that the output will be different than from previous versions. +C++11 and Python 3 +------------------- + +Various code modernizations have been done. The Bitcoin Core code base has +started using C++11. This means that a C++11-capable compiler is now needed for +building. Effectively this means GCC 4.7 or higher, or Clang 3.3 or higher. + +When cross-compiling for a target that doesn't have C++11 libraries, configure with +`./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++`. + +For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now +required. + 0.13.0 Change log ================= From 073225cb01d9c2629c7a423dbe6afcd07601ffb7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 13:35:16 +0200 Subject: [PATCH 0543/1223] chain: define enum used as bit field as uint32_t Bitwise logic combined with `<` with undefined signedness will potentially results in undefined behavior. Fix this by defining the type as a c++11 typed enum. Fixes #6017. --- src/chain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chain.h b/src/chain.h index 5b9605a80..017d4fe45 100644 --- a/src/chain.h +++ b/src/chain.h @@ -54,7 +54,7 @@ struct CDiskBlockPos }; -enum BlockStatus { +enum BlockStatus: uint32_t { //! Unused. BLOCK_VALID_UNKNOWN = 0, From 07e4edb056249e017b0e5a4783e4452ce892b52d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 13:40:20 +0200 Subject: [PATCH 0544/1223] =?UTF-8?q?auto=5Fptr=20=E2=86=92=20unique=5Fptr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the few occurrences of the deprecated `auto_ptr` to c++11 `unique_ptr`. Silences the deprecation warnings. Also add a missing `std::` for consistency. --- src/httpserver.cpp | 4 ++-- src/miner.cpp | 2 +- src/rpc/mining.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index ce1accb04..a98eff7c1 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -252,7 +252,7 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m) /** HTTP request callback */ static void http_request_cb(struct evhttp_request* req, void* arg) { - std::auto_ptr hreq(new HTTPRequest(req)); + std::unique_ptr hreq(new HTTPRequest(req)); LogPrint("http", "Received a %s request for %s from %s\n", RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString()); @@ -288,7 +288,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) // Dispatch to worker thread if (i != iend) { - std::auto_ptr item(new HTTPWorkItem(hreq.release(), path, i->handler)); + std::unique_ptr item(new HTTPWorkItem(hreq.release(), path, i->handler)); assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ diff --git a/src/miner.cpp b/src/miner.cpp index ef8fd4db4..eaf29a767 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -74,7 +74,7 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn) { // Create new block - auto_ptr pblocktemplate(new CBlockTemplate()); + std::unique_ptr pblocktemplate(new CBlockTemplate()); if(!pblocktemplate.get()) return NULL; CBlock *pblock = &pblocktemplate->block; // pointer for convenience diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index b63ee2288..9a7d9d53a 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -111,7 +111,7 @@ UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nG UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { - auto_ptr pblocktemplate(CreateNewBlock(Params(), coinbaseScript->reserveScript)); + std::unique_ptr pblocktemplate(CreateNewBlock(Params(), coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; From aa62b68745ef43ca135fdffbd886818221e85731 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 24 Apr 2016 17:12:34 +0200 Subject: [PATCH 0545/1223] Benchmark rolling bloom filter --- src/Makefile.bench.include | 3 ++- src/bench/rollingbloom.cpp | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/bench/rollingbloom.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 8e7b59b46..24e2b3e0c 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -7,7 +7,8 @@ bench_bench_bitcoin_SOURCES = \ bench/bench_bitcoin.cpp \ bench/bench.cpp \ bench/bench.h \ - bench/Examples.cpp + bench/Examples.cpp \ + bench/rollingbloom.cpp bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/bench/rollingbloom.cpp b/src/bench/rollingbloom.cpp new file mode 100644 index 000000000..73c02cf71 --- /dev/null +++ b/src/bench/rollingbloom.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include "bench.h" +#include "bloom.h" +#include "utiltime.h" + +static void RollingBloom(benchmark::State& state) +{ + CRollingBloomFilter filter(120000, 0.000001); + std::vector data(32); + uint32_t count = 0; + uint32_t nEntriesPerGeneration = (120000 + 1) / 2; + uint32_t countnow = 0; + uint64_t match = 0; + while (state.KeepRunning()) { + count++; + data[0] = count; + data[1] = count >> 8; + data[2] = count >> 16; + data[3] = count >> 24; + if (countnow == nEntriesPerGeneration) { + int64_t b = GetTimeMicros(); + filter.insert(data); + int64_t e = GetTimeMicros(); + std::cout << "RollingBloom-refresh,1," << (e-b)*0.000001 << "," << (e-b)*0.000001 << "," << (e-b)*0.000001 << "\n"; + countnow = 0; + } else { + filter.insert(data); + } + countnow++; + data[0] = count >> 24; + data[1] = count >> 16; + data[2] = count >> 8; + data[3] = count; + match += filter.contains(data); + } +} + +BENCHMARK(RollingBloom); From 1953c40aa9589a03035fd294f3ba3549374a4826 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 24 Apr 2016 18:37:29 +0200 Subject: [PATCH 0546/1223] More efficient bitsliced rolling Bloom filter This patch changes the implementation from one that stores 16 2-bit integers in one uint32_t's, to one that stores the first bit of 64 2-bit integers in one uint64_t and the second bit in another. This allows for 450x faster refreshing and 2.2x faster average speed. --- src/bloom.cpp | 40 +++++++++++++++++++++++++++------------- src/bloom.h | 13 +------------ src/test/bloom_tests.cpp | 5 ++++- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index 4e6f0e5d2..fd328e8e9 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -234,14 +234,18 @@ CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) */ uint32_t nFilterBits = (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs))); data.clear(); - /* We store up to 16 'bits' per data element. */ - data.resize((nFilterBits + 15) / 16); + /* For each data element we need to store 2 bits. If both bits are 0, the + * bit is treated as unset. If the bits are (01), (10), or (11), the bit is + * treated as set in generation 1, 2, or 3 respectively. + * These bits are stored in separate integers: position P corresponds to bit + * (P & 63) of the integers data[(P >> 6) * 2] and data[(P >> 6) * 2 + 1]. */ + data.resize(((nFilterBits + 63) / 64) << 1); reset(); } /* Similar to CBloomFilter::Hash */ -inline unsigned int CRollingBloomFilter::Hash(unsigned int nHashNum, const std::vector& vDataToHash) const { - return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (data.size() * 16); +static inline uint32_t RollingBloomHash(unsigned int nHashNum, uint32_t nTweak, const std::vector& vDataToHash) { + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash); } void CRollingBloomFilter::insert(const std::vector& vKey) @@ -252,18 +256,25 @@ void CRollingBloomFilter::insert(const std::vector& vKey) if (nGeneration == 4) { nGeneration = 1; } + uint64_t nGenerationMask1 = -(uint64_t)(nGeneration & 1); + uint64_t nGenerationMask2 = -(uint64_t)(nGeneration >> 1); /* Wipe old entries that used this generation number. */ - for (uint32_t p = 0; p < data.size() * 16; p++) { - if (get(p) == nGeneration) { - put(p, 0); - } + for (uint32_t p = 0; p < data.size(); p += 2) { + uint64_t p1 = data[p], p2 = data[p + 1]; + uint64_t mask = (p1 ^ nGenerationMask1) | (p2 ^ nGenerationMask2); + data[p] = p1 & mask; + data[p + 1] = p2 & mask; } } nEntriesThisGeneration++; for (int n = 0; n < nHashFuncs; n++) { - uint32_t h = Hash(n, vKey); - put(h, nGeneration); + uint32_t h = RollingBloomHash(n, nTweak, vKey); + int bit = h & 0x3F; + uint32_t pos = (h >> 6) % data.size(); + /* The lowest bit of pos is ignored, and set to zero for the first bit, and to one for the second. */ + data[pos & ~1] = (data[pos & ~1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration & 1)) << bit; + data[pos | 1] = (data[pos | 1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration >> 1)) << bit; } } @@ -276,8 +287,11 @@ void CRollingBloomFilter::insert(const uint256& hash) bool CRollingBloomFilter::contains(const std::vector& vKey) const { for (int n = 0; n < nHashFuncs; n++) { - uint32_t h = Hash(n, vKey); - if (get(h) == 0) { + uint32_t h = RollingBloomHash(n, nTweak, vKey); + int bit = h & 0x3F; + uint32_t pos = (h >> 6) % data.size(); + /* If the relevant bit is not set in either data[pos & ~1] or data[pos | 1], the filter does not contain vKey */ + if (!(((data[pos & ~1] | data[pos | 1]) >> bit) & 1)) { return false; } } @@ -295,7 +309,7 @@ void CRollingBloomFilter::reset() nTweak = GetRand(std::numeric_limits::max()); nEntriesThisGeneration = 0; nGeneration = 1; - for (std::vector::iterator it = data.begin(); it != data.end(); it++) { + for (std::vector::iterator it = data.begin(); it != data.end(); it++) { *it = 0; } } diff --git a/src/bloom.h b/src/bloom.h index b0ad8b875..ad6de625d 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -135,20 +135,9 @@ private: int nEntriesPerGeneration; int nEntriesThisGeneration; int nGeneration; - std::vector data; + std::vector data; unsigned int nTweak; int nHashFuncs; - - unsigned int Hash(unsigned int nHashNum, const std::vector& vDataToHash) const; - - inline int get(uint32_t position) const { - return (data[(position >> 4) % data.size()] >> (2 * (position & 0xF))) & 0x3; - } - - inline void put(uint32_t position, uint32_t val) { - uint32_t& cell = data[(position >> 4) % data.size()]; - cell = (cell & ~(((uint32_t)3) << (2 * (position & 0xF)))) | (val << (2 * (position & 0xF))); - } }; #endif // BITCOIN_BLOOM_H diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 9557000dd..042fad42d 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -514,11 +514,14 @@ BOOST_AUTO_TEST_CASE(rolling_bloom) if (i >= 100) BOOST_CHECK(rb1.contains(data[i-100])); rb1.insert(data[i]); + BOOST_CHECK(rb1.contains(data[i])); } // Insert 999 more random entries: for (int i = 0; i < 999; i++) { - rb1.insert(RandomData()); + std::vector d = RandomData(); + rb1.insert(d); + BOOST_CHECK(rb1.contains(d)); } // Sanity check to make sure the filter isn't just filling up: nHits = 0; From 7db0ecb90c80bd4995bedf8c2982e9a22345ca65 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 27 Apr 2016 12:18:20 -0700 Subject: [PATCH 0547/1223] Test for signing messages New rpc test for signing and verifying messages. --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/signmessages.py | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100755 qa/rpc-tests/signmessages.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index c0637209e..26142c35e 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -123,6 +123,7 @@ testScripts = [ 'abandonconflict.py', 'p2p-versionbits-warning.py', 'importprunedfunds.py', + 'signmessages.py' ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') diff --git a/qa/rpc-tests/signmessages.py b/qa/rpc-tests/signmessages.py new file mode 100755 index 000000000..ff22f3530 --- /dev/null +++ b/qa/rpc-tests/signmessages.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python2 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + + +class SignMessagesTest(BitcoinTestFramework): + """Tests RPC commands for signing and verifying messages.""" + + def setup_chain(self): + print('Initializing test directory ' + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self, split=False): + self.nodes = start_nodes(1, self.options.tmpdir) + self.is_network_split = False + + def run_test(self): + message = 'This is just a test message' + + # Test the signing with a privkey + privKey = 'cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N' + address = 'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB' + signature = self.nodes[0].signmessagewithprivkey(privKey, message) + + # Verify the message + assert(self.nodes[0].verifymessage(address, signature, message)) + + # Test the signing with an address with wallet + address = self.nodes[0].getnewaddress() + signature = self.nodes[0].signmessage(address, message) + + # Verify the message + assert(self.nodes[0].verifymessage(address, signature, message)) + +if __name__ == '__main__': + SignMessagesTest().main() From 3b35e4896b5b8be9ffd6dacddb081f69a5b77903 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 28 Apr 2016 22:04:07 +0200 Subject: [PATCH 0548/1223] [RPC] add feerate option to fundrawtransaction --- qa/rpc-tests/fundrawtransaction.py | 8 ++++++++ src/coincontrol.h | 3 +++ src/wallet/rpcwallet.cpp | 13 +++++++++---- src/wallet/wallet.cpp | 6 +++++- src/wallet/wallet.h | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 496c7fe8b..f76fe90ef 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -677,6 +677,14 @@ class RawTransactionsTest(BitcoinTestFramework): assert(signedtx["complete"]) self.nodes[0].sendrawtransaction(signedtx["hex"]) + inputs = [] + outputs = {self.nodes[2].getnewaddress() : 1} + rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + result = self.nodes[3].fundrawtransaction(rawtx, ) + result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000}) + result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000}) + assert_equal(result['fee']*2, result2['fee']) + assert_equal(result['fee']*10, result3['fee']) if __name__ == '__main__': RawTransactionsTest().main() diff --git a/src/coincontrol.h b/src/coincontrol.h index 12fe9ce21..6129397bc 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -18,6 +18,8 @@ public: bool fAllowWatchOnly; //! Minimum absolute fee (not per kilobyte) CAmount nMinimumTotalFee; + //! Feerate to use (0 = estimate fee with payTxFee fallback) + CFeeRate nFeeRate; CCoinControl() { @@ -31,6 +33,7 @@ public: fAllowWatchOnly = false; setSelected.clear(); nMinimumTotalFee = 0; + nFeeRate = CFeeRate(0); } bool HasSelected() const diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 623037e76..b14d748b3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2458,6 +2458,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" + " \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n" " }\n" " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" @@ -2484,6 +2485,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) int changePosition = -1; bool includeWatching = false; bool lockUnspents = false; + CFeeRate feeRate = CFeeRate(0); if (params.size() > 1) { if (params[1].type() == UniValue::VBOOL) { @@ -2495,7 +2497,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) UniValue options = params[1]; - RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true); + RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true); if (options.exists("changeAddress")) { CBitcoinAddress address(options["changeAddress"].get_str()); @@ -2514,6 +2516,9 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (options.exists("lockUnspents")) lockUnspents = options["lockUnspents"].get_bool(); + + if (options.exists("feeRate")) + feeRate = CFeeRate(options["feeRate"].get_real()); } } @@ -2529,16 +2534,16 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); CMutableTransaction tx(origTx); - CAmount nFee; + CAmount nFeeOut; string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) + if(!pwalletMain->FundTransaction(tx, nFeeOut, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(tx))); result.push_back(Pair("changepos", changePosition)); - result.push_back(Pair("fee", ValueFromAmount(nFee))); + result.push_back(Pair("fee", ValueFromAmount(nFeeOut))); return result; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 29d713854..6b5e3ca7f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1918,7 +1918,7 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) { vector vecSend; @@ -1933,6 +1933,8 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC coinControl.destChange = destChange; coinControl.fAllowOtherInputs = true; coinControl.fAllowWatchOnly = includeWatching; + coinControl.nFeeRate = specificFeeRate; + BOOST_FOREACH(const CTxIn& txin, tx.vin) coinControl.Select(txin.prevout); @@ -2242,6 +2244,8 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) { nFeeNeeded = coinControl->nMinimumTotalFee; } + if (coinControl && coinControl->nFeeRate > CFeeRate(0)) + nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes); // If we made it here and we aren't even able to meet the relay fee on the next pass, give up // because we must be at the maximum allowed fee. diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c3bd343ed..7b5168975 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -740,7 +740,7 @@ public: * Insert additional inputs into the transaction by * calling CreateTransaction(); */ - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); /** * Create a new transaction paying the recipients with a set of coins From faf3d11ad7b10b9acfb59fe186876a3005385e4d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 29 Apr 2016 23:17:18 +0200 Subject: [PATCH 0549/1223] [doc] Update bitcoin-core GitHub links --- contrib/devtools/README.md | 6 +++--- contrib/gitian-descriptors/gitian-osx-signer.yml | 2 +- contrib/gitian-descriptors/gitian-win-signer.yml | 2 +- doc/gitian-building.md | 6 +++--- doc/release-notes/release-notes-0.12.0.md | 2 +- doc/release-process.md | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 1103ca86c..bb8b9246b 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -48,9 +48,9 @@ the commit it claims to have been updated to. To use, make sure that you have fetched the upstream repository branch in which the subtree is maintained: -* for `src/secp256k1`: https://github.com/bitcoin/secp256k1.git (branch master) -* for `src/leveldb`: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork) -* for `src/univalue`: https://github.com/bitcoin/univalue.git (branch master) +* for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master) +* for `src/leveldb`: https://github.com/bitcoin-core/leveldb.git (branch bitcoin-fork) +* for `src/univalue`: https://github.com/bitcoin-core/univalue.git (branch master) Usage: `git-subtree-check.sh DIR COMMIT` diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index c4165470a..fac61aa3d 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -8,7 +8,7 @@ packages: - "faketime" reference_datetime: "2016-01-01 00:00:00" remotes: -- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" +- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" "dir": "signature" files: - "bitcoin-osx-unsigned.tar.gz" diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 27c4f01eb..88edb9662 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -9,7 +9,7 @@ packages: - "autoconf" reference_datetime: "2016-01-01 00:00:00" remotes: -- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" +- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" "dir": "signature" files: - "osslsigncode-1.7.1.tar.gz" diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 312621851..13f8ad316 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -310,7 +310,7 @@ Clone the git repositories for bitcoin and Gitian. ```bash git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin -git clone https://github.com/bitcoin/gitian.sigs.git +git clone https://github.com/bitcoin-core/gitian.sigs.git ``` Setting up the Gitian image @@ -441,7 +441,7 @@ Then when building, override the remote URLs that gbuild would otherwise pull fr ```bash cd /some/root/path/ -git clone https://github.com/bitcoin/bitcoin-detached-sigs.git +git clone https://github.com/bitcoin-core/bitcoin-detached-sigs.git BTCPATH=/some/root/path/bitcoin.git SIGPATH=/some/root/path/bitcoin-detached-sigs.git @@ -473,5 +473,5 @@ Uploading signatures --------------------- After building and signing you can push your signatures (both the `.assert` and `.assert.sig` files) to the -[bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or if that's not possible create a pull +[bitcoin-core/gitian.sigs](https://github.com/bitcoin-core/gitian.sigs/) repository, or if that's not possible create a pull request. You can also mail the files to Wladimir (laanwj@gmail.com) and he will commit them. diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index 135cd68a7..1b7bd06ec 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -61,7 +61,7 @@ Signature validation using libsecp256k1 --------------------------------------- ECDSA signatures inside Bitcoin transactions now use validation using -[libsecp256k1](https://github.com/bitcoin/secp256k1) instead of OpenSSL. +[libsecp256k1](https://github.com/bitcoin-core/secp256k1) instead of OpenSSL. Depending on the platform, this means a significant speedup for raw signature validation speed. The advantage is largest on x86_64, where validation is over diff --git a/doc/release-process.md b/doc/release-process.md index 34dead86b..3bfcc3817 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -20,8 +20,8 @@ Before every major release: Check out the source code in the following directory hierarchy. cd /path/to/your/toplevel/build - git clone https://github.com/bitcoin/gitian.sigs.git - git clone https://github.com/bitcoin/bitcoin-detached-sigs.git + git clone https://github.com/bitcoin-core/gitian.sigs.git + git clone https://github.com/bitcoin-core/bitcoin-detached-sigs.git git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin.git @@ -170,7 +170,7 @@ Commit your signature to gitian.sigs: Wait for Windows/OS X detached signatures: - Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys. -- Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries. +- Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin-core/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries. Create (and optionally verify) the signed OS X binary: From d90351f0504c5d4057e560d64107a2f36d7bf3d4 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 29 Apr 2016 14:23:51 +0000 Subject: [PATCH 0550/1223] More comments on the design of AttemptToEvictConnection. Some developers clearly don't get this and have been posting "improvements" that create clear vulnerabilities. It should have been better explained in the code, since the design is somewhat subtle and getting it right is important. --- src/net.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 7dec8fc1c..ced371164 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -877,6 +877,14 @@ public: } }; +/** Try to find a connection to evict when the node is full. + * Extreme care must be taken to avoid opening the node to attacker + * triggered network partitioning. + * The strategy used here is to protect a small number of peers + * for each of several distinct characteristics which are difficult + * to forge. In order to partition a node the attacker must be + * simultaneously better at all of them than honest peers. + */ static bool AttemptToEvictConnection(bool fPreferNewConnection) { std::vector vEvictionCandidates; { @@ -905,7 +913,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { if (vEvictionCandidates.empty()) return false; - // Protect the 8 nodes with the best ping times. + // Protect the 8 nodes with the lowest minimum ping time. // An attacker cannot manipulate this metric without physically moving nodes closer to the target. std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime); vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); @@ -913,7 +921,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { if (vEvictionCandidates.empty()) return false; // Protect the half of the remaining nodes which have been connected the longest. - // This replicates the existing implicit behavior. + // This replicates the non-eviction implicit behavior, and precludes attacks that start later. std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast(vEvictionCandidates.size() / 2), vEvictionCandidates.end()); @@ -941,6 +949,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { vEvictionCandidates = mapAddrCounts[naMostConnections]; // Do not disconnect peers if there is only one unprotected connection from their network group. + // This step excessively favors netgroup diversity, and should be removed once more protective criteria are established. if (vEvictionCandidates.size() <= 1) // unless we prefer the new connection (for whitelisted peers) if (!fPreferNewConnection) From f7c4f79f07c777801db7dc047cd45eaf2bba81c9 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Sat, 30 Apr 2016 19:25:00 +0200 Subject: [PATCH 0551/1223] [trivial] Add missing const qualifiers. Add some const qualifiers to references that are not modified and should be marked as const. --- src/main.cpp | 2 +- src/txmempool.cpp | 2 +- src/txmempool.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 11ccab253..277724565 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1468,7 +1468,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it int nHeight = -1; { - CCoinsViewCache &view = *pcoinsTip; + const CCoinsViewCache& view = *pcoinsTip; const CCoins* coins = view.AccessCoins(hash); if (coins) nHeight = coins->nHeight; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52c779311..420f6896b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -885,7 +885,7 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const return true; } -CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } +CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { // If an entry in the mempool exists, always return that one, as it's guaranteed to never diff --git a/src/txmempool.h b/src/txmempool.h index de4ba0b37..d17e3322d 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -672,10 +672,10 @@ private: class CCoinsViewMemPool : public CCoinsViewBacked { protected: - CTxMemPool &mempool; + const CTxMemPool& mempool; public: - CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn); + CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn); bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; }; From c8b92486c4eca1287546b0683b6af3551db1fe67 Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Fri, 29 Apr 2016 23:45:20 -0400 Subject: [PATCH 0552/1223] Remove obsolete reference to CValidationState from UpdateCoins. --- src/main.cpp | 8 ++++---- src/main.h | 2 +- src/test/coins_tests.cpp | 3 +-- src/txmempool.cpp | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 11ccab253..c5c614693 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1744,7 +1744,7 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state } } -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight) +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight) { // mark inputs spent if (!tx.IsCoinBase()) { @@ -1770,10 +1770,10 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach inputs.ModifyNewCoins(tx.GetHash(), tx.IsCoinBase())->FromTx(tx, nHeight); } -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) { CTxUndo txundo; - UpdateCoins(tx, state, inputs, txundo, nHeight); + UpdateCoins(tx, inputs, txundo, nHeight); } bool CScriptCheck::operator()() { @@ -2385,7 +2385,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); } - UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); + UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); diff --git a/src/main.h b/src/main.h index 2c9635bcf..792747a33 100644 --- a/src/main.h +++ b/src/main.h @@ -359,7 +359,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi unsigned int flags, bool cacheStore, std::vector *pvChecks = NULL); /** Apply the effects of this transaction on the UTXO set represented by view */ -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight); +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); /** Context-independent validity checks */ bool CheckTransaction(const CTransaction& tx, CValidationState& state); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 129ce04e0..e69232655 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -297,8 +297,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) CCoins &coins = result[tx.GetHash()]; coins.FromTx(tx, height); - CValidationState dummy; - UpdateCoins(tx, dummy, *(stack.back()), height); + UpdateCoins(tx, *(stack.back()), height); } // Once every 1000 iterations and at the end, verify the full cache. diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52c779311..f9c33087f 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -720,7 +720,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const else { CValidationState state; assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); - UpdateCoins(tx, state, mempoolDuplicate, 1000000); + UpdateCoins(tx, mempoolDuplicate, 1000000); } } unsigned int stepsSinceLastRemove = 0; @@ -734,7 +734,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL)); - UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000); + UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000); stepsSinceLastRemove = 0; } } From de982901555b3f168a721a8911dc1ce8a51d3f59 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 28 Apr 2016 17:46:35 -0400 Subject: [PATCH 0553/1223] build: No need to check for leveldb atomics They're guaranteed with c++11 --- configure.ac | 14 -------------- src/Makefile.leveldb.include | 7 ++----- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 558835bbb..a1c04daf5 100644 --- a/configure.ac +++ b/configure.ac @@ -555,18 +555,6 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi -dnl This can go away when we require c++11 -TEMP_CXXFLAGS="$CXXFLAGS" -CXXFLAGS="$CXXFLAGS -std=c++0x" -AC_MSG_CHECKING(for c++11 atomics) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[]])], - [ AC_MSG_RESULT(yes); LEVELDB_ATOMIC_CPPFLAGS="-DLEVELDB_ATOMIC_PRESENT"; LEVELDB_ATOMIC_CXXFLAGS="-std=c++0x"], - [ AC_MSG_RESULT(no)] -) -CXXFLAGS="$TEMP_CXXFLAGS" - LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= @@ -1069,8 +1057,6 @@ AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) -AC_SUBST(LEVELDB_ATOMIC_CPPFLAGS) -AC_SUBST(LEVELDB_ATOMIC_CXXFLAGS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 36a6bc409..88bb0c193 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -13,7 +13,7 @@ LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv LEVELDB_CPPFLAGS_INT = LEVELDB_CPPFLAGS_INT += -I$(srcdir)/leveldb LEVELDB_CPPFLAGS_INT += $(LEVELDB_TARGET_FLAGS) -LEVELDB_CPPFLAGS_INT += $(LEVELDB_ATOMIC_CPPFLAGS) +LEVELDB_CPPFLAGS_INT += -DLEVELDB_ATOMIC_PRESENT LEVELDB_CPPFLAGS_INT += -D__STDC_LIMIT_MACROS if TARGET_WINDOWS @@ -22,11 +22,8 @@ else LEVELDB_CPPFLAGS_INT += -DLEVELDB_PLATFORM_POSIX endif -LEVELDB_CXXFLAGS_INT = -LEVELDB_CXXFLAGS_INT += $(LEVELDB_ATOMIC_CXXFLAGS) - leveldb_libleveldb_a_CPPFLAGS = $(AM_CPPFLAGS) $(LEVELDB_CPPFLAGS_INT) $(LEVELDB_CPPFLAGS) -leveldb_libleveldb_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(LEVELDB_CXXFLAGS_INT) +leveldb_libleveldb_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) leveldb_libleveldb_a_SOURCES= leveldb_libleveldb_a_SOURCES += leveldb/db/builder.cc From 9a8a7d011564c43231d16e6e3a25c73f0c76fde1 Mon Sep 17 00:00:00 2001 From: Puru Date: Mon, 2 May 2016 22:33:04 +0545 Subject: [PATCH 0554/1223] bitcoin-cli.cpp: Use symbolic constant for exit code --- src/bitcoin-cli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 49935699f..a04101d3e 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -314,7 +314,7 @@ int main(int argc, char* argv[]) SetupEnvironment(); if (!SetupNetworking()) { fprintf(stderr, "Error: Initializing networking failed\n"); - exit(1); + return EXIT_FAILURE; } try { From fa17f93fbd2889c020849b941a94c5bd8a619a3c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 30 Apr 2016 23:16:06 +0200 Subject: [PATCH 0555/1223] [qa] smartfees: Properly use ordered dict --- qa/rpc-tests/smartfees.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 2c064ad8a..b3fb8fb10 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -7,6 +7,7 @@ # Test fee estimation code # +from collections import OrderedDict from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -49,8 +50,8 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee if total_in <= amount + fee: raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in)) outputs = {} - outputs[P2SH_1] = total_in - amount - fee - outputs[P2SH_2] = amount + outputs = OrderedDict([(P2SH_1, total_in - amount - fee), + (P2SH_2, amount)]) rawtx = from_node.createrawtransaction(inputs, outputs) # Createrawtransaction constructions a transaction that is ready to be signed # These transactions don't need to be signed, but we still have to insert the ScriptSig @@ -78,12 +79,10 @@ def split_inputs(from_node, txins, txouts, initial_split = False): ''' prevtxout = txins.pop() inputs = [] - outputs = {} inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] }) half_change = satoshi_round(prevtxout["amount"]/2) rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000") - outputs[P2SH_1] = half_change - outputs[P2SH_2] = rem_change + outputs = OrderedDict([(P2SH_1, half_change), (P2SH_2, rem_change)]) rawtx = from_node.createrawtransaction(inputs, outputs) # If this is the initial split we actually need to sign the transaction # Otherwise we just need to insert the property ScriptSig From 43bbcd075355630544a530f3cc52014edb3787b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Mon, 2 May 2016 22:23:21 +0200 Subject: [PATCH 0556/1223] [qa] Fix typos in doc and comments --- qa/rpc-tests/smartfees.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index b3fb8fb10..7239e5a0d 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -23,7 +23,7 @@ SCRIPT_SIG = ["0451025175", "0451025275"] def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment): ''' Create and send a transaction with a random fee. - The transaction pays to a trival P2SH script, and assumes that its inputs + The transaction pays to a trivial P2SH script, and assumes that its inputs are of the same form. The function takes a list of confirmed outputs and unconfirmed outputs and attempts to use the confirmed list first for its inputs. @@ -53,7 +53,7 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee outputs = OrderedDict([(P2SH_1, total_in - amount - fee), (P2SH_2, amount)]) rawtx = from_node.createrawtransaction(inputs, outputs) - # Createrawtransaction constructions a transaction that is ready to be signed + # createrawtransaction constructs a transaction that is ready to be signed. # These transactions don't need to be signed, but we still have to insert the ScriptSig # that will satisfy the ScriptPubKey. completetx = rawtx[0:10] @@ -223,7 +223,7 @@ class EstimateFeeTest(BitcoinTestFramework): sync_mempools(self.nodes[0:3],.1) mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"] sync_blocks(self.nodes[0:3],.1) - #update which txouts are confirmed + # update which txouts are confirmed newmem = [] for utx in self.memutxo: if utx["txid"] in mined: From 9eaa0afa6ec5d3dd01e4d01121314ef51f2bc305 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 4 May 2016 11:35:44 +0200 Subject: [PATCH 0557/1223] tinyformat: force USE_VARIADIC_TEMPLATES Now that we started using c++11, force use of variadic templates. The autodetection may be wonky on some compilers, see discussion [here](https://github.com/bitcoin/bitcoin/pull/7982#issuecomment-216222357) and is unnecessary for us anyhow. --- src/tinyformat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tinyformat.h b/src/tinyformat.h index 73d49a1fe..c6ec0419b 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -113,7 +113,7 @@ namespace tfm = tinyformat; // Define for C++11 variadic templates which make the code shorter & more // general. If you don't define this, C++11 support is autodetected below. -// #define TINYFORMAT_USE_VARIADIC_TEMPLATES +#define TINYFORMAT_USE_VARIADIC_TEMPLATES //------------------------------------------------------------------------------ From 47eda2d8820b8161b6ef550af6575cbe4f1a3207 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 4 May 2016 19:03:59 +0800 Subject: [PATCH 0558/1223] [depends] Add -stdlib=libc++ to darwin CXX flags --- depends/builders/darwin.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 200d6ed22..27f550ab0 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -11,7 +11,7 @@ build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONN #darwin host on darwin builder. overrides darwin host preferences. darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) -darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) +darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) From 08d7b563e91ed2ad226ec2505a5a850ab869d2f0 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 4 May 2016 14:21:04 +0200 Subject: [PATCH 0559/1223] util: switch LogPrint and error to variadic templates --- src/util.h | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/util.h b/src/util.h index ac099f118..25c9b733e 100644 --- a/src/util.h +++ b/src/util.h @@ -76,40 +76,33 @@ int LogPrintStr(const std::string &str); #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) -/** - * When we switch to C++11, this can be switched to variadic templates instead - * of this macro-based construction (see tinyformat.h). - */ -#define MAKE_ERROR_AND_LOG_FUNC(n) \ - /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \ - template \ - static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ - { \ - if(!LogAcceptCategory(category)) return 0; \ - return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ - } \ - /** Log error and return false */ \ - template \ - static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ - { \ - LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \ - return false; \ - } +template +static inline int LogPrint(const char* category, const char* fmt, const T1& v1, const Args&... args) +{ + if(!LogAcceptCategory(category)) return 0; \ + return LogPrintStr(tfm::format(fmt, v1, args...)); +} -TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC) +template +bool error(const char* fmt, const T1& v1, const Args&... args) +{ + LogPrintStr("ERROR: " + tfm::format(fmt, v1, args...) + "\n"); + return false; +} /** * Zero-arg versions of logging and error, these are not covered by - * TINYFORMAT_FOREACH_ARGNUM + * the variadic templates above (and don't take format arguments but + * bare strings). */ -static inline int LogPrint(const char* category, const char* format) +static inline int LogPrint(const char* category, const char* s) { if(!LogAcceptCategory(category)) return 0; - return LogPrintStr(format); + return LogPrintStr(s); } -static inline bool error(const char* format) +static inline bool error(const char* s) { - LogPrintStr(std::string("ERROR: ") + format + "\n"); + LogPrintStr(std::string("ERROR: ") + s + "\n"); return false; } From 0281678d6ebf68dacfb6ecaf7c231fedcd971d66 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Thu, 28 Apr 2016 15:07:31 -0700 Subject: [PATCH 0560/1223] doc: Fedora build requirements --- doc/build-unix.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index dc754fc73..27c57088a 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -124,6 +124,24 @@ libqrencode (optional) can be installed with: Once these are installed, they will be found by configure and a bitcoin-qt executable will be built by default. +Dependency Build Instructions: Fedora +------------------------------------- +Build requirements: + + sudo dnf install libtool make autoconf automake openssl-devel libevent-devel boost-devel libdb4-devel libdb4-cxx-devel + +Optional: + + sudo dnf install miniupnpc-devel + +To build with Qt 5 (recommended) you need the following: + + sudo dnf install qt5-qttools-devel qtr5-qtbase-devel protobuf-devel + +libqrencode (optional) can be installed with: + + sudo dnf install qrencode-devel + Notes ----- The release is built with GCC and then "strip bitcoind" to strip the debug From 1475ecf61141e03f63a79d59831c411e0e8a5c0a Mon Sep 17 00:00:00 2001 From: EthanHeilman Date: Wed, 16 Mar 2016 12:54:30 -0400 Subject: [PATCH 0561/1223] Fix de-serialization bug where AddrMan is corrupted after exception * CAddrDB modified so that when de-serialization code throws an exception Addrman is reset to a clean state * CAddrDB modified to make unit tests possible * Regression test created to ensure bug is fixed * StartNode modifed to clear adrman if CAddrDB::Read returns an error code. --- src/Makefile.test.include | 1 + src/net.cpp | 8 +++ src/net.h | 1 + src/test/net_tests.cpp | 136 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 src/test/net_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 468d3043a..edeca6b28 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -60,6 +60,7 @@ BITCOIN_TESTS =\ test/merkle_tests.cpp \ test/miner_tests.cpp \ test/multisig_tests.cpp \ + test/net_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/policyestimator_tests.cpp \ diff --git a/src/net.cpp b/src/net.cpp index d9c4c1173..cf5381603 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1944,6 +1944,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (adb.Read(addrman)) LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); else { + addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it LogPrintf("Invalid or missing peers.dat; recreating\n"); DumpAddresses(); } @@ -2336,6 +2337,11 @@ bool CAddrDB::Read(CAddrMan& addr) if (hashIn != hashTmp) return error("%s: Checksum mismatch, data corrupted", __func__); + return Read(addr, ssPeers); +} + +bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers) +{ unsigned char pchMsgTmp[4]; try { // de-serialize file header (network specific magic number) and .. @@ -2349,6 +2355,8 @@ bool CAddrDB::Read(CAddrMan& addr) ssPeers >> addr; } catch (const std::exception& e) { + // de-serialization has failed, ensure addrman is left in a clean state + addr.Clear(); return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } diff --git a/src/net.h b/src/net.h index 833c9cf07..dfa270544 100644 --- a/src/net.h +++ b/src/net.h @@ -779,6 +779,7 @@ public: CAddrDB(); bool Write(const CAddrMan& addr); bool Read(CAddrMan& addr); + bool Read(CAddrMan& addr, CDataStream& ssPeers); }; /** Access to the banlist database (banlist.dat) */ diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp new file mode 100644 index 000000000..6debf6ac5 --- /dev/null +++ b/src/test/net_tests.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2012-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "addrman.h" +#include "test/test_bitcoin.h" +#include +#include +#include "hash.h" +#include "serialize.h" +#include "streams.h" +#include "net.h" +#include "chainparams.h" + +using namespace std; + +class CAddrManSerializationMock : public CAddrMan +{ +public: + virtual void Serialize(CDataStream& s, int nType, int nVersionDummy) const = 0; +}; + +class CAddrManUncorrupted : public CAddrManSerializationMock +{ +public: + void Serialize(CDataStream& s, int nType, int nVersionDummy) const + { + CAddrMan::Serialize(s, nType, nVersionDummy); + } +}; + +class CAddrManCorrupted : public CAddrManSerializationMock +{ +public: + void Serialize(CDataStream& s, int nType, int nVersionDummy) const + { + // Produces corrupt output that claims addrman has 20 addrs when it only has one addr. + unsigned char nVersion = 1; + s << nVersion; + s << ((unsigned char)32); + s << nKey; + s << 10; // nNew + s << 10; // nTried + + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); + s << nUBuckets; + + CAddress addr = CAddress(CService("252.1.1.1", 7777)); + CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2")); + s << info; + } +}; + +CDataStream AddrmanToStream(CAddrManSerializationMock& addrman) +{ + CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION); + ssPeersIn << FLATDATA(Params().MessageStart()); + ssPeersIn << addrman; + std::string str = ssPeersIn.str(); + vector vchData(str.begin(), str.end()); + return CDataStream(vchData, SER_DISK, CLIENT_VERSION); +} + +BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(caddrdb_read) +{ + CAddrManUncorrupted addrmanUncorrupted; + + CService addr1 = CService("250.7.1.1", 8333); + CService addr2 = CService("250.7.2.2", 9999); + CService addr3 = CService("250.7.3.3", 9999); + + // Add three addresses to new table. + addrmanUncorrupted.Add(CAddress(addr1), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr2), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr3), CService("252.5.1.1", 8333)); + + // Test that the de-serialization does not throw an exception. + CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); + bool exceptionThrown = false; + CAddrMan addrman1; + + BOOST_CHECK(addrman1.size() == 0); + try { + unsigned char pchMsgTmp[4]; + ssPeers1 >> FLATDATA(pchMsgTmp); + ssPeers1 >> addrman1; + } catch (const std::exception& e) { + exceptionThrown = true; + } + + BOOST_CHECK(addrman1.size() == 3); + BOOST_CHECK(exceptionThrown == false); + + // Test that CAddrDB::Read creates an addrman with the correct number of addrs. + CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted); + + CAddrMan addrman2; + CAddrDB adb; + BOOST_CHECK(addrman2.size() == 0); + adb.Read(addrman2, ssPeers2); + BOOST_CHECK(addrman2.size() == 3); +} + + +BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) +{ + CAddrManCorrupted addrmanCorrupted; + + // Test that the de-serialization of corrupted addrman throws an exception. + CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted); + bool exceptionThrown = false; + CAddrMan addrman1; + BOOST_CHECK(addrman1.size() == 0); + try { + unsigned char pchMsgTmp[4]; + ssPeers1 >> FLATDATA(pchMsgTmp); + ssPeers1 >> addrman1; + } catch (const std::exception& e) { + exceptionThrown = true; + } + // Even through de-serialization failed adddrman is not left in a clean state. + BOOST_CHECK(addrman1.size() == 1); + BOOST_CHECK(exceptionThrown); + + // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails. + CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted); + + CAddrMan addrman2; + CAddrDB adb; + BOOST_CHECK(addrman2.size() == 0); + adb.Read(addrman2, ssPeers2); + BOOST_CHECK(addrman2.size() == 0); +} + +BOOST_AUTO_TEST_SUITE_END() From 091d6e04998d2c88dd7f42ad2d90929f428764c2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 19:03:05 +0200 Subject: [PATCH 0562/1223] http: Do a pending c++11 simplification Use std::unique_ptr for handling work items. This makes the code more RAII and, as mentioned in the comment, is what I planned when I wrote the code in the first place. --- src/httpserver.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a98eff7c1..8297b6f75 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -71,8 +71,7 @@ private: /** Mutex protects entire object */ CWaitableCriticalSection cs; CConditionVariable cond; - /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */ - std::deque queue; + std::deque> queue; bool running; size_t maxDepth; int numThreads; @@ -101,15 +100,11 @@ public: numThreads(0) { } - /*( Precondition: worker threads have all stopped + /** Precondition: worker threads have all stopped * (call WaitExit) */ ~WorkQueue() { - while (!queue.empty()) { - delete queue.front(); - queue.pop_front(); - } } /** Enqueue a work item */ bool Enqueue(WorkItem* item) @@ -118,7 +113,7 @@ public: if (queue.size() >= maxDepth) { return false; } - queue.push_back(item); + queue.emplace_back(std::unique_ptr(item)); cond.notify_one(); return true; } @@ -127,18 +122,17 @@ public: { ThreadCounter count(*this); while (running) { - WorkItem* i = 0; + std::unique_ptr i; { boost::unique_lock lock(cs); while (running && queue.empty()) cond.wait(lock); if (!running) break; - i = queue.front(); + i = std::move(queue.front()); queue.pop_front(); } (*i)(); - delete i; } } /** Interrupt and exit loops */ From f97b410fdd57743f9a26ea49086534000eb9626a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 4 May 2016 15:37:26 +0200 Subject: [PATCH 0563/1223] http: Add log message when work queue is full More useful error reporting. --- src/httpserver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 8297b6f75..67a9e1e92 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -286,8 +286,10 @@ static void http_request_cb(struct evhttp_request* req, void* arg) assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ - else + else { + LogPrintf("WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n"); item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded"); + } } else { hreq->WriteReply(HTTP_NOTFOUND); } From 37b21372a0a3e5d876a87f03c8cbef2e02d8dc92 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 4 May 2016 15:55:23 +0200 Subject: [PATCH 0564/1223] http: Change boost::scoped_ptr to std::unique_ptr in HTTPRequest No need for boost here. --- src/httpserver.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 67a9e1e92..c193d2af1 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -36,7 +36,6 @@ #include // for to_lower() #include -#include /** Maximum size of http request (request line + headers) */ static const size_t MAX_HEADERS_SIZE = 8192; @@ -54,7 +53,7 @@ public: func(req.get(), path); } - boost::scoped_ptr req; + std::unique_ptr req; private: std::string path; From f0188f9178a22fd493ed228c008d4cc25ac2952d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 4 May 2016 16:05:17 +0200 Subject: [PATCH 0565/1223] http: use std::move to move HTTPRequest into HTTPWorkItem Thanks to Cory Fields for the idea. --- src/httpserver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index c193d2af1..812940eaf 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -44,8 +44,8 @@ static const size_t MAX_HEADERS_SIZE = 8192; class HTTPWorkItem : public HTTPClosure { public: - HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func): - req(req), path(path), func(func) + HTTPWorkItem(std::unique_ptr req, const std::string &path, const HTTPRequestHandler& func): + req(std::move(req)), path(path), func(func) { } void operator()() @@ -281,7 +281,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) // Dispatch to worker thread if (i != iend) { - std::unique_ptr item(new HTTPWorkItem(hreq.release(), path, i->handler)); + std::unique_ptr item(new HTTPWorkItem(std::move(hreq), path, i->handler)); assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ From fa389d4edc367073e2ccc6d1f0790c4b72ba17f2 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 19 Mar 2016 20:58:06 +0100 Subject: [PATCH 0566/1223] [qa] Switch to py3 --- .travis.yml | 10 +- doc/zmq.md | 2 +- qa/README.md | 4 +- qa/pull-tester/rpc-tests.py | 10 +- qa/pull-tester/tests_config.py.in | 6 +- qa/rpc-tests/abandonconflict.py | 17 ++- qa/rpc-tests/bip65-cltv-p2p.py | 15 ++- qa/rpc-tests/bip65-cltv.py | 8 +- qa/rpc-tests/bip68-112-113-p2p.py | 109 +++++++++--------- qa/rpc-tests/bip68-sequence.py | 30 ++--- qa/rpc-tests/bip9-softforks.py | 9 +- qa/rpc-tests/bipdersig-p2p.py | 15 ++- qa/rpc-tests/bipdersig.py | 8 +- qa/rpc-tests/blockchain.py | 18 +-- qa/rpc-tests/decodescript.py | 4 +- qa/rpc-tests/disablewallet.py | 4 +- qa/rpc-tests/forknotify.py | 4 +- qa/rpc-tests/fundrawtransaction.py | 12 +- qa/rpc-tests/getblocktemplate_longpoll.py | 6 +- qa/rpc-tests/getblocktemplate_proposals.py | 12 +- qa/rpc-tests/getchaintips.py | 4 +- qa/rpc-tests/httpbasics.py | 38 +++--- qa/rpc-tests/importprunedfunds.py | 4 +- qa/rpc-tests/invalidateblock.py | 30 ++--- qa/rpc-tests/invalidblockrequest.py | 11 +- qa/rpc-tests/invalidtxrequest.py | 11 +- qa/rpc-tests/keypool.py | 4 +- qa/rpc-tests/listtransactions.py | 4 +- qa/rpc-tests/maxblocksinflight.py | 11 +- qa/rpc-tests/maxuploadtarget.py | 35 +++--- qa/rpc-tests/mempool_limit.py | 6 +- qa/rpc-tests/mempool_packages.py | 24 ++-- qa/rpc-tests/mempool_reorg.py | 4 +- qa/rpc-tests/mempool_resurrect_test.py | 4 +- qa/rpc-tests/mempool_spendcoinbase.py | 4 +- qa/rpc-tests/merkle_blocks.py | 6 +- qa/rpc-tests/multi_rpc.py | 29 ++--- qa/rpc-tests/nodehandling.py | 16 +-- qa/rpc-tests/p2p-acceptblock.py | 37 +++--- qa/rpc-tests/p2p-feefilter.py | 14 +-- qa/rpc-tests/p2p-fullblocktest.py | 7 +- qa/rpc-tests/p2p-versionbits-warning.py | 7 +- qa/rpc-tests/prioritise_transaction.py | 14 +-- qa/rpc-tests/proxy_test.py | 7 +- qa/rpc-tests/pruning.py | 68 +++++------ qa/rpc-tests/rawtransactions.py | 4 +- qa/rpc-tests/receivedby.py | 4 +- qa/rpc-tests/reindex.py | 6 +- qa/rpc-tests/replace-by-fee.py | 26 ++--- qa/rpc-tests/rest.py | 25 ++-- qa/rpc-tests/rpcbind_test.py | 6 +- qa/rpc-tests/sendheaders.py | 45 ++++---- qa/rpc-tests/signmessages.py | 2 +- qa/rpc-tests/signrawtransactions.py | 4 +- qa/rpc-tests/smartfees.py | 6 +- qa/rpc-tests/test_framework/bignum.py | 5 +- qa/rpc-tests/test_framework/blockstore.py | 13 ++- qa/rpc-tests/test_framework/blocktools.py | 6 +- qa/rpc-tests/test_framework/comptool.py | 17 ++- qa/rpc-tests/test_framework/coverage.py | 7 +- qa/rpc-tests/test_framework/mininode.py | 77 +++++++------ qa/rpc-tests/test_framework/netutil.py | 4 +- qa/rpc-tests/test_framework/script.py | 11 +- qa/rpc-tests/test_framework/socks5.py | 9 +- qa/rpc-tests/test_framework/test_framework.py | 8 +- qa/rpc-tests/test_framework/util.py | 21 ++-- qa/rpc-tests/txn_clone.py | 4 +- qa/rpc-tests/txn_doublespend.py | 4 +- qa/rpc-tests/wallet.py | 8 +- qa/rpc-tests/walletbackup.py | 4 +- qa/rpc-tests/zapwallettxes.py | 6 +- qa/rpc-tests/zmq_test.py | 17 +-- 72 files changed, 504 insertions(+), 547 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f3ea4e76..fd70d3ab5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,15 +37,15 @@ matrix: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" + env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python3-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" + env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" - env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" exclude: diff --git a/doc/zmq.md b/doc/zmq.md index 8d795a388..6079e3254 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -38,7 +38,7 @@ newer. Typically, it is packaged by distributions as something like *libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. In order to run the example Python client scripts in contrib/ one must -also install *python-zmq*, though this is not necessary for daemon +also install *python3-zmq*, though this is not necessary for daemon operation. ## Enabling diff --git a/qa/README.md b/qa/README.md index 2b476c4d8..3e0a526d1 100644 --- a/qa/README.md +++ b/qa/README.md @@ -11,9 +11,9 @@ Before running the tests, the following must be installed. Unix ---- -The python-zmq library is required. On Ubuntu or Debian it can be installed via: +The python3-zmq library is required. On Ubuntu or Debian it can be installed via: ``` -sudo apt-get install python-zmq +sudo apt-get install python3-zmq ``` Running tests diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 26142c35e..15153b7f5 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -70,14 +70,14 @@ if "BITCOINCLI" not in os.environ: if EXEEXT == ".exe" and "-win" not in opts: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 - print "Win tests currently disabled by default. Use -win option to enable" + print("Win tests currently disabled by default. Use -win option to enable") sys.exit(0) if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): - print "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" + print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") sys.exit(0) -# python-zmq may not be installed. Handle this gracefully and with some helpful info +# python3-zmq may not be installed. Handle this gracefully and with some helpful info if ENABLE_ZMQ: try: import zmq diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in index 937b4231f..2356b5200 100644 --- a/qa/pull-tester/tests_config.py.in +++ b/qa/pull-tester/tests_config.py.in @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2013-2014 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2013-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,5 +11,3 @@ EXEEXT="@EXEEXT@" @BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 @ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 - - diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index a83aa97fc..b6c4b9db4 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -1,15 +1,12 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +import urllib.parse class AbandonConflictTest(BitcoinTestFramework): @@ -34,7 +31,7 @@ class AbandonConflictTest(BitcoinTestFramework): assert(balance - newbalance < Decimal("0.001")) #no more than fees lost balance = newbalance - url = urlparse.urlparse(self.nodes[1].url) + url = urllib.parse.urlparse(self.nodes[1].url) self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) # Identify the 10btc outputs @@ -151,9 +148,9 @@ class AbandonConflictTest(BitcoinTestFramework): self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) newbalance = self.nodes[0].getbalance() #assert(newbalance == balance - Decimal("10")) - print "If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer" - print "conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315" - print balance , " -> " , newbalance , " ?" + print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer") + print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315") + print(str(balance) + " -> " + str(newbalance) + " ?") if __name__ == '__main__': AbandonConflictTest().main() diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 99d74344a..60923b9dd 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -67,13 +66,13 @@ class BIP65Test(ComparisonTestFramework): self.coinbase_blocks = self.nodes[0].generate(2) height = 3 # height of the next block to build - self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = int(time.time()) ''' 98 more version 3 blocks ''' test_blocks = [] - for i in xrange(98): + for i in range(98): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() @@ -86,7 +85,7 @@ class BIP65Test(ComparisonTestFramework): ''' Mine 749 version 4 blocks ''' test_blocks = [] - for i in xrange(749): + for i in range(749): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.rehash() @@ -138,7 +137,7 @@ class BIP65Test(ComparisonTestFramework): ''' Mine 199 new version blocks on last valid tip ''' test_blocks = [] - for i in xrange(199): + for i in range(199): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 4 block.rehash() diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index f666a07c9..9d83fc947 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -32,7 +32,7 @@ class BIP65Test(BitcoinTestFramework): raise AssertionError("Failed to mine 100 version=3 blocks") # Mine 750 new-version blocks - for i in xrange(15): + for i in range(15): self.nodes[2].generate(50) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 850): @@ -49,7 +49,7 @@ class BIP65Test(BitcoinTestFramework): # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced # Mine 198 new-version blocks - for i in xrange(2): + for i in range(2): self.nodes[2].generate(99) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1049): diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 3bcfdabe2..eedb60e3a 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -63,13 +62,13 @@ seq_random_low_bit = 1<<18 # b31,b25,b22,b18 represent the 31st, 25th, 22nd and 18th bits respectively in the nSequence field # relative_locktimes[b31][b25][b22][b18] is a base_relative_locktime with the indicated bits set if their indices are 1 relative_locktimes = [] -for b31 in xrange(2): +for b31 in range(2): b25times = [] - for b25 in xrange(2): + for b25 in range(2): b22times = [] - for b22 in xrange(2): + for b22 in range(2): b18times = [] - for b18 in xrange(2): + for b18 in range(2): rlt = base_relative_locktime if (b31): rlt = rlt | seq_disable_flag @@ -86,10 +85,10 @@ for b31 in xrange(2): def all_rlt_txs(txarray): txs = [] - for b31 in xrange(2): - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b31 in range(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): txs.append(txarray[b31][b25][b22][b18]) return txs @@ -131,7 +130,7 @@ class BIP68_112_113Test(ComparisonTestFramework): return tx def generate_blocks(self, number, version, test_blocks = []): - for i in xrange(number): + for i in range(number): block = self.create_test_block([], version) test_blocks.append([block, True]) self.last_block_time += 600 @@ -152,13 +151,13 @@ class BIP68_112_113Test(ComparisonTestFramework): txs = [] assert(len(bip68inputs) >= 16) i = 0 - for b31 in xrange(2): + for b31 in range(2): b25txs = [] - for b25 in xrange(2): + for b25 in range(2): b22txs = [] - for b22 in xrange(2): + for b22 in range(2): b18txs = [] - for b18 in xrange(2): + for b18 in range(2): tx = self.create_transaction(self.nodes[0], bip68inputs[i], self.nodeaddress, Decimal("49.98")) i += 1 tx.nVersion = txversion @@ -180,13 +179,13 @@ class BIP68_112_113Test(ComparisonTestFramework): txs = [] assert(len(bip112inputs) >= 16) i = 0 - for b31 in xrange(2): + for b31 in range(2): b25txs = [] - for b25 in xrange(2): + for b25 in range(2): b22txs = [] - for b22 in xrange(2): + for b22 in range(2): b18txs = [] - for b18 in xrange(2): + for b18 in range(2): tx = self.create_transaction(self.nodes[0], bip112inputs[i], self.nodeaddress, Decimal("49.98")) i += 1 if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed @@ -212,7 +211,7 @@ class BIP68_112_113Test(ComparisonTestFramework): self.nodes[0].setmocktime(0) # set time back to present so yielded blocks aren't in the future as we advance last_block_time self.tipheight = 82 # height of the next block to build self.last_block_time = long_past_time - self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'defined') @@ -250,20 +249,20 @@ class BIP68_112_113Test(ComparisonTestFramework): # Note we reuse inputs for v1 and v2 txs so must test these separately # 16 normal inputs bip68inputs = [] - for i in xrange(16): + for i in range(16): bip68inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) # 2 sets of 16 inputs with 10 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) bip112basicinputs = [] - for j in xrange(2): + for j in range(2): inputs = [] - for i in xrange(16): + for i in range(16): inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) bip112basicinputs.append(inputs) # 2 sets of 16 varied inputs with (relative_lock_time) OP_CSV OP_DROP (actually will be prepended to spending scriptSig) bip112diverseinputs = [] - for j in xrange(2): + for j in range(2): inputs = [] - for i in xrange(16): + for i in range(16): inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)) bip112diverseinputs.append(inputs) # 1 special input with -1 OP_CSV OP_DROP (actually will be prepended to spending scriptSig) @@ -274,7 +273,7 @@ class BIP68_112_113Test(ComparisonTestFramework): self.nodes[0].setmocktime(self.last_block_time + 600) inputblockhash = self.nodes[0].generate(1)[0] # 1 block generated for inputs to be in chain at height 572 self.nodes[0].setmocktime(0) - self.tip = int("0x" + inputblockhash + "L", 0) + self.tip = int("0x" + inputblockhash, 0) self.tipheight += 1 self.last_block_time += 600 assert_equal(len(self.nodes[0].getblock(inputblockhash,True)["tx"]), 82+1) @@ -398,22 +397,22 @@ class BIP68_112_113Test(ComparisonTestFramework): ### Version 2 txs ### bip68success_txs = [] # All txs with SEQUENCE_LOCKTIME_DISABLE_FLAG set pass - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): bip68success_txs.append(bip68txs_v2[1][b25][b22][b18]) yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 15 self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) # All txs without flag fail as we are at delta height = 8 < 10 and delta time = 8 * 600 < 10 * 512 bip68timetxs = [] - for b25 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b18 in range(2): bip68timetxs.append(bip68txs_v2[0][b25][1][b18]) for tx in bip68timetxs: yield TestInstance([[self.create_test_block([tx]), False]]) # 16 - 19 bip68heighttxs = [] - for b25 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b18 in range(2): bip68heighttxs.append(bip68txs_v2[0][b25][0][b18]) for tx in bip68heighttxs: yield TestInstance([[self.create_test_block([tx]), False]]) # 20 - 23 @@ -445,9 +444,9 @@ class BIP68_112_113Test(ComparisonTestFramework): yield TestInstance([[self.create_test_block([bip112tx_special_v1]), False]]) #32 # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass success_txs = [] - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): success_txs.append(bip112txs_vary_OP_CSV_v1[1][b25][b22][b18]) success_txs.append(bip112txs_vary_OP_CSV_9_v1[1][b25][b22][b18]) yield TestInstance([[self.create_test_block(success_txs), True]]) # 33 @@ -457,9 +456,9 @@ class BIP68_112_113Test(ComparisonTestFramework): fail_txs = [] fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1)) fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1)) - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): fail_txs.append(bip112txs_vary_OP_CSV_v1[0][b25][b22][b18]) fail_txs.append(bip112txs_vary_OP_CSV_9_v1[0][b25][b22][b18]) @@ -472,9 +471,9 @@ class BIP68_112_113Test(ComparisonTestFramework): # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met) success_txs = [] - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): success_txs.append(bip112txs_vary_OP_CSV_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV success_txs.append(bip112txs_vary_OP_CSV_9_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV_9 @@ -485,9 +484,9 @@ class BIP68_112_113Test(ComparisonTestFramework): # All txs with nSequence 9 should fail either due to earlier mismatch or failing the CSV check fail_txs = [] fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) # 16/16 of vary_nSequence_9 - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): fail_txs.append(bip112txs_vary_OP_CSV_9_v2[0][b25][b22][b18]) # 16/16 of vary_OP_CSV_9 for tx in fail_txs: @@ -495,17 +494,17 @@ class BIP68_112_113Test(ComparisonTestFramework): # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail fail_txs = [] - for b25 in xrange(2): - for b22 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b22 in range(2): + for b18 in range(2): fail_txs.append(bip112txs_vary_nSequence_v2[1][b25][b22][b18]) # 8/16 of vary_nSequence for tx in fail_txs: yield TestInstance([[self.create_test_block([tx]), False]]) # 108-115 # If sequencelock types mismatch, tx should fail fail_txs = [] - for b25 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b18 in range(2): fail_txs.append(bip112txs_vary_nSequence_v2[0][b25][1][b18]) # 12/16 of vary_nSequence fail_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][1][b18]) # 12/16 of vary_OP_CSV for tx in fail_txs: @@ -513,8 +512,8 @@ class BIP68_112_113Test(ComparisonTestFramework): # Remaining txs should pass, just test masking works properly success_txs = [] - for b25 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b18 in range(2): success_txs.append(bip112txs_vary_nSequence_v2[0][b25][0][b18]) # 16/16 of vary_nSequence success_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][0][b18]) # 16/16 of vary_OP_CSV yield TestInstance([[self.create_test_block(success_txs), True]]) # 124 @@ -522,8 +521,8 @@ class BIP68_112_113Test(ComparisonTestFramework): # Additional test, of checking that comparison of two time types works properly time_txs = [] - for b25 in xrange(2): - for b18 in xrange(2): + for b25 in range(2): + for b18 in range(2): tx = bip112txs_vary_OP_CSV_v2[0][b25][1][b18] tx.vin[0].nSequence = base_relative_locktime | seq_type_flag signtx = self.sign_transaction(self.nodes[0], tx) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 33e05dfc5..717f7562c 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,28 +35,28 @@ class BIP68Test(BitcoinTestFramework): # Generate some coins self.nodes[0].generate(110) - print "Running test disable flag" + print("Running test disable flag") self.test_disable_flag() - print "Running test sequence-lock-confirmed-inputs" + print("Running test sequence-lock-confirmed-inputs") self.test_sequence_lock_confirmed_inputs() - print "Running test sequence-lock-unconfirmed-inputs" + print("Running test sequence-lock-unconfirmed-inputs") self.test_sequence_lock_unconfirmed_inputs() - print "Running test BIP68 not consensus before versionbits activation" + print("Running test BIP68 not consensus before versionbits activation") self.test_bip68_not_consensus() - print "Verifying nVersion=2 transactions aren't standard" + print("Verifying nVersion=2 transactions aren't standard") self.test_version2_relay(before_activation=True) - print "Activating BIP68 (and 112/113)" + print("Activating BIP68 (and 112/113)") self.activateCSV() - print "Verifying nVersion=2 transactions are now standard" + print("Verifying nVersion=2 transactions are now standard") self.test_version2_relay(before_activation=False) - print "Passed\n" + print("Passed\n") # Test that BIP68 is not in effect if tx version is 1, or if # the first sequence bit is set. @@ -125,7 +125,7 @@ class BIP68Test(BitcoinTestFramework): random.shuffle(addresses) num_outputs = random.randint(1, max_outputs) outputs = {} - for i in xrange(num_outputs): + for i in range(num_outputs): outputs[addresses[i]] = random.randint(1, 20)*0.01 self.nodes[0].sendmany("", outputs) self.nodes[0].generate(1) @@ -137,7 +137,7 @@ class BIP68Test(BitcoinTestFramework): # some of those inputs to be sequence locked (and randomly choose # between height/time locking). Small random chance of making the locks # all pass. - for i in xrange(400): + for i in range(400): # Randomly choose up to 10 inputs num_inputs = random.randint(1, 10) random.shuffle(utxos) @@ -151,7 +151,7 @@ class BIP68Test(BitcoinTestFramework): tx = CTransaction() tx.nVersion = 2 value = 0 - for j in xrange(num_inputs): + for j in range(num_inputs): sequence_value = 0xfffffffe # this disables sequence locks # 50% chance we enable sequence locks @@ -259,7 +259,7 @@ class BIP68Test(BitcoinTestFramework): # Use prioritisetransaction to lower the effective feerate to 0 self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN)) cur_time = int(time.time()) - for i in xrange(10): + for i in range(10): self.nodes[0].setmocktime(cur_time + 600) self.nodes[0].generate(1) cur_time += 600 @@ -324,7 +324,7 @@ class BIP68Test(BitcoinTestFramework): # tx3 to be removed. tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16) height = self.nodes[0].getblockcount() - for i in xrange(2): + for i in range(2): block = create_block(tip, create_coinbase(height), cur_time) block.nVersion = 3 block.rehash() diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index ddca3c2e3..e9b659d50 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -64,7 +63,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): return tx def generate_blocks(self, number, version, test_blocks = []): - for i in xrange(number): + for i in range(number): block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = version block.rehash() @@ -83,7 +82,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): # generate some coins for later self.coinbase_blocks = self.nodes[0].generate(2) self.height = 3 # height of the next block to build - self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = int(time.time()) diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index bba86a50c..c46273084 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * @@ -75,13 +74,13 @@ class BIP66Test(ComparisonTestFramework): self.coinbase_blocks = self.nodes[0].generate(2) height = 3 # height of the next block to build - self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = int(time.time()) ''' 98 more version 2 blocks ''' test_blocks = [] - for i in xrange(98): + for i in range(98): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() @@ -94,7 +93,7 @@ class BIP66Test(ComparisonTestFramework): ''' Mine 749 version 3 blocks ''' test_blocks = [] - for i in xrange(749): + for i in range(749): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() @@ -146,7 +145,7 @@ class BIP66Test(ComparisonTestFramework): ''' Mine 199 new version blocks on last valid tip ''' test_blocks = [] - for i in xrange(199): + for i in range(199): block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index be9121c45..f2d2c14a7 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -32,7 +32,7 @@ class BIP66Test(BitcoinTestFramework): raise AssertionError("Failed to mine 100 version=2 blocks") # Mine 750 new-version blocks - for i in xrange(15): + for i in range(15): self.nodes[2].generate(50) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 850): @@ -49,7 +49,7 @@ class BIP66Test(BitcoinTestFramework): # TODO: check that new DERSIG rules are enforced # Mine 198 new-version blocks - for i in xrange(2): + for i in range(2): self.nodes[2].generate(99) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1049): diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 8f59ee741..c84047b5d 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -51,13 +51,13 @@ class BlockchainTest(BitcoinTestFramework): node = self.nodes[0] res = node.gettxoutsetinfo() - assert_equal(res[u'total_amount'], Decimal('8725.00000000')) - assert_equal(res[u'transactions'], 200) - assert_equal(res[u'height'], 200) - assert_equal(res[u'txouts'], 200) - assert_equal(res[u'bytes_serialized'], 13924), - assert_equal(len(res[u'bestblock']), 64) - assert_equal(len(res[u'hash_serialized']), 64) + assert_equal(res['total_amount'], Decimal('8725.00000000')) + assert_equal(res['transactions'], 200) + assert_equal(res['height'], 200) + assert_equal(res['txouts'], 200) + assert_equal(res['bytes_serialized'], 13924), + assert_equal(len(res['bestblock']), 64) + assert_equal(len(res['hash_serialized']), 64) def _test_getblockheader(self): node = self.nodes[0] diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 578844f2c..0037542e6 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index cb868029f..b25d2ba33 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 20e6ce961..421f3dd87 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 496c7fe8b..74849603f 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,7 +10,7 @@ from test_framework.util import * class RawTransactionsTest(BitcoinTestFramework): def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) + print(("Initializing test directory "+self.options.tmpdir)) initialize_chain_clean(self.options.tmpdir, 4) def setup_network(self, split=False): @@ -25,7 +25,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.sync_all() def run_test(self): - print "Mining blocks..." + print("Mining blocks...") min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] # This test is not meant to test fee estimation and we'd like @@ -198,7 +198,7 @@ class RawTransactionsTest(BitcoinTestFramework): try: self.nodes[2].fundrawtransaction(rawtx, {'foo': 'bar'}) raise AssertionError("Accepted invalid option foo") - except JSONRPCException,e: + except JSONRPCException as e: assert("Unexpected key foo" in e.error['message']) @@ -223,7 +223,7 @@ class RawTransactionsTest(BitcoinTestFramework): try: self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': 'foobar'}) raise AssertionError("Accepted invalid bitcoin address") - except JSONRPCException,e: + except JSONRPCException as e: assert("changeAddress must be a valid bitcoin address" in e.error['message']) diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index e2a839f71..e44334707 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -27,7 +27,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): ''' def run_test(self): - print "Warning: this test will take about 70 seconds in the best case. Be patient." + print("Warning: this test will take about 70 seconds in the best case. Be patient.") self.nodes[0].generate(10) templat = self.nodes[0].getblocktemplate() longpollid = templat['longpollid'] diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index be119031b..1ad2af4c2 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -46,7 +46,7 @@ def genmrklroot(leaflist): cur = n return cur[0] -def template_to_bytes(tmpl, txlist): +def template_to_bytearray(tmpl, txlist): blkver = pack(' MAX_REQUESTS: raise AssertionError("Error, too many blocks (%d) requested" % total_requests) - print "Round %d: success (total requests: %d)" % (count, total_requests) + print("Round %d: success (total requests: %d)" % (count, total_requests)) self.disconnectOkay = True self.connection.disconnect_node() @@ -78,7 +77,7 @@ class MaxBlocksInFlightTest(BitcoinTestFramework): help="Binary to test max block requests behavior") def setup_chain(self): - print "Initializing test directory "+self.options.tmpdir + print("Initializing test directory "+self.options.tmpdir) initialize_chain_clean(self.options.tmpdir, 1) def setup_network(self): diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index be45fecb5..ec802d815 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -101,7 +100,7 @@ class MaxUploadTest(BitcoinTestFramework): def mine_full_block(self, node, address): # Want to create a full block # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit - for j in xrange(14): + for j in range(14): if len(self.utxo) < 14: self.utxo = node.listunspent() inputs=[] @@ -139,7 +138,7 @@ class MaxUploadTest(BitcoinTestFramework): test_nodes = [] connections = [] - for i in xrange(3): + for i in range(3): test_nodes.append(TestNode()) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i])) test_nodes[i].add_connection(connections[i]) @@ -181,7 +180,7 @@ class MaxUploadTest(BitcoinTestFramework): # 144MB will be reserved for relaying new blocks, so expect this to # succeed for ~70 tries. - for i in xrange(success_count): + for i in range(success_count): test_nodes[0].send_message(getdata_request) test_nodes[0].sync_with_ping() assert_equal(test_nodes[0].block_receive_map[big_old_block], i+1) @@ -189,22 +188,22 @@ class MaxUploadTest(BitcoinTestFramework): assert_equal(len(self.nodes[0].getpeerinfo()), 3) # At most a couple more tries should succeed (depending on how long # the test has been running so far). - for i in xrange(3): + for i in range(3): test_nodes[0].send_message(getdata_request) test_nodes[0].wait_for_disconnect() assert_equal(len(self.nodes[0].getpeerinfo()), 2) - print "Peer 0 disconnected after downloading old block too many times" + print("Peer 0 disconnected after downloading old block too many times") # Requesting the current block on test_nodes[1] should succeed indefinitely, # even when over the max upload target. # We'll try 200 times getdata_request.inv = [CInv(2, big_new_block)] - for i in xrange(200): + for i in range(200): test_nodes[1].send_message(getdata_request) test_nodes[1].sync_with_ping() assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1) - print "Peer 1 able to repeatedly download new block" + print("Peer 1 able to repeatedly download new block") # But if test_nodes[1] tries for an old block, it gets disconnected too. getdata_request.inv = [CInv(2, big_old_block)] @@ -212,9 +211,9 @@ class MaxUploadTest(BitcoinTestFramework): test_nodes[1].wait_for_disconnect() assert_equal(len(self.nodes[0].getpeerinfo()), 1) - print "Peer 1 disconnected after trying to download old block" + print("Peer 1 disconnected after trying to download old block") - print "Advancing system time on node to clear counters..." + print("Advancing system time on node to clear counters...") # If we advance the time by 24 hours, then the counters should reset, # and test_nodes[2] should be able to retrieve the old block. @@ -224,12 +223,12 @@ class MaxUploadTest(BitcoinTestFramework): test_nodes[2].sync_with_ping() assert_equal(test_nodes[2].block_receive_map[big_old_block], 1) - print "Peer 2 able to download old block" + print("Peer 2 able to download old block") [c.disconnect_node() for c in connections] #stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1 - print "Restarting nodes with -whitelist=127.0.0.1" + print("Restarting nodes with -whitelist=127.0.0.1") stop_node(self.nodes[0], 0) self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1", "-maxuploadtarget=1", "-blockmaxsize=999000"]) @@ -237,7 +236,7 @@ class MaxUploadTest(BitcoinTestFramework): test_nodes = [] connections = [] - for i in xrange(3): + for i in range(3): test_nodes.append(TestNode()) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i])) test_nodes[i].add_connection(connections[i]) @@ -247,7 +246,7 @@ class MaxUploadTest(BitcoinTestFramework): #retrieve 20 blocks which should be enough to break the 1MB limit getdata_request.inv = [CInv(2, big_new_block)] - for i in xrange(20): + for i in range(20): test_nodes[1].send_message(getdata_request) test_nodes[1].sync_with_ping() assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1) @@ -257,7 +256,7 @@ class MaxUploadTest(BitcoinTestFramework): test_nodes[1].wait_for_disconnect() assert_equal(len(self.nodes[0].getpeerinfo()), 3) #node is still connected because of the whitelist - print "Peer 1 still connected after trying to download old block (whitelisted)" + print("Peer 1 still connected after trying to download old block (whitelisted)") [c.disconnect_node() for c in connections] diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index c19a63c69..bc208709e 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -41,7 +41,7 @@ class MempoolLimitTest(BitcoinTestFramework): relayfee = self.nodes[0].getnetworkinfo()['relayfee'] base_fee = relayfee*100 - for i in xrange (4): + for i in range (4): txids.append([]) txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index bc3f9e051..7ac85c1b6 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -28,7 +28,7 @@ class MempoolPackagesTest(BitcoinTestFramework): send_value = satoshi_round((value - fee)/num_outputs) inputs = [ {'txid' : parent_txid, 'vout' : vout} ] outputs = {} - for i in xrange(num_outputs): + for i in range(num_outputs): outputs[node.getnewaddress()] = send_value rawtx = node.createrawtransaction(inputs, outputs) signedtx = node.signrawtransaction(rawtx) @@ -48,7 +48,7 @@ class MempoolPackagesTest(BitcoinTestFramework): fee = Decimal("0.0001") # MAX_ANCESTORS transactions off a confirmed tx should be fine chain = [] - for i in xrange(MAX_ANCESTORS): + for i in range(MAX_ANCESTORS): (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, 0, value, fee, 1) value = sent_value chain.append(txid) @@ -84,7 +84,7 @@ class MempoolPackagesTest(BitcoinTestFramework): try: self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) except JSONRPCException as e: - print "too-long-ancestor-chain successfully rejected" + print("too-long-ancestor-chain successfully rejected") # Check that prioritising a tx before it's added to the mempool works # First clear the mempool by mining a block. @@ -121,22 +121,22 @@ class MempoolPackagesTest(BitcoinTestFramework): # First create one parent tx with 10 children (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 10) parent_transaction = txid - for i in xrange(10): + for i in range(10): transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) - for i in xrange(MAX_DESCENDANTS): + for i in range(MAX_DESCENDANTS): utxo = transaction_package.pop(0) try: (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) - for j in xrange(10): + for j in range(10): transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) if i == MAX_DESCENDANTS - 2: mempool = self.nodes[0].getrawmempool(True) assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS) except JSONRPCException as e: - print e.error['message'] + print(e.error['message']) assert_equal(i, MAX_DESCENDANTS - 1) - print "tx that would create too large descendant package successfully rejected" + print("tx that would create too large descendant package successfully rejected") # TODO: check that node1's mempool is as expected @@ -171,7 +171,7 @@ class MempoolPackagesTest(BitcoinTestFramework): send_value = satoshi_round((value - fee)/2) inputs = [ {'txid' : txid, 'vout' : vout} ] outputs = {} - for i in xrange(2): + for i in range(2): outputs[self.nodes[0].getnewaddress()] = send_value rawtx = self.nodes[0].createrawtransaction(inputs, outputs) signedtx = self.nodes[0].signrawtransaction(rawtx) @@ -185,7 +185,7 @@ class MempoolPackagesTest(BitcoinTestFramework): # Create tx2-7 vout = 1 txid = tx0_id - for i in xrange(6): + for i in range(6): (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) vout = 0 value = sent_value diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index 5e9856e5d..608e9d0a0 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 0ba46e6f5..b4d9f0a1a 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 507b5ff41..c23f5ef10 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index eb718f39e..9419d9a71 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -32,7 +32,7 @@ class MerkleBlockTest(BitcoinTestFramework): self.sync_all() def run_test(self): - print "Mining blocks..." + print("Mining blocks...") self.nodes[0].generate(105) self.sync_all() diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index afb18cf3d..577d80949 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,16 +9,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import base64 -try: - import http.client as httplib -except ImportError: - import httplib -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +import http.client +import urllib.parse class HTTPBasicsTest (BitcoinTestFramework): def setup_nodes(self): @@ -39,7 +32,7 @@ class HTTPBasicsTest (BitcoinTestFramework): ################################################## # Check correctness of the rpcauth config option # ################################################## - url = urlparse.urlparse(self.nodes[0].url) + url = urllib.parse.urlparse(self.nodes[0].url) #Old authpair authpair = url.username + ':' + url.password @@ -55,7 +48,7 @@ class HTTPBasicsTest (BitcoinTestFramework): headers = {"Authorization": "Basic " + str_to_b64str(authpair)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() @@ -65,7 +58,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Use new authpair to confirm both work headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() @@ -76,7 +69,7 @@ class HTTPBasicsTest (BitcoinTestFramework): authpairnew = "rtwrong:"+password headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() @@ -87,7 +80,7 @@ class HTTPBasicsTest (BitcoinTestFramework): authpairnew = "rt:"+password+"wrong" headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() @@ -98,7 +91,7 @@ class HTTPBasicsTest (BitcoinTestFramework): authpairnew = "rt2:"+password2 headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() @@ -109,7 +102,7 @@ class HTTPBasicsTest (BitcoinTestFramework): authpairnew = "rt2:"+password2+"wrong" headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} - conn = httplib.HTTPConnection(url.hostname, url.port) + conn = http.client.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) resp = conn.getresponse() diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index c6c8c436e..1b6ba021a 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,14 +10,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -try: - import http.client as httplib -except ImportError: - import httplib -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +import http.client +import urllib.parse class NodeHandlingTest (BitcoinTestFramework): def run_test(self): @@ -69,7 +63,7 @@ class NodeHandlingTest (BitcoinTestFramework): ########################### # RPC disconnectnode test # ########################### - url = urlparse.urlparse(self.nodes[1].url) + url = urllib.parse.urlparse(self.nodes[1].url) self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) time.sleep(2) #disconnecting a node needs a little bit of time for node in self.nodes[0].getpeerinfo(): diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index e429fcc5f..21e4c2f46 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -145,13 +144,13 @@ class AcceptBlockTest(BitcoinTestFramework): # 1. Have both nodes mine a block (leave IBD) [ n.generate(1) for n in self.nodes ] - tips = [ int ("0x" + n.getbestblockhash() + "L", 0) for n in self.nodes ] + tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ] # 2. Send one block that builds on each tip. # This should be accepted. blocks_h2 = [] # the height 2 blocks on each node's chain block_time = int(time.time()) + 1 - for i in xrange(2): + for i in range(2): blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2[i].solve() block_time += 1 @@ -161,11 +160,11 @@ class AcceptBlockTest(BitcoinTestFramework): [ x.sync_with_ping() for x in [test_node, white_node] ] assert_equal(self.nodes[0].getblockcount(), 2) assert_equal(self.nodes[1].getblockcount(), 2) - print "First height 2 block accepted by both nodes" + print("First height 2 block accepted by both nodes") # 3. Send another block that builds on the original tip. blocks_h2f = [] # Blocks at height 2 that fork off the main chain - for i in xrange(2): + for i in range(2): blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1)) blocks_h2f[i].solve() test_node.send_message(msg_block(blocks_h2f[0])) @@ -180,11 +179,11 @@ class AcceptBlockTest(BitcoinTestFramework): if x['hash'] == blocks_h2f[1].hash: assert_equal(x['status'], "valid-headers") - print "Second height 2 block accepted only from whitelisted peer" + print("Second height 2 block accepted only from whitelisted peer") # 4. Now send another block that builds on the forking chain. blocks_h3 = [] - for i in xrange(2): + for i in range(2): blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1)) blocks_h3[i].solve() test_node.send_message(msg_block(blocks_h3[0])) @@ -200,13 +199,13 @@ class AcceptBlockTest(BitcoinTestFramework): # But this block should be accepted by node0 since it has more work. try: self.nodes[0].getblock(blocks_h3[0].hash) - print "Unrequested more-work block accepted from non-whitelisted peer" + print("Unrequested more-work block accepted from non-whitelisted peer") except: raise AssertionError("Unrequested more work block was not processed") # Node1 should have accepted and reorged. assert_equal(self.nodes[1].getblockcount(), 3) - print "Successfully reorged to length 3 chain from whitelisted peer" + print("Successfully reorged to length 3 chain from whitelisted peer") # 4b. Now mine 288 more blocks and deliver; all should be processed but # the last (height-too-high) on node0. Node1 should process the tip if @@ -214,8 +213,8 @@ class AcceptBlockTest(BitcoinTestFramework): tips = blocks_h3 headers_message = msg_headers() all_blocks = [] # node0's blocks - for j in xrange(2): - for i in xrange(288): + for j in range(2): + for i in range(288): next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1) next_block.solve() if j==0: @@ -233,7 +232,7 @@ class AcceptBlockTest(BitcoinTestFramework): raise AssertionError("Unrequested block too far-ahead should have been ignored") except: if x == all_blocks[287]: - print "Unrequested block too far-ahead not processed" + print("Unrequested block too far-ahead not processed") else: raise AssertionError("Unrequested block with more work should have been accepted") @@ -243,7 +242,7 @@ class AcceptBlockTest(BitcoinTestFramework): try: white_node.sync_with_ping() self.nodes[1].getblock(tips[1].hash) - print "Unrequested block far ahead of tip accepted from whitelisted peer" + print("Unrequested block far ahead of tip accepted from whitelisted peer") except: raise AssertionError("Unrequested block from whitelisted peer not accepted") @@ -259,7 +258,7 @@ class AcceptBlockTest(BitcoinTestFramework): # a getdata request for this block. test_node.sync_with_ping() assert_equal(self.nodes[0].getblockcount(), 2) - print "Unrequested block that would complete more-work chain was ignored" + print("Unrequested block that would complete more-work chain was ignored") # 6. Try to get node to request the missing block. # Poke the node with an inv for block at height 3 and see if that @@ -275,14 +274,14 @@ class AcceptBlockTest(BitcoinTestFramework): # Check that the getdata includes the right block assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256) - print "Inv at tip triggered getdata for unprocessed block" + print("Inv at tip triggered getdata for unprocessed block") # 7. Send the missing block for the third time (now it is requested) test_node.send_message(msg_block(blocks_h2f[0])) test_node.sync_with_ping() assert_equal(self.nodes[0].getblockcount(), 290) - print "Successfully reorged to longer chain from non-whitelisted peer" + print("Successfully reorged to longer chain from non-whitelisted peer") [ c.disconnect_node() for c in connections ] diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index 281b6ca37..5fb51ed0f 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2016 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -18,7 +18,7 @@ def hashToHex(hash): # Wait up to 60 secs to see if the testnode has received all the expected invs def allInvsMatch(invsExpected, testnode): - for x in xrange(60): + for x in range(60): with mininode_lock: if (sorted(invsExpected) == sorted(testnode.txinvs)): return True; @@ -69,7 +69,7 @@ class FeeFilterTest(BitcoinTestFramework): # Test that invs are received for all txs at feerate of 20 sat/byte node1.settxfee(Decimal("0.00020000")) - txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] assert(allInvsMatch(txids, test_node)) test_node.clear_invs() @@ -77,13 +77,13 @@ class FeeFilterTest(BitcoinTestFramework): test_node.send_filter(15000) # Test that txs are still being received (paying 20 sat/byte) - txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] assert(allInvsMatch(txids, test_node)) test_node.clear_invs() # Change tx fee rate to 10 sat/byte and test they are no longer received node1.settxfee(Decimal("0.00010000")) - [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] sync_mempools(self.nodes) # must be sure node 0 has received all txs time.sleep(10) # wait 10 secs to be sure its doesn't relay any assert(allInvsMatch([], test_node)) @@ -91,7 +91,7 @@ class FeeFilterTest(BitcoinTestFramework): # Remove fee filter and check that txs are received again test_node.send_filter(0) - txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in xrange(3)] + txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] assert(allInvsMatch(txids, test_node)) test_node.clear_invs() diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index ae82d9dca..56df8ffd0 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 061dcbf0e..8c8c2358f 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2016 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -82,7 +81,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): block_time = self.nodes[0].getblockheader(tip)["time"]+1 tip = int(tip, 16) - for i in xrange(numblocks): + for i in range(numblocks): block = create_block(tip, create_coinbase(height+1), block_time) block.nVersion = nVersionToUse block.solve() diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index f8d9063b4..6ab88602b 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,7 +35,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): # Create 3 batches of transactions at 3 different fee rate levels range_size = utxo_count // 3 - for i in xrange(3): + for i in range(3): txids.append([]) start_range = i * range_size end_range = start_range + range_size @@ -46,7 +46,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): # more transactions. mempool = self.nodes[0].getrawmempool(True) sizes = [0, 0, 0] - for i in xrange(3): + for i in range(3): for j in txids[i]: assert(j in mempool) sizes[i] += mempool[j]['size'] @@ -61,7 +61,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.nodes[0].generate(1) mempool = self.nodes[0].getrawmempool() - print "Assert that prioritised transaction was mined" + print("Assert that prioritised transaction was mined") assert(txids[0][0] not in mempool) assert(txids[0][1] in mempool) @@ -93,7 +93,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): # High fee transaction should not have been mined, but other high fee rate # transactions should have been. mempool = self.nodes[0].getrawmempool() - print "Assert that de-prioritised transaction is still in mempool" + print("Assert that de-prioritised transaction is still in mempool") assert(high_fee_tx in mempool) for x in txids[2]: if (x != high_fee_tx): @@ -135,7 +135,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework): # accepted. self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN)) - print "Assert that prioritised free transaction is accepted to mempool" + print("Assert that prioritised free transaction is accepted to mempool") assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id) assert(tx2_id in self.nodes[0].getrawmempool()) diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 91c871ddc..6c7b201d5 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. + import socket from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType @@ -55,7 +56,7 @@ class ProxyTest(BitcoinTestFramework): self.conf3.unauth = True self.conf3.auth = True else: - print "Warning: testing without local IPv6 support" + print("Warning: testing without local IPv6 support") self.serv1 = Socks5Server(self.conf1) self.serv1.start() diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index eccd157e5..92d33bd20 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -57,7 +57,7 @@ class PruneTest(BitcoinTestFramework): sync_blocks(self.nodes[0:2]) self.nodes[0].generate(150) # Then mine enough full blocks to create more than 550MiB of data - for i in xrange(645): + for i in range(645): self.mine_full_block(self.nodes[0], self.address[0]) sync_blocks(self.nodes[0:3]) @@ -65,11 +65,11 @@ class PruneTest(BitcoinTestFramework): def test_height_min(self): if not os.path.isfile(self.prunedir+"blk00000.dat"): raise AssertionError("blk00000.dat is missing, pruning too early") - print "Success" - print "Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir) - print "Mining 25 more blocks should cause the first block file to be pruned" + print("Success") + print("Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir)) + print("Mining 25 more blocks should cause the first block file to be pruned") # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this - for i in xrange(25): + for i in range(25): self.mine_full_block(self.nodes[0],self.address[0]) waitstart = time.time() @@ -78,17 +78,17 @@ class PruneTest(BitcoinTestFramework): if time.time() - waitstart > 10: raise AssertionError("blk00000.dat not pruned when it should be") - print "Success" + print("Success") usage = calc_usage(self.prunedir) - print "Usage should be below target:", usage + print("Usage should be below target:", usage) if (usage > 550): raise AssertionError("Pruning target not being met") def create_chain_with_staleblocks(self): # Create stale blocks in manageable sized chunks - print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds" + print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds") - for j in xrange(12): + for j in range(12): # Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain # Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects # Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine @@ -96,7 +96,7 @@ class PruneTest(BitcoinTestFramework): self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900) # Mine 24 blocks in node 1 self.utxo = self.nodes[1].listunspent() - for i in xrange(24): + for i in range(24): if j == 0: self.mine_full_block(self.nodes[1],self.address[1]) else: @@ -104,7 +104,7 @@ class PruneTest(BitcoinTestFramework): # Reorg back with 25 block chain from node 0 self.utxo = self.nodes[0].listunspent() - for i in xrange(25): + for i in range(25): self.mine_full_block(self.nodes[0],self.address[0]) # Create connections in the order so both nodes can see the reorg at the same time @@ -112,7 +112,7 @@ class PruneTest(BitcoinTestFramework): connect_nodes(self.nodes[2], 0) sync_blocks(self.nodes[0:3]) - print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir) + print("Usage can be over target because of high stale rate:", calc_usage(self.prunedir)) def reorg_test(self): # Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip @@ -123,11 +123,11 @@ class PruneTest(BitcoinTestFramework): self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) height = self.nodes[1].getblockcount() - print "Current block height:", height + print("Current block height:", height) invalidheight = height-287 badhash = self.nodes[1].getblockhash(invalidheight) - print "Invalidating block at height:",invalidheight,badhash + print("Invalidating block at height:",invalidheight,badhash) self.nodes[1].invalidateblock(badhash) # We've now switched to our previously mined-24 block fork on node 1, but thats not what we want @@ -139,29 +139,29 @@ class PruneTest(BitcoinTestFramework): curhash = self.nodes[1].getblockhash(invalidheight - 1) assert(self.nodes[1].getblockcount() == invalidheight - 1) - print "New best height", self.nodes[1].getblockcount() + print("New best height", self.nodes[1].getblockcount()) # Reboot node1 to clear those giant tx's from mempool stop_node(self.nodes[1],1) self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) - print "Generating new longer chain of 300 more blocks" + print("Generating new longer chain of 300 more blocks") self.nodes[1].generate(300) - print "Reconnect nodes" + print("Reconnect nodes") connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[2], 1) sync_blocks(self.nodes[0:3]) - print "Verify height on node 2:",self.nodes[2].getblockcount() - print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir) + print("Verify height on node 2:",self.nodes[2].getblockcount()) + print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) - print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)" + print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects sync_blocks(self.nodes[0:3]) usage = calc_usage(self.prunedir) - print "Usage should be below target:", usage + print("Usage should be below target:", usage) if (usage > 550): raise AssertionError("Pruning target not being met") @@ -173,7 +173,7 @@ class PruneTest(BitcoinTestFramework): self.nodes[2].getblock(self.forkhash) raise AssertionError("Old block wasn't pruned so can't test redownload") except JSONRPCException as e: - print "Will need to redownload block",self.forkheight + print("Will need to redownload block",self.forkheight) # Verify that we have enough history to reorg back to the fork point # Although this is more than 288 blocks, because this chain was written more recently @@ -197,14 +197,14 @@ class PruneTest(BitcoinTestFramework): # At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg if self.nodes[2].getblockcount() < self.mainchainheight: blocks_to_mine = first_reorg_height + 1 - self.mainchainheight - print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine + print("Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine) self.nodes[0].invalidateblock(curchainhash) assert(self.nodes[0].getblockcount() == self.mainchainheight) assert(self.nodes[0].getbestblockhash() == self.mainchainhash2) goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1] goalbestheight = first_reorg_height + 1 - print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload" + print("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload") waitstart = time.time() while self.nodes[2].getblockcount() < goalbestheight: time.sleep(0.1) @@ -217,7 +217,7 @@ class PruneTest(BitcoinTestFramework): def mine_full_block(self, node, address): # Want to create a full block # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit - for j in xrange(14): + for j in range(14): if len(self.utxo) < 14: self.utxo = node.listunspent() inputs=[] @@ -241,8 +241,8 @@ class PruneTest(BitcoinTestFramework): def run_test(self): - print "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)" - print "Mining a big blockchain of 995 blocks" + print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)") + print("Mining a big blockchain of 995 blocks") self.create_big_chain() # Chain diagram key: # * blocks on main chain @@ -253,12 +253,12 @@ class PruneTest(BitcoinTestFramework): # Start by mining a simple chain that all nodes have # N0=N1=N2 **...*(995) - print "Check that we haven't started pruning yet because we're below PruneAfterHeight" + print("Check that we haven't started pruning yet because we're below PruneAfterHeight") self.test_height_min() # Extend this chain past the PruneAfterHeight # N0=N1=N2 **...*(1020) - print "Check that we'll exceed disk space target if we have a very high stale block rate" + print("Check that we'll exceed disk space target if we have a very high stale block rate") self.create_chain_with_staleblocks() # Disconnect N0 # And mine a 24 block chain on N1 and a separate 25 block chain on N0 @@ -282,7 +282,7 @@ class PruneTest(BitcoinTestFramework): self.mainchainheight = self.nodes[2].getblockcount() #1320 self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight) - print "Check that we can survive a 288 block reorg still" + print("Check that we can survive a 288 block reorg still") (self.forkheight,self.forkhash) = self.reorg_test() #(1033, ) # Now create a 288 block reorg by mining a longer chain on N1 # First disconnect N1 @@ -315,7 +315,7 @@ class PruneTest(BitcoinTestFramework): # \ # *...**(1320) - print "Test that we can rerequest a block we previously pruned if needed for a reorg" + print("Test that we can rerequest a block we previously pruned if needed for a reorg") self.reorg_back() # Verify that N2 still has block 1033 on current chain (@), but not on main chain (*) # Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to @@ -335,7 +335,7 @@ class PruneTest(BitcoinTestFramework): # # N1 doesn't change because 1033 on main chain (*) is invalid - print "Done" + print("Done") if __name__ == '__main__': PruneTest().main() diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index e38ef6c8b..7f7b6887a 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 7d8231f5e..a3f97669e 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index 321c2fe42..39564b32b 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,7 +26,7 @@ class ReindexTest(BitcoinTestFramework): wait_bitcoinds() self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"]) assert_equal(self.nodes[0].getblockcount(), 3) - print "Success" + print("Success") if __name__ == '__main__': ReindexTest().main() diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 4c8ef6de2..4afc3981d 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -82,34 +82,34 @@ class ReplaceByFeeTest(BitcoinTestFramework): def run_test(self): make_utxo(self.nodes[0], 1*COIN) - print "Running test simple doublespend..." + print("Running test simple doublespend...") self.test_simple_doublespend() - print "Running test doublespend chain..." + print("Running test doublespend chain...") self.test_doublespend_chain() - print "Running test doublespend tree..." + print("Running test doublespend tree...") self.test_doublespend_tree() - print "Running test replacement feeperkb..." + print("Running test replacement feeperkb...") self.test_replacement_feeperkb() - print "Running test spends of conflicting outputs..." + print("Running test spends of conflicting outputs...") self.test_spends_of_conflicting_outputs() - print "Running test new unconfirmed inputs..." + print("Running test new unconfirmed inputs...") self.test_new_unconfirmed_inputs() - print "Running test too many replacements..." + print("Running test too many replacements...") self.test_too_many_replacements() - print "Running test opt-in..." + print("Running test opt-in...") self.test_opt_in() - print "Running test prioritised transactions..." + print("Running test prioritised transactions...") self.test_prioritised_transactions() - print "Passed\n" + print("Passed\n") def test_simple_doublespend(self): """Simple doublespend""" @@ -459,7 +459,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): except JSONRPCException as exp: assert_equal(exp.error['code'], -26) else: - print tx1b_txid + print(tx1b_txid) assert(False) tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN)) diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index 359f9239f..ec9515528 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,16 +13,9 @@ from test_framework.util import * from struct import * from io import BytesIO from codecs import encode -import binascii -try: - import http.client as httplib -except ImportError: - import httplib -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +import http.client +import urllib.parse def deser_uint256(f): r = 0 @@ -33,7 +26,7 @@ def deser_uint256(f): #allows simple http get calls def http_get_call(host, port, path, response_object = 0): - conn = httplib.HTTPConnection(host, port) + conn = http.client.HTTPConnection(host, port) conn.request('GET', path) if response_object: @@ -43,7 +36,7 @@ def http_get_call(host, port, path, response_object = 0): #allows simple http post calls with a request body def http_post_call(host, port, path, requestdata = '', response_object = 0): - conn = httplib.HTTPConnection(host, port) + conn = http.client.HTTPConnection(host, port) conn.request('POST', path, requestdata) if response_object: @@ -67,8 +60,8 @@ class RESTTest (BitcoinTestFramework): self.sync_all() def run_test(self): - url = urlparse.urlparse(self.nodes[0].url) - print "Mining blocks..." + url = urllib.parse.urlparse(self.nodes[0].url) + print("Mining blocks...") self.nodes[0].generate(1) self.sync_all() @@ -151,7 +144,7 @@ class RESTTest (BitcoinTestFramework): output.write(bin_response) output.seek(0) chainHeight = unpack("i", output.read(4))[0] - hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(65).rstrip("L") + hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(64) assert_equal(bb_hash, hashFromBinResponse) #check if getutxo's chaintip during calculation was fine assert_equal(chainHeight, 102) #chain height must be 102 diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 10a48b555..7b7c01f99 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -51,7 +51,7 @@ def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport): def run_test(tmpdir): - assert(sys.platform == 'linux2') # due to OS-specific network stats queries, this test works only on Linux + assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux # find the first non-loopback interface for testing non_loopback_ip = None for name,ip in all_interfaces(): diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 2bc32584b..96d1da729 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework @@ -266,8 +265,8 @@ class SendHeadersTest(BitcoinTestFramework): # PART 1 # 1. Mine a block; expect inv announcements each time - print "Part 1: headers don't start before sendheaders message..." - for i in xrange(4): + print("Part 1: headers don't start before sendheaders message...") + for i in range(4): old_tip = tip tip = self.mine_blocks(1) assert_equal(inv_node.check_last_announcement(inv=[tip]), True) @@ -297,14 +296,14 @@ class SendHeadersTest(BitcoinTestFramework): inv_node.clear_last_announcement() test_node.clear_last_announcement() - print "Part 1: success!" - print "Part 2: announce blocks with headers after sendheaders message..." + print("Part 1: success!") + print("Part 2: announce blocks with headers after sendheaders message...") # PART 2 # 2. Send a sendheaders message and test that headers announcements # commence and keep working. test_node.send_message(msg_sendheaders()) prev_tip = int(self.nodes[0].getbestblockhash(), 16) - test_node.get_headers(locator=[prev_tip], hashstop=0L) + test_node.get_headers(locator=[prev_tip], hashstop=0) test_node.sync_with_ping() # Now that we've synced headers, headers announcements should work @@ -314,14 +313,14 @@ class SendHeadersTest(BitcoinTestFramework): height = self.nodes[0].getblockcount()+1 block_time += 10 # Advance far enough ahead - for i in xrange(10): + for i in range(10): # Mine i blocks, and alternate announcing either via # inv (of tip) or via headers. After each, new blocks # mined by the node should successfully be announced # with block header, even though the blocks are never requested - for j in xrange(2): + for j in range(2): blocks = [] - for b in xrange(i+1): + for b in range(i+1): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 @@ -360,13 +359,13 @@ class SendHeadersTest(BitcoinTestFramework): height += 1 block_time += 1 - print "Part 2: success!" + print("Part 2: success!") - print "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer..." + print("Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer...") # PART 3. Headers announcements can stop after large reorg, and resume after # getheaders or inv from peer. - for j in xrange(2): + for j in range(2): # First try mining a reorg that can propagate with header announcement new_block_hashes = self.mine_reorg(length=7) tip = new_block_hashes[-1] @@ -392,7 +391,7 @@ class SendHeadersTest(BitcoinTestFramework): test_node.get_data(new_block_hashes) test_node.wait_for_block(new_block_hashes[-1]) - for i in xrange(3): + for i in range(3): # Mine another block, still should get only an inv tip = self.mine_blocks(1) assert_equal(inv_node.check_last_announcement(inv=[tip]), True) @@ -414,7 +413,7 @@ class SendHeadersTest(BitcoinTestFramework): # of headers announcements, or mine a new block and inv it, also # triggering resumption of headers announcements. if j == 0: - test_node.get_headers(locator=[tip], hashstop=0L) + test_node.get_headers(locator=[tip], hashstop=0) test_node.sync_with_ping() else: test_node.send_block_inv(tip) @@ -424,9 +423,9 @@ class SendHeadersTest(BitcoinTestFramework): assert_equal(inv_node.check_last_announcement(inv=[tip]), True) assert_equal(test_node.check_last_announcement(headers=[tip]), True) - print "Part 3: success!" + print("Part 3: success!") - print "Part 4: Testing direct fetch behavior..." + print("Part 4: Testing direct fetch behavior...") tip = self.mine_blocks(1) height = self.nodes[0].getblockcount() + 1 last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time'] @@ -434,7 +433,7 @@ class SendHeadersTest(BitcoinTestFramework): # Create 2 blocks. Send the blocks, then send the headers. blocks = [] - for b in xrange(2): + for b in range(2): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 @@ -452,7 +451,7 @@ class SendHeadersTest(BitcoinTestFramework): # This time, direct fetch should work blocks = [] - for b in xrange(3): + for b in range(3): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 @@ -473,7 +472,7 @@ class SendHeadersTest(BitcoinTestFramework): blocks = [] # Create extra blocks for later - for b in xrange(20): + for b in range(20): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 @@ -507,7 +506,7 @@ class SendHeadersTest(BitcoinTestFramework): with mininode_lock: assert_equal(test_node.last_getdata, None) - print "Part 4: success!" + print("Part 4: success!") # Finally, check that the inv node never received a getdata request, # throughout the test diff --git a/qa/rpc-tests/signmessages.py b/qa/rpc-tests/signmessages.py index ff22f3530..4a47c0ca1 100755 --- a/qa/rpc-tests/signmessages.py +++ b/qa/rpc-tests/signmessages.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py index d51d6ee61..a06ac5319 100755 --- a/qa/rpc-tests/signrawtransactions.py +++ b/qa/rpc-tests/signrawtransactions.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 7239e5a0d..8fcb99c1b 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -238,7 +238,7 @@ class EstimateFeeTest(BitcoinTestFramework): self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting print("Will output estimates for 1/2/3/6/15/25 blocks") - for i in xrange(2): + for i in range(2): print("Creating transactions and mining them with a block size that can't keep up") # Create transactions and mine 10 small blocks with node 2, but create txs faster than we can mine self.transact_and_mine(10, self.nodes[2]) diff --git a/qa/rpc-tests/test_framework/bignum.py b/qa/rpc-tests/test_framework/bignum.py index b0c58ccd4..ef800e4d5 100644 --- a/qa/rpc-tests/test_framework/bignum.py +++ b/qa/rpc-tests/test_framework/bignum.py @@ -1,16 +1,15 @@ -# +#!/usr/bin/env python3 # # bignum.py # # This file is copied from python-bitcoinlib. # -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # """Bignum routines""" -from __future__ import absolute_import, division, print_function, unicode_literals import struct diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 73d9ffbb2..4bc279032 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -1,16 +1,17 @@ +#!/usr/bin/env python3 # BlockStore: a helper class that keeps a map of blocks and implements # helper functions for responding to getheaders and getdata, # and for constructing a getheaders message # from .mininode import * -import dbm from io import BytesIO +import dbm.ndbm class BlockStore(object): def __init__(self, datadir): - self.blockDB = dbm.open(datadir + "/blocks", 'c') - self.currentBlock = 0L + self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') + self.currentBlock = 0 self.headers_map = dict() def close(self): @@ -67,7 +68,7 @@ class BlockStore(object): try: self.blockDB[repr(block.sha256)] = bytes(block.serialize()) except TypeError as e: - print "Unexpected error: ", sys.exc_info()[0], e.args + print("Unexpected error: ", sys.exc_info()[0], e.args) self.currentBlock = block.sha256 self.headers_map[block.sha256] = CBlockHeader(block) @@ -105,7 +106,7 @@ class BlockStore(object): class TxStore(object): def __init__(self, datadir): - self.txDB = dbm.open(datadir + "/transactions", 'c') + self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') def close(self): self.txDB.close() @@ -127,7 +128,7 @@ class TxStore(object): try: self.txDB[repr(tx.sha256)] = bytes(tx.serialize()) except TypeError as e: - print "Unexpected error: ", sys.exc_info()[0], e.args + print("Unexpected error: ", sys.exc_info()[0], e.args) def get_transactions(self, inv): responses = [] diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 384f40e62..44232153a 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -1,8 +1,8 @@ +#!/usr/bin/env python3 # blocktools.py - utilities for manipulating blocks and transactions -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from .mininode import * from .script import CScript, OP_TRUE, OP_CHECKSIG diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 17626cf8d..7c92d3f82 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# from .mininode import * from .blockstore import BlockStore, TxStore @@ -259,10 +258,10 @@ class TestManager(object): if c.cb.bestblockhash == blockhash: return False if blockhash not in c.cb.block_reject_map: - print 'Block not in reject map: %064x' % (blockhash) + print('Block not in reject map: %064x' % (blockhash)) return False if not outcome.match(c.cb.block_reject_map[blockhash]): - print 'Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash) + print('Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash)) return False elif ((c.cb.bestblockhash == blockhash) != outcome): # print c.cb.bestblockhash, blockhash, outcome @@ -287,10 +286,10 @@ class TestManager(object): if txhash in c.cb.lastInv: return False if txhash not in c.cb.tx_reject_map: - print 'Tx not in reject map: %064x' % (txhash) + print('Tx not in reject map: %064x' % (txhash)) return False if not outcome.match(c.cb.tx_reject_map[txhash]): - print 'Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash) + print('Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash)) return False elif ((txhash in c.cb.lastInv) != outcome): # print c.rpc.getrawmempool(), c.cb.lastInv @@ -393,7 +392,7 @@ class TestManager(object): if (not self.check_mempool(tx.sha256, tx_outcome)): raise AssertionError("Mempool test failed at test %d" % test_number) - print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ] + print("Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]) test_number += 1 [ c.disconnect_node() for c in self.connections ] diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index d21a001b6..23fce6101 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# """ This module contains utilities for doing coverage analysis on the RPC diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 30aecfd44..1617daa20 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1,7 +1,12 @@ -# mininode.py - Bitcoin P2P network half-a-node -# -# Distributed under the MIT/X11 software license, see the accompanying +#!/usr/bin/env python3 +# Copyright (c) 2010 ArtForz -- public domain half-a-node +# Copyright (c) 2012 Jeff Garzik +# Copyright (c) 2010-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# mininode.py - Bitcoin P2P network half-a-node # # This python code was modified from ArtForz' public domain half-a-node, as # found in the mini-node branch of http://github.com/jgarzik/pynode. @@ -34,12 +39,12 @@ import copy BIP0031_VERSION = 60000 MY_VERSION = 60001 # past bip-31 for ping/pong -MY_SUBVERSION = b"/python-mininode-tester:0.0.2/" +MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" MAX_INV_SZ = 50000 MAX_BLOCK_SIZE = 1000000 -COIN = 100000000L # 1 btc in satoshis +COIN = 100000000 # 1 btc in satoshis # Keep our own socket map for asyncore, so that we can track disconnects # ourselves (to workaround an issue with closing an asyncore socket when @@ -73,20 +78,18 @@ def deser_string(f): nit = struct.unpack(">= 32 return rs def uint256_from_str(s): - r = 0L + r = 0 t = struct.unpack("> 24) & 0xFF - v = (c & 0xFFFFFFL) << (8 * (nbytes - 3)) + v = (c & 0xFFFFFF) << (8 * (nbytes - 3)) return v @@ -123,7 +126,7 @@ def deser_vector(f, c): elif nit == 255: nit = struct.unpack(" 1: newhashes = [] - for i in xrange(0, len(hashes), 2): + for i in range(0, len(hashes), 2): i2 = min(i+1, len(hashes)-1) newhashes.append(hash256(hashes[i] + hashes[i2])) hashes = newhashes @@ -781,7 +784,7 @@ class msg_getblocks(object): def __init__(self): self.locator = CBlockLocator() - self.hashstop = 0L + self.hashstop = 0 def deserialize(self, f): self.locator = CBlockLocator() @@ -869,7 +872,7 @@ class msg_ping_prebip31(object): class msg_ping(object): command = b"ping" - def __init__(self, nonce=0L): + def __init__(self, nonce=0): self.nonce = nonce def deserialize(self, f): @@ -941,7 +944,7 @@ class msg_getheaders(object): def __init__(self): self.locator = CBlockLocator() - self.hashstop = 0L + self.hashstop = 0 def deserialize(self, f): self.locator = CBlockLocator() @@ -989,7 +992,7 @@ class msg_reject(object): self.message = b"" self.code = 0 self.reason = b"" - self.data = 0L + self.data = 0 def deserialize(self, f): self.message = deser_string(f) @@ -1030,7 +1033,7 @@ def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): class msg_feefilter(object): command = b"feefilter" - def __init__(self, feerate=0L): + def __init__(self, feerate=0): self.feerate = feerate def deserialize(self, f): @@ -1079,10 +1082,10 @@ class NodeConnCB(object): time.sleep(deliver_sleep) with mininode_lock: try: - getattr(self, 'on_' + message.command)(conn, message) + getattr(self, 'on_' + message.command.decode('ascii'))(conn, message) except: - print "ERROR delivering %s (%s)" % (repr(message), - sys.exc_info()[0]) + print("ERROR delivering %s (%s)" % (repr(message), + sys.exc_info()[0])) def on_version(self, conn, message): if message.nVersion >= 209: @@ -1200,8 +1203,8 @@ class NodeConn(asyncore.dispatcher): vt.addrFrom.ip = "0.0.0.0" vt.addrFrom.port = 0 self.send_message(vt, True) - print 'MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ - + str(dstport) + print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ + + str(dstport)) try: self.connect((dstaddr, dstport)) @@ -1294,7 +1297,9 @@ class NodeConn(asyncore.dispatcher): self.show_debug_msg("Unknown command: '" + command + "' " + repr(msg)) except Exception as e: - print 'got_data:', repr(e) + print('got_data:', repr(e)) + # import traceback + # traceback.print_tb(sys.exc_info()[2]) def send_message(self, message, pushbuf=False): if self.state != "connected" and not pushbuf: diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index 52a7ab748..573b06772 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 5fb5758f8..44a894fc8 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -1,18 +1,19 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + # # script.py # # This file is modified from python-bitcoinlib. # -# Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# """Scripts Functionality to build scripts, as well as SignatureHash(). """ -from __future__ import absolute_import, division, print_function, unicode_literals from .mininode import CTransaction, CTxOut, hash256 from binascii import hexlify @@ -658,7 +659,7 @@ class CScript(bytes): other = bchr(CScriptOp(OP_0)) else: other = CScriptNum.encode(other) - elif isinstance(other, (int, long)): + elif isinstance(other, int): if 0 <= other <= 16: other = bytes(bchr(CScriptOp.encode_op_n(other))) elif other == -1: diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py index f725d9770..372f5ed60 100644 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/qa/rpc-tests/test_framework/socks5.py @@ -1,11 +1,12 @@ -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Dummy Socks5 server for testing. ''' -from __future__ import print_function, division, unicode_literals -import socket, threading, Queue + +import socket, threading, queue import traceback, sys ### Protocol constants @@ -132,7 +133,7 @@ class Socks5Server(object): self.s.listen(5) self.running = False self.thread = None - self.queue = Queue.Queue() # report connections and exceptions to client + self.queue = queue.Queue() # report connections and exceptions to client def run(self): while self.running: diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 18ecf64b0..ed12e1efb 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -140,7 +140,7 @@ class BitcoinTestFramework(object): print("JSONRPC error: "+e.error['message']) traceback.print_tb(sys.exc_info()[2]) except AssertionError as e: - print("Assertion failed: "+ str(e)) + print("Assertion failed: " + str(e)) traceback.print_tb(sys.exc_info()[2]) except KeyError as e: print("key not found: "+ str(e)) @@ -189,7 +189,7 @@ class ComparisonTestFramework(BitcoinTestFramework): help="bitcoind binary to use for reference nodes (if any)") def setup_chain(self): - print "Initializing test directory "+self.options.tmpdir + print("Initializing test directory "+self.options.tmpdir) initialize_chain_clean(self.options.tmpdir, self.num_nodes) def setup_network(self): diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index baa1ed679..ea3931cef 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,4 +1,5 @@ -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -191,10 +192,10 @@ def initialize_chain(test_dir): args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: bitcoind started, waiting for RPC to come up" + print("initialize_chain: bitcoind started, waiting for RPC to come up") wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: RPC succesfully started" + print("initialize_chain: RPC succesfully started") rpcs = [] for i in range(4): @@ -275,11 +276,11 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: bitcoind started, waiting for RPC to come up" + print("start_node: bitcoind started, waiting for RPC to come up") url = rpc_url(i, rpchost) wait_for_bitcoind_start(bitcoind_processes[i], url, i) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: RPC succesfully started" + print("start_node: RPC succesfully started") proxy = get_rpc_proxy(url, i, timeout=timewait) if COVERAGE_DIR: @@ -469,7 +470,7 @@ def assert_is_hex_string(string): "Couldn't interpret %r as hexadecimal; raised: %s" % (string, e)) def assert_is_hash_string(string, length=64): - if not isinstance(string, basestring): + if not isinstance(string, str): raise AssertionError("Expected a string, got type %r" % type(string)) elif length and len(string) != length: raise AssertionError( @@ -520,7 +521,7 @@ def create_confirmed_utxos(fee, node, count): addr2 = node.getnewaddress() if iterations <= 0: return utxos - for i in xrange(iterations): + for i in range(iterations): t = utxos.pop() inputs = [] inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) @@ -546,11 +547,11 @@ def gen_return_txouts(): # So we have big transactions (and therefore can't fit very many into each block) # create one script_pubkey script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): + for i in range (512): script_pubkey = script_pubkey + "01" # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change txouts = "81" - for k in xrange(128): + for k in range(128): # add txout value txouts = txouts + "0000000000000000" # add length of script_pubkey @@ -572,7 +573,7 @@ def create_tx(node, coinbase, to_address, amount): def create_lots_of_big_transactions(node, txouts, utxos, fee): addr = node.getnewaddress() txids = [] - for i in xrange(len(utxos)): + for i in range(len(utxos)): t = utxos.pop() inputs = [] inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index b132aec4b..5710c29aa 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 8d7f6e505..1fbb207e2 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 555f83648..42ce0a726 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -38,7 +38,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(len(self.nodes[1].listunspent()), 0) assert_equal(len(self.nodes[2].listunspent()), 0) - print "Mining blocks..." + print("Mining blocks...") self.nodes[0].generate(1) @@ -321,7 +321,7 @@ class WalletTest (BitcoinTestFramework): '-salvagewallet', ] for m in maintenance: - print "check " + m + print("check " + m) stop_nodes(self.nodes) wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 1221a0911..418f3103e 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 1ba4ded24..2f8214f87 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014-2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,7 +22,7 @@ class ZapWalletTXesTest (BitcoinTestFramework): self.sync_all() def run_test (self): - print "Mining blocks..." + print("Mining blocks...") self.nodes[0].generate(1) self.sync_all() self.nodes[1].generate(101) diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index 97850bea3..f5617a084 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,17 +10,10 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import zmq -import binascii import struct -try: - import http.client as httplib -except ImportError: - import httplib -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +import http.client +import urllib.parse class ZMQTest (BitcoinTestFramework): @@ -45,7 +38,7 @@ class ZMQTest (BitcoinTestFramework): genhashes = self.nodes[0].generate(1) self.sync_all() - print "listen..." + print("listen...") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") From 52cbce287a0d9b3184fd3aee9d4f1186fd2dd7da Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 15 Apr 2016 19:53:45 -0400 Subject: [PATCH 0567/1223] net: don't import std namespace This file is about to be broken up into chunks and moved around. Drop the namespace now rather than requiring other files to use it. --- src/net.cpp | 63 ++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 6642ef651..8ae31e715 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -56,7 +56,6 @@ #endif #endif -using namespace std; namespace { const int MAX_OUTBOUND_CONNECTIONS = 8; @@ -78,7 +77,7 @@ bool fDiscover = true; bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; CCriticalSection cs_mapLocalHost; -map mapLocalHost; +std::map mapLocalHost; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; @@ -88,20 +87,20 @@ int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; bool fAddressesInitialized = false; std::string strSubVersion; -vector vNodes; +std::vector vNodes; CCriticalSection cs_vNodes; -map mapRelay; -deque > vRelayExpiration; +std::map mapRelay; +std::deque > vRelayExpiration; CCriticalSection cs_mapRelay; limitedmap mapAlreadyAskedFor(MAX_INV_SZ); -static deque vOneShots; +static std::deque vOneShots; CCriticalSection cs_vOneShots; -set setservAddNodeAddresses; +std::set setservAddNodeAddresses; CCriticalSection cs_setservAddNodeAddresses; -vector vAddedNodes; +std::vector vAddedNodes; CCriticalSection cs_vAddedNodes; NodeId nLastNodeId = 0; @@ -135,7 +134,7 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) int nBestReachability = -1; { LOCK(cs_mapLocalHost); - for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) + for (std::map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) { int nScore = (*it).second.nScore; int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); @@ -796,7 +795,7 @@ void SocketSendData(CNode *pnode) pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it); } -static list vNodesDisconnected; +static std::list vNodesDisconnected; class CNodeRef { public: @@ -1045,7 +1044,7 @@ void ThreadSocketHandler() { LOCK(cs_vNodes); // Disconnect unused nodes - vector vNodesCopy = vNodes; + std::vector vNodesCopy = vNodes; BOOST_FOREACH(CNode* pnode, vNodesCopy) { if (pnode->fDisconnect || @@ -1069,7 +1068,7 @@ void ThreadSocketHandler() } { // Delete disconnected nodes - list vNodesDisconnectedCopy = vNodesDisconnected; + std::list vNodesDisconnectedCopy = vNodesDisconnected; BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) { // wait until threads are done using it @@ -1120,7 +1119,7 @@ void ThreadSocketHandler() BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) { FD_SET(hListenSocket.socket, &fdsetRecv); - hSocketMax = max(hSocketMax, hListenSocket.socket); + hSocketMax = std::max(hSocketMax, hListenSocket.socket); have_fds = true; } @@ -1131,7 +1130,7 @@ void ThreadSocketHandler() if (pnode->hSocket == INVALID_SOCKET) continue; FD_SET(pnode->hSocket, &fdsetError); - hSocketMax = max(hSocketMax, pnode->hSocket); + hSocketMax = std::max(hSocketMax, pnode->hSocket); have_fds = true; // Implement the following logic: @@ -1198,7 +1197,7 @@ void ThreadSocketHandler() // // Service each socket // - vector vNodesCopy; + std::vector vNodesCopy; { LOCK(cs_vNodes); vNodesCopy = vNodes; @@ -1355,7 +1354,7 @@ void ThreadMapPort() } } - string strDesc = "Bitcoin " + FormatFullVersion(); + std::string strDesc = "Bitcoin " + FormatFullVersion(); try { while (true) { @@ -1441,7 +1440,7 @@ void ThreadDNSAddressSeed() } } - const vector &vSeeds = Params().DNSSeeds(); + const std::vector &vSeeds = Params().DNSSeeds(); int found = 0; LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); @@ -1450,8 +1449,8 @@ void ThreadDNSAddressSeed() if (HaveNameProxy()) { AddOneShot(seed.host); } else { - vector vIPs; - vector vAdd; + std::vector vIPs; + std::vector vAdd; if (LookupHost(seed.host.c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) @@ -1508,7 +1507,7 @@ void DumpData() void static ProcessOneShot() { - string strDest; + std::string strDest; { LOCK(cs_vOneShots); if (vOneShots.empty()) @@ -1574,7 +1573,7 @@ void ThreadOpenConnections() // Only connect out to one peer per network group (/16 for IPv4). // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. int nOutbound = 0; - set > setConnected; + std::set > setConnected; { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { @@ -1632,7 +1631,7 @@ void ThreadOpenAddedConnections() if (HaveNameProxy()) { while(true) { - list lAddresses(0); + std::list lAddresses(0); { LOCK(cs_vAddedNodes); BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) @@ -1650,16 +1649,16 @@ void ThreadOpenAddedConnections() for (unsigned int i = 0; true; i++) { - list lAddresses(0); + std::list lAddresses(0); { LOCK(cs_vAddedNodes); BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) lAddresses.push_back(strAddNode); } - list > lservAddressesToAdd(0); + std::list > lservAddressesToAdd(0); BOOST_FOREACH(const std::string& strAddNode, lAddresses) { - vector vservNode(0); + std::vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) { lservAddressesToAdd.push_back(vservNode); @@ -1675,7 +1674,7 @@ void ThreadOpenAddedConnections() { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - for (list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) + for (std::list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) BOOST_FOREACH(const CService& addrNode, *(it)) if (pnode->addr == addrNode) { @@ -1684,7 +1683,7 @@ void ThreadOpenAddedConnections() break; } } - BOOST_FOREACH(vector& vserv, lservAddressesToAdd) + BOOST_FOREACH(std::vector& vserv, lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); @@ -1732,7 +1731,7 @@ void ThreadMessageHandler() SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); while (true) { - vector vNodesCopy; + std::vector vNodesCopy; { LOCK(cs_vNodes); vNodesCopy = vNodes; @@ -1792,7 +1791,7 @@ void ThreadMessageHandler() -bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted) +bool BindListenPort(const CService &addrBind, std::string& strError, bool fWhitelisted) { strError = ""; int nOne = 1; @@ -1900,7 +1899,7 @@ void static Discover(boost::thread_group& threadGroup) char pszHostName[256] = ""; if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { - vector vaddr; + std::vector vaddr; if (LookupHost(pszHostName, vaddr, 0, true)) { BOOST_FOREACH (const CNetAddr &addr, vaddr) @@ -2300,7 +2299,7 @@ bool CAddrDB::Read(CAddrMan& addr) // Don't try to resize to a negative number if file is small if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256); - vector vchData; + std::vector vchData; vchData.resize(dataSize); uint256 hashIn; @@ -2580,7 +2579,7 @@ bool CBanDB::Read(banmap_t& banSet) // Don't try to resize to a negative number if file is small if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256); - vector vchData; + std::vector vchData; vchData.resize(dataSize); uint256 hashIn; From 9faa4902cd32af9742b7ffcc163725bff226da1f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 15 Apr 2016 20:01:40 -0400 Subject: [PATCH 0568/1223] net: remove unused set --- src/net.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 8ae31e715..771d9e862 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -97,9 +97,6 @@ limitedmap mapAlreadyAskedFor(MAX_INV_SZ); static std::deque vOneShots; CCriticalSection cs_vOneShots; -std::set setservAddNodeAddresses; -CCriticalSection cs_setservAddNodeAddresses; - std::vector vAddedNodes; CCriticalSection cs_vAddedNodes; @@ -1660,14 +1657,7 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(const std::string& strAddNode, lAddresses) { std::vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) - { lservAddressesToAdd.push_back(vservNode); - { - LOCK(cs_setservAddNodeAddresses); - BOOST_FOREACH(const CService& serv, vservNode) - setservAddNodeAddresses.insert(serv); - } - } } // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry // (keeping in mind that addnode entries can have many IPs if fNameLookup) From 563f375cdeae3e67a57d8a7187362a4706c33748 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 15 Apr 2016 20:03:18 -0400 Subject: [PATCH 0569/1223] net: use the exposed GetNodeSignals() rather than g_signals directly --- src/net.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 771d9e862..d6034953c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -439,7 +439,7 @@ void CNode::CloseSocketDisconnect() void CNode::PushVersion() { - int nBestHeight = g_signals.GetHeight().get_value_or(0); + int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0); int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); @@ -1742,7 +1742,7 @@ void ThreadMessageHandler() TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); if (lockRecv) { - if (!g_signals.ProcessMessages(pnode)) + if (!GetNodeSignals().ProcessMessages(pnode)) pnode->CloseSocketDisconnect(); if (pnode->nSendSize < SendBufferSize()) @@ -1760,7 +1760,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode); + GetNodeSignals().SendMessages(pnode); } boost::this_thread::interruption_point(); } From cca221fd211f63b338bd90afc505bd4a22a01d5d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 18 Apr 2016 15:58:19 -0400 Subject: [PATCH 0570/1223] net: Drop CNodeRef for AttemptToEvictConnection Locking for each operation here is unnecessary, and solves the wrong problem. Additionally, it introduces a problem when cs_vNodes is held in an owning class, to which invididual CNodeRefs won't have access. These should be weak pointers anyway, once vNodes contain shared pointers. Rather than using a refcounting class, use a 3-step process instead. 1. Lock vNodes long enough to snapshot the fields necessary for comparing 2. Unlock and do the comparison 3. Re-lock and mark the resulting node for disconnection if it still exists --- src/net.cpp | 84 ++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index d6034953c..41e657fba 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -794,51 +794,22 @@ void SocketSendData(CNode *pnode) static std::list vNodesDisconnected; -class CNodeRef { -public: - CNodeRef(CNode *pnode) : _pnode(pnode) { - LOCK(cs_vNodes); - _pnode->AddRef(); - } - - ~CNodeRef() { - LOCK(cs_vNodes); - _pnode->Release(); - } - - CNode& operator *() const {return *_pnode;}; - CNode* operator ->() const {return _pnode;}; - - CNodeRef& operator =(const CNodeRef& other) - { - if (this != &other) { - LOCK(cs_vNodes); - - _pnode->Release(); - _pnode = other._pnode; - _pnode->AddRef(); - } - return *this; - } - - CNodeRef(const CNodeRef& other): - _pnode(other._pnode) - { - LOCK(cs_vNodes); - _pnode->AddRef(); - } -private: - CNode *_pnode; +struct NodeEvictionCandidate +{ + NodeId id; + int64_t nTimeConnected; + int64_t nMinPingUsecTime; + CAddress addr; }; -static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b) +static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { - return a->nMinPingUsecTime > b->nMinPingUsecTime; + return a.nMinPingUsecTime > b.nMinPingUsecTime; } -static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b) +static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { - return a->nTimeConnected > b->nTimeConnected; + return a.nTimeConnected > b.nTimeConnected; } class CompareNetGroupKeyed @@ -851,14 +822,14 @@ public: GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); } - bool operator()(const CNodeRef &a, const CNodeRef &b) + bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { std::vector vchGroupA, vchGroupB; CSHA256 hashA, hashB; std::vector vchA(32), vchB(32); - vchGroupA = a->addr.GetGroup(); - vchGroupB = b->addr.GetGroup(); + vchGroupA = a.addr.GetGroup(); + vchGroupB = b.addr.GetGroup(); hashA.Write(begin_ptr(vchGroupA), vchGroupA.size()); hashB.Write(begin_ptr(vchGroupB), vchGroupB.size()); @@ -882,7 +853,7 @@ public: * simultaneously better at all of them than honest peers. */ static bool AttemptToEvictConnection(bool fPreferNewConnection) { - std::vector vEvictionCandidates; + std::vector vEvictionCandidates; { LOCK(cs_vNodes); @@ -893,7 +864,8 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - vEvictionCandidates.push_back(CNodeRef(node)); + NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr}; + vEvictionCandidates.push_back(candidate); } } @@ -928,16 +900,16 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { std::vector naMostConnections; unsigned int nMostConnections = 0; int64_t nMostConnectionsTime = 0; - std::map, std::vector > mapAddrCounts; - BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { - mapAddrCounts[node->addr.GetGroup()].push_back(node); - int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected; - size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size(); + std::map, std::vector > mapAddrCounts; + BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) { + mapAddrCounts[node.addr.GetGroup()].push_back(node); + int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected; + size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size(); if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { nMostConnections = groupsize; nMostConnectionsTime = grouptime; - naMostConnections = node->addr.GetGroup(); + naMostConnections = node.addr.GetGroup(); } } @@ -952,9 +924,15 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { return false; // Disconnect from the network group with the most connections - vEvictionCandidates[0]->fDisconnect = true; - - return true; + NodeId evicted = vEvictionCandidates.front().id; + LOCK(cs_vNodes); + for(std::vector::const_iterator it(vNodes.begin()); it != vNodes.end(); ++it) { + if ((*it)->GetId() == evicted) { + (*it)->fDisconnect = true; + return true; + } + } + return false; } static void AcceptConnection(const ListenSocket& hListenSocket) { From e53e7c54736b98098553ba1a5191e093684f9114 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Thu, 5 May 2016 11:55:46 -0700 Subject: [PATCH 0571/1223] don't run ThreadMessageHandler at lowered priority There's no clear reason ThreadMessageHandler should be low priority. Fixes #8010 (priority inversion). --- src/compat.h | 11 ----------- src/net.cpp | 1 - src/util.cpp | 13 ------------- src/util.h | 1 - 4 files changed, 26 deletions(-) diff --git a/src/compat.h b/src/compat.h index 1225ea18e..79a297e5e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -78,17 +78,6 @@ typedef u_int SOCKET; #define MSG_NOSIGNAL 0 #endif -#ifndef WIN32 -// PRIO_MAX is not defined on Solaris -#ifndef PRIO_MAX -#define PRIO_MAX 20 -#endif -#define THREAD_PRIORITY_LOWEST PRIO_MAX -#define THREAD_PRIORITY_BELOW_NORMAL 2 -#define THREAD_PRIORITY_NORMAL 0 -#define THREAD_PRIORITY_ABOVE_NORMAL (-2) -#endif - #if HAVE_DECL_STRNLEN == 0 size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN diff --git a/src/net.cpp b/src/net.cpp index 6642ef651..5e810a0f1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1729,7 +1729,6 @@ void ThreadMessageHandler() boost::mutex condition_mutex; boost::unique_lock lock(condition_mutex); - SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); while (true) { vector vNodesCopy; diff --git a/src/util.cpp b/src/util.cpp index 00b75fbdb..3f0f8be54 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -790,19 +790,6 @@ bool SetupNetworking() return true; } -void SetThreadPriority(int nPriority) -{ -#ifdef WIN32 - SetThreadPriority(GetCurrentThread(), nPriority); -#else // WIN32 -#ifdef PRIO_THREAD - setpriority(PRIO_THREAD, 0, nPriority); -#else // PRIO_THREAD - setpriority(PRIO_PROCESS, 0, nPriority); -#endif // PRIO_THREAD -#endif // WIN32 -} - int GetNumCores() { #if BOOST_VERSION >= 105600 diff --git a/src/util.h b/src/util.h index 25c9b733e..45e81ab67 100644 --- a/src/util.h +++ b/src/util.h @@ -208,7 +208,6 @@ std::string HelpMessageOpt(const std::string& option, const std::string& message */ int GetNumCores(); -void SetThreadPriority(int nPriority); void RenameThread(const char* name); /** From b06f6a992b4a80c6a9ef2387bfd81e30a407b245 Mon Sep 17 00:00:00 2001 From: JeremyRand Date: Thu, 5 May 2016 23:08:47 +0000 Subject: [PATCH 0572/1223] Fixed invalid example paths in gitian-building.md The example local paths for "Building fully offline" have an extraneous ".git". This caused an error when trying to run gbuild, like this fatal: '/home/user/bitcoin.git' does not appear to be a git repository fatal: Could not read from remote repository. This commit fixes that. --- doc/gitian-building.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 13f8ad316..791f209bb 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -443,8 +443,8 @@ Then when building, override the remote URLs that gbuild would otherwise pull fr cd /some/root/path/ git clone https://github.com/bitcoin-core/bitcoin-detached-sigs.git -BTCPATH=/some/root/path/bitcoin.git -SIGPATH=/some/root/path/bitcoin-detached-sigs.git +BTCPATH=/some/root/path/bitcoin +SIGPATH=/some/root/path/bitcoin-detached-sigs ./bin/gbuild --url bitcoin=${BTCPATH},signature=${SIGPATH} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml ``` From b3d18ba072f21d5fdb43c9e3cbf6963190d787bd Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Thu, 5 May 2016 18:24:27 -0700 Subject: [PATCH 0573/1223] doc: Fedora build requirements, add gcc-c++ and fix typo --- doc/build-unix.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 27c57088a..bd89978cc 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -128,7 +128,7 @@ Dependency Build Instructions: Fedora ------------------------------------- Build requirements: - sudo dnf install libtool make autoconf automake openssl-devel libevent-devel boost-devel libdb4-devel libdb4-cxx-devel + sudo dnf install gcc-c++ libtool make autoconf automake openssl-devel libevent-devel boost-devel libdb4-devel libdb4-cxx-devel Optional: @@ -136,7 +136,7 @@ Optional: To build with Qt 5 (recommended) you need the following: - sudo dnf install qt5-qttools-devel qtr5-qtbase-devel protobuf-devel + sudo dnf install qt5-qttools-devel qt5-qtbase-devel protobuf-devel libqrencode (optional) can be installed with: From a4d5855a2518c0727faf737de4febcee5f5c4901 Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Fri, 6 May 2016 00:10:49 -0400 Subject: [PATCH 0574/1223] CCoinsViewErrorCatcher raison-d-etre --- src/init.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index b06f448a0..d74e6272e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -136,6 +136,11 @@ bool ShutdownRequested() return fRequestShutdown; } +/** + * This is a minimally invasive approach to shutdown on LevelDB read errors from the + * chainstate, while keeping user interface out of the common library, which is shared + * between bitcoind, and bitcoin-qt and non-server tools. +*/ class CCoinsViewErrorCatcher : public CCoinsViewBacked { public: From 04eaa9095813b854c4299027c595fb9ebaf6f934 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 6 May 2016 11:01:50 +0200 Subject: [PATCH 0575/1223] Add more clear interface for CoinControl.h regarding individual feerate --- src/coincontrol.h | 5 ++++- src/wallet/rpcwallet.cpp | 6 +++++- src/wallet/wallet.cpp | 5 +++-- src/wallet/wallet.h | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/coincontrol.h b/src/coincontrol.h index 6129397bc..e33adc4d2 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -18,7 +18,9 @@ public: bool fAllowWatchOnly; //! Minimum absolute fee (not per kilobyte) CAmount nMinimumTotalFee; - //! Feerate to use (0 = estimate fee with payTxFee fallback) + //! Override estimated feerate + bool fOverrideFeeRate; + //! Feerate to use if overrideFeeRate is true CFeeRate nFeeRate; CCoinControl() @@ -34,6 +36,7 @@ public: setSelected.clear(); nMinimumTotalFee = 0; nFeeRate = CFeeRate(0); + fOverrideFeeRate = false; } bool HasSelected() const diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b14d748b3..933cd1e80 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2486,6 +2486,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) bool includeWatching = false; bool lockUnspents = false; CFeeRate feeRate = CFeeRate(0); + bool overrideEstimatedFeerate = false; if (params.size() > 1) { if (params[1].type() == UniValue::VBOOL) { @@ -2518,7 +2519,10 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) lockUnspents = options["lockUnspents"].get_bool(); if (options.exists("feeRate")) + { feeRate = CFeeRate(options["feeRate"].get_real()); + overrideEstimatedFeerate = true; + } } } @@ -2537,7 +2541,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CAmount nFeeOut; string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFeeOut, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) + if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6b5e3ca7f..96c5c416a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1918,7 +1918,7 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) { vector vecSend; @@ -1933,6 +1933,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const C coinControl.destChange = destChange; coinControl.fAllowOtherInputs = true; coinControl.fAllowWatchOnly = includeWatching; + coinControl.fOverrideFeeRate = overrideEstimatedFeeRate; coinControl.nFeeRate = specificFeeRate; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -2244,7 +2245,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) { nFeeNeeded = coinControl->nMinimumTotalFee; } - if (coinControl && coinControl->nFeeRate > CFeeRate(0)) + if (coinControl && coinControl->fOverrideFeeRate) nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes); // If we made it here and we aren't even able to meet the relay fee on the next pass, give up diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7b5168975..7a9e306f6 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -740,7 +740,7 @@ public: * Insert additional inputs into the transaction by * calling CreateTransaction(); */ - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); /** * Create a new transaction paying the recipients with a set of coins From 0bf6f302626497184a26b88c61fe6af1741e2a44 Mon Sep 17 00:00:00 2001 From: Pedro Branco Date: Tue, 8 Mar 2016 10:37:18 +0000 Subject: [PATCH 0576/1223] Prevent multiple calls to ExtractDestination --- src/wallet/rpcwallet.cpp | 41 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 623037e76..8da749f52 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2341,13 +2341,14 @@ UniValue listunspent(const UniValue& params, bool fHelp) "\nResult\n" "[ (array of json object)\n" " {\n" - " \"txid\" : \"txid\", (string) the transaction id \n" + " \"txid\" : \"txid\", (string) the transaction id \n" " \"vout\" : n, (numeric) the vout value\n" - " \"address\" : \"address\", (string) the bitcoin address\n" - " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" - " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"address\" : \"address\", (string) the bitcoin address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" " }\n" @@ -2393,38 +2394,34 @@ UniValue listunspent(const UniValue& params, bool fHelp) if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) continue; - if (setAddress.size()) { - CTxDestination address; - if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) - continue; + CTxDestination address; + const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey; + bool fValidAddress = ExtractDestination(scriptPubKey, address); - if (!setAddress.count(address)) - continue; - } + if (setAddress.size() && (!fValidAddress || !setAddress.count(address))) + continue; - CAmount nValue = out.tx->vout[out.i].nValue; - const CScript& pk = out.tx->vout[out.i].scriptPubKey; UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); entry.push_back(Pair("vout", out.i)); - CTxDestination address; - if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { + + if (fValidAddress) { entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + if (pwalletMain->mapAddressBook.count(address)) entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); - } - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); - if (pk.IsPayToScriptHash()) { - CTxDestination address; - if (ExtractDestination(pk, address)) { + + if (scriptPubKey.IsPayToScriptHash()) { const CScriptID& hash = boost::get(address); CScript redeemScript; if (pwalletMain->GetCScript(hash, redeemScript)) entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); } } - entry.push_back(Pair("amount",ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations",out.nDepth)); + + entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + entry.push_back(Pair("amount", ValueFromAmount(out.tx->vout[out.i].nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); entry.push_back(Pair("spendable", out.fSpendable)); entry.push_back(Pair("solvable", out.fSolvable)); results.push_back(entry); From fabbf6bd62c1d8a290841b63fb1e5acec42ba3b0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 27 Apr 2016 22:29:52 +0200 Subject: [PATCH 0577/1223] [qa] Refactor test_framework and pull tester * log to stdout * increase range for p2p and rpc ports * UPPERCASE_CONSTANTS * Stop nodes on CTRL+C --- qa/pull-tester/rpc-tests.py | 83 +++++++++---------- qa/rpc-tests/test_framework/test_framework.py | 4 +- qa/rpc-tests/test_framework/util.py | 17 +++- qa/rpc-tests/walletbackup.py | 2 +- 4 files changed, 56 insertions(+), 50 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 15153b7f5..e8434b4a6 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -31,6 +31,14 @@ import re from tests_config import * +BOLD = ("","") +if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + +RPC_TESTS_DIR = BUILDDIR + '/qa/rpc-tests/' + #If imported values are not defined then set to zero (or disabled) if 'ENABLE_WALLET' not in vars(): ENABLE_WALLET=0 @@ -43,29 +51,29 @@ if 'ENABLE_ZMQ' not in vars(): ENABLE_COVERAGE=0 -#Create a set to store arguments and create the passOn string +#Create a set to store arguments and create the passon string opts = set() -passOn = "" -p = re.compile("^--") +passon_args = "" +PASSON_REGEX = re.compile("^--") -bold = ("","") -if (os.name == 'posix'): - bold = ('\033[0m', '\033[1m') +print_help = False for arg in sys.argv[1:]: + if arg == "--help" or arg == "-h" or arg == "-?": + print_help = True + break if arg == '--coverage': ENABLE_COVERAGE = 1 - elif (p.match(arg) or arg == "-h"): - passOn += " " + arg + elif PASSON_REGEX.match(arg): + passon_args += " " + arg else: opts.add(arg) #Set env vars -buildDir = BUILDDIR if "BITCOIND" not in os.environ: - os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT + os.environ["BITCOIND"] = BUILDDIR + '/src/bitcoind' + EXEEXT if "BITCOINCLI" not in os.environ: - os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT + os.environ["BITCOINCLI"] = BUILDDIR + '/src/bitcoin-cli' + EXEEXT if EXEEXT == ".exe" and "-win" not in opts: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 @@ -153,48 +161,35 @@ testScriptsExt = [ ] def runtests(): + test_list = [] + if '-extended' in opts: + test_list = testScripts + testScriptsExt + elif len(opts) == 0 or (len(opts) == 1 and "-win" in opts): + test_list = testScripts + else: + for t in testScripts + testScriptsExt: + if t in opts or re.sub(".py$", "", t) in opts: + test_list.append(t) + + if print_help: + # Help should be the same for all scripts, so just + # call the first and exit + subprocess.check_call(RPC_TESTS_DIR + test_list[0] + ' -h', shell=True) + sys.exit(0) + coverage = None if ENABLE_COVERAGE: coverage = RPCCoverage() print("Initializing coverage directory at %s\n" % coverage.dir) - - rpcTestDir = buildDir + '/qa/rpc-tests/' - run_extended = '-extended' in opts - cov_flag = coverage.flag if coverage else '' - flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn) + flags = " --srcdir %s/src %s %s" % (BUILDDIR, coverage.flag if coverage else '', passon_args) #Run Tests - for i in range(len(testScripts)): - if (len(opts) == 0 - or (len(opts) == 1 and "-win" in opts ) - or run_extended - or testScripts[i] in opts - or re.sub(".py$", "", testScripts[i]) in opts ): - - print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0])) + for t in test_list: + print("Running testscript %s%s%s ..." % (BOLD[1], t, BOLD[0])) time0 = time.time() subprocess.check_call( - rpcTestDir + testScripts[i] + flags, shell=True) - print("Duration: %s s\n" % (int(time.time() - time0))) - - # exit if help is called so we print just one set of - # instructions - p = re.compile(" -h| --help") - if p.match(passOn): - sys.exit(0) - - # Run Extended Tests - for i in range(len(testScriptsExt)): - if (run_extended or testScriptsExt[i] in opts - or re.sub(".py$", "", testScriptsExt[i]) in opts): - - print( - "Running 2nd level testscript " - + "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0])) - time0 = time.time() - subprocess.check_call( - rpcTestDir + testScriptsExt[i] + flags, shell=True) + RPC_TESTS_DIR + t + flags, shell=True) print("Duration: %s s\n" % (int(time.time() - time0))) if coverage: diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index ed12e1efb..103d9a068 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -115,7 +115,7 @@ class BitcoinTestFramework(object): if self.options.trace_rpc: import logging - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) if self.options.coveragedir: enable_coverage(self.options.coveragedir) @@ -148,6 +148,8 @@ class BitcoinTestFramework(object): except Exception as e: print("Unexpected exception caught during testing: " + repr(e)) traceback.print_tb(sys.exc_info()[2]) + except KeyboardInterrupt as e: + print("Exiting after " + repr(e)) if not self.options.noshutdown: print("Stopping nodes") diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index ea3931cef..4c129b78b 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -28,6 +28,13 @@ from .authproxy import AuthServiceProxy, JSONRPCException COVERAGE_DIR = None +# The maximum number of nodes a single test can spawn +MAX_NODES = 8 +# Don't assign rpc or p2p ports lower than this +PORT_MIN = 11000 +# The number of ports to "reserve" for p2p and rpc, each +PORT_RANGE = 5000 + #Set Mocktime default to OFF. #MOCKTIME is only needed for scripts that use the #cached version of the blockchain. If the cached @@ -82,9 +89,11 @@ def get_rpc_proxy(url, node_number, timeout=None): def p2p_port(n): - return 11000 + n + os.getpid()%999 + assert(n <= MAX_NODES) + return PORT_MIN + n + (MAX_NODES * os.getpid()) % (PORT_RANGE - 1 - MAX_NODES) + def rpc_port(n): - return 12000 + n + os.getpid()%999 + return PORT_MIN + PORT_RANGE + n + (MAX_NODES * os.getpid()) % (PORT_RANGE -1 - MAX_NODES) def check_json_precision(): """Make sure json library being used does not lose precision converting BTC values""" @@ -292,8 +301,8 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): """ Start multiple bitcoinds, return RPC connections to them """ - if extra_args is None: extra_args = [ None for i in range(num_nodes) ] - if binary is None: binary = [ None for i in range(num_nodes) ] + if extra_args is None: extra_args = [ None for _ in range(num_nodes) ] + if binary is None: binary = [ None for _ in range(num_nodes) ] rpcs = [] try: for i in range(num_nodes): diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 418f3103e..c3d53669c 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -37,7 +37,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from random import randint import logging -logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout) class WalletBackupTest(BitcoinTestFramework): From 2222dae6e31c433f83aa9fd0e8f028cbee59199b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 30 Apr 2016 00:03:06 +0200 Subject: [PATCH 0578/1223] [qa] Update README.md --- qa/README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/qa/README.md b/qa/README.md index 3e0a526d1..c7e574ff7 100644 --- a/qa/README.md +++ b/qa/README.md @@ -19,15 +19,25 @@ sudo apt-get install python3-zmq Running tests ============= -You can run any single test by calling `qa/pull-tester/rpc-tests.py `. +You can run any single test by calling -Or you can run any combination of tests by calling `qa/pull-tester/rpc-tests.py ...` + qa/pull-tester/rpc-tests.py -Run the regression test suite with `qa/pull-tester/rpc-tests.py` +Or you can run any combination of tests by calling -Run all possible tests with `qa/pull-tester/rpc-tests.py -extended` + qa/pull-tester/rpc-tests.py ... -Possible options: +Run the regression test suite with + + qa/pull-tester/rpc-tests.py + +Run all possible tests with + + qa/pull-tester/rpc-tests.py -extended + +If you want to create a basic coverage report for the rpc test suite, append `--coverage`. + +Possible options, which apply to each individual test run: ``` -h, --help show this help message and exit From fafb33cdefd2d8ce065263978075d26a1672b630 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 30 Apr 2016 14:55:31 +0200 Subject: [PATCH 0579/1223] [qa] Stop other nodes, even when one fails to stop --- qa/rpc-tests/test_framework/util.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 4c129b78b..6dc685ea1 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -16,6 +16,7 @@ from binascii import hexlify, unhexlify from base64 import b64encode from decimal import Decimal, ROUND_DOWN import json +import http.client import random import shutil import subprocess @@ -316,13 +317,19 @@ def log_filename(dirname, n_node, logname): return os.path.join(dirname, "node"+str(n_node), "regtest", logname) def stop_node(node, i): - node.stop() + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) bitcoind_processes[i].wait() del bitcoind_processes[i] def stop_nodes(nodes): for node in nodes: - node.stop() + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) del nodes[:] # Emptying array closes connections as a side effect def set_node_times(nodes, t): From addb9d2a092b4fd0384d4ff82e9607e5411eab97 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 6 May 2016 12:53:23 -0400 Subject: [PATCH 0580/1223] Remove state arg from ReconsiderBlock --- src/main.cpp | 2 +- src/main.h | 2 +- src/rpc/blockchain.cpp | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 92a38f230..9489bb1c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3011,7 +3011,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C return true; } -bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) { +bool ReconsiderBlock(CBlockIndex *pindex) { AssertLockHeld(cs_main); int nHeight = pindex->nHeight; diff --git a/src/main.h b/src/main.h index bdf7f5a68..e48cebecb 100644 --- a/src/main.h +++ b/src/main.h @@ -464,7 +464,7 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ -bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); +bool ReconsiderBlock(CBlockIndex *pindex); /** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6960415e2..d221012af 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -973,7 +973,6 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); - CValidationState state; { LOCK(cs_main); @@ -981,12 +980,11 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - ReconsiderBlock(state, pblockindex); + ReconsiderBlock(pblockindex); } - if (state.IsValid()) { - ActivateBestChain(state, Params()); - } + CValidationState state; + ActivateBestChain(state, Params()); if (!state.IsValid()) { throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); From db18ab28c7a74bb289bfe6a5f9a4a9f963f71c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 6 May 2016 11:00:01 +0200 Subject: [PATCH 0581/1223] Reenable multithread scheduler test. --- src/test/scheduler_tests.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index 9acd0e243..aa12dfbd5 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -40,7 +40,6 @@ static void MicroSleep(uint64_t n) #endif } -#if 0 /* Disabled for now because there is a race condition issue in this test - see #6540 */ BOOST_AUTO_TEST_CASE(manythreads) { seed_insecure_rand(false); @@ -116,6 +115,5 @@ BOOST_AUTO_TEST_CASE(manythreads) } BOOST_CHECK_EQUAL(counterSum, 200); } -#endif BOOST_AUTO_TEST_SUITE_END() From 166e4b0dfa283fbdedc9a6a1e83296500c853a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 6 May 2016 11:01:51 +0200 Subject: [PATCH 0582/1223] Notify other serviceQueue thread we are finished to prevent deadlocks. --- src/scheduler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 184ddc28a..52777b61f 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -79,6 +79,7 @@ void CScheduler::serviceQueue() } } --nThreadsServicingQueue; + newTaskScheduled.notify_one(); } void CScheduler::stop(bool drain) From fad336648c848c7a4b3e32bae68ea9a22f97e668 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 8 May 2016 14:09:49 +0200 Subject: [PATCH 0583/1223] [qa] pull-tester: Adjust comment --- qa/pull-tester/rpc-tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index e8434b4a6..c6f91f8cb 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -172,8 +172,7 @@ def runtests(): test_list.append(t) if print_help: - # Help should be the same for all scripts, so just - # call the first and exit + # Only print help of the first script and exit subprocess.check_call(RPC_TESTS_DIR + test_list[0] + ' -h', shell=True) sys.exit(0) From 0fd599767d2dabf25ac8c3543cb586cfc4b9d816 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 9 May 2016 00:15:12 -0700 Subject: [PATCH 0584/1223] Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk --- src/wallet/wallet.cpp | 14 ++++---------- src/wallet/wallet.h | 2 -- src/wallet/walletdb.cpp | 10 +++++----- src/wallet/walletdb.h | 2 +- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 29d713854..d6895b80f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -729,7 +729,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD // Write to disk if (fInsertedNew || fUpdated) - if (!wtx.WriteToDisk(pwalletdb)) + if (!pwalletdb->WriteTx(wtx)) return false; // Break debit/credit balance caches: @@ -829,7 +829,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) wtx.nIndex = -1; wtx.setAbandoned(); wtx.MarkDirty(); - wtx.WriteToDisk(&walletdb); + walletdb.WriteTx(wtx); NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED); // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0)); @@ -891,7 +891,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) wtx.nIndex = -1; wtx.hashBlock = hashBlock; wtx.MarkDirty(); - wtx.WriteToDisk(&walletdb); + walletdb.WriteTx(wtx); // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0)); while (iter != mapTxSpends.end() && iter->first.hash == now) { @@ -1186,12 +1186,6 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, } } - -bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) -{ - return pwalletdb->WriteTx(GetHash(), *this); -} - /** * Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already @@ -3194,7 +3188,7 @@ bool CWallet::InitLoadWallet() copyTo->fFromMe = copyFrom->fFromMe; copyTo->strFromAccount = copyFrom->strFromAccount; copyTo->nOrderPos = copyFrom->nOrderPos; - copyTo->WriteToDisk(&walletdb); + walletdb.WriteTx(*copyTo); } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c3bd343ed..cc568c374 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -394,8 +394,6 @@ public: bool InMempool() const; bool IsTrusted() const; - bool WriteToDisk(CWalletDB *pwalletdb); - int64_t GetTxTime() const; int GetRequestCount() const; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index f2b5408e9..48579b282 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -55,10 +55,10 @@ bool CWalletDB::ErasePurpose(const string& strPurpose) return Erase(make_pair(string("purpose"), strPurpose)); } -bool CWalletDB::WriteTx(uint256 hash, const CWalletTx& wtx) +bool CWalletDB::WriteTx(const CWalletTx& wtx) { nWalletDBUpdated++; - return Write(std::make_pair(std::string("tx"), hash), wtx); + return Write(std::make_pair(std::string("tx"), wtx.GetHash()), wtx); } bool CWalletDB::EraseTx(uint256 hash) @@ -291,7 +291,7 @@ DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) if (pwtx) { - if (!WriteTx(pwtx->GetHash(), *pwtx)) + if (!WriteTx(*pwtx)) return DB_LOAD_FAIL; } else @@ -315,7 +315,7 @@ DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) // Since we're changing the order, write it back if (pwtx) { - if (!WriteTx(pwtx->GetHash(), *pwtx)) + if (!WriteTx(*pwtx)) return DB_LOAD_FAIL; } else @@ -698,7 +698,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value' BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade) - WriteTx(hash, pwallet->mapWallet[hash]); + WriteTx(pwallet->mapWallet[hash]); // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index fe6c36634..5345c0907 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -87,7 +87,7 @@ public: bool WritePurpose(const std::string& strAddress, const std::string& purpose); bool ErasePurpose(const std::string& strAddress); - bool WriteTx(uint256 hash, const CWalletTx& wtx); + bool WriteTx(const CWalletTx& wtx); bool EraseTx(uint256 hash); bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta); From 65fee8e699eb458291810e2d70cfa904d994fecf Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 9 May 2016 12:08:56 +0200 Subject: [PATCH 0585/1223] test: Revert fatal-ness of missing python-zmq It looks like travis is using the `travis.yml` from the branch, but runs the test script from the branch merged into master. This causes pull requests created before the QA tests python 3 transition to fail. This temporarily reverts fa05e22e919b7e2e816606f0c0d3dea1bd325bfd (#7851). It can be restored when this is no longer an issue. --- qa/pull-tester/rpc-tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 15153b7f5..01c2736e6 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -82,9 +82,9 @@ if ENABLE_ZMQ: try: import zmq except ImportError as e: - print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ + print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ "to run zmq tests, see dependency info in /qa/README.md.") - raise e + ENABLE_ZMQ=0 #Tests testScripts = [ From fe80102d3320c973b34daa245b3e41fb38413223 Mon Sep 17 00:00:00 2001 From: Matthew English Date: Mon, 9 May 2016 14:00:28 +0200 Subject: [PATCH 0586/1223] changing "(tests are) automatically run" to correspond to the earlier instance of "run automatically (on the build server)" --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 85b198556..8e816e7a4 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,7 @@ There are also [regression and integration tests](/qa) of the RPC interface, wri in Python, that are run automatically on the build server. These tests can be run (if the [test dependencies](/qa) are installed) with: `qa/pull-tester/rpc-tests.py` -The Travis CI system makes sure that every pull request is built for Windows -and Linux, OS X, and that unit and sanity tests are automatically run. +The Travis CI system makes sure that every pull request is built for Windows, Linux, and OS X, and that unit/sanity tests are run automatically. ### Manual Quality Assurance (QA) Testing From 5ea450834ed3abae9d85deae336ed65111e02906 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 6 May 2016 12:40:12 +0200 Subject: [PATCH 0587/1223] Autofind rpc tests --srcdir --- qa/rpc-tests/test_framework/test_framework.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index ed12e1efb..0b6d1b6ab 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -102,7 +102,7 @@ class BitcoinTestFramework(object): help="Leave bitcoinds and test.* datadir on exit or error") parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true", help="Don't stop bitcoinds after the test execution") - parser.add_option("--srcdir", dest="srcdir", default="../../src", + parser.add_option("--srcdir", dest="srcdir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__))+"/../../../src"), help="Source directory containing bitcoind/bitcoin-cli (default: %default)") parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), help="Root directory for datadirs") From 326231611bda6808b579ab7286e471c36f62e98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chirag=20Dav=C3=A9?= Date: Wed, 4 May 2016 21:40:28 -0700 Subject: [PATCH 0588/1223] fReopenDebugLog and fRequestShutdown should be type sig_atomic_t This allows access as an atomic variable in the presence of async interrupts. See issue #7433 for more details fixes: #7433 --- src/init.cpp | 2 +- src/util.cpp | 2 +- src/util.h | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b06f448a0..a9b3f88a3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -125,7 +125,7 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; // shutdown thing. // -volatile bool fRequestShutdown = false; +volatile sig_atomic_t fRequestShutdown = false; void StartShutdown() { diff --git a/src/util.cpp b/src/util.cpp index 00b75fbdb..579be338e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -113,7 +113,7 @@ string strMiscWarning; bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; bool fLogIPs = DEFAULT_LOGIPS; -volatile bool fReopenDebugLog = false; +volatile sig_atomic_t fReopenDebugLog = false; CTranslationInterface translationInterface; /** Init OpenSSL library multithreading support */ diff --git a/src/util.h b/src/util.h index ac099f118..33db0f9e4 100644 --- a/src/util.h +++ b/src/util.h @@ -28,6 +28,10 @@ #include #include +#ifndef WIN32 +#include +#endif + static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; @@ -50,7 +54,7 @@ extern std::string strMiscWarning; extern bool fLogTimestamps; extern bool fLogTimeMicros; extern bool fLogIPs; -extern volatile bool fReopenDebugLog; +extern volatile sig_atomic_t fReopenDebugLog; extern CTranslationInterface translationInterface; extern const char * const BITCOIN_CONF_FILENAME; From 657e07efa34ffe9d8614a618e00452c9ee7c0e0d Mon Sep 17 00:00:00 2001 From: instagibbs Date: Mon, 9 May 2016 11:26:37 -0400 Subject: [PATCH 0589/1223] Rename ReconsiderBlock func to reflect real behavior --- src/main.cpp | 2 +- src/main.h | 2 +- src/rpc/blockchain.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9489bb1c4..11eaa055d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3011,7 +3011,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C return true; } -bool ReconsiderBlock(CBlockIndex *pindex) { +bool ResetBlockFailureFlags(CBlockIndex *pindex) { AssertLockHeld(cs_main); int nHeight = pindex->nHeight; diff --git a/src/main.h b/src/main.h index e48cebecb..ebbd12c8c 100644 --- a/src/main.h +++ b/src/main.h @@ -464,7 +464,7 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ -bool ReconsiderBlock(CBlockIndex *pindex); +bool ResetBlockFailureFlags(CBlockIndex *pindex); /** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d221012af..cf3c73c4d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -980,7 +980,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - ReconsiderBlock(pblockindex); + ResetBlockFailureFlags(pblockindex); } CValidationState state; From fa494dec79b9d469b7eb38d2f0b8cf9832cdc398 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 29 Apr 2016 12:51:15 +0200 Subject: [PATCH 0590/1223] [qa] pull-tester: Run rpc test in parallel --- qa/README.md | 3 ++ qa/pull-tester/rpc-tests.py | 92 +++++++++++++++++++++++++++++++----- qa/rpc-tests/create_cache.py | 23 +++++++++ 3 files changed, 105 insertions(+), 13 deletions(-) create mode 100755 qa/rpc-tests/create_cache.py diff --git a/qa/README.md b/qa/README.md index c7e574ff7..7489eb513 100644 --- a/qa/README.md +++ b/qa/README.md @@ -35,6 +35,9 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended +By default, tests will be run in parallel if you want to specify how many +tests should be run in parallel, append `-paralell=n` (default n=4). + If you want to create a basic coverage report for the rpc test suite, append `--coverage`. Possible options, which apply to each individual test run: diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 10c3799b8..f926398d5 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -53,10 +53,12 @@ ENABLE_COVERAGE=0 #Create a set to store arguments and create the passon string opts = set() -passon_args = "" +passon_args = [] PASSON_REGEX = re.compile("^--") +PARALLEL_REGEX = re.compile('^-parallel=') print_help = False +run_parallel = 4 for arg in sys.argv[1:]: if arg == "--help" or arg == "-h" or arg == "-?": @@ -65,7 +67,9 @@ for arg in sys.argv[1:]: if arg == '--coverage': ENABLE_COVERAGE = 1 elif PASSON_REGEX.match(arg): - passon_args += " " + arg + passon_args.append(arg) + elif PARALLEL_REGEX.match(arg): + run_parallel = int(arg.split(sep='=', maxsplit=1)[1]) else: opts.add(arg) @@ -96,6 +100,7 @@ if ENABLE_ZMQ: #Tests testScripts = [ + 'walletbackup.py', 'bip68-112-113-p2p.py', 'wallet.py', 'listtransactions.py', @@ -116,7 +121,6 @@ testScripts = [ 'merkle_blocks.py', 'fundrawtransaction.py', 'signrawtransactions.py', - 'walletbackup.py', 'nodehandling.py', 'reindex.py', 'decodescript.py', @@ -131,7 +135,7 @@ testScripts = [ 'abandonconflict.py', 'p2p-versionbits-warning.py', 'importprunedfunds.py', - 'signmessages.py' + 'signmessages.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') @@ -160,6 +164,7 @@ testScriptsExt = [ 'pruning.py', # leave pruning last as it takes a REALLY long time ] + def runtests(): test_list = [] if '-extended' in opts: @@ -173,7 +178,7 @@ def runtests(): if print_help: # Only print help of the first script and exit - subprocess.check_call(RPC_TESTS_DIR + test_list[0] + ' -h', shell=True) + subprocess.check_call((RPC_TESTS_DIR + test_list[0]).split() + ['-h']) sys.exit(0) coverage = None @@ -181,15 +186,34 @@ def runtests(): if ENABLE_COVERAGE: coverage = RPCCoverage() print("Initializing coverage directory at %s\n" % coverage.dir) - flags = " --srcdir %s/src %s %s" % (BUILDDIR, coverage.flag if coverage else '', passon_args) + flags = ["--srcdir=%s/src" % BUILDDIR] + passon_args + if coverage: + flags.append(coverage.flag) + + if len(test_list) > 1: + # Populate cache + subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) #Run Tests - for t in test_list: - print("Running testscript %s%s%s ..." % (BOLD[1], t, BOLD[0])) - time0 = time.time() - subprocess.check_call( - RPC_TESTS_DIR + t + flags, shell=True) - print("Duration: %s s\n" % (int(time.time() - time0))) + max_len_name = len(max(test_list, key=len)) + time_sum = 0 + time0 = time.time() + job_queue = RPCTestHandler(run_parallel, test_list, flags) + results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] + all_passed = True + for _ in range(len(test_list)): + (name, stdout, stderr, passed, duration) = job_queue.get_next() + all_passed = all_passed and passed + time_sum += duration + + print('\n' + BOLD[1] + name + BOLD[0] + ":") + print(stdout) + print('stderr:\n' if not stderr == '' else '', stderr) + results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) + print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) + results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] + print(results) + print("\nRuntime: %s s" % (int(time.time() - time0))) if coverage: coverage.report_rpc_coverage() @@ -197,6 +221,48 @@ def runtests(): print("Cleaning up coverage data") coverage.cleanup() + sys.exit(not all_passed) + + +class RPCTestHandler: + """ + Trigger the testscrips passed in via the list. + """ + + def __init__(self, num_tests_parallel, test_list=None, flags=None): + assert(num_tests_parallel >= 1) + self.num_jobs = num_tests_parallel + self.test_list = test_list + self.flags = flags + self.num_running = 0 + self.jobs = [] + + def get_next(self): + while self.num_running < self.num_jobs and self.test_list: + # Add tests + self.num_running += 1 + t = self.test_list.pop(0) + self.jobs.append((t, + time.time(), + subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE))) + if not self.jobs: + raise IndexError('%s from empty list' % __name__) + while True: + # Return first proc that finishes + time.sleep(.5) + for j in self.jobs: + (name, time0, proc) = j + if proc.poll() is not None: + (stdout, stderr) = proc.communicate(timeout=3) + passed = stderr == "" and proc.returncode == 0 + self.num_running -= 1 + self.jobs.remove(j) + return name, stdout, stderr, passed, int(time.time() - time0) + print('.', end='', flush=True) + class RPCCoverage(object): """ @@ -215,7 +281,7 @@ class RPCCoverage(object): """ def __init__(self): self.dir = tempfile.mkdtemp(prefix="coverage") - self.flag = '--coveragedir %s' % self.dir + self.flag = '--coveragedir=%s' % self.dir def report_rpc_coverage(self): """ diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py new file mode 100755 index 000000000..b6161e091 --- /dev/null +++ b/qa/rpc-tests/create_cache.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Helper script to create the cache +# (see BitcoinTestFramework.setup_chain) +# + +from test_framework.test_framework import BitcoinTestFramework + +class CreateCache(BitcoinTestFramework): + + def setup_network(self): + # Don't setup any test nodes + self.options.noshutdown = True + + def run_test(self): + pass + +if __name__ == '__main__': + CreateCache().main() From ccccc591a456f9a8fcf5f8e68a5bacdbbaeb0937 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 9 May 2016 19:55:49 +0200 Subject: [PATCH 0591/1223] [qa] Add option --portseed to test_framework --- qa/pull-tester/rpc-tests.py | 3 ++- qa/rpc-tests/test_framework/test_framework.py | 13 ++++++++----- qa/rpc-tests/test_framework/util.py | 10 +++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index f926398d5..f810f89a5 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -242,9 +242,10 @@ class RPCTestHandler: # Add tests self.num_running += 1 t = self.test_list.pop(0) + port_seed = ["--portseed=%s" % len(self.test_list)] self.jobs.append((t, time.time(), - subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags, + subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE))) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 4e7246309..3480de6c6 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -5,10 +5,10 @@ # Base class for RPC testing -# Add python-bitcoinrpc to module search path: +import logging +import optparse import os import sys - import shutil import tempfile import traceback @@ -25,8 +25,9 @@ from .util import ( enable_coverage, check_json_precision, initialize_chain_clean, + PortSeed, ) -from .authproxy import AuthServiceProxy, JSONRPCException +from .authproxy import JSONRPCException class BitcoinTestFramework(object): @@ -95,7 +96,6 @@ class BitcoinTestFramework(object): self.setup_network(False) def main(self): - import optparse parser = optparse.OptionParser(usage="%prog [options]") parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", @@ -108,18 +108,21 @@ class BitcoinTestFramework(object): help="Root directory for datadirs") parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true", help="Print out all RPC calls as they are made") + parser.add_option("--portseed", dest="port_seed", default=os.getpid(), type='int', + help="The seed to use for assigning port numbers (default: current process id)") parser.add_option("--coveragedir", dest="coveragedir", help="Write tested RPC commands into this directory") self.add_options(parser) (self.options, self.args) = parser.parse_args() if self.options.trace_rpc: - import logging logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) if self.options.coveragedir: enable_coverage(self.options.coveragedir) + PortSeed.n = self.options.port_seed + os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH'] check_json_precision() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 6dc685ea1..6784177aa 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -8,7 +8,6 @@ # Helpful routines for regression testing # -# Add python-bitcoinrpc to module search path: import os import sys @@ -36,6 +35,11 @@ PORT_MIN = 11000 # The number of ports to "reserve" for p2p and rpc, each PORT_RANGE = 5000 + +class PortSeed: + # Must be initialized with a unique integer for each process + n = None + #Set Mocktime default to OFF. #MOCKTIME is only needed for scripts that use the #cached version of the blockchain. If the cached @@ -91,10 +95,10 @@ def get_rpc_proxy(url, node_number, timeout=None): def p2p_port(n): assert(n <= MAX_NODES) - return PORT_MIN + n + (MAX_NODES * os.getpid()) % (PORT_RANGE - 1 - MAX_NODES) + return PORT_MIN + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) def rpc_port(n): - return PORT_MIN + PORT_RANGE + n + (MAX_NODES * os.getpid()) % (PORT_RANGE -1 - MAX_NODES) + return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) def check_json_precision(): """Make sure json library being used does not lose precision converting BTC values""" From 00678bdb0aeb296456501f818faaa012a75ce18e Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Mon, 9 May 2016 17:01:33 -0700 Subject: [PATCH 0592/1223] Make failures to connect via Socks5() more informative and less unnecessarily scary. * The "ERROR" was printed far too often during normal operation for what was not an error. * Makes the Socks5() connect failure similar to the IP connect failure in debug.log. Before: `2016-05-09 00:15:00 ERROR: Proxy error: host unreachable` After: `2016-05-09 00:15:00 Socks5() connect to t6xj6wilh4ytvcs7.onion:18333 failed: host unreachable"` --- src/netbase.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index b44a8b16e..6e81fdcac 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -379,19 +379,21 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Proxy failed to accept request"); } if (pchRet2[1] != 0x00) { + // Failures to connect to a peer that are not proxy errors CloseSocket(hSocket); switch (pchRet2[1]) { - case 0x01: return error("Proxy error: general failure"); - case 0x02: return error("Proxy error: connection not allowed"); - case 0x03: return error("Proxy error: network unreachable"); - case 0x04: return error("Proxy error: host unreachable"); - case 0x05: return error("Proxy error: connection refused"); - case 0x06: return error("Proxy error: TTL expired"); - case 0x07: return error("Proxy error: protocol error"); - case 0x08: return error("Proxy error: address type not supported"); - default: return error("Proxy error: unknown"); + case 0x01: LogPrintf("Socks5() connect to %s:%d failed: general failure\n", strDest, port); break; + case 0x02: LogPrintf("Socks5() connect to %s:%d failed: connection not allowed\n", strDest, port); break; + case 0x03: LogPrintf("Socks5() connect to %s:%d failed: network unreachable\n", strDest, port); break; + case 0x04: LogPrintf("Socks5() connect to %s:%d failed: host unreachable\n", strDest, port); break; + case 0x05: LogPrintf("Socks5() connect to %s:%d failed: connection refused\n", strDest, port); break; + case 0x06: LogPrintf("Socks5() connect to %s:%d failed: TTL expired\n", strDest, port); break; + case 0x07: LogPrintf("Socks5() connect to %s:%d failed: protocol error\n", strDest, port); break; + case 0x08: LogPrintf("Socks5() connect to %s:%d failed: address type not supported\n", strDest, port); break; + default: LogPrintf("Socks5() connect to %s:%d failed: unknown\n", strDest, port); } + return false; } if (pchRet2[2] != 0x00) { CloseSocket(hSocket); From 0d9af79e5084dc2fb6a73abd9dd113dda4e993b4 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Mon, 9 May 2016 17:35:14 -0700 Subject: [PATCH 0593/1223] SOCKS5 connecting and connected messages with -debug=net. They were too noisy and not necessary for normal operation. --- src/netbase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 6e81fdcac..5ab12c9a7 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -294,7 +294,7 @@ struct ProxyCredentials /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { - LogPrintf("SOCKS5 connecting %s\n", strDest); + LogPrint("net", "SOCKS5 connecting %s\n", strDest); if (strDest.size() > 255) { CloseSocket(hSocket); return error("Hostname too long"); @@ -425,7 +425,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials CloseSocket(hSocket); return error("Error reading from proxy"); } - LogPrintf("SOCKS5 connected %s\n", strDest); + LogPrint("net", "SOCKS5 connected %s\n", strDest); return true; } From 3902a291abecad4da25d496f0e3e2b45f43a7947 Mon Sep 17 00:00:00 2001 From: Tyler Hardin Date: Mon, 9 May 2016 22:26:57 -0400 Subject: [PATCH 0594/1223] Qt: Delay user confirmation of send I made a subclass of QMessageBox that disables the send button in exec() and starts a timer that calls a slot to re-enable it after a configurable delay. It also has a countdown in the send/yes button while it is disabled to hint to the user why the send button is disabled (and that it is actually supposed to be disabled). --- src/qt/sendcoinsdialog.cpp | 53 +++++++++++++++++++++++++++++++++++--- src/qt/sendcoinsdialog.h | 22 ++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 780a6c970..54ebd2583 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -26,6 +26,9 @@ #include #include #include +#include + +#define SEND_CONFIRM_DELAY 3 SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), @@ -311,10 +314,10 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append(QString("
(=%2)
") .arg(alternativeUnits.join(" " + tr("or") + "
"))); - QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), - questionString.arg(formatted.join("
")), - QMessageBox::Yes | QMessageBox::Cancel, - QMessageBox::Cancel); + SendConfirmationDialog confirmationDialog(tr("Confirm send coins"), + questionString.arg(formatted.join("
")), SEND_CONFIRM_DELAY, this); + confirmationDialog.exec(); + QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result(); if(retval != QMessageBox::Yes) { @@ -828,3 +831,45 @@ void SendCoinsDialog::coinControlUpdateLabels() ui->labelCoinControlInsuffFunds->hide(); } } + +SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int secDelay, + QWidget *parent) : + QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(secDelay) +{ + setDefaultButton(QMessageBox::Cancel); + yesButton = button(QMessageBox::Yes); + updateYesButton(); + connect(&countDownTimer, SIGNAL(timeout()), this, SLOT(countDown())); +} + +int SendConfirmationDialog::exec() +{ + updateYesButton(); + countDownTimer.start(1000); + return QMessageBox::exec(); +} + +void SendConfirmationDialog::countDown() +{ + secDelay--; + updateYesButton(); + + if(secDelay <= 0) + { + countDownTimer.stop(); + } +} + +void SendConfirmationDialog::updateYesButton() +{ + if(secDelay > 0) + { + yesButton->setEnabled(false); + yesButton->setText(tr("Yes") + " (" + QString::number(secDelay) + ")"); + } + else + { + yesButton->setEnabled(true); + yesButton->setText(tr("Yes")); + } +} diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index ec171734f..be4f2ee44 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -8,7 +8,9 @@ #include "walletmodel.h" #include +#include #include +#include class ClientModel; class OptionsModel; @@ -100,4 +102,24 @@ Q_SIGNALS: void message(const QString &title, const QString &message, unsigned int style); }; + + +class SendConfirmationDialog : public QMessageBox +{ + Q_OBJECT + +public: + SendConfirmationDialog(const QString &title, const QString &text, int secDelay = 0, QWidget *parent = 0); + int exec(); + +private Q_SLOTS: + void countDown(); + void updateYesButton(); + +private: + QAbstractButton *yesButton; + QTimer countDownTimer; + int secDelay; +}; + #endif // BITCOIN_QT_SENDCOINSDIALOG_H From 2d5603c7e8316c3051304ed22553da64d686df56 Mon Sep 17 00:00:00 2001 From: Tyler Hardin Date: Mon, 9 May 2016 22:46:33 -0400 Subject: [PATCH 0595/1223] Qt: Sort transactions by date Conflicted transactions can get stuck at the top. This fixes that. --- src/qt/overviewpage.cpp | 2 +- src/qt/transactionview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index d577345e4..6a0404cbf 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -219,7 +219,7 @@ void OverviewPage::setWalletModel(WalletModel *model) filter->setDynamicSortFilter(true); filter->setSortRole(Qt::EditRole); filter->setShowInactive(false); - filter->sort(TransactionTableModel::Status, Qt::DescendingOrder); + filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); ui->listTransactions->setModel(filter); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index eb6111e68..199a7b2d7 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -203,7 +203,7 @@ void TransactionView::setModel(WalletModel *model) transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); transactionView->setSortingEnabled(true); - transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder); + transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder); transactionView->verticalHeader()->hide(); transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH); From 90963e53707cf244e6a2a804341e9280628b0c34 Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 10 May 2016 14:23:49 +0800 Subject: [PATCH 0596/1223] [doc] Add basic git squash example --- CONTRIBUTING.md | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53d6527d4..5c1138b81 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,13 +17,13 @@ To contribute a patch, the workflow is as follows: - Create topic branch - Commit patches -The project coding conventions in [doc/developer-notes.md](doc/developer-notes.md) must be adhered to. +The project coding conventions in the [developer notes](doc/developer-notes.md) must be adhered to. In general [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) and diffs should be easy to read. For this reason do not mix any formatting fixes or code moves with actual code changes. Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate paragraph(s); unless the title alone is self-explanatory (like "Corrected typo in main.cpp") then a single title line is sufficient. Commit messages should be helpful to people reading your code in the future, so explain the reasoning for your decisions. Further explanation [here](http://chris.beams.io/posts/git-commit/). -If a particular commit references another issue, please add the reference, for example "refs #1234", or "fixes #4321". Using "fixes or closes" keywords will cause the corresponding issue to be closed when the pull request is merged. +If a particular commit references another issue, please add the reference, for example `refs #1234`, or `fixes #4321`. Using the `fixes` or `closes` keywords will cause the corresponding issue to be closed when the pull request is merged. Please refer to the [Git manual](https://git-scm.com/doc) for more information about Git. @@ -35,13 +35,27 @@ The title of the pull request should be prefixed by the component or area that t Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG Net: Automatically create hidden service, listen on Tor Qt: Add feed bump button - Trivial: fix typo + Trivial: Fix typo in main.cpp -If a pull request is specifically not to be considered for merging (yet) please prefix the title with [WIP] or use [Tasks Lists](https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments) in the body of the pull request to indicate tasks are pending. +If a pull request is specifically not to be considered for merging (yet) please prefix the title with [WIP] or use [Tasks Lists](https://help.github.com/articles/basic-writing-and-formatting-syntax/#task-lists) in the body of the pull request to indicate tasks are pending. The body of the pull request should contain enough description about what the patch does together with any justification/reasoning. You should include references to any discussions (for example other tickets or mailing list discussions). -At this stage one should expect comments and review from other contributors. You can add more commits to your pull request by committing them locally and pushing to your fork until you have satisfied all feedback. If your pull request is accepted for merging, you may be asked by a maintainer to squash and or rebase your commits before it will be merged. The length of time required for peer review is unpredictable and will vary from patch to patch. +At this stage one should expect comments and review from other contributors. You can add more commits to your pull request by committing them locally and pushing to your fork until you have satisfied all feedback. + +Squashing Commits +--------------------------- +If your pull request is accepted for merging, you may be asked by a maintainer to squash and or [rebase](https://git-scm.com/docs/git-rebase) your commits before it will be merged. The basic squashing workflow is shown below. + + git checkout your_branch_name + git rebase -i HEAD~n + # n is normally the number of commits in the pull + # set commits from 'pick' to 'squash', save and quit + # on the next screen, edit/refine commit messages + # save and quit + git push -f # (force push to GitHub) + +The length of time required for peer review is unpredictable and will vary from pull request to pull request. Pull Request Philosophy @@ -61,7 +75,7 @@ Refactoring is a necessary part of any software project's evolution. The followi There are three categories of refactoring, code only moves, code style fixes, code refactoring. In general refactoring pull requests should not mix these three kinds of activity in order to make refactoring pull requests easy to review and uncontroversial. In all cases, refactoring PRs must not change the behaviour of code within the pull request (bugs must be preserved as is). -Project maintainers aim for a quick turnaround on refactoring pull requests, so where possible keep them short, uncomplex and easy to verify. +Project maintainers aim for a quick turnaround on refactoring pull requests, so where possible keep them short, uncomplex and easy to verify. "Decision Making" Process @@ -69,7 +83,7 @@ Project maintainers aim for a quick turnaround on refactoring pull requests, so The following applies to code changes to the Bitcoin Core project (and related projects such as libsecp256k1), and is not to be confused with overall Bitcoin Network Protocol consensus changes. -Whether a pull request is merged into Bitcoin Core rests with the project merge maintainers and ultimately the project lead. +Whether a pull request is merged into Bitcoin Core rests with the project merge maintainers and ultimately the project lead. Maintainers will take into consideration if a patch is in line with the general principles of the project; meets the minimum standards for inclusion; and will judge the general consensus of contributors. From 3e2c946cfdfdaae4b00793a554157762d1971705 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 10 May 2016 12:53:49 +0200 Subject: [PATCH 0597/1223] init: Move berkeleydb version reporting to wallet Move the version reporting to Wallet::Verify, before starting verification of the wallet. This removes the dependency of init on a specific wallet database library. A further, trivial step towards resolving #7965. --- src/init.cpp | 5 ----- src/wallet/wallet.cpp | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b06f448a0..a46cc52a8 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -37,9 +37,7 @@ #include "utilmoneystr.h" #include "validationinterface.h" #ifdef ENABLE_WALLET -#include "wallet/db.h" #include "wallet/wallet.h" -#include "wallet/walletdb.h" #endif #include #include @@ -986,9 +984,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fPrintToDebugLog) OpenDebugLog(); -#ifdef ENABLE_WALLET - LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); -#endif if (!fLogTimestamps) LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 29d713854..d32fe43ed 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -368,6 +368,7 @@ void CWallet::Flush(bool shutdown) bool CWallet::Verify() { + LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); LogPrintf("Using wallet %s\n", walletFile); From ac40ed780079861e67d5c026e5026e8cc387eb24 Mon Sep 17 00:00:00 2001 From: error10 Date: Fri, 4 Dec 2015 14:00:18 -0500 Subject: [PATCH 0598/1223] Increase timeout waiting for pruned blk00000.dat In my ever-growing list of test failures, I was seeing this one intermittently. ``` Running 2nd level testscript pruning.py... Initializing test directory /tmp/testY5ypCv Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours) Mining a big blockchain of 995 blocks Check that we haven't started pruning yet because we're below PruneAfterHeight Success Though we're already using more than 550MB, current usage: 587 Mining 25 more blocks should cause the first block file to be pruned Assertion failed: blk00000.dat not pruned when it should be File "/home/error/bitcoinxt-0.11D/qa/rpc-tests/test_framework/test_framework.py", line 118, in main self.run_test() File "/home/error/bitcoinxt-0.11D/qa/rpc-tests/pruning.py", line 272, in run_test self.test_height_min() File "/home/error/bitcoinxt-0.11D/qa/rpc-tests/pruning.py", line 94, in test_height_min raise AssertionError("blk00000.dat not pruned when it should be") Stopping nodes Failed ``` After digging into the test, I found that the code is waiting 10 seconds for blk00000.dat to be deleted, and then throwing this failure if it still exists after 10 seconds. I increased this amount, had the script print the actual time taken, and ran the test a few more times. The time taken ranged between 8 to 12 seconds. So, I feel that this timeout is too short. After changing the timeout to 30 seconds, the test passes consistently. (cherry picked from commit 3469911c89a48dd2fefe4d1c2a0c176256e14ee0) --- qa/rpc-tests/pruning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 92d33bd20..eac2272db 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -75,7 +75,7 @@ class PruneTest(BitcoinTestFramework): waitstart = time.time() while os.path.isfile(self.prunedir+"blk00000.dat"): time.sleep(0.1) - if time.time() - waitstart > 10: + if time.time() - waitstart > 30: raise AssertionError("blk00000.dat not pruned when it should be") print("Success") From fa72f7d99deeebe8bd088753a9a378170ec71f91 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 10 May 2016 17:54:34 +0200 Subject: [PATCH 0599/1223] [doc] Remove outdated line from listunspent RPC help, fix typo --- src/wallet/rpcwallet.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 623037e76..27596929f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2233,7 +2233,7 @@ UniValue settxfee(const UniValue& params, bool fHelp) "settxfee amount\n" "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" "\nArguments:\n" - "1. amount (numeric or sting, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n" + "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2328,8 +2328,6 @@ UniValue listunspent(const UniValue& params, bool fHelp) "\nReturns array of unspent transaction outputs\n" "with between minconf and maxconf (inclusive) confirmations.\n" "Optionally filter to only include txouts paid to specified addresses.\n" - "Results are an array of Objects, each of which has:\n" - "{txid, vout, scriptPubKey, amount, confirmations}\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" From fadd0485922de94720dfe60c859633041d67b22f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 14 Mar 2016 22:13:04 +0100 Subject: [PATCH 0600/1223] [doc] Link to clang-format in the developer notes --- doc/developer-notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 8affb2158..add2fb500 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -5,7 +5,9 @@ Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to a single style, so please use it in new code. Old code will be converted gradually. -- Basic rules specified in src/.clang-format. Use a recent clang-format-3.5 to format automatically. +- Basic rules specified in [src/.clang-format](/src/.clang-format). + Use a recent clang-format to format automatically using one of the [dev scripts] + (/contrib/devtools/README.md#clang-formatpy). - Braces on new lines for namespaces, classes, functions, methods. - Braces on the same line for everything else. - 4 space indentation (no tabs) for every block except namespaces. From fa83a5dbce0b76e78744c9ad5578c93e89b123e5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 10 May 2016 17:22:01 +0200 Subject: [PATCH 0601/1223] [qa] wallet: Temporarily disable salvagewallet test --- qa/rpc-tests/wallet.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 42ce0a726..f321f5e90 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -306,7 +306,7 @@ class WalletTest (BitcoinTestFramework): # Check that the txid and balance is found by node1 self.nodes[1].gettransaction(cbTxId) - #check if wallet or blochchain maintenance changes the balance + # check if wallet or blockchain maintenance changes the balance self.sync_all() blocks = self.nodes[0].generate(2) self.sync_all() @@ -318,7 +318,8 @@ class WalletTest (BitcoinTestFramework): '-reindex', '-zapwallettxes=1', '-zapwallettxes=2', - '-salvagewallet', + # disabled until issue is fixed: https://github.com/bitcoin/bitcoin/issues/7463 + # '-salvagewallet', ] for m in maintenance: print("check " + m) @@ -338,4 +339,4 @@ class WalletTest (BitcoinTestFramework): assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) if __name__ == '__main__': - WalletTest ().main () + WalletTest().main() From 8b8f87714df8c1e0868e6411c8f09c838ea736ab Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 18 Apr 2016 17:02:43 -0400 Subject: [PATCH 0602/1223] net: make Ban/Unban/ClearBan functionality consistent - Ban/Unban/ClearBan call uiInterface.BannedListChanged() as necessary - Ban/Unban/ClearBan sync to disk if the operation is user-invoked - Mark node for disconnection automatically when banning - Lock cs_vNodes while setting disconnected - Don't spin in a tight loop while setting disconnected --- src/net.cpp | 44 +++++++++++++++++++++++++++++++------------ src/qt/rpcconsole.cpp | 5 +---- src/rpc/net.cpp | 10 ---------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 41e657fba..3f953a72d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -463,9 +463,13 @@ bool CNode::setBannedIsDirty; void CNode::ClearBanned() { - LOCK(cs_setBanned); - setBanned.clear(); - setBannedIsDirty = true; + { + LOCK(cs_setBanned); + setBanned.clear(); + setBannedIsDirty = true; + } + DumpBanlist(); //store banlist to disk + uiInterface.BannedListChanged(); } bool CNode::IsBanned(CNetAddr ip) @@ -516,11 +520,25 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; - LOCK(cs_setBanned); - if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) - setBanned[subNet] = banEntry; - - setBannedIsDirty = true; + { + LOCK(cs_setBanned); + if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) { + setBanned[subNet] = banEntry; + setBannedIsDirty = true; + } + else + return; + } + uiInterface.BannedListChanged(); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (subNet.Match((CNetAddr)pnode->addr)) + pnode->fDisconnect = true; + } + } + if(banReason == BanReasonManuallyAdded) + DumpBanlist(); //store banlist to disk immediately if user requested ban } bool CNode::Unban(const CNetAddr &addr) { @@ -529,13 +547,15 @@ bool CNode::Unban(const CNetAddr &addr) { } bool CNode::Unban(const CSubNet &subNet) { - LOCK(cs_setBanned); - if (setBanned.erase(subNet)) { + LOCK(cs_setBanned); + if (!setBanned.erase(subNet)) + return false; setBannedIsDirty = true; - return true; } - return false; + uiInterface.BannedListChanged(); + DumpBanlist(); //store banlist to disk immediately + return true; } void CNode::GetBanned(banmap_t &banMap) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index d8647d902..18552f073 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -885,15 +885,13 @@ void RPCConsole::banSelectedNode(int bantime) // Get currently selected peer address QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address); // Find possible nodes, ban it and clear the selected node - if (CNode *bannedNode = FindNode(strNode.toStdString())) { + if (FindNode(strNode.toStdString())) { std::string nStr = strNode.toStdString(); std::string addr; int port = 0; SplitHostPort(nStr, port, addr); CNode::Ban(CNetAddr(addr), BanReasonManuallyAdded, bantime); - bannedNode->fDisconnect = true; - DumpBanlist(); clearSelectedNode(); clientModel->getBanTableModel()->refresh(); @@ -912,7 +910,6 @@ void RPCConsole::unbanSelectedNode() if (possibleSubnet.IsValid()) { CNode::Unban(possibleSubnet); - DumpBanlist(); clientModel->getBanTableModel()->refresh(); } } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 320091b9c..e09af8965 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -565,20 +565,12 @@ UniValue setban(const UniValue& params, bool fHelp) absolute = true; isSubnet ? CNode::Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : CNode::Ban(netAddr, BanReasonManuallyAdded, banTime, absolute); - - //disconnect possible nodes - while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr))) - bannedNode->fDisconnect = true; } else if(strCommand == "remove") { if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) )) throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed"); } - - DumpBanlist(); //store banlist to disk - uiInterface.BannedListChanged(); - return NullUniValue; } @@ -624,8 +616,6 @@ UniValue clearbanned(const UniValue& params, bool fHelp) ); CNode::ClearBanned(); - DumpBanlist(); //store banlist to disk - uiInterface.BannedListChanged(); return NullUniValue; } From e9ed6206b32a05547dfa4bfa1e090044ddad7c82 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 18 Apr 2016 17:59:31 -0400 Subject: [PATCH 0603/1223] net: No need to export DumpBanlist --- src/net.cpp | 40 ++++++++++++++++++++-------------------- src/net.h | 2 -- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 3f953a72d..f5aa6abde 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -422,6 +422,26 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) return NULL; } +static void DumpBanlist() +{ + CNode::SweepBanned(); // clean unused entries (if bantime has expired) + + if (!CNode::BannedSetIsDirty()) + return; + + int64_t nStart = GetTimeMillis(); + + CBanDB bandb; + banmap_t banmap; + CNode::SetBannedSetDirty(false); + CNode::GetBanned(banmap); + if (!bandb.Write(banmap)) + CNode::SetBannedSetDirty(true); + + LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); +} + void CNode::CloseSocketDisconnect() { fDisconnect = true; @@ -2607,26 +2627,6 @@ bool CBanDB::Read(banmap_t& banSet) return true; } -void DumpBanlist() -{ - CNode::SweepBanned(); // clean unused entries (if bantime has expired) - - if (!CNode::BannedSetIsDirty()) - return; - - int64_t nStart = GetTimeMillis(); - - CBanDB bandb; - banmap_t banmap; - CNode::SetBannedSetDirty(false); - CNode::GetBanned(banmap); - if (!bandb.Write(banmap)) - CNode::SetBannedSetDirty(true); - - LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); -} - int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); } diff --git a/src/net.h b/src/net.h index b6ec7bf3e..167dc36a5 100644 --- a/src/net.h +++ b/src/net.h @@ -807,8 +807,6 @@ public: bool Read(banmap_t& banSet); }; -void DumpBanlist(); - /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); From 5d5e7a097a87e0fe6efb5e2d622daadc10c2ad79 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Sat, 16 Apr 2016 14:46:14 -0400 Subject: [PATCH 0604/1223] net: No need to export ConnectNode --- src/net.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/net.h b/src/net.h index 167dc36a5..70df27573 100644 --- a/src/net.h +++ b/src/net.h @@ -83,7 +83,6 @@ CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); -CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); From 10e83d795672ba2790f66cb023f9a78e7105c0e6 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Tue, 3 May 2016 09:18:36 -0500 Subject: [PATCH 0605/1223] Adding basic tests for OP_CSV inside of script_tests.json Changing NOP3 op name to OP_CHECKSEQUENCEVERIFY, renaming instances of OP_NOP3 in script_tests.json to CHECKSEQUENCEVERIFY Cleaning up NOP3 comment Re-adding test cases that were accidentally deleted, removing dupicated test case, fixing formatting Removing re-labeling of OP_NOP3 to OP_CSV Fixing whitespace issues --- src/test/data/script_tests.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index e75b7825e..757d94b52 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -700,6 +700,8 @@ ["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Zero-length R is correctly encoded"], ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"], + +["2147483648", "NOP3", "CHECKSEQUENCEVERIFY", "OK", "CSV passes if stack top bit 1 << 31 is set"], ["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], [" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], @@ -855,7 +857,7 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], @@ -1820,5 +1822,12 @@ "P2SH with CLEANSTACK" ], +["CHECKSEQUENCEVERIFY tests"], +["", "NOP3", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["-1", "NOP3", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], +["0x0100", "NOP3", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], +["0", "NOP3", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], +["4294967296", "NOP3", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", + "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], ["The End"] ] From fad60b3911236eabf89f4e06274500e57bb08d0d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 11 May 2016 13:19:10 +0200 Subject: [PATCH 0606/1223] [qa] Fix bip9-softforks blockstore issue --- qa/rpc-tests/bip9-softforks.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index e9b659d50..a8fb878dc 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -3,6 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +from test_framework.blockstore import BlockStore from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * from test_framework.mininode import CTransaction, NetworkThread @@ -167,11 +168,13 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance([[block, False]]) # Restart all + self.test.block_store.close() stop_nodes(self.nodes) wait_bitcoinds() shutil.rmtree(self.options.tmpdir) self.setup_chain() self.setup_network() + self.test.block_store = BlockStore(self.options.tmpdir) self.test.clear_all_connections() self.test.add_all_connections(self.nodes) NetworkThread().start() # Start up network handling in another thread From a545127fbccef4ee674d18d43732ce00ba97f782 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 11 May 2016 19:36:38 +0200 Subject: [PATCH 0607/1223] Squashed 'src/crypto/ctaes/' content from commit cd3c3ac git-subtree-dir: src/crypto/ctaes git-subtree-split: cd3c3ac31fac41cc253bf5780b55ecd8d7368545 --- COPYING | 21 +++ README.md | 41 ++++ bench.c | 170 +++++++++++++++++ ctaes.c | 556 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ctaes.h | 41 ++++ test.c | 110 +++++++++++ 6 files changed, 939 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 bench.c create mode 100644 ctaes.c create mode 100644 ctaes.h create mode 100644 test.c diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..415b202a2 --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 000000000..0e7fe1775 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +ctaes +===== + +Simple C module for constant-time AES encryption and decryption. + +Features: +* Simple, pure C code without any dependencies. +* No tables or data-dependent branches whatsoever, but using bit sliced approach from https://eprint.iacr.org/2009/129.pdf. +* Very small object code: slightly over 4k of executable code when compiled with -Os. +* Slower than implementations based on precomputed tables or specialized instructions, but can do ~15 MB/s on modern CPUs. + +Performance +----------- + +Compiled with GCC 5.3.1 with -O3, on an Intel(R) Core(TM) i7-4800MQ CPU, numbers in CPU cycles: + +| Algorithm | Key schedule | Encryption per byte | Decryption per byte | +| --------- | ------------:| -------------------:| -------------------:| +| AES-128 | 2.8k | 154 | 161 | +| AES-192 | 3.1k | 169 | 181 | +| AES-256 | 4.0k | 191 | 203 | + +Build steps +----------- + +Object code: + + $ gcc -O3 ctaes.c -c -o ctaes.o + +Tests: + + $ gcc -O3 ctaes.c test.c -o test + +Benchmark: + + $ gcc -O3 ctaes.c bench.c -o bench + +Review +------ + +Results of a formal review of the code can be found in http://bitcoin.sipa.be/ctaes/review.zip diff --git a/bench.c b/bench.c new file mode 100644 index 000000000..a86df496c --- /dev/null +++ b/bench.c @@ -0,0 +1,170 @@ +#include +#include +#include "sys/time.h" + +#include "ctaes.h" + +static double gettimedouble(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec * 0.000001 + tv.tv_sec; +} + +static void print_number(double x) { + double y = x; + int c = 0; + if (y < 0.0) { + y = -y; + } + while (y < 100.0) { + y *= 10.0; + c++; + } + printf("%.*f", c, x); +} + +static void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { + int i; + double min = HUGE_VAL; + double sum = 0.0; + double max = 0.0; + for (i = 0; i < count; i++) { + double begin, total; + if (setup != NULL) { + setup(data); + } + begin = gettimedouble(); + benchmark(data); + total = gettimedouble() - begin; + if (teardown != NULL) { + teardown(data); + } + if (total < min) { + min = total; + } + if (total > max) { + max = total; + } + sum += total; + } + printf("%s: min ", name); + print_number(min * 1000000000.0 / iter); + printf("ns / avg "); + print_number((sum / count) * 1000000000.0 / iter); + printf("ns / max "); + print_number(max * 1000000000.0 / iter); + printf("ns\n"); +} + +static void bench_AES128_init(void* data) { + AES128_ctx* ctx = (AES128_ctx*)data; + int i; + for (i = 0; i < 50000; i++) { + AES128_init(ctx, (unsigned char*)ctx); + } +} + +static void bench_AES128_encrypt_setup(void* data) { + AES128_ctx* ctx = (AES128_ctx*)data; + static const unsigned char key[16] = {0}; + AES128_init(ctx, key); +} + +static void bench_AES128_encrypt(void* data) { + const AES128_ctx* ctx = (const AES128_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES128_encrypt(ctx, 1, scratch, scratch); + } +} + +static void bench_AES128_decrypt(void* data) { + const AES128_ctx* ctx = (const AES128_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES128_decrypt(ctx, 1, scratch, scratch); + } +} + +static void bench_AES192_init(void* data) { + AES192_ctx* ctx = (AES192_ctx*)data; + int i; + for (i = 0; i < 50000; i++) { + AES192_init(ctx, (unsigned char*)ctx); + } +} + +static void bench_AES192_encrypt_setup(void* data) { + AES192_ctx* ctx = (AES192_ctx*)data; + static const unsigned char key[16] = {0}; + AES192_init(ctx, key); +} + +static void bench_AES192_encrypt(void* data) { + const AES192_ctx* ctx = (const AES192_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES192_encrypt(ctx, 1, scratch, scratch); + } +} + +static void bench_AES192_decrypt(void* data) { + const AES192_ctx* ctx = (const AES192_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES192_decrypt(ctx, 1, scratch, scratch); + } +} + +static void bench_AES256_init(void* data) { + AES256_ctx* ctx = (AES256_ctx*)data; + int i; + for (i = 0; i < 50000; i++) { + AES256_init(ctx, (unsigned char*)ctx); + } +} + + +static void bench_AES256_encrypt_setup(void* data) { + AES256_ctx* ctx = (AES256_ctx*)data; + static const unsigned char key[16] = {0}; + AES256_init(ctx, key); +} + +static void bench_AES256_encrypt(void* data) { + const AES256_ctx* ctx = (const AES256_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES256_encrypt(ctx, 1, scratch, scratch); + } +} + +static void bench_AES256_decrypt(void* data) { + const AES256_ctx* ctx = (const AES256_ctx*)data; + unsigned char scratch[16] = {0}; + int i; + for (i = 0; i < 4000000 / 16; i++) { + AES256_decrypt(ctx, 1, scratch, scratch); + } +} + +int main(void) { + AES128_ctx ctx128; + AES192_ctx ctx192; + AES256_ctx ctx256; + run_benchmark("aes128_init", bench_AES128_init, NULL, NULL, &ctx128, 20, 50000); + run_benchmark("aes128_encrypt_byte", bench_AES128_encrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000); + run_benchmark("aes128_decrypt_byte", bench_AES128_decrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000); + run_benchmark("aes192_init", bench_AES192_init, NULL, NULL, &ctx192, 20, 50000); + run_benchmark("aes192_encrypt_byte", bench_AES192_encrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000); + run_benchmark("aes192_decrypt_byte", bench_AES192_decrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000); + run_benchmark("aes256_init", bench_AES256_init, NULL, NULL, &ctx256, 20, 50000); + run_benchmark("aes256_encrypt_byte", bench_AES256_encrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000); + run_benchmark("aes256_decrypt_byte", bench_AES256_decrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000); + return 0; +} diff --git a/ctaes.c b/ctaes.c new file mode 100644 index 000000000..2389fc0bb --- /dev/null +++ b/ctaes.c @@ -0,0 +1,556 @@ + /********************************************************************* + * Copyright (c) 2016 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/* Constant time, unoptimized, concise, plain C, AES implementation + * Based On: + * Emilia Kasper and Peter Schwabe, Faster and Timing-Attack Resistant AES-GCM + * http://www.iacr.org/archive/ches2009/57470001/57470001.pdf + * But using 8 16-bit integers representing a single AES state rather than 8 128-bit + * integers representing 8 AES states. + */ + +#include "ctaes.h" + +/* Slice variable slice_i contains the i'th bit of the 16 state variables in this order: + * 0 1 2 3 + * 4 5 6 7 + * 8 9 10 11 + * 12 13 14 15 + */ + +/** Convert a byte to sliced form, storing it corresponding to given row and column in s */ +static void LoadByte(AES_state* s, unsigned char byte, int r, int c) { + int i; + for (i = 0; i < 8; i++) { + s->slice[i] |= (byte & 1) << (r * 4 + c); + byte >>= 1; + } +} + +/** Load 16 bytes of data into 8 sliced integers */ +static void LoadBytes(AES_state *s, const unsigned char* data16) { + int c; + for (c = 0; c < 4; c++) { + int r; + for (r = 0; r < 4; r++) { + LoadByte(s, *(data16++), r, c); + } + } +} + +/** Convert 8 sliced integers into 16 bytes of data */ +static void SaveBytes(unsigned char* data16, const AES_state *s) { + int c; + for (c = 0; c < 4; c++) { + int r; + for (r = 0; r < 4; r++) { + int b; + uint8_t v = 0; + for (b = 0; b < 8; b++) { + v |= ((s->slice[b] >> (r * 4 + c)) & 1) << b; + } + *(data16++) = v; + } + } +} + +/* S-box implementation based on the gate logic from: + * Joan Boyar and Rene Peralta, A depth-16 circuit for the AES S-box. + * https://eprint.iacr.org/2011/332.pdf +*/ +static void SubBytes(AES_state *s, int inv) { + /* Load the bit slices */ + uint16_t U0 = s->slice[7], U1 = s->slice[6], U2 = s->slice[5], U3 = s->slice[4]; + uint16_t U4 = s->slice[3], U5 = s->slice[2], U6 = s->slice[1], U7 = s->slice[0]; + + uint16_t T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16; + uint16_t T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, D; + uint16_t M1, M6, M11, M13, M15, M20, M21, M22, M23, M25, M37, M38, M39, M40; + uint16_t M41, M42, M43, M44, M45, M46, M47, M48, M49, M50, M51, M52, M53, M54; + uint16_t M55, M56, M57, M58, M59, M60, M61, M62, M63; + + if (inv) { + uint16_t R5, R13, R17, R18, R19; + /* Undo linear postprocessing */ + T23 = U0 ^ U3; + T22 = ~(U1 ^ U3); + T2 = ~(U0 ^ U1); + T1 = U3 ^ U4; + T24 = ~(U4 ^ U7); + R5 = U6 ^ U7; + T8 = ~(U1 ^ T23); + T19 = T22 ^ R5; + T9 = ~(U7 ^ T1); + T10 = T2 ^ T24; + T13 = T2 ^ R5; + T3 = T1 ^ R5; + T25 = ~(U2 ^ T1); + R13 = U1 ^ U6; + T17 = ~(U2 ^ T19); + T20 = T24 ^ R13; + T4 = U4 ^ T8; + R17 = ~(U2 ^ U5); + R18 = ~(U5 ^ U6); + R19 = ~(U2 ^ U4); + D = U0 ^ R17; + T6 = T22 ^ R17; + T16 = R13 ^ R19; + T27 = T1 ^ R18; + T15 = T10 ^ T27; + T14 = T10 ^ R18; + T26 = T3 ^ T16; + } else { + /* Linear preprocessing. */ + T1 = U0 ^ U3; + T2 = U0 ^ U5; + T3 = U0 ^ U6; + T4 = U3 ^ U5; + T5 = U4 ^ U6; + T6 = T1 ^ T5; + T7 = U1 ^ U2; + T8 = U7 ^ T6; + T9 = U7 ^ T7; + T10 = T6 ^ T7; + T11 = U1 ^ U5; + T12 = U2 ^ U5; + T13 = T3 ^ T4; + T14 = T6 ^ T11; + T15 = T5 ^ T11; + T16 = T5 ^ T12; + T17 = T9 ^ T16; + T18 = U3 ^ U7; + T19 = T7 ^ T18; + T20 = T1 ^ T19; + T21 = U6 ^ U7; + T22 = T7 ^ T21; + T23 = T2 ^ T22; + T24 = T2 ^ T10; + T25 = T20 ^ T17; + T26 = T3 ^ T16; + T27 = T1 ^ T12; + D = U7; + } + + /* Non-linear transformation (identical to the code in SubBytes) */ + M1 = T13 & T6; + M6 = T3 & T16; + M11 = T1 & T15; + M13 = (T4 & T27) ^ M11; + M15 = (T2 & T10) ^ M11; + M20 = T14 ^ M1 ^ (T23 & T8) ^ M13; + M21 = (T19 & D) ^ M1 ^ T24 ^ M15; + M22 = T26 ^ M6 ^ (T22 & T9) ^ M13; + M23 = (T20 & T17) ^ M6 ^ M15 ^ T25; + M25 = M22 & M20; + M37 = M21 ^ ((M20 ^ M21) & (M23 ^ M25)); + M38 = M20 ^ M25 ^ (M21 | (M20 & M23)); + M39 = M23 ^ ((M22 ^ M23) & (M21 ^ M25)); + M40 = M22 ^ M25 ^ (M23 | (M21 & M22)); + M41 = M38 ^ M40; + M42 = M37 ^ M39; + M43 = M37 ^ M38; + M44 = M39 ^ M40; + M45 = M42 ^ M41; + M46 = M44 & T6; + M47 = M40 & T8; + M48 = M39 & D; + M49 = M43 & T16; + M50 = M38 & T9; + M51 = M37 & T17; + M52 = M42 & T15; + M53 = M45 & T27; + M54 = M41 & T10; + M55 = M44 & T13; + M56 = M40 & T23; + M57 = M39 & T19; + M58 = M43 & T3; + M59 = M38 & T22; + M60 = M37 & T20; + M61 = M42 & T1; + M62 = M45 & T4; + M63 = M41 & T2; + + if (inv){ + /* Undo linear preprocessing */ + uint16_t P0 = M52 ^ M61; + uint16_t P1 = M58 ^ M59; + uint16_t P2 = M54 ^ M62; + uint16_t P3 = M47 ^ M50; + uint16_t P4 = M48 ^ M56; + uint16_t P5 = M46 ^ M51; + uint16_t P6 = M49 ^ M60; + uint16_t P7 = P0 ^ P1; + uint16_t P8 = M50 ^ M53; + uint16_t P9 = M55 ^ M63; + uint16_t P10 = M57 ^ P4; + uint16_t P11 = P0 ^ P3; + uint16_t P12 = M46 ^ M48; + uint16_t P13 = M49 ^ M51; + uint16_t P14 = M49 ^ M62; + uint16_t P15 = M54 ^ M59; + uint16_t P16 = M57 ^ M61; + uint16_t P17 = M58 ^ P2; + uint16_t P18 = M63 ^ P5; + uint16_t P19 = P2 ^ P3; + uint16_t P20 = P4 ^ P6; + uint16_t P22 = P2 ^ P7; + uint16_t P23 = P7 ^ P8; + uint16_t P24 = P5 ^ P7; + uint16_t P25 = P6 ^ P10; + uint16_t P26 = P9 ^ P11; + uint16_t P27 = P10 ^ P18; + uint16_t P28 = P11 ^ P25; + uint16_t P29 = P15 ^ P20; + s->slice[7] = P13 ^ P22; + s->slice[6] = P26 ^ P29; + s->slice[5] = P17 ^ P28; + s->slice[4] = P12 ^ P22; + s->slice[3] = P23 ^ P27; + s->slice[2] = P19 ^ P24; + s->slice[1] = P14 ^ P23; + s->slice[0] = P9 ^ P16; + } else { + /* Linear postprocessing */ + uint16_t L0 = M61 ^ M62; + uint16_t L1 = M50 ^ M56; + uint16_t L2 = M46 ^ M48; + uint16_t L3 = M47 ^ M55; + uint16_t L4 = M54 ^ M58; + uint16_t L5 = M49 ^ M61; + uint16_t L6 = M62 ^ L5; + uint16_t L7 = M46 ^ L3; + uint16_t L8 = M51 ^ M59; + uint16_t L9 = M52 ^ M53; + uint16_t L10 = M53 ^ L4; + uint16_t L11 = M60 ^ L2; + uint16_t L12 = M48 ^ M51; + uint16_t L13 = M50 ^ L0; + uint16_t L14 = M52 ^ M61; + uint16_t L15 = M55 ^ L1; + uint16_t L16 = M56 ^ L0; + uint16_t L17 = M57 ^ L1; + uint16_t L18 = M58 ^ L8; + uint16_t L19 = M63 ^ L4; + uint16_t L20 = L0 ^ L1; + uint16_t L21 = L1 ^ L7; + uint16_t L22 = L3 ^ L12; + uint16_t L23 = L18 ^ L2; + uint16_t L24 = L15 ^ L9; + uint16_t L25 = L6 ^ L10; + uint16_t L26 = L7 ^ L9; + uint16_t L27 = L8 ^ L10; + uint16_t L28 = L11 ^ L14; + uint16_t L29 = L11 ^ L17; + s->slice[7] = L6 ^ L24; + s->slice[6] = ~(L16 ^ L26); + s->slice[5] = ~(L19 ^ L28); + s->slice[4] = L6 ^ L21; + s->slice[3] = L20 ^ L22; + s->slice[2] = L25 ^ L29; + s->slice[1] = ~(L13 ^ L27); + s->slice[0] = ~(L6 ^ L23); + } +} + +#define BIT_RANGE(from,to) (((1 << ((to) - (from))) - 1) << (from)) + +#define BIT_RANGE_LEFT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) << (shift)) +#define BIT_RANGE_RIGHT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) >> (shift)) + +static void ShiftRows(AES_state* s) { + int i; + for (i = 0; i < 8; i++) { + uint16_t v = s->slice[i]; + s->slice[i] = + (v & BIT_RANGE(0, 4)) | + BIT_RANGE_LEFT(v, 4, 5, 3) | BIT_RANGE_RIGHT(v, 5, 8, 1) | + BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) | + BIT_RANGE_LEFT(v, 12, 15, 1) | BIT_RANGE_RIGHT(v, 15, 16, 3); + } +} + +static void InvShiftRows(AES_state* s) { + int i; + for (i = 0; i < 8; i++) { + uint16_t v = s->slice[i]; + s->slice[i] = + (v & BIT_RANGE(0, 4)) | + BIT_RANGE_LEFT(v, 4, 7, 1) | BIT_RANGE_RIGHT(v, 7, 8, 3) | + BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) | + BIT_RANGE_LEFT(v, 12, 13, 3) | BIT_RANGE_RIGHT(v, 13, 16, 1); + } +} + +#define ROT(x,b) (((x) >> ((b) * 4)) | ((x) << ((4-(b)) * 4))) + +static void MixColumns(AES_state* s, int inv) { + /* The MixColumns transform treats the bytes of the columns of the state as + * coefficients of a 3rd degree polynomial over GF(2^8) and multiplies them + * by the fixed polynomial a(x) = {03}x^3 + {01}x^2 + {01}x + {02}, modulo + * x^4 + {01}. + * + * In the inverse transform, we multiply by the inverse of a(x), + * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. This is equal to + * a(x) * ({04}x^2 + {05}), so we can reuse the forward transform's code + * (found in OpenSSL's bsaes-x86_64.pl, attributed to Jussi Kivilinna) + * + * In the bitsliced representation, a multiplication of every column by x + * mod x^4 + 1 is simply a right rotation. + */ + + /* Shared for both directions is a multiplication by a(x), which can be + * rewritten as (x^3 + x^2 + x) + {02}*(x^3 + {01}). + * + * First compute s into the s? variables, (x^3 + {01}) * s into the s?_01 + * variables and (x^3 + x^2 + x)*s into the s?_123 variables. + */ + uint16_t s0 = s->slice[0], s1 = s->slice[1], s2 = s->slice[2], s3 = s->slice[3]; + uint16_t s4 = s->slice[4], s5 = s->slice[5], s6 = s->slice[6], s7 = s->slice[7]; + uint16_t s0_01 = s0 ^ ROT(s0, 1), s0_123 = ROT(s0_01, 1) ^ ROT(s0, 3); + uint16_t s1_01 = s1 ^ ROT(s1, 1), s1_123 = ROT(s1_01, 1) ^ ROT(s1, 3); + uint16_t s2_01 = s2 ^ ROT(s2, 1), s2_123 = ROT(s2_01, 1) ^ ROT(s2, 3); + uint16_t s3_01 = s3 ^ ROT(s3, 1), s3_123 = ROT(s3_01, 1) ^ ROT(s3, 3); + uint16_t s4_01 = s4 ^ ROT(s4, 1), s4_123 = ROT(s4_01, 1) ^ ROT(s4, 3); + uint16_t s5_01 = s5 ^ ROT(s5, 1), s5_123 = ROT(s5_01, 1) ^ ROT(s5, 3); + uint16_t s6_01 = s6 ^ ROT(s6, 1), s6_123 = ROT(s6_01, 1) ^ ROT(s6, 3); + uint16_t s7_01 = s7 ^ ROT(s7, 1), s7_123 = ROT(s7_01, 1) ^ ROT(s7, 3); + /* Now compute s = s?_123 + {02} * s?_01. */ + s->slice[0] = s7_01 ^ s0_123; + s->slice[1] = s7_01 ^ s0_01 ^ s1_123; + s->slice[2] = s1_01 ^ s2_123; + s->slice[3] = s7_01 ^ s2_01 ^ s3_123; + s->slice[4] = s7_01 ^ s3_01 ^ s4_123; + s->slice[5] = s4_01 ^ s5_123; + s->slice[6] = s5_01 ^ s6_123; + s->slice[7] = s6_01 ^ s7_123; + if (inv) { + /* In the reverse direction, we further need to multiply by + * {04}x^2 + {05}, which can be written as {04} * (x^2 + {01}) + {01}. + * + * First compute (x^2 + {01}) * s into the t?_02 variables: */ + uint16_t t0_02 = s->slice[0] ^ ROT(s->slice[0], 2); + uint16_t t1_02 = s->slice[1] ^ ROT(s->slice[1], 2); + uint16_t t2_02 = s->slice[2] ^ ROT(s->slice[2], 2); + uint16_t t3_02 = s->slice[3] ^ ROT(s->slice[3], 2); + uint16_t t4_02 = s->slice[4] ^ ROT(s->slice[4], 2); + uint16_t t5_02 = s->slice[5] ^ ROT(s->slice[5], 2); + uint16_t t6_02 = s->slice[6] ^ ROT(s->slice[6], 2); + uint16_t t7_02 = s->slice[7] ^ ROT(s->slice[7], 2); + /* And then update s += {04} * t?_02 */ + s->slice[0] ^= t6_02; + s->slice[1] ^= t6_02 ^ t7_02; + s->slice[2] ^= t0_02 ^ t7_02; + s->slice[3] ^= t1_02 ^ t6_02; + s->slice[4] ^= t2_02 ^ t6_02 ^ t7_02; + s->slice[5] ^= t3_02 ^ t7_02; + s->slice[6] ^= t4_02; + s->slice[7] ^= t5_02; + } +} + +static void AddRoundKey(AES_state* s, const AES_state* round) { + int b; + for (b = 0; b < 8; b++) { + s->slice[b] ^= round->slice[b]; + } +} + +/** column_0(s) = column_c(a) */ +static void GetOneColumn(AES_state* s, const AES_state* a, int c) { + int b; + for (b = 0; b < 8; b++) { + s->slice[b] = (a->slice[b] >> c) & 0x1111; + } +} + +/** column_c1(r) |= (column_0(s) ^= column_c2(a)) */ +static void KeySetupColumnMix(AES_state* s, AES_state* r, const AES_state* a, int c1, int c2) { + int b; + for (b = 0; b < 8; b++) { + r->slice[b] |= ((s->slice[b] ^= ((a->slice[b] >> c2) & 0x1111)) & 0x1111) << c1; + } +} + +/** Rotate the rows in s one position upwards, and xor in r */ +static void KeySetupTransform(AES_state* s, const AES_state* r) { + int b; + for (b = 0; b < 8; b++) { + s->slice[b] = ((s->slice[b] >> 4) | (s->slice[b] << 12)) ^ r->slice[b]; + } +} + +/* Multiply the cells in s by x, as polynomials over GF(2) mod x^8 + x^4 + x^3 + x + 1 */ +static void MultX(AES_state* s) { + uint16_t top = s->slice[7]; + s->slice[7] = s->slice[6]; + s->slice[6] = s->slice[5]; + s->slice[5] = s->slice[4]; + s->slice[4] = s->slice[3] ^ top; + s->slice[3] = s->slice[2] ^ top; + s->slice[2] = s->slice[1]; + s->slice[1] = s->slice[0] ^ top; + s->slice[0] = top; +} + +/** Expand the cipher key into the key schedule. + * + * state must be a pointer to an array of size nrounds + 1. + * key must be a pointer to 4 * nkeywords bytes. + * + * AES128 uses nkeywords = 4, nrounds = 10 + * AES192 uses nkeywords = 6, nrounds = 12 + * AES256 uses nkeywords = 8, nrounds = 14 + */ +static void AES_setup(AES_state* rounds, const uint8_t* key, int nkeywords, int nrounds) +{ + int i; + + /* The one-byte round constant */ + AES_state rcon = {{1,0,0,0,0,0,0,0}}; + /* The number of the word being generated, modulo nkeywords */ + int pos = 0; + /* The column representing the word currently being processed */ + AES_state column; + + for (i = 0; i < nrounds + 1; i++) { + int b; + for (b = 0; b < 8; b++) { + rounds[i].slice[b] = 0; + } + } + + /* The first nkeywords round columns are just taken from the key directly. */ + for (i = 0; i < nkeywords; i++) { + int r; + for (r = 0; r < 4; r++) { + LoadByte(&rounds[i >> 2], *(key++), r, i & 3); + } + } + + GetOneColumn(&column, &rounds[(nkeywords - 1) >> 2], (nkeywords - 1) & 3); + + for (i = nkeywords; i < 4 * (nrounds + 1); i++) { + /* Transform column */ + if (pos == 0) { + SubBytes(&column, 0); + KeySetupTransform(&column, &rcon); + MultX(&rcon); + } else if (nkeywords > 6 && pos == 4) { + SubBytes(&column, 0); + } + if (++pos == nkeywords) pos = 0; + KeySetupColumnMix(&column, &rounds[i >> 2], &rounds[(i - nkeywords) >> 2], i & 3, (i - nkeywords) & 3); + } +} + +static void AES_encrypt(const AES_state* rounds, int nrounds, unsigned char* cipher16, const unsigned char* plain16) { + AES_state s = {{0}}; + int round; + + LoadBytes(&s, plain16); + AddRoundKey(&s, rounds++); + + for (round = 1; round < nrounds; round++) { + SubBytes(&s, 0); + ShiftRows(&s); + MixColumns(&s, 0); + AddRoundKey(&s, rounds++); + } + + SubBytes(&s, 0); + ShiftRows(&s); + AddRoundKey(&s, rounds); + + SaveBytes(cipher16, &s); +} + +static void AES_decrypt(const AES_state* rounds, int nrounds, unsigned char* plain16, const unsigned char* cipher16) { + /* Most AES decryption implementations use the alternate scheme + * (the Equivalent Inverse Cipher), which looks more like encryption, but + * needs different round constants. We can't reuse any code here anyway, so + * don't bother. */ + AES_state s = {{0}}; + int round; + + rounds += nrounds; + + LoadBytes(&s, cipher16); + AddRoundKey(&s, rounds--); + + for (round = 1; round < nrounds; round++) { + InvShiftRows(&s); + SubBytes(&s, 1); + AddRoundKey(&s, rounds--); + MixColumns(&s, 1); + } + + InvShiftRows(&s); + SubBytes(&s, 1); + AddRoundKey(&s, rounds); + + SaveBytes(plain16, &s); +} + +void AES128_init(AES128_ctx* ctx, const unsigned char* key16) { + AES_setup(ctx->rk, key16, 4, 10); +} + +void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) { + while (blocks--) { + AES_encrypt(ctx->rk, 10, cipher16, plain16); + cipher16 += 16; + plain16 += 16; + } +} + +void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) { + while (blocks--) { + AES_decrypt(ctx->rk, 10, plain16, cipher16); + cipher16 += 16; + plain16 += 16; + } +} + +void AES192_init(AES192_ctx* ctx, const unsigned char* key24) { + AES_setup(ctx->rk, key24, 6, 12); +} + +void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) { + while (blocks--) { + AES_encrypt(ctx->rk, 12, cipher16, plain16); + cipher16 += 16; + plain16 += 16; + } + +} + +void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) { + while (blocks--) { + AES_decrypt(ctx->rk, 12, plain16, cipher16); + cipher16 += 16; + plain16 += 16; + } +} + +void AES256_init(AES256_ctx* ctx, const unsigned char* key32) { + AES_setup(ctx->rk, key32, 8, 14); +} + +void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) { + while (blocks--) { + AES_encrypt(ctx->rk, 14, cipher16, plain16); + cipher16 += 16; + plain16 += 16; + } +} + +void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) { + while (blocks--) { + AES_decrypt(ctx->rk, 14, plain16, cipher16); + cipher16 += 16; + plain16 += 16; + } +} diff --git a/ctaes.h b/ctaes.h new file mode 100644 index 000000000..2f0af0421 --- /dev/null +++ b/ctaes.h @@ -0,0 +1,41 @@ + /********************************************************************* + * Copyright (c) 2016 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _CTAES_H_ +#define _CTAES_H_ 1 + +#include +#include + +typedef struct { + uint16_t slice[8]; +} AES_state; + +typedef struct { + AES_state rk[11]; +} AES128_ctx; + +typedef struct { + AES_state rk[13]; +} AES192_ctx; + +typedef struct { + AES_state rk[15]; +} AES256_ctx; + +void AES128_init(AES128_ctx* ctx, const unsigned char* key16); +void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16); +void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16); + +void AES192_init(AES192_ctx* ctx, const unsigned char* key24); +void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16); +void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16); + +void AES256_init(AES256_ctx* ctx, const unsigned char* key32); +void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16); +void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16); + +#endif diff --git a/test.c b/test.c new file mode 100644 index 000000000..fce1696ac --- /dev/null +++ b/test.c @@ -0,0 +1,110 @@ + /********************************************************************* + * Copyright (c) 2016 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include "ctaes.h" + +#include +#include +#include + +typedef struct { + int keysize; + const char* key; + const char* plain; + const char* cipher; +} ctaes_test; + +static const ctaes_test ctaes_tests[] = { + /* AES test vectors from FIPS 197. */ + {128, "000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a"}, + {192, "000102030405060708090a0b0c0d0e0f1011121314151617", "00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191"}, + {256, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089"}, + + /* AES-ECB test vectors from NIST sp800-38a. */ + {128, "2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"}, + {128, "2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"}, + {128, "2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"}, + {128, "2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"}, + {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "6bc1bee22e409f96e93d7e117393172a", "bd334f1d6e45f25ff712a214571fa5cc"}, + {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "ae2d8a571e03ac9c9eb76fac45af8e51", "974104846d0ad3ad7734ecb3ecee4eef"}, + {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "30c81c46a35ce411e5fbc1191a0a52ef", "ef7afd2270e2e60adce0ba2face6444e"}, + {192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "f69f2445df4f9b17ad2b417be66c3710", "9a4b41ba738d6c72fb16691603c18e0e"}, + {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"}, + {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"}, + {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"}, + {256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"} +}; + +static void from_hex(unsigned char* data, int len, const char* hex) { + int p; + for (p = 0; p < len; p++) { + int v = 0; + int n; + for (n = 0; n < 2; n++) { + assert((*hex >= '0' && *hex <= '9') || (*hex >= 'a' && *hex <= 'f')); + if (*hex >= '0' && *hex <= '9') { + v |= (*hex - '0') << (4 * (1 - n)); + } else { + v |= (*hex - 'a' + 10) << (4 * (1 - n)); + } + hex++; + } + *(data++) = v; + } + assert(*hex == 0); +} + +int main(void) { + int i; + int fail = 0; + for (i = 0; i < sizeof(ctaes_tests) / sizeof(ctaes_tests[0]); i++) { + unsigned char key[32], plain[16], cipher[16], ciphered[16], deciphered[16]; + const ctaes_test* test = &ctaes_tests[i]; + assert(test->keysize == 128 || test->keysize == 192 || test->keysize == 256); + from_hex(plain, 16, test->plain); + from_hex(cipher, 16, test->cipher); + switch (test->keysize) { + case 128: { + AES128_ctx ctx; + from_hex(key, 16, test->key); + AES128_init(&ctx, key); + AES128_encrypt(&ctx, 1, ciphered, plain); + AES128_decrypt(&ctx, 1, deciphered, cipher); + break; + } + case 192: { + AES192_ctx ctx; + from_hex(key, 24, test->key); + AES192_init(&ctx, key); + AES192_encrypt(&ctx, 1, ciphered, plain); + AES192_decrypt(&ctx, 1, deciphered, cipher); + break; + } + case 256: { + AES256_ctx ctx; + from_hex(key, 32, test->key); + AES256_init(&ctx, key); + AES256_encrypt(&ctx, 1, ciphered, plain); + AES256_decrypt(&ctx, 1, deciphered, cipher); + break; + } + } + if (memcmp(cipher, ciphered, 16)) { + fprintf(stderr, "E(key=\"%s\", plain=\"%s\") != \"%s\"\n", test->key, test->plain, test->cipher); + fail++; + } + if (memcmp(plain, deciphered, 16)) { + fprintf(stderr, "D(key=\"%s\", cipher=\"%s\") != \"%s\"\n", test->key, test->cipher, test->plain); + fail++; + } + } + if (fail == 0) { + fprintf(stderr, "All tests succesful\n"); + } else { + fprintf(stderr, "%i tests failed\n", fail); + } + return (fail != 0); +} From 32114dd63493fd169bf666fc3a5b4a912c083766 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 10 May 2016 18:19:03 +0200 Subject: [PATCH 0608/1223] bench: Add crypto hash benchmarks Add benchmarks for the cryptographic hash algorithms: - RIPEMD160 - SHA1 - SHA256 - SHA512 Continues work on #7883. --- src/Makefile.bench.include | 3 ++- src/bench/crypto_hash.cpp | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/bench/crypto_hash.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 24e2b3e0c..65fd24e05 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -8,7 +8,8 @@ bench_bench_bitcoin_SOURCES = \ bench/bench.cpp \ bench/bench.h \ bench/Examples.cpp \ - bench/rollingbloom.cpp + bench/rollingbloom.cpp \ + bench/crypto_hash.cpp bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp new file mode 100644 index 000000000..6b753f630 --- /dev/null +++ b/src/bench/crypto_hash.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include "bench.h" +#include "bloom.h" +#include "utiltime.h" +#include "crypto/ripemd160.h" +#include "crypto/sha1.h" +#include "crypto/sha256.h" +#include "crypto/sha512.h" + +/* Number of bytes to hash per iteration */ +static const uint64_t BUFFER_SIZE = 1000*1000; + +static void RIPEMD160(benchmark::State& state) +{ + uint8_t hash[CRIPEMD160::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CRIPEMD160().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA1(benchmark::State& state) +{ + uint8_t hash[CSHA1::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA1().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA256(benchmark::State& state) +{ + uint8_t hash[CSHA256::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA256().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA512(benchmark::State& state) +{ + uint8_t hash[CSHA512::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA512().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +BENCHMARK(RIPEMD160); +BENCHMARK(SHA1); +BENCHMARK(SHA256); +BENCHMARK(SHA512); From 8b0e4970281de15472a93a529302f3de15163943 Mon Sep 17 00:00:00 2001 From: Tyler Hardin Date: Wed, 11 May 2016 22:28:02 -0400 Subject: [PATCH 0609/1223] Qt: Add option to hide the system tray icon My changes leave all tray icon and menu creation/initialization logic untouched. It only shows or hides the icon according to the setting. A new checkbox was added to the OptionsDialog under the Window tab. A bool option named "hideTrayIcon" was added to OptionsModel. This checkbox was mapped like other all options to the OptionsModel. A signal was added to the OptionsModel for broadcasting changes the the hideTrayIcon option. This signal was connected to a new slot added to BitcoinGUI named setTrayIconVisible(bool). The slot simply hides or shows the trayIcon in BitcoinGUI according to the parameter recieved. --- src/qt/bitcoingui.cpp | 20 +++++++++++++++++++- src/qt/bitcoingui.h | 3 +++ src/qt/forms/optionsdialog.ui | 10 ++++++++++ src/qt/optionsdialog.cpp | 14 ++++++++++++++ src/qt/optionsdialog.h | 2 ++ src/qt/optionsmodel.cpp | 14 +++++++++++++- src/qt/optionsmodel.h | 4 ++++ 7 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b00cdfcaf..998448636 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -474,6 +474,16 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(clientModel->getOptionsModel()); + + OptionsModel* optionsModel = clientModel->getOptionsModel(); + if(optionsModel) + { + // be aware of the tray icon disable state change reported by the OptionsModel object. + connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool))); + + // initialize the disable state of the tray icon with the current value in the model. + setTrayIconVisible(optionsModel->getHideTrayIcon()); + } } else { // Disable possibility to show main window via action toggleHideAction->setEnabled(false); @@ -535,7 +545,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText(); trayIcon->setToolTip(toolTip); trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); - trayIcon->show(); + trayIcon->hide(); #endif notificator = new Notificator(QApplication::applicationName(), trayIcon, this); @@ -1044,6 +1054,14 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress) progressDialog->setValue(nProgress); } +void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) +{ + if (trayIcon) + { + trayIcon->setVisible(!fHideTrayIcon); + } +} + static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 871ca1ba3..27ef11c75 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -218,6 +218,9 @@ private Q_SLOTS: /** Show progress dialog e.g. for verifychain */ void showProgress(const QString &title, int nProgress); + + /** When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly. */ + void setTrayIconVisible(bool); }; class UnitDisplayStatusBarControl : public QLabel diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index c712e6ea0..0b2920187 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -504,6 +504,16 @@ &Window + + + + &Hide the icon from the system tray. + + + Hide tray icon + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 95a3fa8d2..f2db39889 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -198,6 +198,7 @@ void OptionsDialog::setMapper() /* Window */ #ifndef Q_OS_MAC + mapper->addMapping(ui->hideTrayIcon, OptionsModel::HideTrayIcon); mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose); #endif @@ -243,6 +244,19 @@ void OptionsDialog::on_cancelButton_clicked() reject(); } +void OptionsDialog::on_hideTrayIcon_stateChanged(int fState) +{ + if(fState) + { + ui->minimizeToTray->setChecked(false); + ui->minimizeToTray->setEnabled(false); + } + else + { + ui->minimizeToTray->setEnabled(true); + } +} + void OptionsDialog::showRestartWarning(bool fPersistent) { ui->statusLabel->setStyleSheet("QLabel { color: red; }"); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index e944fb9ee..41b56d138 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -49,6 +49,8 @@ private Q_SLOTS: void on_resetButton_clicked(); void on_okButton_clicked(); void on_cancelButton_clicked(); + + void on_hideTrayIcon_stateChanged(int fState); void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d091bb9e6..cc2cbc0e6 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -51,9 +51,14 @@ void OptionsModel::Init(bool resetSettings) // These are Qt-only settings: // Window + if (!settings.contains("fHideTrayIcon")) + settings.setValue("fHideTrayIcon", false); + fHideTrayIcon = settings.value("fHideTrayIcon").toBool(); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + if (!settings.contains("fMinimizeToTray")) settings.setValue("fMinimizeToTray", false); - fMinimizeToTray = settings.value("fMinimizeToTray").toBool(); + fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon; if (!settings.contains("fMinimizeOnClose")) settings.setValue("fMinimizeOnClose", false); @@ -166,6 +171,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const { case StartAtStartup: return GUIUtil::GetStartOnSystemStartup(); + case HideTrayIcon: + return fHideTrayIcon; case MinimizeToTray: return fMinimizeToTray; case MapPortUPnP: @@ -242,6 +249,11 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case StartAtStartup: successful = GUIUtil::SetStartOnSystemStartup(value.toBool()); break; + case HideTrayIcon: + fHideTrayIcon = value.toBool(); + settings.setValue("fHideTrayIcon", fHideTrayIcon); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + break; case MinimizeToTray: fMinimizeToTray = value.toBool(); settings.setValue("fMinimizeToTray", fMinimizeToTray); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 841711dd2..3b491ceac 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -28,6 +28,7 @@ public: enum OptionID { StartAtStartup, // bool + HideTrayIcon, // bool MinimizeToTray, // bool MapPortUPnP, // bool MinimizeOnClose, // bool @@ -58,6 +59,7 @@ public: void setDisplayUnit(const QVariant &value); /* Explicit getters */ + bool getHideTrayIcon() { return fHideTrayIcon; } bool getMinimizeToTray() { return fMinimizeToTray; } bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } @@ -72,6 +74,7 @@ public: private: /* Qt-only settings */ + bool fHideTrayIcon; bool fMinimizeToTray; bool fMinimizeOnClose; QString language; @@ -87,6 +90,7 @@ private: Q_SIGNALS: void displayUnitChanged(int unit); void coinControlFeaturesChanged(bool); + void hideTrayIconChanged(bool); }; #endif // BITCOIN_QT_OPTIONSMODEL_H From 276ce84fd3a9561a11ae4c5a00c71ff44d3a59a9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 11 May 2016 21:08:36 +0200 Subject: [PATCH 0610/1223] [Qt] Disable some menu items during splashscreen/verification state --- src/qt/bitcoingui.cpp | 12 ++++++++++++ src/qt/bitcoingui.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b00cdfcaf..aa8276a69 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -320,12 +320,14 @@ void BitcoinGUI::createActions() aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About %1").arg(tr(PACKAGE_NAME)), this); aboutAction->setStatusTip(tr("Show information about %1").arg(tr(PACKAGE_NAME))); aboutAction->setMenuRole(QAction::AboutRole); + aboutAction->setEnabled(false); aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(tr(PACKAGE_NAME))); optionsAction->setMenuRole(QAction::PreferencesRole); + optionsAction->setEnabled(false); toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); @@ -343,6 +345,8 @@ void BitcoinGUI::createActions() openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); + // initially disable the debug window menu item + openRPCConsoleAction->setEnabled(false); usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels")); @@ -891,6 +895,14 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) QMainWindow::closeEvent(event); } +void BitcoinGUI::showEvent(QShowEvent *event) +{ + // enable the debug window when the main window shows up + openRPCConsoleAction->setEnabled(true); + aboutAction->setEnabled(true); + optionsAction->setEnabled(true); +} + #ifdef ENABLE_WALLET void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label) { diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 871ca1ba3..ef8b8726f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -72,6 +72,7 @@ public: protected: void changeEvent(QEvent *e); void closeEvent(QCloseEvent *event); + void showEvent(QShowEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); bool eventFilter(QObject *object, QEvent *event); From 34ebceb25a40a2160349656265951cbe9a5b0f34 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 12 May 2016 09:51:43 +0200 Subject: [PATCH 0611/1223] [Qt][OSX] Fix Cmd-Q / Menu Quit shutdown on OSX --- src/qt/bitcoin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 9c21bb24c..6218ab6ab 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -370,6 +370,7 @@ void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) splash->setAttribute(Qt::WA_DeleteOnClose); splash->show(); connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); + connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); } void BitcoinApplication::startThread() From fab5233fe6c99d446a2cebc48cf479c3f026c2cc Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 12 May 2016 12:54:00 +0200 Subject: [PATCH 0612/1223] [qa] test_framework: Set wait-timeout for bitcoind procs --- qa/rpc-tests/test_framework/util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 6784177aa..d62b8ac55 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -35,6 +35,8 @@ PORT_MIN = 11000 # The number of ports to "reserve" for p2p and rpc, each PORT_RANGE = 5000 +BITCOIND_PROC_WAIT_TIMEOUT = 60 + class PortSeed: # Must be initialized with a unique integer for each process @@ -325,7 +327,7 @@ def stop_node(node, i): node.stop() except http.client.CannotSendRequest as e: print("WARN: Unable to stop node: " + repr(e)) - bitcoind_processes[i].wait() + bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) del bitcoind_processes[i] def stop_nodes(nodes): @@ -343,7 +345,7 @@ def set_node_times(nodes, t): def wait_bitcoinds(): # Wait for all bitcoinds to cleanly exit for bitcoind in bitcoind_processes.values(): - bitcoind.wait() + bitcoind.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) bitcoind_processes.clear() def connect_nodes(from_connection, node_num): From e5764e69cbd0bf4eb98c96eeb31c94349bbe7b7c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 12 May 2016 13:48:58 +0200 Subject: [PATCH 0613/1223] doc: Remove outdated qt4 install information from README.md This text is aimed at users installing the binaries. Now that Qt5 is linked statically, there is no need to install Qt as a run-time dependency. --- doc/README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/README.md b/doc/README.md index cf475ef18..a5524889d 100644 --- a/doc/README.md +++ b/doc/README.md @@ -11,17 +11,11 @@ The following are some helpful notes on how to run Bitcoin on your native platfo ### Unix -You need the Qt4 run-time libraries to run Bitcoin-Qt. On Debian or Ubuntu: - - sudo apt-get install libqtgui4 - Unpack the files into a directory and run: - bin/32/bitcoin-qt (GUI, 32-bit) or bin/32/bitcoind (headless, 32-bit) - bin/64/bitcoin-qt (GUI, 64-bit) or bin/64/bitcoind (headless, 64-bit) - - ### Windows Unpack the files into a directory, and then run bitcoin-qt.exe. From 581ddff05c92eb835a20c2be9ccf5d2d37b94883 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 12 May 2016 14:00:22 +0200 Subject: [PATCH 0614/1223] net: Add fRelayTxes flag Add a fRelayTxes to keep track of the relay transaction flag we send to other peers. --- src/init.cpp | 1 + src/main.cpp | 4 ++-- src/net.cpp | 3 ++- src/net.h | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d19ca530b..3218321a3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1102,6 +1102,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fListen = GetBoolArg("-listen", DEFAULT_LISTEN); fDiscover = GetBoolArg("-discover", true); fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); + fRelayTxes = !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); bool fBound = false; if (fListen) { diff --git a/src/main.cpp b/src/main.cpp index ee30954b4..f813056a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4751,7 +4751,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return error("message inv size() = %u", vInv.size()); } - bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); + bool fBlocksOnly = !fRelayTxes; // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) @@ -4934,7 +4934,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { // Stop processing the transaction early if // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) + if (!fRelayTxes && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) { LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id); return true; diff --git a/src/net.cpp b/src/net.cpp index 5e810a0f1..da5090dbc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -77,6 +77,7 @@ const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; bool fDiscover = true; bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; +bool fRelayTxes = true; CCriticalSection cs_mapLocalHost; map mapLocalHost; static bool vfLimited[NET_MAX] = {}; @@ -454,7 +455,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); + nLocalHostNonce, strSubVersion, nBestHeight, fRelayTxes); } diff --git a/src/net.h b/src/net.h index b6ec7bf3e..66511e0fb 100644 --- a/src/net.h +++ b/src/net.h @@ -153,6 +153,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); extern bool fDiscover; extern bool fListen; extern uint64_t nLocalServices; +extern bool fRelayTxes; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; From 1ab1dc3140ff521df42f1f396a49a50e91bf2740 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 12 May 2016 14:09:43 +0200 Subject: [PATCH 0615/1223] rpc: Add `relaytxes` flag to `getnetworkinfo` Re-work of PR #7841 by dragongem45. Closes #7771. --- src/rpc/net.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 320091b9c..3297d2c6e 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -460,6 +460,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n" + " \"localrelay\": true|false, (bool) true if transaction relay is requested from peers\n" " \"timeoffset\": xxxxx, (numeric) the time offset\n" " \"connections\": xxxxx, (numeric) the number of connections\n" " \"networks\": [ (array) information per network\n" @@ -494,6 +495,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("subversion", strSubVersion)); obj.push_back(Pair("protocolversion",PROTOCOL_VERSION)); obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices))); + obj.push_back(Pair("localrelay", fRelayTxes)); obj.push_back(Pair("timeoffset", GetTimeOffset())); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); From 2692e1b10bd7a0be644ed8a69c54152bc741e855 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 9 May 2016 16:30:27 +0800 Subject: [PATCH 0616/1223] [Doc] Simplify OS X build notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add —c++11 flags to brew dependancies that support it Remove release-build section, this is covered by depends/release-notes --- doc/build-osx.md | 138 ++++++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 87 deletions(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index 296e0aa1f..89d7816c9 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,68 +1,78 @@ Mac OS X Build Instructions and Notes ==================================== -This guide will show you how to build Bitcoin Core for OS X. - -Notes ------ - -* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only. - -* All of the commands should be executed in a Terminal application. The -built-in one is located in `/Applications/Utilities`. +The commands in this guide should be executed in a Terminal application. +The built-in one is located in `/Applications/Utilities/Terminal.app`. Preparation ----------- +Download and install [Xcode](https://developer.apple.com/xcode/download). -You need to install Xcode with all the options checked so that the compiler -and everything is available in /usr not just /Developer. Xcode should be -available on your OS X installation media, but if not, you can get the -current version from https://developer.apple.com/xcode/. If you install -Xcode 4.3 or later, you'll need to install its command line tools. This can -be done in `Xcode > Preferences > Downloads > Components` and generally must -be re-done or updated every time Xcode is updated. +Once installed, run `xcode-select --install` to install the OS X command line tools. -You will also need to install [Homebrew](http://brew.sh) in order to install library -dependencies. +Install [Homebrew](http://brew.sh). -The installation of the actual dependencies is covered in the instructions -sections below. - -Instructions: Homebrew +Dependencies ---------------------- -#### Install dependencies using Homebrew + brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent - brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf qt5 libevent +NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended. -NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended. +Build Bitcoin Core +------------------------ -### Building `bitcoin` +1. Clone the bitcoin source code and cd into `bitcoin` -1. Clone the GitHub tree to get the source code and go into the directory. - - git clone https://github.com/bitcoin/bitcoin.git + git clone https://github.com/bitcoin/bitcoin cd bitcoin 2. Build bitcoin-core: - This will configure and build the headless bitcoin binaries as well as the gui (if Qt is found). - You can disable the gui build by passing `--without-gui` to configure. + + Configure and build the headless bitcoin binaries as well as the GUI (if Qt is found). + + You can disable the GUI build by passing `--without-gui` to configure. ./autogen.sh ./configure make -3. It is also a good idea to build and run the unit tests: +3. It is recommended to build and run the unit tests: make check -4. (Optional) You can also install bitcoind to your path: +4. You can also create a .dmg that contains the .app bundle (optional): - make install + make deploy -Use Qt Creator as IDE +Running +------- + +Bitcoin Core is now available at `./src/bitcoind` + +Before running, it's recommended you create an RPC configuration file. + + echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" + + chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" + +The first time you run bitcoind, it will start downloading the blockchain. This process could take several hours. + +You can monitor the download process by looking at the debug.log file: + + tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log + +Other commands: +------- + + ./src/bitcoind -daemon # Starts the bitcoin daemon. + ./src/bitcoin-cli --help # Outputs a list of command-line options. + ./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. + +Using Qt Creator as IDE ------------------------ -You can use Qt Creator as IDE, for debugging and for manipulating forms, etc. -Download Qt Creator from https://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process). +You can use Qt Creator as an IDE, for bitcoin development. +Download and install the community edition of [Qt Creator](https://www.qt.io/download/). +Uncheck everything except Qt Creator during the installation process. 1. Make sure you installed everything through Homebrew mentioned above 2. Do a proper ./configure --enable-debug @@ -75,55 +85,9 @@ Download Qt Creator from https://www.qt.io/download/. Download the "community ed 9. Select LLDB as debugger (you might need to set the path to your installation) 10. Start debugging with Qt Creator -Creating a release build ------------------------- -You can ignore this section if you are building `bitcoind` for your own use. +Notes +----- -bitcoind/bitcoin-cli binaries are not included in the Bitcoin-Qt.app bundle. +* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only. -If you are building `bitcoind` or `Bitcoin Core` for others, your build machine should be set up -as follows for maximum compatibility: - -All dependencies should be compiled with these flags: - - -mmacosx-version-min=10.7 - -arch x86_64 - -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk - -Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin Core -bundle is packaged and signed to create the .dmg disk image that is distributed. - -Running -------- - -It's now available at `./bitcoind`, provided that you are still in the `src` -directory. We have to first create the RPC configuration file, though. - -Run `./bitcoind` to get the filename where it should be put, or just try these -commands: - - echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" - chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" - -The next time you run it, it will start downloading the blockchain, but it won't -output anything while it's doing this. This process may take several hours; -you can monitor its process by looking at the debug.log file, like this: - - tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log - -Other commands: -------- - - ./bitcoind -daemon # to start the bitcoin daemon. - ./bitcoin-cli --help # for a list of command-line options. - ./bitcoin-cli help # When the daemon is running, to get a list of RPC commands - -Using Qt official installer while building ------------------------------------------- - -If you prefer to use the latest Qt installed from the official binary -installer over the brew version, you have to make several changes to -the installed tree and its binaries (all these changes are contained -in the brew version already). The changes needed are described in -[#7714](https://github.com/bitcoin/bitcoin/issues/7714). We do not -support building Bitcoin Core this way though. +* Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) From 6bec172eb95e195847bb6dd6d4e62ada79c98c6d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 30 Mar 2016 15:37:41 +0200 Subject: [PATCH 0617/1223] Add ctaes-based constant time AES implementation --- src/Makefile.am | 4 ++- src/crypto/aes.cpp | 73 +++++++++++++++++++++++++++++++++++++++ src/crypto/aes.h | 66 +++++++++++++++++++++++++++++++++++ src/test/crypto_tests.cpp | 56 ++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 src/crypto/aes.cpp create mode 100644 src/crypto/aes.h diff --git a/src/Makefile.am b/src/Makefile.am index 3c056386f..0ab0d66ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -225,6 +225,8 @@ libbitcoin_wallet_a_SOURCES = \ crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES) crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_SOURCES = \ + crypto/aes.cpp \ + crypto/aes.h \ crypto/common.h \ crypto/hmac_sha256.cpp \ crypto/hmac_sha256.h \ @@ -434,7 +436,7 @@ CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb +EXTRA_DIST = leveldb crypto/ctaes clean-local: -$(MAKE) -C leveldb clean diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp new file mode 100644 index 000000000..035abd75b --- /dev/null +++ b/src/crypto/aes.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "aes.h" +#include "crypto/common.h" + +#include +#include + +extern "C" { +#include "crypto/ctaes/ctaes.c" +} + +AES128Encrypt::AES128Encrypt(const unsigned char key[16]) +{ + AES128_init(&ctx, key); +} + +AES128Encrypt::~AES128Encrypt() +{ + memset(&ctx, 0, sizeof(ctx)); +} + +void AES128Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const +{ + AES128_encrypt(&ctx, 1, ciphertext, plaintext); +} + +AES128Decrypt::AES128Decrypt(const unsigned char key[16]) +{ + AES128_init(&ctx, key); +} + +AES128Decrypt::~AES128Decrypt() +{ + memset(&ctx, 0, sizeof(ctx)); +} + +void AES128Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const +{ + AES128_decrypt(&ctx, 1, plaintext, ciphertext); +} + +AES256Encrypt::AES256Encrypt(const unsigned char key[32]) +{ + AES256_init(&ctx, key); +} + +AES256Encrypt::~AES256Encrypt() +{ + memset(&ctx, 0, sizeof(ctx)); +} + +void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const +{ + AES256_encrypt(&ctx, 1, ciphertext, plaintext); +} + +AES256Decrypt::AES256Decrypt(const unsigned char key[32]) +{ + AES256_init(&ctx, key); +} + +AES256Decrypt::~AES256Decrypt() +{ + memset(&ctx, 0, sizeof(ctx)); +} + +void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const +{ + AES256_decrypt(&ctx, 1, plaintext, ciphertext); +} diff --git a/src/crypto/aes.h b/src/crypto/aes.h new file mode 100644 index 000000000..4bf17a33e --- /dev/null +++ b/src/crypto/aes.h @@ -0,0 +1,66 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// +// C++ wrapper around ctaes, a constant-time AES implementation + +#ifndef BITCOIN_CRYPTO_AES_H +#define BITCOIN_CRYPTO_AES_H + +extern "C" { +#include "crypto/ctaes/ctaes.h" +} + +static const int AES_BLOCKSIZE = 16; +static const int AES128_KEYSIZE = 16; +static const int AES256_KEYSIZE = 32; + +/** An encryption class for AES-128. */ +class AES128Encrypt +{ +private: + AES128_ctx ctx; + +public: + AES128Encrypt(const unsigned char key[16]); + ~AES128Encrypt(); + void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; +}; + +/** A decryption class for AES-128. */ +class AES128Decrypt +{ +private: + AES128_ctx ctx; + +public: + AES128Decrypt(const unsigned char key[16]); + ~AES128Decrypt(); + void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; +}; + +/** An encryption class for AES-256. */ +class AES256Encrypt +{ +private: + AES256_ctx ctx; + +public: + AES256Encrypt(const unsigned char key[32]); + ~AES256Encrypt(); + void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const; +}; + +/** A decryption class for AES-256. */ +class AES256Decrypt +{ +private: + AES256_ctx ctx; + +public: + AES256Decrypt(const unsigned char key[32]); + ~AES256Decrypt(); + void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; +}; + +#endif // BITCOIN_CRYPTO_AES_H diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 0b46d718d..3fc9855d6 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_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 "crypto/aes.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" @@ -63,6 +64,45 @@ void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const s TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout)); } +void TestAES128(const std::string &hexkey, const std::string &hexin, const std::string &hexout) +{ + std::vector key = ParseHex(hexkey); + std::vector in = ParseHex(hexin); + std::vector correctout = ParseHex(hexout); + std::vector buf, buf2; + + assert(key.size() == 16); + assert(in.size() == 16); + assert(correctout.size() == 16); + AES128Encrypt enc(&key[0]); + buf.resize(correctout.size()); + buf2.resize(correctout.size()); + enc.Encrypt(&buf[0], &in[0]); + BOOST_CHECK_EQUAL(HexStr(buf), HexStr(correctout)); + AES128Decrypt dec(&key[0]); + dec.Decrypt(&buf2[0], &buf[0]); + BOOST_CHECK_EQUAL(HexStr(buf2), HexStr(in)); +} + +void TestAES256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) +{ + std::vector key = ParseHex(hexkey); + std::vector in = ParseHex(hexin); + std::vector correctout = ParseHex(hexout); + std::vector buf; + + assert(key.size() == 32); + assert(in.size() == 16); + assert(correctout.size() == 16); + AES256Encrypt enc(&key[0]); + buf.resize(correctout.size()); + enc.Encrypt(&buf[0], &in[0]); + BOOST_CHECK(buf == correctout); + AES256Decrypt dec(&key[0]); + dec.Decrypt(&buf[0], &buf[0]); + BOOST_CHECK(buf == in); +} + std::string LongTestString(void) { std::string ret; for (int i=0; i<200000; i++) { @@ -248,4 +288,20 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) { "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); } +BOOST_AUTO_TEST_CASE(aes_testvectors) { + // AES test vectors from FIPS 197. + TestAES128("000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a"); + TestAES256("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089"); + + // AES-ECB test vectors from NIST sp800-38a. + TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"); + TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"); + TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"); + TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"); + TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"); + TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"); + TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"); + TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"); +} + BOOST_AUTO_TEST_SUITE_END() From 27a212dcb4fe842ead77d01b98f2c1a58ecca609 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 00:49:13 -0400 Subject: [PATCH 0618/1223] crypto: add AES 128/256 CBC classes The output should always match openssl's, even for failed operations. Even for a decrypt with broken padding, the output is always deterministic (and attemtps to be constant-time). --- src/crypto/aes.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++++ src/crypto/aes.h | 52 ++++++++++++++++ 2 files changed, 196 insertions(+) diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp index 035abd75b..1d469d0fb 100644 --- a/src/crypto/aes.cpp +++ b/src/crypto/aes.cpp @@ -71,3 +71,147 @@ void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char cip { AES256_decrypt(&ctx, 1, plaintext, ciphertext); } + + +template +static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out) +{ + int written = 0; + int padsize = size % AES_BLOCKSIZE; + unsigned char mixed[AES_BLOCKSIZE]; + + if (!data || !size || !out) + return 0; + + if (!pad && padsize != 0) + return 0; + + memcpy(mixed, iv, AES_BLOCKSIZE); + + // Write all but the last block + while (written + AES_BLOCKSIZE <= size) { + for (int i = 0; i != AES_BLOCKSIZE; i++) + mixed[i] ^= *data++; + enc.Encrypt(out + written, mixed); + memcpy(mixed, out + written, AES_BLOCKSIZE); + written += AES_BLOCKSIZE; + } + if (pad) { + // For all that remains, pad each byte with the value of the remaining + // space. If there is none, pad by a full block. + for (int i = 0; i != padsize; i++) + mixed[i] ^= *data++; + for (int i = padsize; i != AES_BLOCKSIZE; i++) + mixed[i] ^= AES_BLOCKSIZE - padsize; + enc.Encrypt(out + written, mixed); + written += AES_BLOCKSIZE; + } + return written; +} + +template +static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out) +{ + unsigned char padsize = 0; + int written = 0; + bool fail = false; + const unsigned char* prev = iv; + + if (!data || !size || !out) + return 0; + + if (size % AES_BLOCKSIZE != 0) + return 0; + + // Decrypt all data. Padding will be checked in the output. + while (written != size) { + dec.Decrypt(out, data + written); + for (int i = 0; i != AES_BLOCKSIZE; i++) + *out++ ^= prev[i]; + prev = data + written; + written += AES_BLOCKSIZE; + } + + // When decrypting padding, attempt to run in constant-time + if (pad) { + // If used, padding size is the value of the last decrypted byte. For + // it to be valid, It must be between 1 and AES_BLOCKSIZE. + padsize = *--out; + fail = !padsize | (padsize > AES_BLOCKSIZE); + + // If not well-formed, treat it as though there's no padding. + padsize *= !fail; + + // All padding must equal the last byte otherwise it's not well-formed + for (int i = AES_BLOCKSIZE; i != 0; i--) + fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize)); + + written -= padsize; + } + return written * !fail; +} + +AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn) + : enc(key), pad(padIn) +{ + memcpy(iv, ivIn, AES_BLOCKSIZE); +} + +int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const +{ + return CBCEncrypt(enc, iv, data, size, pad, out); +} + +AES256CBCEncrypt::~AES256CBCEncrypt() +{ + memset(iv, 0, sizeof(iv)); +} + +AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn) + : dec(key), pad(padIn) +{ + memcpy(iv, ivIn, AES_BLOCKSIZE); +} + + +int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const +{ + return CBCDecrypt(dec, iv, data, size, pad, out); +} + +AES256CBCDecrypt::~AES256CBCDecrypt() +{ + memset(iv, 0, sizeof(iv)); +} + +AES128CBCEncrypt::AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn) + : enc(key), pad(padIn) +{ + memcpy(iv, ivIn, AES_BLOCKSIZE); +} + +AES128CBCEncrypt::~AES128CBCEncrypt() +{ + memset(iv, 0, AES_BLOCKSIZE); +} + +int AES128CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const +{ + return CBCEncrypt(enc, iv, data, size, pad, out); +} + +AES128CBCDecrypt::AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn) + : dec(key), pad(padIn) +{ + memcpy(iv, ivIn, AES_BLOCKSIZE); +} + +AES128CBCDecrypt::~AES128CBCDecrypt() +{ + memset(iv, 0, AES_BLOCKSIZE); +} + +int AES128CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const +{ + return CBCDecrypt(dec, iv, data, size, pad, out); +} diff --git a/src/crypto/aes.h b/src/crypto/aes.h index 4bf17a33e..8cae357c1 100644 --- a/src/crypto/aes.h +++ b/src/crypto/aes.h @@ -63,4 +63,56 @@ public: void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const; }; +class AES256CBCEncrypt +{ +public: + AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn); + ~AES256CBCEncrypt(); + int Encrypt(const unsigned char* data, int size, unsigned char* out) const; + +private: + const AES256Encrypt enc; + const bool pad; + unsigned char iv[AES_BLOCKSIZE]; +}; + +class AES256CBCDecrypt +{ +public: + AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn); + ~AES256CBCDecrypt(); + int Decrypt(const unsigned char* data, int size, unsigned char* out) const; + +private: + const AES256Decrypt dec; + const bool pad; + unsigned char iv[AES_BLOCKSIZE]; +}; + +class AES128CBCEncrypt +{ +public: + AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn); + ~AES128CBCEncrypt(); + int Encrypt(const unsigned char* data, int size, unsigned char* out) const; + +private: + const AES128Encrypt enc; + const bool pad; + unsigned char iv[AES_BLOCKSIZE]; +}; + +class AES128CBCDecrypt +{ +public: + AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn); + ~AES128CBCDecrypt(); + int Decrypt(const unsigned char* data, int size, unsigned char* out) const; + +private: + const AES128Decrypt dec; + const bool pad; + unsigned char iv[AES_BLOCKSIZE]; +}; + #endif // BITCOIN_CRYPTO_AES_H From daa384120a63542257d4ca73047d775f16fac654 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 00:52:58 -0400 Subject: [PATCH 0619/1223] crypto: add aes cbc tests --- src/test/crypto_tests.cpp | 135 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 3fc9855d6..58a62ee02 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -17,6 +17,8 @@ #include #include +#include +#include BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup) @@ -103,6 +105,88 @@ void TestAES256(const std::string &hexkey, const std::string &hexin, const std:: BOOST_CHECK(buf == in); } +void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout) +{ + std::vector key = ParseHex(hexkey); + std::vector iv = ParseHex(hexiv); + std::vector in = ParseHex(hexin); + std::vector correctout = ParseHex(hexout); + std::vector realout(in.size() + AES_BLOCKSIZE); + + // Encrypt the plaintext and verify that it equals the cipher + AES128CBCEncrypt enc(&key[0], &iv[0], pad); + int size = enc.Encrypt(&in[0], in.size(), &realout[0]); + realout.resize(size); + BOOST_CHECK(realout.size() == correctout.size()); + BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout); + + // Decrypt the cipher and verify that it equals the plaintext + std::vector decrypted(correctout.size()); + AES128CBCDecrypt dec(&key[0], &iv[0], pad); + size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]); + decrypted.resize(size); + BOOST_CHECK(decrypted.size() == in.size()); + BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin); + + // Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other + for(std::vector::iterator i(in.begin()); i != in.end(); ++i) + { + std::vector sub(i, in.end()); + std::vector subout(sub.size() + AES_BLOCKSIZE); + int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + if (size != 0) + { + subout.resize(size); + std::vector subdecrypted(subout.size()); + size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + subdecrypted.resize(size); + BOOST_CHECK(decrypted.size() == in.size()); + BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); + } + } +} + +void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout) +{ + std::vector key = ParseHex(hexkey); + std::vector iv = ParseHex(hexiv); + std::vector in = ParseHex(hexin); + std::vector correctout = ParseHex(hexout); + std::vector realout(in.size() + AES_BLOCKSIZE); + + // Encrypt the plaintext and verify that it equals the cipher + AES256CBCEncrypt enc(&key[0], &iv[0], pad); + int size = enc.Encrypt(&in[0], in.size(), &realout[0]); + realout.resize(size); + BOOST_CHECK(realout.size() == correctout.size()); + BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout); + + // Decrypt the cipher and verify that it equals the plaintext + std::vector decrypted(correctout.size()); + AES256CBCDecrypt dec(&key[0], &iv[0], pad); + size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]); + decrypted.resize(size); + BOOST_CHECK(decrypted.size() == in.size()); + BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin); + + // Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other + for(std::vector::iterator i(in.begin()); i != in.end(); ++i) + { + std::vector sub(i, in.end()); + std::vector subout(sub.size() + AES_BLOCKSIZE); + int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + if (size != 0) + { + subout.resize(size); + std::vector subdecrypted(subout.size()); + size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + subdecrypted.resize(size); + BOOST_CHECK(decrypted.size() == in.size()); + BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); + } + } +} + std::string LongTestString(void) { std::string ret; for (int i=0; i<200000; i++) { @@ -304,4 +388,55 @@ BOOST_AUTO_TEST_CASE(aes_testvectors) { TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"); } +BOOST_AUTO_TEST_CASE(aes_cbc_testvectors) { + + // NIST AES CBC 128-bit encryption test-vectors + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", false, \ + "6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", false, \ + "ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", false, \ + "30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", false, \ + "f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a7"); + + // The same vectors with padding enabled + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", true, \ + "6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d8964e0b149c10b7b682e6e39aaeb731c"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", true, \ + "ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b255e21d7100b988ffec32feeafaf23538"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", true, \ + "30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516f6eccda327bf8e5ec43718b0039adceb"); + TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", true, \ + "f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012"); + + // NIST AES CBC 256-bit encryption test-vectors + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "000102030405060708090A0B0C0D0E0F", false, "6bc1bee22e409f96e93d7e117393172a", \ + "f58c4c04d6e5f1ba779eabfb5f7bfbd6"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "F58C4C04D6E5F1BA779EABFB5F7BFBD6", false, "ae2d8a571e03ac9c9eb76fac45af8e51", \ + "9cfc4e967edb808d679f777bc6702c7d"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "9CFC4E967EDB808D679F777BC6702C7D", false, "30c81c46a35ce411e5fbc1191a0a52ef", + "39f23369a9d9bacfa530e26304231461"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "39F23369A9D9BACFA530E26304231461", false, "f69f2445df4f9b17ad2b417be66c3710", \ + "b2eb05e2c39be9fcda6c19078c6a9d1b"); + + // The same vectors with padding enabled + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "000102030405060708090A0B0C0D0E0F", true, "6bc1bee22e409f96e93d7e117393172a", \ + "f58c4c04d6e5f1ba779eabfb5f7bfbd6485a5c81519cf378fa36d42b8547edc0"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "F58C4C04D6E5F1BA779EABFB5F7BFBD6", true, "ae2d8a571e03ac9c9eb76fac45af8e51", \ + "9cfc4e967edb808d679f777bc6702c7d3a3aa5e0213db1a9901f9036cf5102d2"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "9CFC4E967EDB808D679F777BC6702C7D", true, "30c81c46a35ce411e5fbc1191a0a52ef", + "39f23369a9d9bacfa530e263042314612f8da707643c90a6f732b3de1d3f5cee"); + TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \ + "39F23369A9D9BACFA530E26304231461", true, "f69f2445df4f9b17ad2b417be66c3710", \ + "b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644"); +} + BOOST_AUTO_TEST_SUITE_END() From 1c391a5866e1342617b51041afebee2215e9a30c Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 01:05:47 -0400 Subject: [PATCH 0620/1223] crypter: fix the stored initialization vector size AES IV's are 16bytes, not 32. This was harmless but confusing. Add WALLET_CRYPTO_IV_SIZE to make its usage explicit. --- src/wallet/crypter.cpp | 10 +++++----- src/wallet/crypter.h | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 95aa4c259..8f555579f 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -37,7 +37,7 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector& chNewIV) { - if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) + if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_IV_SIZE) return false; memcpy(&chKey[0], &chNewKey[0], sizeof chKey); @@ -105,8 +105,8 @@ bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingM static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) { CCrypter cKeyCrypter; - std::vector chIV(WALLET_CRYPTO_KEY_SIZE); - memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + std::vector chIV(WALLET_CRYPTO_IV_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE); if(!cKeyCrypter.SetKey(vMasterKey, chIV)) return false; return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext); @@ -115,8 +115,8 @@ static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMateri static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext) { CCrypter cKeyCrypter; - std::vector chIV(WALLET_CRYPTO_KEY_SIZE); - memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + std::vector chIV(WALLET_CRYPTO_IV_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE); if(!cKeyCrypter.SetKey(vMasterKey, chIV)) return false; return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index eb06a7866..b4727ac8a 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -13,6 +13,7 @@ class uint256; const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; +const unsigned int WALLET_CRYPTO_IV_SIZE = 16; /** * Private key encryption is done based on a CMasterKey, @@ -71,7 +72,7 @@ class CCrypter { private: unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; - unsigned char chIV[WALLET_CRYPTO_KEY_SIZE]; + unsigned char chIV[WALLET_CRYPTO_IV_SIZE]; bool fKeySet; public: From fb96831c1ff767cd86099f66127fa4dc1ec6e277 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 26 Mar 2015 17:37:29 -0400 Subject: [PATCH 0621/1223] crypter: constify encrypt/decrypt This makes CCrypter easier to pass aroundf for tests --- src/wallet/crypter.cpp | 4 ++-- src/wallet/crypter.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 8f555579f..e37a9c4c8 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -47,7 +47,7 @@ bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector &vchCiphertext) +bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext) const { if (!fKeySet) return false; @@ -74,7 +74,7 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext) +bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext) const { if (!fKeySet) return false; diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index b4727ac8a..3457d40ff 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -77,8 +77,8 @@ private: public: bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); - bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext); - bool Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext); + bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext) const; + bool Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext) const; bool SetKey(const CKeyingMaterial& chNewKey, const std::vector& chNewIV); void CleanKey() From 9049cde4d962862f507f9ddf1c0dbd49ea04be51 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 01:10:30 -0400 Subject: [PATCH 0622/1223] crypter: hook up the new aes cbc classes --- src/wallet/crypter.cpp | 45 +++++++++++++----------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index e37a9c4c8..0a19139a3 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -4,6 +4,7 @@ #include "crypter.h" +#include "crypto/aes.h" #include "script/script.h" #include "script/standard.h" #include "util.h" @@ -53,24 +54,15 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector (nCLen); + // n + AES_BLOCKSIZE bytes + vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE); - EVP_CIPHER_CTX ctx; + AES256CBCEncrypt enc(chKey, chIV, true); + size_t nLen = enc.Encrypt(&vchPlaintext[0], vchPlaintext.size(), &vchCiphertext[0]); + if(nLen < vchPlaintext.size()) + return false; + vchCiphertext.resize(nLen); - bool fOk = true; - - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; - if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); - - if (!fOk) return false; - - vchCiphertext.resize(nCLen + nFLen); return true; } @@ -81,23 +73,14 @@ bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingM // plaintext will always be equal to or lesser than length of ciphertext int nLen = vchCiphertext.size(); - int nPLen = nLen, nFLen = 0; - vchPlaintext = CKeyingMaterial(nPLen); + vchPlaintext.resize(nLen); - EVP_CIPHER_CTX ctx; - - bool fOk = true; - - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); - - if (!fOk) return false; - - vchPlaintext.resize(nPLen + nFLen); + AES256CBCDecrypt dec(chKey, chIV, true); + nLen = dec.Decrypt(&vchCiphertext[0], vchCiphertext.size(), &vchPlaintext[0]); + if(nLen == 0) + return false; + vchPlaintext.resize(nLen); return true; } From 976f9ec2645242032d34ab68a60d963f2ac586d8 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 01:24:12 -0400 Subject: [PATCH 0623/1223] crypter: add a BytesToKey clone to replace the use of openssl BytesToKeySHA512AES should be functionally identical to EVP_BytesToKey, but drops the dependency on openssl. --- src/wallet/crypter.cpp | 33 +++++++++++++++++++++++++++++---- src/wallet/crypter.h | 2 ++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 0a19139a3..190f8ecf2 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -5,6 +5,7 @@ #include "crypter.h" #include "crypto/aes.h" +#include "crypto/sha512.h" #include "script/script.h" #include "script/standard.h" #include "util.h" @@ -12,8 +13,33 @@ #include #include #include -#include -#include + +int CCrypter::BytesToKeySHA512AES(const std::vector& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const +{ + // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc + // cipher and sha512 message digest. Because sha512's output size (64b) is + // greater than the aes256 block size (16b) + aes256 key size (32b), + // there's no need to process more than once (D_0). + + if(!count || !key || !iv) + return 0; + + unsigned char buf[CSHA512::OUTPUT_SIZE]; + CSHA512 di; + + di.Write((const unsigned char*)strKeyData.c_str(), strKeyData.size()); + if(chSalt.size()) + di.Write(&chSalt[0], chSalt.size()); + di.Finalize(buf); + + for(int i = 0; i != count - 1; i++) + di.Reset().Write(buf, sizeof(buf)).Finalize(buf); + + memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE); + memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE); + memory_cleanse(buf, sizeof(buf)); + return WALLET_CRYPTO_KEY_SIZE; +} bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) { @@ -22,8 +48,7 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v int i = 0; if (nDerivationMethod == 0) - i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], - (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, chKey, chIV); if (i != (int)WALLET_CRYPTO_KEY_SIZE) { diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 3457d40ff..16f2ba622 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -75,6 +75,8 @@ private: unsigned char chIV[WALLET_CRYPTO_IV_SIZE]; bool fKeySet; + int BytesToKeySHA512AES(const std::vector& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const; + public: bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext) const; From 0a36b9af281e31b080ca0835eec7704097527bda Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 26 Mar 2015 19:15:28 -0400 Subject: [PATCH 0624/1223] crypter: shuffle Makefile so that crypto can be used by the wallet Wallet must come before crypto, otherwise linking fails on some platforms. Includes a tangentially-related general cleanup rather than making the Makefile sloppier. --- src/Makefile.am | 55 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0ab0d66ac..31917f135 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,13 +15,12 @@ LIBUNIVALUE = $(UNIVALUE_LIBS) endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config -BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) +BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS) LIBBITCOIN_SERVER=libbitcoin_server.a -LIBBITCOIN_WALLET=libbitcoin_wallet.a LIBBITCOIN_COMMON=libbitcoin_common.a LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a LIBBITCOIN_CLI=libbitcoin_cli.a @@ -30,32 +29,32 @@ LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBBITCOINQT=qt/libbitcoinqt.a LIBSECP256K1=secp256k1/libsecp256k1.la +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a +endif +if BUILD_BITCOIN_LIBS +LIBBITCOINCONSENSUS=libbitcoinconsensus.la +endif +if ENABLE_WALLET +LIBBITCOIN_WALLET=libbitcoin_wallet.a +endif + $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: EXTRA_LIBRARIES += \ - crypto/libbitcoin_crypto.a \ - libbitcoin_util.a \ - libbitcoin_common.a \ - libbitcoin_consensus.a \ - libbitcoin_server.a \ - libbitcoin_cli.a -if ENABLE_WALLET -BITCOIN_INCLUDES += $(BDB_CPPFLAGS) -EXTRA_LIBRARIES += libbitcoin_wallet.a -endif -if ENABLE_ZMQ -EXTRA_LIBRARIES += libbitcoin_zmq.a -endif + $(LIBBITCOIN_CRYPTO) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_CONSENSUS) \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_CLI) \ + $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_ZMQ) -if BUILD_BITCOIN_LIBS -lib_LTLIBRARIES = libbitcoinconsensus.la -LIBBITCOINCONSENSUS=libbitcoinconsensus.la -else -LIBBITCOINCONSENSUS= -endif +lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS) bin_PROGRAMS = TESTS = @@ -196,8 +195,6 @@ libbitcoin_server_a_SOURCES = \ $(BITCOIN_CORE_H) if ENABLE_ZMQ -LIBBITCOIN_ZMQ=libbitcoin_zmq.a - libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ @@ -347,21 +344,15 @@ bitcoind_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_ZMQ) \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ $(LIBSECP256K1) -if ENABLE_ZMQ -bitcoind_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) -endif - -if ENABLE_WALLET -bitcoind_LDADD += libbitcoin_wallet.a -endif - -bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp From 34ed64a404fb6da691f67f00f47c4dd748e3e428 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 20 Mar 2015 01:27:50 -0400 Subject: [PATCH 0625/1223] crypter: add tests for crypter Verify that results correct (match known values), consistent (encrypt->decrypt matches the original), and compatible with the previous openssl implementation. Also check that failed encrypts/decrypts fail the exact same way as openssl. --- src/Makefile.test.include | 1 + src/wallet/crypter.h | 6 + src/wallet/test/crypto_tests.cpp | 230 +++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 src/wallet/test/crypto_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 08e2f6af4..d443b6d34 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -94,6 +94,7 @@ BITCOIN_TESTS += \ wallet/test/wallet_test_fixture.h \ wallet/test/accounting_tests.cpp \ wallet/test/wallet_tests.cpp \ + wallet/test/crypto_tests.cpp \ wallet/test/rpc_wallet_tests.cpp endif diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 16f2ba622..5d0a4a330 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -67,9 +67,15 @@ public: typedef std::vector > CKeyingMaterial; +namespace wallet_crypto +{ + class TestCrypter; +} + /** Encryption/decryption context with key information */ class CCrypter { +friend class wallet_crypto::TestCrypter; // for test access to chKey/chIV private: unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; unsigned char chIV[WALLET_CRYPTO_IV_SIZE]; diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp new file mode 100644 index 000000000..05387f5f2 --- /dev/null +++ b/src/wallet/test/crypto_tests.cpp @@ -0,0 +1,230 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "random.h" +#include "utilstrencodings.h" +#include "test/test_bitcoin.h" +#include "wallet/crypter.h" + +#include + +#include +#include +#include + +BOOST_FIXTURE_TEST_SUITE(wallet_crypto, BasicTestingSetup) + +bool OldSetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod, unsigned char* chKey, unsigned char* chIV) +{ + if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) + return false; + + int i = 0; + if (nDerivationMethod == 0) + i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], + (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + + if (i != (int)WALLET_CRYPTO_KEY_SIZE) + { + memory_cleanse(chKey, sizeof(chKey)); + memory_cleanse(chIV, sizeof(chIV)); + return false; + } + return true; +} + +bool OldEncrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext, const unsigned char chKey[32], const unsigned char chIV[16]) +{ + // max ciphertext len for a n bytes of plaintext is + // n + AES_BLOCK_SIZE - 1 bytes + int nLen = vchPlaintext.size(); + int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; + vchCiphertext = std::vector (nCLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; + if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchCiphertext.resize(nCLen + nFLen); + return true; +} + +bool OldDecrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext, const unsigned char chKey[32], const unsigned char chIV[16]) +{ + // plaintext will always be equal to or lesser than length of ciphertext + int nLen = vchCiphertext.size(); + int nPLen = nLen, nFLen = 0; + + vchPlaintext = CKeyingMaterial(nPLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; + if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchPlaintext.resize(nPLen + nFLen); + return true; +} + +class TestCrypter +{ +public: +static void TestPassphraseSingle(const std::vector& vchSalt, const SecureString& passphrase, uint32_t rounds, + const std::vector& correctKey = std::vector(), + const std::vector& correctIV=std::vector()) +{ + unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; + unsigned char chIV[WALLET_CRYPTO_IV_SIZE]; + + CCrypter crypt; + crypt.SetKeyFromPassphrase(passphrase, vchSalt, rounds, 0); + + OldSetKeyFromPassphrase(passphrase, vchSalt, rounds, 0, chKey, chIV); + + BOOST_CHECK_MESSAGE(memcmp(chKey, crypt.chKey, sizeof(chKey)) == 0, \ + HexStr(chKey, chKey+sizeof(chKey)) + std::string(" != ") + HexStr(crypt.chKey, crypt.chKey + (sizeof crypt.chKey))); + BOOST_CHECK_MESSAGE(memcmp(chIV, crypt.chIV, sizeof(chIV)) == 0, \ + HexStr(chIV, chIV+sizeof(chIV)) + std::string(" != ") + HexStr(crypt.chIV, crypt.chIV + (sizeof crypt.chIV))); + + if(!correctKey.empty()) + BOOST_CHECK_MESSAGE(memcmp(chKey, &correctKey[0], sizeof(chKey)) == 0, \ + HexStr(chKey, chKey+sizeof(chKey)) + std::string(" != ") + HexStr(correctKey.begin(), correctKey.end())); + if(!correctIV.empty()) + BOOST_CHECK_MESSAGE(memcmp(chIV, &correctIV[0], sizeof(chIV)) == 0, + HexStr(chIV, chIV+sizeof(chIV)) + std::string(" != ") + HexStr(correctIV.begin(), correctIV.end())); +} + +static void TestPassphrase(const std::vector& vchSalt, const SecureString& passphrase, uint32_t rounds, + const std::vector& correctKey = std::vector(), + const std::vector& correctIV=std::vector()) +{ + TestPassphraseSingle(vchSalt, passphrase, rounds, correctKey, correctIV); + for(SecureString::const_iterator i(passphrase.begin()); i != passphrase.end(); ++i) + TestPassphraseSingle(vchSalt, SecureString(i, passphrase.end()), rounds); +} + + +static void TestDecrypt(const CCrypter& crypt, const std::vector& vchCiphertext, \ + const std::vector& vchPlaintext = std::vector()) +{ + CKeyingMaterial vchDecrypted1; + CKeyingMaterial vchDecrypted2; + int result1, result2; + result1 = crypt.Decrypt(vchCiphertext, vchDecrypted1); + result2 = OldDecrypt(vchCiphertext, vchDecrypted2, crypt.chKey, crypt.chIV); + BOOST_CHECK(result1 == result2); + + // These two should be equal. However, OpenSSL 1.0.1j introduced a change + // that would zero all padding except for the last byte for failed decrypts. + // This behavior was reverted for 1.0.1k. + if (vchDecrypted1 != vchDecrypted2 && vchDecrypted1.size() >= AES_BLOCK_SIZE && SSLeay() == 0x100010afL) + { + for(CKeyingMaterial::iterator it = vchDecrypted1.end() - AES_BLOCK_SIZE; it != vchDecrypted1.end() - 1; it++) + *it = 0; + } + + BOOST_CHECK_MESSAGE(vchDecrypted1 == vchDecrypted2, HexStr(vchDecrypted1.begin(), vchDecrypted1.end()) + " != " + HexStr(vchDecrypted2.begin(), vchDecrypted2.end())); + + if (vchPlaintext.size()) + BOOST_CHECK(CKeyingMaterial(vchPlaintext.begin(), vchPlaintext.end()) == vchDecrypted2); +} + +static void TestEncryptSingle(const CCrypter& crypt, const CKeyingMaterial& vchPlaintext, + const std::vector& vchCiphertextCorrect = std::vector()) +{ + std::vector vchCiphertext1; + std::vector vchCiphertext2; + int result1 = crypt.Encrypt(vchPlaintext, vchCiphertext1); + + int result2 = OldEncrypt(vchPlaintext, vchCiphertext2, crypt.chKey, crypt.chIV); + BOOST_CHECK(result1 == result2); + BOOST_CHECK(vchCiphertext1 == vchCiphertext2); + + if (!vchCiphertextCorrect.empty()) + BOOST_CHECK(vchCiphertext2 == vchCiphertextCorrect); + + const std::vector vchPlaintext2(vchPlaintext.begin(), vchPlaintext.end()); + + if(vchCiphertext1 == vchCiphertext2) + TestDecrypt(crypt, vchCiphertext1, vchPlaintext2); +} + +static void TestEncrypt(const CCrypter& crypt, const std::vector& vchPlaintextIn, \ + const std::vector& vchCiphertextCorrect = std::vector()) +{ + TestEncryptSingle(crypt, CKeyingMaterial(vchPlaintextIn.begin(), vchPlaintextIn.end()), vchCiphertextCorrect); + for(std::vector::const_iterator i(vchPlaintextIn.begin()); i != vchPlaintextIn.end(); ++i) + TestEncryptSingle(crypt, CKeyingMaterial(i, vchPlaintextIn.end())); +} + +}; + +BOOST_AUTO_TEST_CASE(passphrase) { + // These are expensive. + + TestCrypter::TestPassphrase(ParseHex("0000deadbeef0000"), "test", 25000, \ + ParseHex("fc7aba077ad5f4c3a0988d8daa4810d0d4a0e3bcb53af662998898f33df0556a"), \ + ParseHex("cf2f2691526dd1aa220896fb8bf7c369")); + + std::string hash(GetRandHash().ToString()); + std::vector vchSalt(8); + GetRandBytes(&vchSalt[0], vchSalt.size()); + uint32_t rounds = insecure_rand(); + if (rounds > 30000) + rounds = 30000; + TestCrypter::TestPassphrase(vchSalt, SecureString(hash.begin(), hash.end()), rounds); +} + +BOOST_AUTO_TEST_CASE(encrypt) { + std::vector vchSalt = ParseHex("0000deadbeef0000"); + BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE); + CCrypter crypt; + crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0); + TestCrypter::TestEncrypt(crypt, ParseHex("22bcade09ac03ff6386914359cfe885cfeb5f77ff0d670f102f619687453b29d")); + + for (int i = 0; i != 100; i++) + { + uint256 hash(GetRandHash()); + TestCrypter::TestEncrypt(crypt, std::vector(hash.begin(), hash.end())); + } + +} + +BOOST_AUTO_TEST_CASE(decrypt) { + std::vector vchSalt = ParseHex("0000deadbeef0000"); + BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE); + CCrypter crypt; + crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0); + + // Some corner cases the came up while testing + TestCrypter::TestDecrypt(crypt,ParseHex("795643ce39d736088367822cdc50535ec6f103715e3e48f4f3b1a60a08ef59ca")); + TestCrypter::TestDecrypt(crypt,ParseHex("de096f4a8f9bd97db012aa9d90d74de8cdea779c3ee8bc7633d8b5d6da703486")); + TestCrypter::TestDecrypt(crypt,ParseHex("32d0a8974e3afd9c6c3ebf4d66aa4e6419f8c173de25947f98cf8b7ace49449c")); + TestCrypter::TestDecrypt(crypt,ParseHex("e7c055cca2faa78cb9ac22c9357a90b4778ded9b2cc220a14cea49f931e596ea")); + TestCrypter::TestDecrypt(crypt,ParseHex("b88efddd668a6801d19516d6830da4ae9811988ccbaf40df8fbb72f3f4d335fd")); + TestCrypter::TestDecrypt(crypt,ParseHex("8cae76aa6a43694e961ebcb28c8ca8f8540b84153d72865e8561ddd93fa7bfa9")); + + for (int i = 0; i != 100; i++) + { + uint256 hash(GetRandHash()); + TestCrypter::TestDecrypt(crypt, std::vector(hash.begin(), hash.end())); + } +} + +BOOST_AUTO_TEST_SUITE_END() From fac93497986b5f74716383bf26c78406253c625a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 14 May 2016 13:01:31 +0200 Subject: [PATCH 0626/1223] [qa] Remove hardcoded "4 nodes" from test_framework --- qa/rpc-tests/abandonconflict.py | 4 +++ qa/rpc-tests/bip65-cltv-p2p.py | 3 +- qa/rpc-tests/bip65-cltv.py | 4 +++ qa/rpc-tests/bip68-112-113-p2p.py | 3 +- qa/rpc-tests/bip68-sequence.py | 4 +++ qa/rpc-tests/bip9-softforks.py | 3 +- qa/rpc-tests/bipdersig-p2p.py | 3 +- qa/rpc-tests/bipdersig.py | 4 +++ qa/rpc-tests/blockchain.py | 10 +++--- qa/rpc-tests/decodescript.py | 9 ++--- qa/rpc-tests/disablewallet.py | 9 ++--- qa/rpc-tests/forknotify.py | 5 +++ qa/rpc-tests/fundrawtransaction.py | 11 ++++--- qa/rpc-tests/getblocktemplate_longpoll.py | 5 +++ qa/rpc-tests/getblocktemplate_proposals.py | 9 +++++ qa/rpc-tests/getchaintips.py | 5 ++- qa/rpc-tests/httpbasics.py | 9 +++-- qa/rpc-tests/importprunedfunds.py | 9 ++--- qa/rpc-tests/invalidateblock.py | 9 ++--- qa/rpc-tests/invalidblockrequest.py | 1 + qa/rpc-tests/invalidtxrequest.py | 1 + qa/rpc-tests/keypool.py | 11 +++---- qa/rpc-tests/listtransactions.py | 6 +++- qa/rpc-tests/maxblocksinflight.py | 9 ++--- qa/rpc-tests/maxuploadtarget.py | 12 ++++--- qa/rpc-tests/mempool_limit.py | 12 +++---- qa/rpc-tests/mempool_packages.py | 4 +++ qa/rpc-tests/mempool_reorg.py | 4 +++ qa/rpc-tests/mempool_resurrect_test.py | 5 +++ qa/rpc-tests/mempool_spendcoinbase.py | 5 +++ qa/rpc-tests/merkle_blocks.py | 7 ++-- qa/rpc-tests/multi_rpc.py | 16 ++++++--- qa/rpc-tests/nodehandling.py | 6 ++++ qa/rpc-tests/p2p-acceptblock.py | 6 ++-- qa/rpc-tests/p2p-feefilter.py | 6 ++++ qa/rpc-tests/p2p-fullblocktest.py | 1 + qa/rpc-tests/p2p-versionbits-warning.py | 6 ++-- qa/rpc-tests/prioritise_transaction.py | 8 ++--- qa/rpc-tests/proxy_test.py | 6 +++- qa/rpc-tests/pruning.py | 8 ++--- qa/rpc-tests/rawtransactions.py | 9 ++--- qa/rpc-tests/receivedby.py | 7 +++- qa/rpc-tests/reindex.py | 7 ++-- qa/rpc-tests/replace-by-fee.py | 5 +++ qa/rpc-tests/rest.py | 9 ++--- qa/rpc-tests/rpcbind_test.py | 4 +-- qa/rpc-tests/sendheaders.py | 8 +++-- qa/rpc-tests/signmessages.py | 9 ++--- qa/rpc-tests/signrawtransactions.py | 9 ++--- qa/rpc-tests/smartfees.py | 5 +++ qa/rpc-tests/test_framework/test_framework.py | 25 +++++++------- qa/rpc-tests/test_framework/util.py | 33 +++++++++++-------- qa/rpc-tests/txn_clone.py | 5 +++ qa/rpc-tests/txn_doublespend.py | 5 +++ qa/rpc-tests/wallet.py | 7 ++-- qa/rpc-tests/walletbackup.py | 9 ++--- qa/rpc-tests/zapwallettxes.py | 9 ++--- qa/rpc-tests/zmq_test.py | 6 +++- 58 files changed, 291 insertions(+), 138 deletions(-) diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index b6c4b9db4..c50c3cc56 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -9,6 +9,10 @@ from test_framework.util import * import urllib.parse class AbandonConflictTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 60923b9dd..754b6873b 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -37,11 +37,12 @@ Mine 1 old version block, see that the node rejects. class BIP65Test(ComparisonTestFramework): def __init__(self): + super().__init__() self.num_nodes = 1 def setup_network(self): # Must set the blockversion for this test - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']], binary=[self.options.testbinary]) diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index 9d83fc947..abba7fc20 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -11,6 +11,10 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * class BIP65Test(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index eedb60e3a..8ba070438 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -94,11 +94,12 @@ def all_rlt_txs(txarray): class BIP68_112_113Test(ComparisonTestFramework): def __init__(self): + super().__init__() self.num_nodes = 1 def setup_network(self): # Must set the blockversion for this test - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=4']], binary=[self.options.testbinary]) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 717f7562c..a12bf10eb 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -22,6 +22,10 @@ SEQUENCE_LOCKTIME_MASK = 0x0000ffff NOT_FINAL_ERROR = "64: non-BIP68-final" class BIP68Test(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index a8fb878dc..aae258315 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -32,10 +32,11 @@ test that enforcement has triggered class BIP9SoftForksTest(ComparisonTestFramework): def __init__(self): + super().__init__() self.num_nodes = 1 def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index c46273084..4e4936a4a 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -45,11 +45,12 @@ Mine 1 old version block, see that the node rejects. class BIP66Test(ComparisonTestFramework): def __init__(self): + super().__init__() self.num_nodes = 1 def setup_network(self): # Must set the blockversion for this test - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']], binary=[self.options.testbinary]) diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index f2d2c14a7..17c2ced79 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -11,6 +11,10 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * class BIP66Test(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index c84047b5d..410b85d15 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -13,7 +13,6 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import ( - initialize_chain, assert_equal, assert_raises, assert_is_hex_string, @@ -32,12 +31,13 @@ class BlockchainTest(BitcoinTestFramework): """ - def setup_chain(self): - print("Initializing test directory " + self.options.tmpdir) - initialize_chain(self.options.tmpdir) + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 2 def setup_network(self, split=False): - self.nodes = start_nodes(2, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) connect_nodes_bi(self.nodes, 0, 1) self.is_network_split = False self.sync_all() diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 0037542e6..24768c265 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -11,12 +11,13 @@ from io import BytesIO class DecodeScriptTest(BitcoinTestFramework): """Tests decoding scripts via RPC command "decodescript".""" - def setup_chain(self): - print('Initializing test directory ' + self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self, split=False): - self.nodes = start_nodes(1, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) self.is_network_split = False def decodescript_script_sig(self): diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index b25d2ba33..36c147eda 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -13,12 +13,13 @@ from test_framework.util import * class DisableWalletTest (BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self, split=False): - self.nodes = start_nodes(1, self.options.tmpdir, [['-disablewallet']]) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [['-disablewallet']]) self.is_network_split = False self.sync_all() diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 421f3dd87..5a3f75c80 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -12,6 +12,11 @@ from test_framework.util import * class ForkNotifyTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False + alert_filename = None # Set by setup_network def setup_network(self): diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 74849603f..57b850a6a 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -9,12 +9,13 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): - def setup_chain(self): - print(("Initializing test directory "+self.options.tmpdir)) - initialize_chain_clean(self.options.tmpdir, 4) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 def setup_network(self, split=False): - self.nodes = start_nodes(4, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -521,7 +522,7 @@ class RawTransactionsTest(BitcoinTestFramework): stop_nodes(self.nodes) wait_bitcoinds() - self.nodes = start_nodes(4, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like # to be sure all txs are sent at a consistent desired feerate for node in self.nodes: diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index e44334707..3cddf4046 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -26,6 +26,11 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): Test longpolling with getblocktemplate. ''' + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + def run_test(self): print("Warning: this test will take about 70 seconds in the best case. Be patient.") self.nodes[0].generate(10) diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 1ad2af4c2..7a4f8f8fd 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -70,6 +70,15 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework): Test block proposals with getblocktemplate. ''' + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False + + def setup_network(self): + self.nodes = self.setup_nodes() + connect_nodes_bi(self.nodes, 0, 1) + def run_test(self): node = self.nodes[0] node.generate(1) # Mine a block to leave initial block download diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index da354b0c9..1c66b8c28 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -11,9 +11,12 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal class GetChainTipsTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False def run_test (self): - BitcoinTestFramework.run_test (self) tips = self.nodes[0].getchaintips () assert_equal (len (tips), 1) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index c62edc8e1..10bc927e1 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -14,8 +14,13 @@ import http.client import urllib.parse class HTTPBasicsTest (BitcoinTestFramework): - def setup_nodes(self): - return start_nodes(4, self.options.tmpdir) + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False + + def setup_network(self): + self.nodes = self.setup_nodes() def run_test(self): diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index def1d891c..761c9af90 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -9,12 +9,13 @@ import decimal class ImportPrunedFundsTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 def setup_network(self, split=False): - self.nodes = start_nodes(2, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) self.is_network_split=False self.sync_all() diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index 2e3a449f5..0faadd33a 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -13,10 +13,11 @@ from test_framework.util import * class InvalidateTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) - + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + def setup_network(self): self.nodes = [] self.is_network_split = False diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 78dc7199d..3d8107a76 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -25,6 +25,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): ''' Can either run this test as 1 node with expected answers, or two and compare them. Change the "outcome" variable from each TestInstance object to only do the comparison. ''' def __init__(self): + super().__init__() self.num_nodes = 1 def run_test(self): diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py index d4200b0e8..93205d79d 100755 --- a/qa/rpc-tests/invalidtxrequest.py +++ b/qa/rpc-tests/invalidtxrequest.py @@ -19,6 +19,7 @@ class InvalidTxRequestTest(ComparisonTestFramework): ''' Can either run this test as 1 node with expected answers, or two and compare them. Change the "outcome" variable from each TestInstance object to only do the comparison. ''' def __init__(self): + super().__init__() self.num_nodes = 1 def run_test(self): diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index bdc144bfb..c75303ecb 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -5,8 +5,6 @@ # Exercise the wallet keypool, and interaction with wallet encryption/locking -# Add python-bitcoinrpc to module search path: - from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -65,12 +63,13 @@ class KeyPoolTest(BitcoinTestFramework): except JSONRPCException as e: assert(e.error['code']==-12) - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain(self.options.tmpdir) + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir) + self.nodes = self.setup_nodes() if __name__ == '__main__': KeyPoolTest().main() diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 8dad687ed..5ec6ce17e 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -17,11 +17,15 @@ def txFromHex(hexstring): return tx class ListTransactionsTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False def setup_nodes(self): #This test requires mocktime enable_mocktime() - return start_nodes(4, self.options.tmpdir) + return start_nodes(self.num_nodes, self.options.tmpdir) def run_test(self): # Simple send, 0 to 1: diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index 6f105a77e..1df1c484b 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -76,12 +76,13 @@ class MaxBlocksInFlightTest(BitcoinTestFramework): default=os.getenv("BITCOIND", "bitcoind"), help="Binary to test max block requests behavior") - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir, + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index ec802d815..42235a511 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -80,17 +80,19 @@ class TestNode(NodeConnCB): return success class MaxUploadTest(BitcoinTestFramework): - def __init__(self): - self.utxo = [] - self.txouts = gen_return_txouts() def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", default=os.getenv("BITCOIND", "bitcoind"), help="bitcoind binary to test") - def setup_chain(self): - initialize_chain_clean(self.options.tmpdir, 2) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 + + self.utxo = [] + self.txouts = gen_return_txouts() def setup_network(self): # Start a node with maxuploadtarget of 200 MB (/24h) diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index bc208709e..c1c5558a9 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -10,9 +10,6 @@ from test_framework.util import * class MempoolLimitTest(BitcoinTestFramework): - def __init__(self): - self.txouts = gen_return_txouts() - def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) @@ -20,9 +17,12 @@ class MempoolLimitTest(BitcoinTestFramework): self.sync_all() self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 2) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 + + self.txouts = gen_return_txouts() def run_test(self): txids = [] diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 7ac85c1b6..693ff593b 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -13,6 +13,10 @@ MAX_ANCESTORS = 25 MAX_DESCENDANTS = 25 class MempoolPackagesTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index 608e9d0a0..301b094eb 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -13,6 +13,10 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False alert_filename = None # Set by setup_network diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index b4d9f0a1a..3db12cbf7 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -14,6 +14,11 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = False + def setup_network(self): # Just need one node for this test args = ["-checkmempool", "-debug=mempool"] diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index c23f5ef10..d5e4bf52d 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -19,6 +19,11 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: class MempoolSpendCoinbaseTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = False + def setup_network(self): # Just need one node for this test args = ["-checkmempool", "-debug=mempool"] diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 9419d9a71..b2155d7fc 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -12,9 +12,10 @@ from test_framework.util import * class MerkleBlockTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 577d80949..24373b257 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -8,18 +8,21 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import str_to_b64str, assert_equal +import os import http.client import urllib.parse class HTTPBasicsTest (BitcoinTestFramework): - def setup_nodes(self): - return start_nodes(4, self.options.tmpdir) + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain(self.options.tmpdir) + super().setup_chain() #Append rpcauth to bitcoin.conf before initialization rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" @@ -27,6 +30,9 @@ class HTTPBasicsTest (BitcoinTestFramework): f.write(rpcauth+"\n") f.write(rpcauth2+"\n") + def setup_network(self): + self.nodes = self.setup_nodes() + def run_test(self): ################################################## diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index 1b6ba021a..e9682c490 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -14,6 +14,12 @@ import http.client import urllib.parse class NodeHandlingTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + def run_test(self): ########################### # setban/listbanned tests # diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 21e4c2f46..015ec34ef 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -111,8 +111,10 @@ class AcceptBlockTest(BitcoinTestFramework): default=os.getenv("BITCOIND", "bitcoind"), help="bitcoind binary to test") - def setup_chain(self): - initialize_chain_clean(self.options.tmpdir, 2) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 def setup_network(self): # Node0 will be used to test behavior of processing unrequested blocks diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index 5fb51ed0f..cd0501a31 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -46,6 +46,12 @@ class TestNode(SingleNodeConnCB): self.sync_with_ping() class FeeFilterTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False + def setup_network(self): # Node1 will be used to generate txs which should be relayed from Node0 # to our test node diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index 56df8ffd0..aa0501c5e 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -29,6 +29,7 @@ class FullBlockTest(ComparisonTestFramework): ''' Can either run this test as 1 node with expected answers, or two and compare them. Change the "outcome" variable from each TestInstance object to only do the comparison. ''' def __init__(self): + super().__init__() self.num_nodes = 1 self.block_heights = {} self.coinbase_key = CECKey() diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 8c8c2358f..962cafef0 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -59,8 +59,10 @@ class TestNode(NodeConnCB): class VersionBitsWarningTest(BitcoinTestFramework): - def setup_chain(self): - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 6ab88602b..e1771231c 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -14,11 +14,11 @@ from test_framework.mininode import COIN, MAX_BLOCK_SIZE class PrioritiseTransactionTest(BitcoinTestFramework): def __init__(self): - self.txouts = gen_return_txouts() + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + self.txouts = gen_return_txouts() def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 6c7b201d5..27160cae0 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -36,6 +36,10 @@ addnode connect to generic DNS name class ProxyTest(BitcoinTestFramework): def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + self.have_ipv6 = test_ipv6_local() # Create two proxies on different ports # ... one unauthenticated @@ -77,7 +81,7 @@ class ProxyTest(BitcoinTestFramework): ] if self.have_ipv6: args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion'] - return start_nodes(4, self.options.tmpdir, extra_args=args) + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=args) def node_test(self, node, proxies, auth, test_onion=True): rv = [] diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 92d33bd20..4c0530b35 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -20,14 +20,14 @@ def calc_usage(blockdir): class PruneTest(BitcoinTestFramework): def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + self.utxo = [] self.address = ["",""] self.txouts = gen_return_txouts() - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) - def setup_network(self): self.nodes = [] self.is_network_split = False diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 7f7b6887a..df02c1697 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -14,12 +14,13 @@ from test_framework.util import * # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) #connect to a local machine for debugging #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332) diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index a3f97669e..4f17b661c 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -27,10 +27,15 @@ def get_sub_array_from_array(object_array, to_match): class ReceivedByTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + def setup_nodes(self): #This test requires mocktime enable_mocktime() - return start_nodes(4, self.options.tmpdir) + return start_nodes(self.num_nodes, self.options.tmpdir) def run_test(self): ''' diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index 39564b32b..87e6239b5 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -11,9 +11,10 @@ from test_framework.util import * class ReindexTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self): self.nodes = [] diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py index 4afc3981d..34c0f9d79 100755 --- a/qa/rpc-tests/replace-by-fee.py +++ b/qa/rpc-tests/replace-by-fee.py @@ -68,6 +68,11 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): class ReplaceByFeeTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = False + def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug", diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index ec9515528..c9c2eaf7f 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -47,12 +47,13 @@ def http_post_call(host, port, path, requestdata = '', response_object = 0): class RESTTest (BitcoinTestFramework): FORMAT_SEPARATOR = "." - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 7b7c01f99..572273566 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -24,7 +24,7 @@ def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected): if allow_ips: base_args += ['-rpcallowip=' + x for x in allow_ips] binds = ['-rpcbind='+addr for addr in addresses] - nodes = start_nodes(1, tmpdir, [base_args + binds], connect_to) + nodes = start_nodes(self.num_nodes, tmpdir, [base_args + binds], connect_to) try: pid = bitcoind_processes[0].pid assert_equal(set(get_bind_addrs(pid)), set(expected)) @@ -38,7 +38,7 @@ def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport): at a non-localhost IP. ''' base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] - nodes = start_nodes(1, tmpdir, [base_args]) + nodes = start_nodes(self.num_nodes, tmpdir, [base_args]) try: # connect to node through non-loopback interface url = "http://rt:rt@%s:%d" % (rpchost, rpcport,) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 96d1da729..6ab17d59b 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -208,12 +208,14 @@ class TestNode(BaseNode): BaseNode.__init__(self) class SendHeadersTest(BitcoinTestFramework): - def setup_chain(self): - initialize_chain_clean(self.options.tmpdir, 2) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 def setup_network(self): self.nodes = [] - self.nodes = start_nodes(2, self.options.tmpdir, [["-debug", "-logtimemicros=1"]]*2) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [["-debug", "-logtimemicros=1"]]*2) connect_nodes(self.nodes[0], 1) # mine count blocks and return the new tip diff --git a/qa/rpc-tests/signmessages.py b/qa/rpc-tests/signmessages.py index 4a47c0ca1..31b6f14a2 100755 --- a/qa/rpc-tests/signmessages.py +++ b/qa/rpc-tests/signmessages.py @@ -10,12 +10,13 @@ from test_framework.util import * class SignMessagesTest(BitcoinTestFramework): """Tests RPC commands for signing and verifying messages.""" - def setup_chain(self): - print('Initializing test directory ' + self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self, split=False): - self.nodes = start_nodes(1, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) self.is_network_split = False def run_test(self): diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py index a06ac5319..c61a28061 100755 --- a/qa/rpc-tests/signrawtransactions.py +++ b/qa/rpc-tests/signrawtransactions.py @@ -10,12 +10,13 @@ from test_framework.util import * class SignRawTransactionsTest(BitcoinTestFramework): """Tests transaction signing via RPC command "signrawtransaction".""" - def setup_chain(self): - print('Initializing test directory ' + self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 1) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 def setup_network(self, split=False): - self.nodes = start_nodes(1, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) self.is_network_split = False def successful_signing_test(self): diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 8fcb99c1b..d76fba4b0 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -145,6 +145,11 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True): class EstimateFeeTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False + def setup_network(self): ''' We'll setup the network to have 3 nodes that all mine with different parameters. diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 3480de6c6..b9b803429 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -15,7 +15,6 @@ import traceback from .util import ( initialize_chain, - assert_equal, start_nodes, connect_nodes_bi, sync_blocks, @@ -32,21 +31,26 @@ from .authproxy import JSONRPCException class BitcoinTestFramework(object): - # These may be over-ridden by subclasses: + def __init__(self): + self.num_nodes = 4 + self.setup_clean_chain = False + self.nodes = None + def run_test(self): - for node in self.nodes: - assert_equal(node.getblockcount(), 200) - assert_equal(node.getbalance(), 25*50) + raise NotImplementedError def add_options(self, parser): pass def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) - initialize_chain(self.options.tmpdir) + if self.setup_clean_chain: + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + else: + initialize_chain(self.options.tmpdir, self.num_nodes) def setup_nodes(self): - return start_nodes(4, self.options.tmpdir) + return start_nodes(self.num_nodes, self.options.tmpdir) def setup_network(self, split = False): self.nodes = self.setup_nodes() @@ -181,9 +185,10 @@ class BitcoinTestFramework(object): class ComparisonTestFramework(BitcoinTestFramework): - # Can override the num_nodes variable to indicate how many nodes to run. def __init__(self): + super().__init__() self.num_nodes = 2 + self.setup_clean_chain = True def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", @@ -193,10 +198,6 @@ class ComparisonTestFramework(BitcoinTestFramework): default=os.getenv("BITCOIND", "bitcoind"), help="bitcoind binary to use for reference nodes (if any)") - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, self.num_nodes) - def setup_network(self): self.nodes = start_nodes( self.num_nodes, self.options.tmpdir, diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 6784177aa..0e522e78d 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -182,24 +182,28 @@ def wait_for_bitcoind_start(process, url, i): raise # unkown JSON RPC exception time.sleep(0.25) -def initialize_chain(test_dir): +def initialize_chain(test_dir, num_nodes): """ - Create (or copy from cache) a 200-block-long chain and - 4 wallets. + Create a cache of a 200-block-long chain (with wallet) for MAX_NODES + Afterward, create num_nodes copies from the cache """ - if (not os.path.isdir(os.path.join("cache","node0")) - or not os.path.isdir(os.path.join("cache","node1")) - or not os.path.isdir(os.path.join("cache","node2")) - or not os.path.isdir(os.path.join("cache","node3"))): + assert num_nodes <= MAX_NODES + create_cache = False + for i in range(MAX_NODES): + if not os.path.isdir(os.path.join('cache', 'node'+str(i))): + create_cache = True + break + + if create_cache: #find and delete old cache directories if any exist - for i in range(4): + for i in range(MAX_NODES): if os.path.isdir(os.path.join("cache","node"+str(i))): shutil.rmtree(os.path.join("cache","node"+str(i))) # Create cache directories, run bitcoinds: - for i in range(4): + for i in range(MAX_NODES): datadir=initialize_datadir("cache", i) args = [ os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir="+datadir, "-discover=0" ] if i > 0: @@ -212,15 +216,18 @@ def initialize_chain(test_dir): print("initialize_chain: RPC succesfully started") rpcs = [] - for i in range(4): + for i in range(MAX_NODES): try: rpcs.append(get_rpc_proxy(rpc_url(i), i)) except: sys.stderr.write("Error connecting to "+url+"\n") sys.exit(1) - # Create a 200-block-long chain; each of the 4 nodes + # Create a 200-block-long chain; each of the 4 first nodes # gets 25 mature blocks and 25 immature. + # Note: To preserve compatibility with older versions of + # initialize_chain, only 4 nodes will generate coins. + # # blocks are created with timestamps 10 minutes apart # starting from 2010 minutes in the past enable_mocktime() @@ -238,13 +245,13 @@ def initialize_chain(test_dir): stop_nodes(rpcs) wait_bitcoinds() disable_mocktime() - for i in range(4): + for i in range(MAX_NODES): os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "db.log")) os.remove(log_filename("cache", i, "peers.dat")) os.remove(log_filename("cache", i, "fee_estimates.dat")) - for i in range(4): + for i in range(num_nodes): from_dir = os.path.join("cache", "node"+str(i)) to_dir = os.path.join(test_dir, "node"+str(i)) shutil.copytree(from_dir, to_dir) diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index 5710c29aa..22f850ece 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -12,6 +12,11 @@ from test_framework.util import * class TxnMallTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + def add_options(self, parser): parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true", help="Test double-spend of 1-confirmed transaction") diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 1fbb207e2..84944c3c1 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -12,6 +12,11 @@ from test_framework.util import * class TxnMallTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + def add_options(self, parser): parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true", help="Test double-spend of 1-confirmed transaction") diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 42ce0a726..2d24ced97 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -19,9 +19,10 @@ class WalletTest (BitcoinTestFramework): raise AssertionError("Fee of %s BTC too high! (Should be %s BTC)"%(str(fee), str(target_fee))) return curr_balance - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 def setup_network(self, split=False): self.nodes = start_nodes(3, self.options.tmpdir) diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index c3d53669c..b991d5c76 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -41,15 +41,16 @@ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, str class WalletBackupTest(BitcoinTestFramework): - def setup_chain(self): - logging.info("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 # This mirrors how the network was setup in the bash test def setup_network(self, split=False): # nodes 1, 2,3 are spenders, let's give them a keypool=100 extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] - self.nodes = start_nodes(4, self.options.tmpdir, extra_args) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) connect_nodes(self.nodes[0], 3) connect_nodes(self.nodes[1], 3) connect_nodes(self.nodes[2], 3) diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 2f8214f87..17ba53a84 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -9,12 +9,13 @@ from test_framework.util import * class ZapWalletTXesTest (BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index f5617a084..3a116317f 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -17,6 +17,10 @@ import urllib.parse class ZMQTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + port = 28332 def setup_nodes(self): @@ -25,7 +29,7 @@ class ZMQTest (BitcoinTestFramework): self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock") self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx") self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) - return start_nodes(4, self.options.tmpdir, extra_args=[ + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[ ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], [], [], From fad68f751aff024bcbc1587640c3591aab5a80f7 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 15 May 2016 12:20:15 +0200 Subject: [PATCH 0627/1223] [qa] Reduce node count for some tests --- qa/rpc-tests/importprunedfunds.py | 2 +- qa/rpc-tests/maxuploadtarget.py | 2 +- qa/rpc-tests/mempool_limit.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index 761c9af90..d86f51b7f 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -12,7 +12,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework): def __init__(self): super().__init__() self.setup_clean_chain = True - self.num_nodes = 4 + self.num_nodes = 2 def setup_network(self, split=False): self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 42235a511..5087f0762 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -89,7 +89,7 @@ class MaxUploadTest(BitcoinTestFramework): def __init__(self): super().__init__() self.setup_clean_chain = True - self.num_nodes = 2 + self.num_nodes = 1 self.utxo = [] self.txouts = gen_return_txouts() diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py index c1c5558a9..4438c152d 100755 --- a/qa/rpc-tests/mempool_limit.py +++ b/qa/rpc-tests/mempool_limit.py @@ -20,7 +20,7 @@ class MempoolLimitTest(BitcoinTestFramework): def __init__(self): super().__init__() self.setup_clean_chain = True - self.num_nodes = 2 + self.num_nodes = 1 self.txouts = gen_return_txouts() From f93c2a1b7ee912f0651ebb4c8a5eca220e434f4a Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Sun, 15 May 2016 20:15:02 +0200 Subject: [PATCH 0628/1223] net: Avoid duplicate getheaders requests. The current logic for syncing headers may lead to lots of duplicate getheaders requests being sent: If a new block arrives while the node is in headers sync, it will send getheaders in response to the block announcement. When the headers arrive, the message will be of maximum size and so a follow-up request will be sent---all of that in addition to the existing headers syncing. This will create a second "chain" of getheaders requests. If more blocks arrive, this may even lead to arbitrarily many parallel chains of redundant requests. This patch changes the behaviour to only request more headers after a maximum-sized message when it contained at least one unknown header. This avoids sustaining parallel chains of redundant requests. Note that this patch avoids the issues raised in the discussion of https://github.com/bitcoin/bitcoin/pull/6821: There is no risk of the node being permanently blocked. At the latest when a new block arrives this will trigger a new getheaders request and restart syncing. --- src/main.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index ee30954b4..5816f799a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5091,6 +5091,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } + // If we already know the last header in the message, then it contains + // no new information for us. In this case, we do not request + // more headers later. This prevents multiple chains of redundant + // getheader requests from running in parallel if triggered by incoming + // blocks while the node is still in initial headers sync. + const bool hasNewHeaders = (mapBlockIndex.count(headers.back().GetHash()) == 0); + CBlockIndex *pindexLast = NULL; BOOST_FOREACH(const CBlockHeader& header, headers) { CValidationState state; @@ -5111,7 +5118,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pindexLast) UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); - if (nCount == MAX_HEADERS_RESULTS && pindexLast) { + if (nCount == MAX_HEADERS_RESULTS && pindexLast && hasNewHeaders) { // Headers message had its maximum size; the peer may have more headers. // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. From d87b198b7334317952ca6a1377e25b5c859a1767 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 20 Apr 2016 19:38:19 +0000 Subject: [PATCH 0629/1223] Remove unneeded feerate param from RelayTransaction/AcceptToMemoryPool. --- src/main.cpp | 23 +++++++++-------------- src/main.h | 2 +- src/net.cpp | 2 +- src/net.h | 2 +- src/rpc/rawtransaction.cpp | 5 ++--- src/test/txvalidationcache_tests.cpp | 2 +- src/wallet/wallet.cpp | 6 ++---- 7 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ee30954b4..09f82312a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1005,7 +1005,7 @@ std::string FormatStateMessage(const CValidationState &state) } bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree, - bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, + bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector& vHashTxnToUncache) { const uint256 hash = tx.GetHash(); @@ -1170,9 +1170,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps, lp); unsigned int nSize = entry.GetTxSize(); - if (txFeeRate) { - *txFeeRate = CFeeRate(nFees, nSize); - } // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction @@ -1421,10 +1418,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) + bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) { std::vector vHashTxToUncache; - bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, txFeeRate, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache); + bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache); if (!res) { BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache) pcoinsTip->Uncache(hashTx); @@ -2651,7 +2648,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara // ignore validation errors in resurrected transactions list removed; CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, NULL, true)) { + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { mempool.removeRecursive(tx, removed); } else if (mempool.exists(tx.GetHash())) { vHashUpdate.push_back(tx.GetHash()); @@ -4956,10 +4953,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->setAskFor.erase(inv.hash); mapAlreadyAskedFor.erase(inv.hash); - CFeeRate txFeeRate = CFeeRate(0); - if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, &txFeeRate)) { + if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); - RelayTransaction(tx, txFeeRate); + RelayTransaction(tx); vWorkQueue.push_back(inv.hash); LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n", @@ -4990,10 +4986,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (setMisbehaving.count(fromPeer)) continue; - CFeeRate orphanFeeRate = CFeeRate(0); - if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2, &orphanFeeRate)) { + if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); - RelayTransaction(orphanTx, orphanFeeRate); + RelayTransaction(orphanTx); vWorkQueue.push_back(orphanHash); vEraseQueue.push_back(orphanHash); } @@ -5046,7 +5041,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS = 0; if (!state.IsInvalid(nDoS) || nDoS == 0) { LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id); - RelayTransaction(tx, txFeeRate); + RelayTransaction(tx); } else { LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->id, FormatStateMessage(state)); } diff --git a/src/main.h b/src/main.h index 548218a1b..576f73b5f 100644 --- a/src/main.h +++ b/src/main.h @@ -295,7 +295,7 @@ void PruneAndFlush(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, CFeeRate* txFeeRate, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); + bool* pfMissingInputs, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state); diff --git a/src/net.cpp b/src/net.cpp index 5e810a0f1..aa5b47340 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2069,7 +2069,7 @@ public: instance_of_cnetcleanup; -void RelayTransaction(const CTransaction& tx, CFeeRate feerate) +void RelayTransaction(const CTransaction& tx) { CInv inv(MSG_TX, tx.GetHash()); { diff --git a/src/net.h b/src/net.h index b6ec7bf3e..fd80056c6 100644 --- a/src/net.h +++ b/src/net.h @@ -783,7 +783,7 @@ public: class CTransaction; -void RelayTransaction(const CTransaction& tx, CFeeRate feerate); +void RelayTransaction(const CTransaction& tx); /** Access to the (IP) address database (peers.dat) */ class CAddrDB diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index de8cd68f6..bec7ebe55 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -819,12 +819,11 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) const CCoins* existingCoins = view.AccessCoins(hashTx); bool fHaveMempool = mempool.exists(hashTx); bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000; - CFeeRate txFeeRate = CFeeRate(0); if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; bool fMissingInputs; - if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, &txFeeRate, false, nMaxRawTxFee)) { + if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, nMaxRawTxFee)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { @@ -837,7 +836,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) } else if (fHaveChain) { throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); } - RelayTransaction(tx, txFeeRate); + RelayTransaction(tx); return hashTx.GetHex(); } diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 237b26329..c29e30792 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, tx, false, NULL, NULL, true, 0); + return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a18b669b3..6b942e29d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1272,9 +1272,7 @@ bool CWalletTx::RelayWalletTransaction() { if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); - CFeeRate feeRate; - mempool.lookupFeeRate(GetHash(), feeRate); - RelayTransaction((CTransaction)*this, feeRate); + RelayTransaction((CTransaction)*this); return true; } } @@ -3331,5 +3329,5 @@ int CMerkleTx::GetBlocksToMaturity() const bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, NULL, false, nAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); } From d253ec4baa21cc292cf72d453f71b4043b53e591 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 20 Apr 2016 14:53:36 +0200 Subject: [PATCH 0630/1223] Make ProcessNewBlock dbp const and update comment --- src/main.cpp | 4 ++-- src/main.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 09f82312a..981d98771 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3398,7 +3398,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state } /** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ -static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) +static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp) { AssertLockHeld(cs_main); @@ -3474,7 +3474,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) { { LOCK(cs_main); diff --git a/src/main.h b/src/main.h index 576f73b5f..f287171f1 100644 --- a/src/main.h +++ b/src/main.h @@ -212,10 +212,10 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. - * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. + * @param[out] dbp The already known disk position of pblock, or NULL if not yet stored. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ From 316623f2c197971db9b5bcb9c84e446254b552c3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 20 Apr 2016 15:45:41 +0200 Subject: [PATCH 0631/1223] Switch reindexing to AcceptBlock in-loop and ActivateBestChain afterwards --- src/init.cpp | 20 ++++++++++---------- src/main.cpp | 13 ++++++++----- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d19ca530b..beb848ddb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -404,7 +404,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent, tor, zmq"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + @@ -554,9 +554,10 @@ void ThreadImport(std::vector vImportFiles) { const CChainParams& chainparams = Params(); RenameThread("bitcoin-loadblk"); + CImportingNow imp; + // -reindex if (fReindex) { - CImportingNow imp; int nFile = 0; while (true) { CDiskBlockPos pos(nFile, 0); @@ -581,7 +582,6 @@ void ThreadImport(std::vector vImportFiles) if (boost::filesystem::exists(pathBootstrap)) { FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); if (file) { - CImportingNow imp; boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); LoadExternalBlockFile(chainparams, file); @@ -595,7 +595,6 @@ void ThreadImport(std::vector vImportFiles) BOOST_FOREACH(const boost::filesystem::path& path, vImportFiles) { FILE *file = fopen(path.string().c_str(), "rb"); if (file) { - CImportingNow imp; LogPrintf("Importing blocks file %s...\n", path.string()); LoadExternalBlockFile(chainparams, file); } else { @@ -603,6 +602,13 @@ void ThreadImport(std::vector vImportFiles) } } + // scan for better chains in the block chain database, that are not yet connected in the active best chain + CValidationState state; + if (!ActivateBestChain(state, chainparams)) { + LogPrintf("Failed to connect best block"); + StartShutdown(); + } + if (GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); @@ -1358,12 +1364,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); - uiInterface.InitMessage(_("Activating best chain...")); - // scan for better chains in the block chain database, that are not yet connected in the active best chain - CValidationState state; - if (!ActivateBestChain(state, chainparams)) - strErrors << "Failed to connect best block"; - std::vector vImportFiles; if (mapArgs.count("-loadblock")) { diff --git a/src/main.cpp b/src/main.cpp index 981d98771..42733ee2d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3402,7 +3402,8 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha { AssertLockHeld(cs_main); - CBlockIndex *&pindex = *ppindex; + CBlockIndex *pindexDummy = NULL; + CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; if (!AcceptBlockHeader(block, state, chainparams, &pindex)) return false; @@ -4037,13 +4038,14 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB // process in case the block isn't known yet if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { + LOCK(cs_main); CValidationState state; - if (ProcessNewBlock(state, chainparams, NULL, &block, true, dbp)) + if (AcceptBlock(block, state, chainparams, NULL, true, dbp)) nLoaded++; if (state.IsError()) break; } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) { - LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); + LogPrint("reindex", "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); } // Recursively process earlier encountered successors of this block @@ -4057,10 +4059,11 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB std::multimap::iterator it = range.first; if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus())) { - LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), + LogPrint("reindex", "%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); + LOCK(cs_main); CValidationState dummy; - if (ProcessNewBlock(dummy, chainparams, NULL, &block, true, &it->second)) + if (AcceptBlock(block, dummy, chainparams, NULL, true, &it->second)) { nLoaded++; queue.push_back(block.GetHash()); From fb8fad1586ced69fa37c665a11916ae4c4d0df05 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 20 Apr 2016 16:02:19 +0200 Subject: [PATCH 0632/1223] Optimize ActivateBestChain for long chains --- src/main.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 42733ee2d..38851cda3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2811,10 +2811,9 @@ static void PruneBlockIndexCandidates() { * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock) +static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock, bool& fInvalidFound) { AssertLockHeld(cs_main); - bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); @@ -2902,15 +2901,22 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, { LOCK(cs_main); CBlockIndex *pindexOldTip = chainActive.Tip(); - pindexMostWork = FindMostWorkChain(); + if (pindexMostWork == NULL) { + pindexMostWork = FindMostWorkChain(); + } // Whether we have anything to do at all. if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) return true; - if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) + bool fInvalidFound = false; + if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL, fInvalidFound)) return false; + if (fInvalidFound) { + // Wipe cache, we may need another branch now. + pindexMostWork = NULL; + } pindexNewTip = chainActive.Tip(); pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload(); From d3d75479115bc3480f163df774ee9dd2f8bd9f54 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 21 Apr 2016 14:14:37 +0200 Subject: [PATCH 0633/1223] Add -reindex-chainstate that does not rebuild block index --- qa/rpc-tests/reindex.py | 15 +++++++++++---- src/init.cpp | 8 +++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index 39564b32b..cb5e413fd 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -# Test -reindex with CheckBlockIndex +# Test -reindex and -reindex-chainstate with CheckBlockIndex # from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -20,13 +20,20 @@ class ReindexTest(BitcoinTestFramework): self.is_network_split = False self.nodes.append(start_node(0, self.options.tmpdir)) - def run_test(self): + def reindex(self, justchainstate=False): self.nodes[0].generate(3) + blockcount = self.nodes[0].getblockcount() stop_node(self.nodes[0], 0) wait_bitcoinds() - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"]) - assert_equal(self.nodes[0].getblockcount(), 3) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) + assert_equal(self.nodes[0].getblockcount(), blockcount) print("Success") + def run_test(self): + self.reindex(False) + self.reindex(True) + self.reindex(False) + self.reindex(True) + if __name__ == '__main__': ReindexTest().main() diff --git a/src/init.cpp b/src/init.cpp index beb848ddb..8688381ec 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -327,7 +327,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-prune=", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); - strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup")); + strUsage += HelpMessageOpt("-reindex-chainstate", _("Rebuild chain state from the currently indexed blocks")); + strUsage += HelpMessageOpt("-reindex", _("Rebuild chain state and block index from the blk*.dat files on disk")); #ifndef WIN32 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif @@ -1164,6 +1165,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); + bool fReindexChainState = GetBoolArg("-reindex-chainstate", false); // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ boost::filesystem::path blocksDir = GetDataDir() / "blocks"; @@ -1225,7 +1227,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) delete pblocktree; pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); - pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex); + pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); pcoinsTip = new CCoinsViewCache(pcoinscatcher); @@ -1254,7 +1256,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Check for changed -txindex state if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); + strLoadError = _("You need to rebuild the database using -reindex-chainstate to change -txindex"); break; } From b4d24e142e25a21c78ab74146c3520f2259fd7c2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 28 Apr 2016 16:18:45 +0200 Subject: [PATCH 0634/1223] Report reindexing progress in GUI --- qa/rpc-tests/reindex.py | 3 +++ src/main.cpp | 39 ++++++++++++++++++++++++++++++++++++++ src/qt/bitcoingui.cpp | 18 ++++++++++++++---- src/qt/bitcoingui.h | 2 +- src/qt/clientmodel.cpp | 18 ++++++++++++------ src/qt/clientmodel.h | 2 +- src/qt/rpcconsole.cpp | 12 +++++++----- src/qt/rpcconsole.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/ui_interface.h | 3 +++ 10 files changed, 82 insertions(+), 19 deletions(-) diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index cb5e413fd..a3f4d6ea0 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -8,6 +8,7 @@ # from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +import time class ReindexTest(BitcoinTestFramework): @@ -26,6 +27,8 @@ class ReindexTest(BitcoinTestFramework): stop_node(self.nodes[0], 0) wait_bitcoinds() self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) + while self.nodes[0].getblockcount() < blockcount: + time.sleep(0.1) assert_equal(self.nodes[0].getblockcount(), blockcount) print("Success") diff --git a/src/main.cpp b/src/main.cpp index 38851cda3..66930b3b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2883,6 +2883,28 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c return true; } +static void NotifyHeaderTip() { + bool fNotify = false; + bool fInitialBlockDownload = false; + static CBlockIndex* pindexHeaderOld = NULL; + CBlockIndex* pindexHeader = NULL; + { + LOCK(cs_main); + if (!setBlockIndexCandidates.empty()) { + pindexHeader = *setBlockIndexCandidates.rbegin(); + } + if (pindexHeader != pindexHeaderOld) { + fNotify = true; + fInitialBlockDownload = IsInitialBlockDownload(); + pindexHeaderOld = pindexHeader; + } + } + // Send block tip changed notifications without cs_main + if (fNotify) { + uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader); + } +} + /** * Make the best chain active, in multiple steps. The result is either failure * or an activated best chain. pblock is either NULL or a pointer to a block @@ -3499,6 +3521,8 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c return error("%s: AcceptBlock FAILED", __func__); } + NotifyHeaderTip(); + if (!ActivateBestChain(state, chainparams, pblock)) return error("%s: ActivateBestChain failed", __func__); @@ -4054,6 +4078,16 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB LogPrint("reindex", "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); } + // Activate the genesis block so normal node progress can continue + if (hash == chainparams.GetConsensus().hashGenesisBlock) { + CValidationState state; + if (!ActivateBestChain(state, chainparams)) { + break; + } + } + + NotifyHeaderTip(); + // Recursively process earlier encountered successors of this block deque queue; queue.push_back(hash); @@ -4077,6 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB } range.first++; mapBlocksUnknownParent.erase(it); + NotifyHeaderTip(); } } } catch (const std::exception& e) { @@ -5088,6 +5123,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ReadCompactSize(vRecv); // ignore tx count; assume it is 0. } + { LOCK(cs_main); if (nCount == 0) { @@ -5171,6 +5207,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } CheckBlockIndex(chainparams.GetConsensus()); + } + + NotifyHeaderTip(); } else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 998448636..4998848e9 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -457,8 +457,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumConnections(clientModel->getNumConnections()); connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL)); - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); + setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL), false); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); // Receive and report messages from client model connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); @@ -696,7 +696,7 @@ void BitcoinGUI::setNumConnections(int count) labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } -void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header) { if(!clientModel) return; @@ -708,15 +708,25 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer enum BlockSource blockSource = clientModel->getBlockSource(); switch (blockSource) { case BLOCK_SOURCE_NETWORK: + if (header) { + return; + } progressBarLabel->setText(tr("Synchronizing with network...")); break; case BLOCK_SOURCE_DISK: - progressBarLabel->setText(tr("Importing blocks from disk...")); + if (header) { + progressBarLabel->setText(tr("Indexing blocks on disk...")); + } else { + progressBarLabel->setText(tr("Processing blocks on disk...")); + } break; case BLOCK_SOURCE_REINDEX: progressBarLabel->setText(tr("Reindexing blocks on disk...")); break; case BLOCK_SOURCE_NONE: + if (header) { + return; + } // Case: not Importing, not Reindexing and no network connection progressBarLabel->setText(tr("No block source available...")); break; diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 27ef11c75..33639ed5a 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -150,7 +150,7 @@ public Q_SLOTS: /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers); /** Notify the user of an event from the core network or transaction handling code. @param[in] title the message box / notification title diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 697736cc8..108500654 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -24,6 +24,7 @@ class CBlockIndex; static const int64_t nClientStartupTime = GetTime(); +static int64_t nLastHeaderTipUpdateNotification = 0; static int64_t nLastBlockTipUpdateNotification = 0; ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : @@ -226,7 +227,7 @@ static void BannedListChanged(ClientModel *clientmodel) QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); } -static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex) +static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader) { // lock free async UI updates in case we have a new block tip // during initial sync, only update the UI if the last update @@ -235,14 +236,17 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB if (initialSync) now = GetTimeMillis(); + int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification; + // if we are in-sync, update the UI regardless of last update time - if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) { + if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { //pass a async signal to the UI thread QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), - Q_ARG(double, clientmodel->getVerificationProgress(pIndex))); - nLastBlockTipUpdateNotification = now; + Q_ARG(double, clientmodel->getVerificationProgress(pIndex)), + Q_ARG(bool, fHeader)); + nLastUpdateNotification = now; } } @@ -253,7 +257,8 @@ void ClientModel::subscribeToCoreSignals() uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this)); uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); - uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2)); + uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false)); + uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true)); } void ClientModel::unsubscribeFromCoreSignals() @@ -263,5 +268,6 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this)); uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); - uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2)); + uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false)); + uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 109f95a2a..439680431 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -89,7 +89,7 @@ private: Q_SIGNALS: void numConnectionsChanged(int count); - void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress); + void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, bool header); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index d8647d902..fd627eb4a 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -353,8 +353,8 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL)); - connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL), false); + connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); @@ -585,10 +585,12 @@ void RPCConsole::setNumConnections(int count) ui->numberOfConnections->setText(connections); } -void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) +void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers) { - ui->numberOfBlocks->setText(QString::number(count)); - ui->lastBlockTime->setText(blockDate.toString()); + if (!headers) { + ui->numberOfBlocks->setText(QString::number(count)); + ui->lastBlockTime->setText(blockDate.toString()); + } } void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 2923587bc..28affa954 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -87,7 +87,7 @@ public Q_SLOTS: /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers); /** Set size (number of transactions and memory usage) of the mempool in the UI */ void setMempoolSize(long numberOfTxs, size_t dynUsage); /** Go forward or back in history */ diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 54ebd2583..6d50be56e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -124,7 +124,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel) this->clientModel = clientModel; if (clientModel) { - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(updateSmartFeeLabel())); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel())); } } diff --git a/src/ui_interface.h b/src/ui_interface.h index a27918c50..7ebfc17e5 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -96,6 +96,9 @@ public: /** New block has been accepted */ boost::signals2::signal NotifyBlockTip; + /** Best header has changed */ + boost::signals2::signal NotifyHeaderTip; + /** Banlist did change. */ boost::signals2::signal BannedListChanged; }; From ecb9741ec3067f67f595126869d0200c62064bbd Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 16 May 2016 17:11:24 -0700 Subject: [PATCH 0635/1223] Move GetAccountBalance from rpcwallet.cpp into CWallet::GetAccountBalance --- src/wallet/rpcwallet.cpp | 38 +++----------------------------------- src/wallet/wallet.cpp | 31 +++++++++++++++++++++++++++++++ src/wallet/wallet.h | 2 ++ 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 623037e76..8bd1279b7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -673,38 +673,6 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) } -CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) -{ - CAmount nBalance = 0; - - // Tally wallet transactions - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) - continue; - - CAmount nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); - - if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) - nBalance += nReceived; - nBalance -= nSent + nFee; - } - - // Tally internal accounting entries - nBalance += walletdb.GetAccountCreditDebit(strAccount); - - return nBalance; -} - -CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) -{ - CWalletDB walletdb(pwalletMain->strWalletFile); - return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); -} - - UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) @@ -775,7 +743,7 @@ UniValue getbalance(const UniValue& params, bool fHelp) string strAccount = AccountFromValue(params[0]); - CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter); + CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } @@ -923,7 +891,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); @@ -1026,7 +994,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6b942e29d..4809e3baa 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2759,6 +2759,37 @@ set< set > CWallet::GetAddressGroupings() return ret; } +CAmount CWallet::GetAccountBalance(const std::string& strAccount, int nMinDepth, const isminefilter& filter) +{ + CWalletDB walletdb(strWalletFile); + return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); +} + +CAmount CWallet::GetAccountBalance(CWalletDB& walletdb, const std::string& strAccount, int nMinDepth, const isminefilter& filter) +{ + CAmount nBalance = 0; + + // Tally wallet transactions + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) + continue; + + CAmount nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); + + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) + nBalance += nReceived; + nBalance -= nSent + nFee; + } + + // Tally internal accounting entries + nBalance += walletdb.GetAccountCreditDebit(strAccount); + + return nBalance; +} + std::set CWallet::GetAccountAddresses(const std::string& strAccount) const { LOCK(cs_wallet); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index cc568c374..631f2b31e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -776,6 +776,8 @@ public: std::set< std::set > GetAddressGroupings(); std::map GetAddressBalances(); + CAmount GetAccountBalance(const std::string& strAccount, int nMinDepth, const isminefilter& filter); + CAmount GetAccountBalance(CWalletDB& walletdb, const std::string& strAccount, int nMinDepth, const isminefilter& filter); std::set GetAccountAddresses(const std::string& strAccount) const; isminetype IsMine(const CTxIn& txin) const; From 380498aba4f6aebe53a8241f163e3c7fe424b7e0 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 16 May 2016 17:31:16 -0700 Subject: [PATCH 0636/1223] Move BackupWallet to CWallet::BackupWallet --- src/qt/walletmodel.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 2 ++ src/wallet/walletdb.cpp | 40 ---------------------------------------- src/wallet/walletdb.h | 1 - 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a0d0e7044..3867310cd 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -447,7 +447,7 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri bool WalletModel::backupWallet(const QString &filename) { - return BackupWallet(*wallet, filename.toLocal8Bit().data()); + return wallet->BackupWallet(filename.toLocal8Bit().data()); } // Handlers for core signals diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8bd1279b7..f11f29914 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1804,7 +1804,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strDest = params[0].get_str(); - if (!BackupWallet(*pwalletMain, strDest)) + if (!pwalletMain->BackupWallet(strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); return NullUniValue; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4809e3baa..5d1a43119 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3283,6 +3283,46 @@ bool CWallet::ParameterInteraction() return true; } +bool CWallet::BackupWallet(const std::string& strDest) +{ + if (!fFileBacked) + return false; + while (true) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(strWalletFile) || bitdb.mapFileUseCount[strWalletFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(strWalletFile); + bitdb.CheckpointLSN(strWalletFile); + bitdb.mapFileUseCount.erase(strWalletFile); + + // Copy wallet file + boost::filesystem::path pathSrc = GetDataDir() / strWalletFile; + boost::filesystem::path pathDest(strDest); + if (boost::filesystem::is_directory(pathDest)) + pathDest /= strWalletFile; + + try { +#if BOOST_VERSION >= 104000 + boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); +#else + boost::filesystem::copy_file(pathSrc, pathDest); +#endif + LogPrintf("copied %s to %s\n", strWalletFile, pathDest.string()); + return true; + } catch (const boost::filesystem::filesystem_error& e) { + LogPrintf("error copying %s to %s - %s\n", strWalletFile, pathDest.string(), e.what()); + return false; + } + } + } + MilliSleep(100); + } + return false; +} + CKeyPool::CKeyPool() { nTime = GetTime(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 631f2b31e..b2180a5a2 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -885,6 +885,8 @@ public: /* Wallets parameter interaction */ static bool ParameterInteraction(); + + bool BackupWallet(const std::string& strDest); }; /** A key allocated from the key pool. */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 48579b282..b5037c9a6 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -903,46 +903,6 @@ void ThreadFlushWalletDB(const string& strFile) } } -bool BackupWallet(const CWallet& wallet, const string& strDest) -{ - if (!wallet.fFileBacked) - return false; - while (true) - { - { - LOCK(bitdb.cs_db); - if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) - { - // Flush log data to the dat file - bitdb.CloseDb(wallet.strWalletFile); - bitdb.CheckpointLSN(wallet.strWalletFile); - bitdb.mapFileUseCount.erase(wallet.strWalletFile); - - // Copy wallet file - boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; - boost::filesystem::path pathDest(strDest); - if (boost::filesystem::is_directory(pathDest)) - pathDest /= wallet.strWalletFile; - - try { -#if BOOST_VERSION >= 104000 - boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); -#else - boost::filesystem::copy_file(pathSrc, pathDest); -#endif - LogPrintf("copied %s to %s\n", wallet.strWalletFile, pathDest.string()); - return true; - } catch (const boost::filesystem::filesystem_error& e) { - LogPrintf("error copying %s to %s - %s\n", wallet.strWalletFile, pathDest.string(), e.what()); - return false; - } - } - } - MilliSleep(100); - } - return false; -} - // // Try to (very carefully!) recover wallet file if there is a problem. // diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 5345c0907..00c10ea70 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -141,7 +141,6 @@ private: bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); }; -bool BackupWallet(const CWallet& wallet, const std::string& strDest); void ThreadFlushWalletDB(const std::string& strFile); #endif // BITCOIN_WALLET_WALLETDB_H From 46b0c3b688dccf6ba9ac08cbd6d6981249a73b1a Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 16 May 2016 20:33:32 -0700 Subject: [PATCH 0637/1223] Acquire lock to check for genesis block. --- src/init.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d19ca530b..fd1241d93 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1371,10 +1371,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); - if (chainActive.Tip() == NULL) { - LogPrintf("Waiting for genesis block to be imported...\n"); - while (!fRequestShutdown && chainActive.Tip() == NULL) + + // Wait for genesis block to be processed + bool fHaveGenesis = false; + while (!fHaveGenesis && !fRequestShutdown) { + { + LOCK(cs_main); + fHaveGenesis = (chainActive.Tip() != NULL); + } + + if (!fHaveGenesis) { MilliSleep(10); + } } // ********************************************************* Step 11: start node From 94fd1d8d53adceb80e5a41cc6438c7704aeac0f7 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Tue, 17 May 2016 16:43:23 +0900 Subject: [PATCH 0638/1223] Make Socks5() InterruptibleRecv() timeout/failures informative. Before: 2016-05-16 06:10:45 ERROR: Error reading proxy response After: 2016-05-16 06:10:45 Socks5() connect to k7s5d6jqig4ej4v4.onion:18333 failed: InterruptibleRecv() timeout or other failure --- src/netbase.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 5ab12c9a7..d2a4188ff 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -318,7 +318,8 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials char pchRet1[2]; if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { CloseSocket(hSocket); - return error("Error reading proxy response"); + LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port); + return false; } if (pchRet1[0] != 0x05) { CloseSocket(hSocket); From fad184550e1c507a897be59169f9c5dabce8d652 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 3 Apr 2016 20:36:27 +0200 Subject: [PATCH 0639/1223] [qa] test_framework: Use different rpc_auth_pair for each node --- qa/rpc-tests/test_framework/util.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 6784177aa..d6bb32b18 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -150,17 +150,22 @@ def initialize_datadir(dirname, n): datadir = os.path.join(dirname, "node"+str(n)) if not os.path.isdir(datadir): os.makedirs(datadir) + rpc_u, rpc_p = rpc_auth_pair(n) with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: f.write("regtest=1\n") - f.write("rpcuser=rt\n") - f.write("rpcpassword=rt\n") + f.write("rpcuser=" + rpc_u + "\n") + f.write("rpcpassword=" + rpc_p + "\n") f.write("port="+str(p2p_port(n))+"\n") f.write("rpcport="+str(rpc_port(n))+"\n") f.write("listenonion=0\n") return datadir +def rpc_auth_pair(n): + return 'rpcuser💻' + str(n), 'rpcpass🔑' + str(n) + def rpc_url(i, rpchost=None): - return "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + rpc_u, rpc_p = rpc_auth_pair(i) + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) def wait_for_bitcoind_start(process, url, i): ''' From 5ec0cde371149e5be6ca5e9803183021b10928f8 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 13:43:17 -0500 Subject: [PATCH 0640/1223] Refactor logic for converting mempool entries to JSON --- src/rpc/blockchain.cpp | 90 ++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cf3c73c4d..fe628097a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -183,6 +183,54 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) return GetDifficulty(); } +std::string EntryDescriptionString() +{ + return " \"size\" : n, (numeric) transaction size in bytes\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" + " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n"; +} + +void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) +{ + AssertLockHeld(mempool.cs); + + info.push_back(Pair("size", (int)e.GetTxSize())); + info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); + info.push_back(Pair("time", e.GetTime())); + info.push_back(Pair("height", (int)e.GetHeight())); + info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); + info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); + info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + const CTransaction& tx = e.GetTx(); + set setDepends; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + if (mempool.exists(txin.prevout.hash)) + setDepends.insert(txin.prevout.hash.ToString()); + } + + UniValue depends(UniValue::VARR); + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + + info.push_back(Pair("depends", depends)); +} + UniValue mempoolToJSON(bool fVerbose = false) { if (fVerbose) @@ -193,31 +241,7 @@ UniValue mempoolToJSON(bool fVerbose = false) { const uint256& hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); - info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); - info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); - const CTransaction& tx = e.GetTx(); - set setDepends; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - if (mempool.exists(txin.prevout.hash)) - setDepends.insert(txin.prevout.hash.ToString()); - } - - UniValue depends(UniValue::VARR); - BOOST_FOREACH(const string& dep, setDepends) - { - depends.push_back(dep); - } - - info.push_back(Pair("depends", depends)); + entryToJSON(info, e); o.push_back(Pair(hash.ToString(), info)); } return o; @@ -251,20 +275,8 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) "\nResult: (for verbose = true):\n" "{ (json object)\n" " \"transactionid\" : { (json object)\n" - " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" - " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" - " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" - " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" - " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" - " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" - " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" - " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" - " \"transactionid\", (string) parent transaction id\n" - " ... ]\n" - " }, ...\n" + + EntryDescriptionString() + + " }, ...\n" "}\n" "\nExamples\n" + HelpExampleCli("getrawmempool", "true") From 8f7b5dc4afb28e38ce0223339b8ce77aa0a47845 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 13:58:59 -0500 Subject: [PATCH 0641/1223] Add getmempoolancestors RPC call --- src/rpc/blockchain.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ src/rpc/client.cpp | 1 + 2 files changed, 66 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index fe628097a..6c005068d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -292,6 +292,70 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) return mempoolToJSON(fVerbose); } +UniValue getmempoolancestors(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) { + throw runtime_error( + "getmempoolancestors txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempoolancestors", "\"mytxid\"") + + HelpExampleRpc("getmempoolancestors", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setAncestors; + uint64_t noLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + o.push_back(ancestorIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + const CTxMemPoolEntry &e = *ancestorIt; + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1016,6 +1080,7 @@ static const CRPCCommand commands[] = { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, + { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index c89af6bfa..3dfc27fff 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -102,6 +102,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "prioritisetransaction", 2 }, { "setban", 2 }, { "setban", 3 }, + { "getmempoolancestors", 1 }, }; class CRPCConvertTable From 0b1295b066b9369decb2e664e60b0129dbc30dfb Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 May 2016 20:41:28 +0200 Subject: [PATCH 0642/1223] Add SipHash-2-4 primitives to hash --- src/hash.cpp | 94 +++++++++++++++++++++++++++++++++++++++++ src/hash.h | 15 +++++++ src/test/hash_tests.cpp | 20 +++++++++ src/uint256.h | 13 ++++++ 4 files changed, 142 insertions(+) diff --git a/src/hash.cpp b/src/hash.cpp index 7f3cf1a1f..a518314a5 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -81,3 +81,97 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he num[3] = (nChild >> 0) & 0xFF; CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output); } + +#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) + +#define SIPROUND do { \ + v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \ + v0 = ROTL(v0, 32); \ + v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \ + v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \ + v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \ + v2 = ROTL(v2, 32); \ +} while (0) + +CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) +{ + v[0] = 0x736f6d6570736575ULL ^ k0; + v[1] = 0x646f72616e646f6dULL ^ k1; + v[2] = 0x6c7967656e657261ULL ^ k0; + v[3] = 0x7465646279746573ULL ^ k1; + count = 0; +} + +CSipHasher& CSipHasher::Write(uint64_t data) +{ + uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; + + v3 ^= data; + SIPROUND; + SIPROUND; + v0 ^= data; + + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + + count++; + return *this; +} + +uint64_t CSipHasher::Finalize() const +{ + uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; + + v3 ^= ((uint64_t)count) << 59; + SIPROUND; + SIPROUND; + v0 ^= ((uint64_t)count) << 59; + v2 ^= 0xFF; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + return v0 ^ v1 ^ v2 ^ v3; +} + +uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val) +{ + /* Specialized implementation for efficiency */ + uint64_t d = val.GetUint64(0); + + uint64_t v0 = 0x736f6d6570736575ULL ^ k0; + uint64_t v1 = 0x646f72616e646f6dULL ^ k1; + uint64_t v2 = 0x6c7967656e657261ULL ^ k0; + uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d; + + SIPROUND; + SIPROUND; + v0 ^= d; + d = val.GetUint64(1); + v3 ^= d; + SIPROUND; + SIPROUND; + v0 ^= d; + d = val.GetUint64(2); + v3 ^= d; + SIPROUND; + SIPROUND; + v0 ^= d; + d = val.GetUint64(3); + v3 ^= d; + SIPROUND; + SIPROUND; + v0 ^= d; + v3 ^= ((uint64_t)4) << 59; + SIPROUND; + SIPROUND; + v0 ^= ((uint64_t)4) << 59; + v2 ^= 0xFF; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + return v0 ^ v1 ^ v2 ^ v3; +} diff --git a/src/hash.h b/src/hash.h index 97955c8d5..600dabec5 100644 --- a/src/hash.h +++ b/src/hash.h @@ -171,4 +171,19 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector void Serialize(Stream& s, int nType, int nVersion) const { From 382c871d28b95cc52309a128edd8dc23822bcd60 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 May 2016 20:47:12 +0200 Subject: [PATCH 0643/1223] Use SipHash-2-4 for CCoinsCache index This is ~1.7x slower than the Lookup3-of-Xor-with-salt construct we were using before, but it is a primitive designed for exactly this. --- src/coins.cpp | 6 ++++- src/coins.h | 14 ++++++----- src/uint256.cpp | 64 ------------------------------------------------- src/uint256.h | 5 ---- 4 files changed, 13 insertions(+), 76 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 1c329740b..b7dd293d6 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -56,7 +56,11 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); } -CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} +SaltedTxidHasher::SaltedTxidHasher() +{ + GetRandBytes((unsigned char*)&k0, sizeof(k0)); + GetRandBytes((unsigned char*)&k1, sizeof(k1)); +} CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { } diff --git a/src/coins.h b/src/coins.h index d72f88547..1dd908700 100644 --- a/src/coins.h +++ b/src/coins.h @@ -8,6 +8,7 @@ #include "compressor.h" #include "core_memusage.h" +#include "hash.h" #include "memusage.h" #include "serialize.h" #include "uint256.h" @@ -264,21 +265,22 @@ public: } }; -class CCoinsKeyHasher +class SaltedTxidHasher { private: - uint256 salt; + /** Salt */ + uint64_t k0, k1; public: - CCoinsKeyHasher(); + SaltedTxidHasher(); /** * This *must* return size_t. With Boost 1.46 on 32-bit systems the * unordered_map will behave unpredictably if the custom hasher returns a * uint64_t, resulting in failures when syncing the chain (#4634). */ - size_t operator()(const uint256& key) const { - return key.GetHash(salt); + size_t operator()(const uint256& txid) const { + return SipHashUint256(k0, k1, txid); } }; @@ -295,7 +297,7 @@ struct CCoinsCacheEntry CCoinsCacheEntry() : coins(), flags(0) {} }; -typedef boost::unordered_map CCoinsMap; +typedef boost::unordered_map CCoinsMap; /** Cursor for iterating over CoinsView state */ class CCoinsViewCursor diff --git a/src/uint256.cpp b/src/uint256.cpp index c58c88bf4..f22ddcd1e 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -80,67 +80,3 @@ template std::string base_blob<256>::GetHex() const; template std::string base_blob<256>::ToString() const; template void base_blob<256>::SetHex(const char*); template void base_blob<256>::SetHex(const std::string&); - -static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - a -= c; - a ^= ((c << 4) | (c >> 28)); - c += b; - b -= a; - b ^= ((a << 6) | (a >> 26)); - a += c; - c -= b; - c ^= ((b << 8) | (b >> 24)); - b += a; - a -= c; - a ^= ((c << 16) | (c >> 16)); - c += b; - b -= a; - b ^= ((a << 19) | (a >> 13)); - a += c; - c -= b; - c ^= ((b << 4) | (b >> 28)); - b += a; -} - -static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - c ^= b; - c -= ((b << 14) | (b >> 18)); - a ^= c; - a -= ((c << 11) | (c >> 21)); - b ^= a; - b -= ((a << 25) | (a >> 7)); - c ^= b; - c -= ((b << 16) | (b >> 16)); - a ^= c; - a -= ((c << 4) | (c >> 28)); - b ^= a; - b -= ((a << 14) | (a >> 18)); - c ^= b; - c -= ((b << 24) | (b >> 8)); -} - -uint64_t uint256::GetHash(const uint256& salt) const -{ - uint32_t a, b, c; - const uint32_t *pn = (const uint32_t*)data; - const uint32_t *salt_pn = (const uint32_t*)salt.data; - a = b = c = 0xdeadbeef + WIDTH; - - a += pn[0] ^ salt_pn[0]; - b += pn[1] ^ salt_pn[1]; - c += pn[2] ^ salt_pn[2]; - HashMix(a, b, c); - a += pn[3] ^ salt_pn[3]; - b += pn[4] ^ salt_pn[4]; - c += pn[5] ^ salt_pn[5]; - HashMix(a, b, c); - a += pn[6] ^ salt_pn[6]; - b += pn[7] ^ salt_pn[7]; - HashFinal(a, b, c); - - return ((((uint64_t)b) << 32) | c); -} diff --git a/src/uint256.h b/src/uint256.h index af1f3ab7d..dd8432d74 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -140,11 +140,6 @@ public: { return ReadLE64(data); } - - /** A more secure, salted hash function. - * @note This hash is not stable between little and big endian. - */ - uint64_t GetHash(const uint256& salt) const; }; /* uint256 from const char *. From 8cc9cfe1605432be43d49e09094121bdb93caac8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 May 2016 21:36:36 +0200 Subject: [PATCH 0644/1223] Switch CTxMempool::mapTx to use a hash index for txids --- src/txmempool.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/txmempool.h b/src/txmempool.h index bca8dd979..3e1d38797 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -17,6 +17,7 @@ #undef foreach #include "boost/multi_index_container.hpp" #include "boost/multi_index/ordered_index.hpp" +#include "boost/multi_index/hashed_index.hpp" class CAutoFile; class CBlockIndex; @@ -422,7 +423,7 @@ public: CTxMemPoolEntry, boost::multi_index::indexed_by< // sorted by txid - boost::multi_index::ordered_unique, + boost::multi_index::hashed_unique, // sorted by fee rate boost::multi_index::ordered_non_unique< boost::multi_index::tag, From a68ec21f7ed2978d8945a0f4cfd7e80bfa5fd917 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 May 2016 21:53:38 +0200 Subject: [PATCH 0645/1223] Use SipHash-2-4 for address relay selection --- src/main.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 09f82312a..a1c027bef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4698,25 +4698,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_vNodes); // Use deterministic randomness to send to the same nodes for 24 hours // at a time so the addrKnowns of the chosen nodes prevent repeats - static uint256 hashSalt; - if (hashSalt.IsNull()) - hashSalt = GetRandHash(); + static uint64_t salt0 = 0, salt1 = 0; + while (salt0 == 0 && salt1 == 0) { + GetRandBytes((unsigned char*)&salt0, sizeof(salt0)); + GetRandBytes((unsigned char*)&salt1, sizeof(salt1)); + } uint64_t hashAddr = addr.GetHash(); - uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60))); - hashRand = Hash(BEGIN(hashRand), END(hashRand)); - multimap mapMix; + multimap mapMix; + const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60)); BOOST_FOREACH(CNode* pnode, vNodes) { if (pnode->nVersion < CADDR_TIME_VERSION) continue; - unsigned int nPointer; - memcpy(&nPointer, &pnode, sizeof(nPointer)); - uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer); - hashKey = Hash(BEGIN(hashKey), END(hashKey)); + uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); mapMix.insert(make_pair(hashKey, pnode)); } int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) - for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) ((*mi).second)->PushAddress(addr); } } From 269a4402a8617a539a70b2c332e86f0fe292a7a6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 2 May 2016 17:52:31 -0700 Subject: [PATCH 0646/1223] Add test for dbwrapper iterators with same-prefix keys. --- src/test/dbwrapper_tests.cpp | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 8745d1439..a0bdcf4af 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -238,4 +238,90 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) } } +struct StringContentsSerializer { + // Used to make two serialized objects the same while letting them have a different lengths + // This is a terrible idea + string str; + StringContentsSerializer() {} + StringContentsSerializer(const string& inp) : str(inp) {} + + StringContentsSerializer& operator+=(const string& s) { + str += s; + return *this; + } + StringContentsSerializer& operator+=(const StringContentsSerializer& s) { return *this += s.str; } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (ser_action.ForRead()) { + str.clear(); + char c = 0; + while (true) { + try { + READWRITE(c); + str.push_back(c); + } catch (const std::ios_base::failure& e) { + break; + } + } + } else { + for (size_t i = 0; i < str.size(); i++) + READWRITE(str[i]); + } + } +}; + +BOOST_AUTO_TEST_CASE(iterator_string_ordering) +{ + char buf[10]; + + path ph = temp_directory_path() / unique_path(); + CDBWrapper dbw(ph, (1 << 20), true, false, false); + for (int x=0x00; x<10; ++x) { + for (int y = 0; y < 10; y++) { + sprintf(buf, "%d", x); + StringContentsSerializer key(buf); + for (int z = 0; z < y; z++) + key += key; + uint32_t value = x*x; + BOOST_CHECK(dbw.Write(key, value)); + } + } + + boost::scoped_ptr it(const_cast(&dbw)->NewIterator()); + for (int c=0; c<2; ++c) { + int seek_start; + if (c == 0) + seek_start = 0; + else + seek_start = 5; + sprintf(buf, "%d", seek_start); + StringContentsSerializer seek_key(buf); + it->Seek(seek_key); + for (int x=seek_start; x<10; ++x) { + for (int y = 0; y < 10; y++) { + sprintf(buf, "%d", x); + string exp_key(buf); + for (int z = 0; z < y; z++) + exp_key += exp_key; + StringContentsSerializer key; + uint32_t value; + BOOST_CHECK(it->Valid()); + if (!it->Valid()) // Avoid spurious errors about invalid iterator's key and value in case of failure + break; + BOOST_CHECK(it->GetKey(key)); + BOOST_CHECK(it->GetValue(value)); + BOOST_CHECK_EQUAL(key.str, exp_key); + BOOST_CHECK_EQUAL(value, x*x); + it->Next(); + } + } + BOOST_CHECK(!it->Valid()); + } +} + + + BOOST_AUTO_TEST_SUITE_END() From 6075bc4d67bcd5f95561dc6d53b4fdbaf2c63f4b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 18 May 2016 11:10:34 +0200 Subject: [PATCH 0647/1223] doc: 32 and 64 bit packages are seperate --- doc/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/README.md b/doc/README.md index a5524889d..357334dfb 100644 --- a/doc/README.md +++ b/doc/README.md @@ -13,8 +13,8 @@ The following are some helpful notes on how to run Bitcoin on your native platfo Unpack the files into a directory and run: -- bin/32/bitcoin-qt (GUI, 32-bit) or bin/32/bitcoind (headless, 32-bit) -- bin/64/bitcoin-qt (GUI, 64-bit) or bin/64/bitcoind (headless, 64-bit) +- `bin/bitcoin-qt` (GUI) or +- `bin/bitcoind` (headless) ### Windows From f4119c6c988ea24a5218aa6bc67e57e47e051547 Mon Sep 17 00:00:00 2001 From: EthanHeilman Date: Wed, 18 May 2016 12:04:07 -0400 Subject: [PATCH 0648/1223] Remove non-determinism which is breaking net_tests #8069 --- src/test/net_tests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 6debf6ac5..df1a4d2fb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -17,6 +17,13 @@ class CAddrManSerializationMock : public CAddrMan { public: virtual void Serialize(CDataStream& s, int nType, int nVersionDummy) const = 0; + + //! Ensure that bucket placement is always the same for testing purposes. + void MakeDeterministic() + { + nKey.SetNull(); + seed_insecure_rand(true); + } }; class CAddrManUncorrupted : public CAddrManSerializationMock @@ -65,6 +72,7 @@ BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(caddrdb_read) { CAddrManUncorrupted addrmanUncorrupted; + addrmanUncorrupted.MakeDeterministic(); CService addr1 = CService("250.7.1.1", 8333); CService addr2 = CService("250.7.2.2", 9999); @@ -106,6 +114,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) { CAddrManCorrupted addrmanCorrupted; + addrmanCorrupted.MakeDeterministic(); // Test that the de-serialization of corrupted addrman throws an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted); From 4dc94d1036576fe988a066fdabc047350ccddda9 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 15 Dec 2015 15:26:44 -0500 Subject: [PATCH 0649/1223] Refactor CreateNewBlock to be a method of the BlockAssembler class --- src/miner.cpp | 444 ++++++++++++++++++++++---------------- src/miner.h | 56 ++++- src/rpc/mining.cpp | 4 +- src/test/miner_tests.cpp | 28 +-- src/test/test_bitcoin.cpp | 2 +- 5 files changed, 328 insertions(+), 206 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index eaf29a767..91e05f9ce 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -71,44 +71,237 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam return nNewTime - nOldTime; } -CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn) +BlockAssembler::BlockAssembler(const CChainParams& _chainparams) + : chainparams(_chainparams) { - // Create new block - std::unique_ptr pblocktemplate(new CBlockTemplate()); + // Largest block you're willing to create: + nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); + // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + + // Minimum block size you want to create; block will be filled with free transactions + // until there are no more or the block reaches this size: + nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); + nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); +} + +void BlockAssembler::resetBlock() +{ + inBlock.clear(); + + // Reserve space for coinbase tx + nBlockSize = 1000; + nBlockSigOps = 100; + + // These counters do not include coinbase tx + nBlockTx = 0; + nFees = 0; + + lastFewTxs = 0; + blockFinished = false; +} + +CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) +{ + resetBlock(); + + pblocktemplate.reset(new CBlockTemplate()); + if(!pblocktemplate.get()) return NULL; - CBlock *pblock = &pblocktemplate->block; // pointer for convenience - - // Create coinbase tx - CMutableTransaction txNew; - txNew.vin.resize(1); - txNew.vin[0].prevout.SetNull(); - txNew.vout.resize(1); - txNew.vout[0].scriptPubKey = scriptPubKeyIn; + pblock = &pblocktemplate->block; // pointer for convenience // Add dummy coinbase tx as first transaction pblock->vtx.push_back(CTransaction()); pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOps.push_back(-1); // updated at end - // Largest block you're willing to create: - unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + LOCK2(cs_main, mempool.cs); + CBlockIndex* pindexPrev = chainActive.Tip(); + nHeight = pindexPrev->nHeight + 1; + pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); + // -regtest only: allow overriding block.nVersion with + // -blockversion=N to test forking scenarios + if (chainparams.MineBlocksOnDemand()) + pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + + pblock->nTime = GetAdjustedTime(); + const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + + nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) + ? nMedianTimePast + : pblock->GetBlockTime(); + + addPriorityTxs(); + addScoreTxs(); + + nLastBlockTx = nBlockTx; + nLastBlockSize = nBlockSize; + LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps); + + // Create coinbase transaction. + CMutableTransaction coinbaseTx; + coinbaseTx.vin.resize(1); + coinbaseTx.vin[0].prevout.SetNull(); + coinbaseTx.vout.resize(1); + coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; + coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); + coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; + pblock->vtx[0] = coinbaseTx; + pblocktemplate->vTxFees[0] = -nFees; + + // Fill in header + pblock->hashPrevBlock = pindexPrev->GetBlockHash(); + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); + pblock->nNonce = 0; + pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); + + CValidationState state; + if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { + throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); + } + + return pblocktemplate.release(); +} + +bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) +{ + BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter)) + { + if (!inBlock.count(parent)) { + return true; + } + } + return false; +} + + + +bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) +{ + if (nBlockSize + iter->GetTxSize() >= nBlockMaxSize) { + // If the block is so close to full that no more txs will fit + // or if we've tried more than 50 times to fill remaining space + // then flag that the block is finished + if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { + blockFinished = true; + return false; + } + // Once we're within 1000 bytes of a full block, only look at 50 more txs + // to try to fill the remaining space. + if (nBlockSize > nBlockMaxSize - 1000) { + lastFewTxs++; + } + return false; + } + + if (nBlockSigOps + iter->GetSigOpCount() >= MAX_BLOCK_SIGOPS) { + // If the block has room for no more sig ops then + // flag that the block is finished + if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) { + blockFinished = true; + return false; + } + // Otherwise attempt to find another tx with fewer sigops + // to put in the block. + return false; + } + + // Must check that lock times are still valid + // This can be removed once MTP is always enforced + // as long as reorgs keep the mempool consistent. + if (!IsFinalTx(iter->GetTx(), nHeight, nLockTimeCutoff)) + return false; + + return true; +} + +void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) +{ + pblock->vtx.push_back(iter->GetTx()); + pblocktemplate->vTxFees.push_back(iter->GetFee()); + pblocktemplate->vTxSigOps.push_back(iter->GetSigOpCount()); + nBlockSize += iter->GetTxSize(); + ++nBlockTx; + nBlockSigOps += iter->GetSigOpCount(); + nFees += iter->GetFee(); + inBlock.insert(iter); + + bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); + if (fPrintPriority) { + double dPriority = iter->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(iter->GetTx().GetHash(), dPriority, dummy); + LogPrintf("priority %.1f fee %s txid %s\n", + dPriority, + CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(), + iter->GetTx().GetHash().ToString()); + } +} + +void BlockAssembler::addScoreTxs() +{ + std::priority_queue, ScoreCompare> clearedTxs; + CTxMemPool::setEntries waitSet; + CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); + CTxMemPool::txiter iter; + while (!blockFinished && (mi != mempool.mapTx.get().end() || !clearedTxs.empty())) + { + // If no txs that were previously postponed are available to try + // again, then try the next highest score tx + if (clearedTxs.empty()) { + iter = mempool.mapTx.project<0>(mi); + mi++; + } + // If a previously postponed tx is available to try again, then it + // has higher score than all untried so far txs + else { + iter = clearedTxs.top(); + clearedTxs.pop(); + } + + // If tx is dependent on other mempool txs which haven't yet been included + // then put it in the waitSet + if (isStillDependent(iter)) { + waitSet.insert(iter); + continue; + } + + // If the fee rate is below the min fee rate for mining, then we're done + // adding txs based on score (fee rate) + if (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(iter->GetTxSize()) && nBlockSize >= nBlockMinSize) { + return; + } + + // If this tx fits in the block add it, otherwise keep looping + if (TestForBlock(iter)) { + AddToBlock(iter); + + // This tx was successfully added, so + // add transactions that depend on this one to the priority queue to try again + BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) + { + if (waitSet.count(child)) { + clearedTxs.push(child); + waitSet.erase(child); + } + } + } + } +} + +void BlockAssembler::addPriorityTxs() +{ // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE); nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); - - // Collect memory pool transactions into the block - CTxMemPool::setEntries inBlock; - CTxMemPool::setEntries waitSet; + if (nBlockPrioritySize == 0) { + return; + } // This vector will be sorted into a priority queue: vector vecPriority; @@ -117,185 +310,60 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s typedef std::map::iterator waitPriIter; double actualPriority = -1; - std::priority_queue, ScoreCompare> clearedTxs; - bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); - uint64_t nBlockSize = 1000; - uint64_t nBlockTx = 0; - unsigned int nBlockSigOps = 100; - int lastFewTxs = 0; - CAmount nFees = 0; - + vecPriority.reserve(mempool.mapTx.size()); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); + mi != mempool.mapTx.end(); ++mi) { - LOCK2(cs_main, mempool.cs); - CBlockIndex* pindexPrev = chainActive.Tip(); - const int nHeight = pindexPrev->nHeight + 1; - pblock->nTime = GetAdjustedTime(); - const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + double dPriority = mi->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy); + vecPriority.push_back(TxCoinAgePriority(dPriority, mi)); + } + std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); - // -regtest only: allow overriding block.nVersion with - // -blockversion=N to test forking scenarios - if (chainparams.MineBlocksOnDemand()) - pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + CTxMemPool::txiter iter; + while (!vecPriority.empty() && !blockFinished) { // add a tx from priority queue to fill the blockprioritysize + iter = vecPriority.front().second; + actualPriority = vecPriority.front().first; + std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + vecPriority.pop_back(); - int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) - ? nMedianTimePast - : pblock->GetBlockTime(); - - bool fPriorityBlock = nBlockPrioritySize > 0; - if (fPriorityBlock) { - vecPriority.reserve(mempool.mapTx.size()); - for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); - mi != mempool.mapTx.end(); ++mi) - { - double dPriority = mi->GetPriority(nHeight); - CAmount dummy; - mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy); - vecPriority.push_back(TxCoinAgePriority(dPriority, mi)); - } - std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + // If tx already in block, skip + if (inBlock.count(iter)) { + assert(false); // shouldn't happen for priority txs + continue; } - CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); - CTxMemPool::txiter iter; + // If tx is dependent on other mempool txs which haven't yet been included + // then put it in the waitSet + if (isStillDependent(iter)) { + waitPriMap.insert(std::make_pair(iter, actualPriority)); + continue; + } - while (mi != mempool.mapTx.get().end() || !clearedTxs.empty()) - { - bool priorityTx = false; - if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize - priorityTx = true; - iter = vecPriority.front().second; - actualPriority = vecPriority.front().first; - std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - vecPriority.pop_back(); - } - else if (clearedTxs.empty()) { // add tx with next highest score - iter = mempool.mapTx.project<0>(mi); - mi++; - } - else { // try to add a previously postponed child tx - iter = clearedTxs.top(); - clearedTxs.pop(); + // If this tx fits in the block add it, otherwise keep looping + if (TestForBlock(iter)) { + AddToBlock(iter); + + // If now that this txs is added we've surpassed our desired priority size + // or have dropped below the AllowFreeThreshold, then we're done adding priority txs + if (nBlockSize + iter->GetTxSize() >= nBlockPrioritySize || !AllowFree(actualPriority)) { + return; } - if (inBlock.count(iter)) - continue; // could have been added to the priorityBlock - - const CTransaction& tx = iter->GetTx(); - - bool fOrphan = false; - BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter)) - { - if (!inBlock.count(parent)) { - fOrphan = true; - break; - } - } - if (fOrphan) { - if (priorityTx) - waitPriMap.insert(std::make_pair(iter,actualPriority)); - else - waitSet.insert(iter); - continue; - } - - unsigned int nTxSize = iter->GetTxSize(); - if (fPriorityBlock && - (nBlockSize + nTxSize >= nBlockPrioritySize || !AllowFree(actualPriority))) { - fPriorityBlock = false; - waitPriMap.clear(); - } - if (!priorityTx && - (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(nTxSize) && nBlockSize >= nBlockMinSize)) { - break; - } - if (nBlockSize + nTxSize >= nBlockMaxSize) { - if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { - break; - } - // Once we're within 1000 bytes of a full block, only look at 50 more txs - // to try to fill the remaining space. - if (nBlockSize > nBlockMaxSize - 1000) { - lastFewTxs++; - } - continue; - } - - if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) - continue; - - unsigned int nTxSigOps = iter->GetSigOpCount(); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) { - if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) { - break; - } - continue; - } - - CAmount nTxFees = iter->GetFee(); - // Added - pblock->vtx.push_back(tx); - pblocktemplate->vTxFees.push_back(nTxFees); - pblocktemplate->vTxSigOps.push_back(nTxSigOps); - nBlockSize += nTxSize; - ++nBlockTx; - nBlockSigOps += nTxSigOps; - nFees += nTxFees; - - if (fPrintPriority) - { - double dPriority = iter->GetPriority(nHeight); - CAmount dummy; - mempool.ApplyDeltas(tx.GetHash(), dPriority, dummy); - LogPrintf("priority %.1f fee %s txid %s\n", - dPriority , CFeeRate(iter->GetModifiedFee(), nTxSize).ToString(), tx.GetHash().ToString()); - } - - inBlock.insert(iter); - - // Add transactions that depend on this one to the priority queue + // This tx was successfully added, so + // add transactions that depend on this one to the priority queue to try again BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) { - if (fPriorityBlock) { - waitPriIter wpiter = waitPriMap.find(child); - if (wpiter != waitPriMap.end()) { - vecPriority.push_back(TxCoinAgePriority(wpiter->second,child)); - std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - waitPriMap.erase(wpiter); - } - } - else { - if (waitSet.count(child)) { - clearedTxs.push(child); - waitSet.erase(child); - } + waitPriIter wpiter = waitPriMap.find(child); + if (wpiter != waitPriMap.end()) { + vecPriority.push_back(TxCoinAgePriority(wpiter->second,child)); + std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + waitPriMap.erase(wpiter); } } } - nLastBlockTx = nBlockTx; - nLastBlockSize = nBlockSize; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps); - - // Compute final coinbase transaction. - txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); - txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; - pblock->vtx[0] = txNew; - pblocktemplate->vTxFees[0] = -nFees; - - // Fill in header - pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); - pblock->nNonce = 0; - pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); - - CValidationState state; - if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { - throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); - } } - - return pblocktemplate.release(); } void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) diff --git a/src/miner.h b/src/miner.h index cd0f13662..74f19693c 100644 --- a/src/miner.h +++ b/src/miner.h @@ -7,14 +7,17 @@ #define BITCOIN_MINER_H #include "primitives/block.h" +#include "txmempool.h" #include +#include class CBlockIndex; class CChainParams; class CReserveKey; class CScript; class CWallet; + namespace Consensus { struct Params; }; static const bool DEFAULT_PRINTPRIORITY = false; @@ -27,7 +30,58 @@ struct CBlockTemplate }; /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn); +class BlockAssembler +{ +private: + // The constructed block template + std::unique_ptr pblocktemplate; + // A convenience pointer that always refers to the CBlock in pblocktemplate + CBlock* pblock; + + // Configuration parameters for the block size + unsigned int nBlockMaxSize, nBlockMinSize; + + // Information on the current status of the block + uint64_t nBlockSize; + uint64_t nBlockTx; + unsigned int nBlockSigOps; + CAmount nFees; + CTxMemPool::setEntries inBlock; + + // Chain context for the block + int nHeight; + int64_t nLockTimeCutoff; + const CChainParams& chainparams; + + // Variables used for addScoreTxs and addPriorityTxs + int lastFewTxs; + bool blockFinished; + +public: + BlockAssembler(const CChainParams& chainparams); + /** Construct a new block template with coinbase to scriptPubKeyIn */ + CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); + +private: + // utility functions + /** Clear the block's state and prepare for assembling a new block */ + void resetBlock(); + /** Add a tx to the block */ + void AddToBlock(CTxMemPool::txiter iter); + + // Methods for how to add transactions to a block. + /** Add transactions based on modified feerate */ + void addScoreTxs(); + /** Add transactions based on tx "priority" */ + void addPriorityTxs(); + + // helper function for addScoreTxs and addPriorityTxs + /** Test if tx will still "fit" in the block */ + bool TestForBlock(CTxMemPool::txiter iter); + /** Test if tx still has unconfirmed parents not yet in block */ + bool isStillDependent(CTxMemPool::txiter iter); +}; + /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 9a7d9d53a..bd90cca1c 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -111,7 +111,7 @@ UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nG UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { - std::unique_ptr pblocktemplate(CreateNewBlock(Params(), coinbaseScript->reserveScript)); + std::unique_ptr pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; @@ -493,7 +493,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(Params(), scriptDummy); + pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 469862518..329b488c0 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) fCheckpointsEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; const CAmount BLOCKSUBSIDY = 50*COIN; @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -181,14 +181,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); // orphan in mempool, template creation fails hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); - BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); // give it a fee so it'll get mined mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // invalid (pre-p2sh) txn in mempool, template creation fails @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // double spend txn pair in mempool, template creation fails @@ -247,7 +247,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // subsidy changing @@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; // Extend to a 210000-long block chain. while (chainActive.Tip()->nHeight < 210000) { @@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); delete pblocktemplate; // Delete the dummy blocks again. while (chainActive.Tip()->nHeight > nHeight) { @@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); // None of the of the absolute height/time locked tx should have made // it into the template because we still check IsFinalTx in CreateNewBlock, @@ -377,7 +377,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight++; SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); delete pblocktemplate; diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 9bcb07626..c68320ba8 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -98,7 +98,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector& txns, const CScript& scriptPubKey) { const CChainParams& chainparams = Params(); - CBlockTemplate *pblocktemplate = CreateNewBlock(chainparams, scriptPubKey); + CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); CBlock& block = pblocktemplate->block; // Replace mempool-selected txns with just coinbase plus passed-in txns: From 2a8b3589b5a6c0863012329ddb40e7d901decf0e Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Wed, 18 May 2016 20:14:26 -0400 Subject: [PATCH 0650/1223] Fix typo adddrman to addrman as requested in #8070 --- src/test/net_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index df1a4d2fb..b38d61f33 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) } catch (const std::exception& e) { exceptionThrown = true; } - // Even through de-serialization failed adddrman is not left in a clean state. + // Even through de-serialization failed addrman is not left in a clean state. BOOST_CHECK(addrman1.size() == 1); BOOST_CHECK(exceptionThrown); From bf9266e017b286c36e08fd09b91d9e39f14b2cf3 Mon Sep 17 00:00:00 2001 From: Warren Togami Date: Thu, 19 May 2016 14:19:08 +0900 Subject: [PATCH 0651/1223] Use Socks5ErrorString() to decode error responses from socks proxy. --- src/netbase.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index d2a4188ff..572ae7087 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -291,6 +291,21 @@ struct ProxyCredentials std::string password; }; +std::string Socks5ErrorString(int err) +{ + switch(err) { + case 0x01: return "general failure"; + case 0x02: return "connection not allowed"; + case 0x03: return "network unreachable"; + case 0x04: return "host unreachable"; + case 0x05: return "connection refused"; + case 0x06: return "TTL expired"; + case 0x07: return "protocol error"; + case 0x08: return "address type not supported"; + default: return "unknown"; + } +} + /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { @@ -382,18 +397,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials if (pchRet2[1] != 0x00) { // Failures to connect to a peer that are not proxy errors CloseSocket(hSocket); - switch (pchRet2[1]) - { - case 0x01: LogPrintf("Socks5() connect to %s:%d failed: general failure\n", strDest, port); break; - case 0x02: LogPrintf("Socks5() connect to %s:%d failed: connection not allowed\n", strDest, port); break; - case 0x03: LogPrintf("Socks5() connect to %s:%d failed: network unreachable\n", strDest, port); break; - case 0x04: LogPrintf("Socks5() connect to %s:%d failed: host unreachable\n", strDest, port); break; - case 0x05: LogPrintf("Socks5() connect to %s:%d failed: connection refused\n", strDest, port); break; - case 0x06: LogPrintf("Socks5() connect to %s:%d failed: TTL expired\n", strDest, port); break; - case 0x07: LogPrintf("Socks5() connect to %s:%d failed: protocol error\n", strDest, port); break; - case 0x08: LogPrintf("Socks5() connect to %s:%d failed: address type not supported\n", strDest, port); break; - default: LogPrintf("Socks5() connect to %s:%d failed: unknown\n", strDest, port); - } + LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1])); return false; } if (pchRet2[2] != 0x00) { From 401ae654b247d80e29e76ebd094e9e37409941bd Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 17 May 2016 17:54:41 -0400 Subject: [PATCH 0652/1223] travis: 'make check' in parallel and verbose - 'make check' in parallel, since the log will take care of clean output - 'make check' verbose, so that test failure causes aren't hidden --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fd70d3ab5..bc2c7faf7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,7 +78,7 @@ script: - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi after_script: - echo $TRAVIS_COMMIT_RANGE From 02ce2a3ca773e2d10ff37ecf50d15c71113f3335 Mon Sep 17 00:00:00 2001 From: Pavel Vasin Date: Mon, 3 Aug 2015 03:03:14 +0300 Subject: [PATCH 0653/1223] qt: askpassphrasedialog: Clear pass fields on accept This is usability improvement in a case if user gets re-asked passphrase. (e.g. made a typo) --- src/qt/askpassphrasedialog.cpp | 21 +++++++++++++++++---- src/qt/askpassphrasedialog.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 415bffb99..e8aa79679 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -77,10 +77,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : AskPassphraseDialog::~AskPassphraseDialog() { - // Attempt to overwrite text so that they do not linger around in memory - ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size())); - ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size())); - ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size())); + secureClearPassFields(); delete ui; } @@ -103,6 +100,8 @@ void AskPassphraseDialog::accept() newpass1.assign(ui->passEdit2->text().toStdString().c_str()); newpass2.assign(ui->passEdit3->text().toStdString().c_str()); + secureClearPassFields(); + switch(mode) { case Encrypt: { @@ -260,3 +259,17 @@ bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event) } return QDialog::eventFilter(object, event); } + +static void SecureClearQLineEdit(QLineEdit* edit) +{ + // Attempt to overwrite text so that they do not linger around in memory + edit->setText(QString(" ").repeated(edit->text().size())); + edit->clear(); +} + +void AskPassphraseDialog::secureClearPassFields() +{ + SecureClearQLineEdit(ui->passEdit1); + SecureClearQLineEdit(ui->passEdit2); + SecureClearQLineEdit(ui->passEdit3); +} diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 727b5a1ad..34bf7ccb3 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -42,6 +42,7 @@ private: private Q_SLOTS: void textChanged(); + void secureClearPassFields(); protected: bool event(QEvent *event); From fa57b0c5ef8101e1228d17a2bdce28a36e6f2ff6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 15 May 2016 11:06:23 +0200 Subject: [PATCH 0654/1223] [qa] test_framework: Append portseed to tmpdir This makes it possible to specify a tmpdir while running tests in parallel --- qa/rpc-tests/test_framework/test_framework.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 3480de6c6..091378186 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -115,6 +115,8 @@ class BitcoinTestFramework(object): self.add_options(parser) (self.options, self.args) = parser.parse_args() + self.options.tmpdir += '/' + str(self.options.port_seed) + if self.options.trace_rpc: logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) From ee9f4a5b1505113eae0fe8d70fd0414bd5bce0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 20 May 2016 14:43:37 +0200 Subject: [PATCH 0655/1223] Consensus: Decouple from chainparams.o and timedata.o Do it for the consensus-critical functions: - CheckBlockHeader - CheckBlock - ContextualCheckBlockHeader --- src/main.cpp | 27 +++++++++++++-------------- src/main.h | 6 +++--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9ba90b4ea..f66de42aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2223,7 +2223,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTimeStart = GetTimeMicros(); // Check it again in case a previous version let a bad block in - if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) + if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), !fJustCheck, !fJustCheck)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block @@ -3234,20 +3234,20 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne return true; } -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW) { // Check proof of work matches claimed amount - if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) + if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); // Check timestamp - if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) + if (block.GetBlockTime() > nAdjustedTime + 2 * 60 * 60) return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); return true; } -bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW, bool fCheckMerkleRoot) { // These are checks that are independent of context. @@ -3256,7 +3256,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. - if (!CheckBlockHeader(block, state, fCheckPOW)) + if (!CheckBlockHeader(block, state, consensusParams, nAdjustedTime, fCheckPOW)) return false; // Check the merkle root. @@ -3322,9 +3322,8 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati return true; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex * const pindexPrev) { - const Consensus::Params& consensusParams = Params().GetConsensus(); // Check proof of work if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); @@ -3397,7 +3396,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return true; } - if (!CheckBlockHeader(block, state)) + if (!CheckBlockHeader(block, state, chainparams.GetConsensus(), GetAdjustedTime())) return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index @@ -3413,7 +3412,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); - if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } if (pindex == NULL) @@ -3457,7 +3456,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha if (fTooFarAhead) return true; // Block height is too high } - if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) { + if ((!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) || !ContextualCheckBlock(block, state, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); @@ -3542,9 +3541,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, indexDummy.nHeight = pindexPrev->nHeight + 1; // NOTE: CheckBlockHeader is called by CheckBlock - if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); - if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) + if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), fCheckPOW, fCheckMerkleRoot)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); if (!ContextualCheckBlock(block, state, pindexPrev)) return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); @@ -3876,7 +3875,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state)) + if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity diff --git a/src/main.h b/src/main.h index f287171f1..4e93c084f 100644 --- a/src/main.h +++ b/src/main.h @@ -425,13 +425,13 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus /** Functions for validating blocks and updating the block tree */ /** Context-independent validity checks */ -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); -bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW = true); +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** Context-dependent validity checks. * By "context", we mean only the previous block headers, but not the UTXO * set; UTXO-related validity checks are done in ConnectBlock(). */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex* pindexPrev); bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); /** Apply the effects of this block (with given index) on the UTXO set represented by coins. From beceac9bbf14bf4a81f6f63b9cca2a64157054ae Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 20 May 2016 14:44:32 +0100 Subject: [PATCH 0656/1223] Disable the mempool P2P command when bloom filters disabled Only useful to SPV peers, and attackers... like bloom is a DoS vector as far more data is sent than received. --- src/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 9ba90b4ea..2ad2a8e3f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5277,6 +5277,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::MEMPOOL) { + if (!(nLocalServices & NODE_BLOOM) && !pfrom->fWhitelisted) + { + LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId()); + pfrom->fDisconnect = true; + return true; + } + if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) { LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId()); From 3d3602faf4a47855be264f05d9d52253e8bd0f9d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 20 May 2016 16:50:48 +0200 Subject: [PATCH 0657/1223] Add RPC test for the p2p mempool command in conjunction with disabled bloomfilters --- qa/rpc-tests/p2p-mempool.py | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 qa/rpc-tests/p2p-mempool.py diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py new file mode 100755 index 000000000..5d2daf39f --- /dev/null +++ b/qa/rpc-tests/p2p-mempool.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time + +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + self.block_receive_map = {} + + def add_connection(self, conn): + self.connection = conn + self.peer_disconnected = False + + def on_inv(self, conn, message): + pass + + # Track the last getdata message we receive (used in the test) + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_block(self, conn, message): + message.block.calc_sha256() + try: + self.block_receive_map[message.block.sha256] += 1 + except KeyError as e: + self.block_receive_map[message.block.sha256] = 1 + + # Spin until verack message is received from the node. + # We use this to signal that our test can begin. This + # is called from the testing thread, so it needs to acquire + # the global lock. + def wait_for_verack(self): + def veracked(): + return self.verack_received + return wait_until(veracked, timeout=10) + + def wait_for_disconnect(self): + def disconnected(): + return self.peer_disconnected + return wait_until(disconnected, timeout=10) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_pong(self, conn, message): + self.last_pong = message + + def on_close(self, conn): + self.peer_disconnected = True + + # Sync up with the node after delivery of a block + def sync_with_ping(self, timeout=30): + def received_pong(): + return (self.last_pong.nonce == self.ping_counter) + self.connection.send_message(msg_ping(nonce=self.ping_counter)) + success = wait_until(received_pong, timeout) + self.ping_counter += 1 + return success + + def send_mempool(self): + self.lastInv = [] + self.send_message(msg_mempool()) + +class P2PMempoolTests(BitcoinTestFramework): + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + # Start a node with maxuploadtarget of 200 MB (/24h) + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-peerbloomfilters=0"])) + + def run_test(self): + #connect a mininode + aTestNode = TestNode() + node = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], aTestNode) + aTestNode.add_connection(node) + NetworkThread().start() + aTestNode.wait_for_verack() + + #request mempool + aTestNode.send_mempool() + aTestNode.wait_for_disconnect() + + #mininode must be disconnected at this point + assert_equal(len(self.nodes[0].getpeerinfo()), 0) + +if __name__ == '__main__': + P2PMempoolTests().main() From 2ca8962a095ee29709316d163508f26ab1c340ae Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 17 May 2016 17:54:41 -0400 Subject: [PATCH 0658/1223] travis: use slim generic image, and some fixups Now that caches are distinct (https://github.com/travis-ci/travis-ci/issues/4393), we can use the Travis minimal image. The minimal image should take less time to setup and lead to quicker builds. Also addressed while I'm in here: - No need to delete the broken google-chrome repo in the minimal image - Set the hostname to work-around an openjdk bug - Remove the non-functional apt-cache option - Remove useless message at completion - Install jre where the java tests are run --- .travis.yml | 63 ++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index bc2c7faf7..53fe4f807 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,17 @@ -# errata: -# - A travis bug causes caches to trample eachother when using the same -# compiler key (which we don't use anyway). This is worked around for now by -# replacing the "compilers" with a build name prefixed by the no-op ":" -# command. See: https://github.com/travis-ci/travis-ci/issues/4393 -# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback] -# IPv6 support - sudo: required dist: trusty +#workaround for https://github.com/travis-ci/travis-ci/issues/5227 +addons: + hostname: bitcoin-tester + os: linux -language: cpp -compiler: gcc +language: generic +cache: + directories: + - depends/built + - depends/sdk-sources + - $HOME/.ccache env: global: - MAKEJOBS=-j3 @@ -25,35 +25,25 @@ env: - SDK_URL=https://bitcoincore.org/depends-sources/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all -cache: - apt: true - directories: - - depends/built - - depends/sdk-sources - - $HOME/.ccache -matrix: - fast_finish: true - include: - - compiler: ": ARM" - env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - - compiler: ": Win32" - env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python3-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" - - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - - compiler: ": No wallet" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" - exclude: - - compiler: gcc + matrix: +# ARM + - HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" +# Win32 + - HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6 bc openjdk-7-jre-headless" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" +# 32-bit + dash + - HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python3-zmq openjdk-7-jre-headless" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" +# Win64 + - HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 bc openjdk-7-jre-headless" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" +# bitcoind + - HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq openjdk-7-jre-headless" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" +# No wallet + - HOST=x86_64-unknown-linux-gnu PACKAGES=" openjdk-7-jre-headless python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" +# Cross-Mac + - HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + before_install: - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") install: - - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/google-chrome.list; fi - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi @@ -83,4 +73,3 @@ script: after_script: - echo $TRAVIS_COMMIT_RANGE - echo $TRAVIS_COMMIT_LOG - - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi From f7d4a25fe6b1bd52e70fa0779d1cd145f32bd2ab Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 20 May 2016 18:29:15 -0700 Subject: [PATCH 0659/1223] Make verify-commits POSIX-compliant --- contrib/verify-commits/gpg.sh | 10 +++++----- contrib/verify-commits/verify-commits.sh | 15 ++++++--------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 0218b82e1..375d71172 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,8 +1,9 @@ #!/bin/sh -INPUT=$(/dev/null); do case "$LINE" in "[GNUPG:] VALIDSIG "*) @@ -13,10 +14,9 @@ for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do "[GNUPG:] REVKEYSIG "*) [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1 while read KEY; do - case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY:24:40} "*) + case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY#????????????????????????} "*) REVSIG=true - GOODREVSIG="[GNUPG:] GOODSIG ${KEY:24:40} " - ;; + GOODREVSIG="[GNUPG:] GOODSIG ${KEY#????????????????????????} " esac done < ./contrib/verify-commits/trusted-keys ;; diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 9ba781008..c9d2b96d8 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -1,4 +1,6 @@ #!/bin/sh +# Not technically POSIX-compliant due to use of "local", but almost every +# shell anyone uses today supports it, so its probably fine DIR=$(dirname "$0") @@ -6,20 +8,14 @@ echo "Please verify all commits in the following list are not evil:" git log "$DIR" VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") - -IS_REVSIG_ALLOWED () { - while read LINE; do - [ "$LINE" = "$1" ] && return 0 - done < "${DIR}/allow-revsig-commits" - return 1 -} +REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits") HAVE_FAILED=false IS_SIGNED () { if [ $1 = $VERIFIED_ROOT ]; then return 0; fi - if IS_REVSIG_ALLOWED "$1"; then + if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1 else export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0 @@ -27,7 +23,8 @@ IS_SIGNED () { if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then return 1; fi - local PARENTS=$(git show -s --format=format:%P $1) + local PARENTS + PARENTS=$(git show -s --format=format:%P $1) for PARENT in $PARENTS; do if IS_SIGNED $PARENT > /dev/null; then return 0; From 9523e8adafd24f1c9358c437b857f0f2f25eeb47 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 21 May 2016 01:44:29 -0700 Subject: [PATCH 0660/1223] Make verify-commits path-independent --- contrib/verify-commits/verify-commits.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index c9d2b96d8..a859e6785 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -3,6 +3,7 @@ # shell anyone uses today supports it, so its probably fine DIR=$(dirname "$0") +[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0") echo "Please verify all commits in the following list are not evil:" git log "$DIR" From 22421faa199b7922259b4b55e6471a1b5f91d0da Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 18 Mar 2016 06:04:08 -0400 Subject: [PATCH 0661/1223] Remove pointless warning Any attacker who managed to make an evil commit that changed something in the contrib/verify-commits/ directory could just as easily remove the warning and/or modify it to not display the evil commits; telling the user to check those commits specifically misleads them into checking just those commits rather than the script itself. --- contrib/verify-commits/verify-commits.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index a859e6785..5219331e2 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -5,9 +5,6 @@ DIR=$(dirname "$0") [ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0") -echo "Please verify all commits in the following list are not evil:" -git log "$DIR" - VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits") From 11164ec0b4c1790059220b09b5827e5618a46c76 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 20 May 2016 08:55:57 +0100 Subject: [PATCH 0662/1223] Remove keys that are no longer used for merging Also updated trusted git root to be right after gmaxwell's last merge. --- contrib/verify-commits/trusted-git-root | 2 +- contrib/verify-commits/trusted-keys | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root index 838b8d1ea..c60f8ab69 100644 --- a/contrib/verify-commits/trusted-git-root +++ b/contrib/verify-commits/trusted-git-root @@ -1 +1 @@ -165e323d851cc87213c7673c6f278e87a6f2e752 +82bcf405f6db1d55b684a1f63a4aabad376cdad7 diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index ad1b28be0..9c36d58cd 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -1,8 +1,5 @@ 71A3B16735405025D447E8F274810B012346C9A6 1F4410F6A89268CE3197A84C57896D2FF8F0B657 -01CDF4627A3B88AAE4A571C87588242FBE38D3A8 -AF8BE07C7049F3A26B239D5325B3083201782B2F -81291FA67D2C379A006A053FEAB5AF94D9E9ABE7 3F1888C6DCA92A6499C4911FDBA1A67379A1A931 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC FE09B823E6D83A3BC7983EAA2D7F2372E50FE137 From bd477f4e8ba9e632f42649f2fca10d698c6b7181 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 20 May 2016 04:59:57 -0400 Subject: [PATCH 0663/1223] VerifyDB: don't check blocks that have been pruned --- src/init.cpp | 4 ++-- src/main.cpp | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 8688381ec..a17377f6f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1269,8 +1269,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { - LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", - MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", DEFAULT_CHECKBLOCKS)); + LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", + MIN_BLOCKS_TO_KEEP); } { diff --git a/src/main.cpp b/src/main.cpp index 9ba90b4ea..33abf3957 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3871,6 +3871,11 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))))); if (pindex->nHeight < chainActive.Height()-nCheckDepth) break; + if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) { + // If pruning, only go back as far as we have data. + LogPrintf("VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->nHeight); + break; + } CBlock block; // check level 0: read from disk if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) From 678513cc94995a243a7e56593fe3e44e003cb597 Mon Sep 17 00:00:00 2001 From: Mitchell Cash Date: Tue, 24 May 2016 10:43:01 +1000 Subject: [PATCH 0664/1223] Correct small typo in extract_strings_qt.py --- share/qt/extract_strings_qt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 7728a4377..2ba8bb9b3 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -32,7 +32,7 @@ def parse_po(text): in_msgstr = False # message start in_msgid = True - + msgid = [line[6:]] elif line.startswith('msgstr '): in_msgid = False @@ -67,7 +67,7 @@ f.write(""" #include -// Automatically generated by extract_strings.py +// Automatically generated by extract_strings_qt.py #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #else From a27876474819ffff80614f966fea06d5da2d5c15 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 24 May 2016 14:23:15 -0400 Subject: [PATCH 0665/1223] FIX: Account for txs already added to block in addPriorityTxs --- src/miner.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 91e05f9ce..1eab8f949 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -74,7 +74,7 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam BlockAssembler::BlockAssembler(const CChainParams& _chainparams) : chainparams(_chainparams) { - // Largest block you're willing to create: + // Largest block you're willing to create: nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); @@ -262,6 +262,11 @@ void BlockAssembler::addScoreTxs() clearedTxs.pop(); } + // If tx already in block, skip (added by addPriorityTxs) + if (inBlock.count(iter)) { + continue; + } + // If tx is dependent on other mempool txs which haven't yet been included // then put it in the waitSet if (isStillDependent(iter)) { From 1ad933950884ae3411cce78e3b8e92e9a649e735 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 24 May 2016 11:35:06 -0400 Subject: [PATCH 0666/1223] Test framework: only cleanup on successful test runs --- qa/rpc-tests/test_framework/test_framework.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index b9b803429..49f419226 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -165,9 +165,11 @@ class BitcoinTestFramework(object): else: print("Note: bitcoinds were not stopped and may still be running") - if not self.options.nocleanup and not self.options.noshutdown: + if not self.options.nocleanup and not self.options.noshutdown and success: print("Cleaning up") shutil.rmtree(self.options.tmpdir) + else: + print("Not cleaning up dir %s" % self.options.tmpdir) if success: print("Tests successful") From 2d83013dc54320b3f0c978475517da6156f7b50d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 21 May 2016 23:55:22 +0200 Subject: [PATCH 0667/1223] Add support for dnsseeds with option to filter by servicebits --- src/chainparams.cpp | 10 ++++++++++ src/chainparams.h | 7 +++++-- src/net.cpp | 5 +++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5c7d19012..000511567 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -16,6 +16,14 @@ #include "chainparamsseeds.h" +std::string CDNSSeedData::getHost(uint64_t requiredServiceBits) const { + //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) + if (!supportsServiceBitsFiltering || requiredServiceBits == NODE_NETWORK) + return host; + + return strprintf("x%x.%s", requiredServiceBits, host); +} + static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; @@ -197,6 +205,8 @@ public: vFixedSeeds.clear(); vSeeds.clear(); + // nodes with support for servicebits filtering should be at the top + vSeeds.push_back(CDNSSeedData("testnetbitcoin.jonasschnelli.ch", "testnet-seed.bitcoin.jonasschnelli.ch", true)); vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); diff --git a/src/chainparams.h b/src/chainparams.h index 59202f548..7168daaf4 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,9 +13,12 @@ #include -struct CDNSSeedData { +class CDNSSeedData { +public: std::string name, host; - CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {} + bool supportsServiceBitsFiltering; + std::string getHost(uint64_t requiredServiceBits) const; + CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; struct SeedSpec6 { diff --git a/src/net.cpp b/src/net.cpp index bbd23d292..54d14a723 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1466,12 +1466,13 @@ void ThreadDNSAddressSeed() } else { std::vector vIPs; std::vector vAdd; - if (LookupHost(seed.host.c_str(), vIPs, 0, true)) + uint64_t requiredServiceBits = NODE_NETWORK; + if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { int nOneDay = 24*3600; - CAddress addr = CAddress(CService(ip, Params().GetDefaultPort())); + CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits); addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old vAdd.push_back(addr); found++; From 7e908c7b826cedbf29560ce7a668af809ee71524 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 20 May 2016 16:19:26 +0000 Subject: [PATCH 0668/1223] Do not use mempool for GETDATA for tx accepted after the last mempool req. The ability to GETDATA a transaction which has not (yet) been relayed is a privacy loss vector. The use of the mempool for this was added as part of the mempool p2p message and is only needed to fetch transactions returned by it. --- src/main.cpp | 6 +++++- src/net.cpp | 1 + src/net.h | 3 +++ src/txmempool.cpp | 10 +++++++++- src/txmempool.h | 1 + 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9ba90b4ea..2ee6bc531 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4503,7 +4503,10 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } if (!pushed && inv.type == MSG_TX) { CTransaction tx; - if (mempool.lookup(inv.hash, tx)) { + int64_t txtime; + // To protect privacy, do not answer getdata using the mempool when + // that TX couldn't have been INVed in reply to a MEMPOOL request. + if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) { pfrom->PushMessage(NetMsgType::TX, tx); pushed = true; } @@ -5902,6 +5905,7 @@ bool SendMessages(CNode* pto) vInv.clear(); } } + pto->timeLastMempoolReq = GetTime(); } // Determine transactions to relay diff --git a/src/net.cpp b/src/net.cpp index bbd23d292..df3221e84 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2396,6 +2396,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa fRelayTxes = false; fSentAddr = false; pfilter = new CBloomFilter(); + timeLastMempoolReq = 0; nPingNonceSent = 0; nPingUsecStart = 0; nPingUsecTime = 0; diff --git a/src/net.h b/src/net.h index 998ee4926..66cc912a5 100644 --- a/src/net.h +++ b/src/net.h @@ -17,6 +17,7 @@ #include "sync.h" #include "uint256.h" +#include #include #include @@ -413,6 +414,8 @@ public: // Used for BIP35 mempool sending, also protected by cs_inventory bool fSendMempool; + // Last time a "MEMPOOL" request was serviced. + std::atomic timeLastMempoolReq; // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. uint64_t nPingNonceSent; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index aa5df6ca4..4f17e7f8c 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -789,15 +789,23 @@ void CTxMemPool::queryHashes(vector& vtxid) std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this)); } -bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const + +bool CTxMemPool::lookup(uint256 hash, CTransaction& result, int64_t& time) const { LOCK(cs); indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) return false; result = i->GetTx(); + time = i->GetTime(); return true; } +bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const +{ + int64_t time; + return CTxMemPool::lookup(hash, result, time); +} + bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const { LOCK(cs); diff --git a/src/txmempool.h b/src/txmempool.h index 3e1d38797..75cf0f4c1 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -602,6 +602,7 @@ public: } bool lookup(uint256 hash, CTransaction& result) const; + bool lookup(uint256 hash, CTransaction& result, int64_t& time) const; bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const; /** Estimate fee rate needed to get into the next nBlocks From c769c4af11fc58dd4813d328c7f71042bc577676 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 19 Apr 2015 12:34:43 -0700 Subject: [PATCH 0669/1223] Avoid counting failed connect attempts when probably offline. If a node is offline failed outbound connection attempts will crank up the addrman counter and effectively blow away our state. This change reduces the problem by only counting attempts made while the node believes it has outbound connections to at least two netgroups. Connect and addnode connections are also not counted, as there is no reason to unequally penalize them for their more frequent connections -- though there should be no real effect from this unless their addnode configureation is later removed. Wasteful repeated connection attempts while only a few connections are up are avoided via nLastTry. This is still somewhat incomplete protection because our outbound peers could be down but not timed out or might all be on 'local' networks (although the requirement for multiple netgroups helps). --- src/addrman.cpp | 4 ++-- src/addrman.h | 6 +++--- src/net.cpp | 20 ++++++++++---------- src/net.h | 2 +- src/rpc/net.cpp | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 6c54cfa4c..0a1745c10 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -311,7 +311,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP return fNew; } -void CAddrMan::Attempt_(const CService& addr, int64_t nTime) +void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) { CAddrInfo* pinfo = Find(addr); @@ -327,7 +327,7 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime) // update info info.nLastTry = nTime; - info.nAttempts++; + if (fCountFailure) info.nAttempts++; } CAddrInfo CAddrMan::Select_(bool newOnly) diff --git a/src/addrman.h b/src/addrman.h index 308545045..65ca79fa0 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -230,7 +230,7 @@ protected: bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); //! Mark an entry as attempted to connect. - void Attempt_(const CService &addr, int64_t nTime); + void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime); //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. CAddrInfo Select_(bool newOnly); @@ -532,12 +532,12 @@ public: } //! Mark an entry as connection attempted to. - void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime()) + void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime()) { { LOCK(cs); Check(); - Attempt_(addr, nTime); + Attempt_(addr, fCountFailure, nTime); Check(); } } diff --git a/src/net.cpp b/src/net.cpp index bbd23d292..f30321869 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -367,7 +367,7 @@ CNode* FindNode(const CService& addr) return NULL; } -CNode* ConnectNode(CAddress addrConnect, const char *pszDest) +CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == NULL) { if (IsLocal(addrConnect)) @@ -399,7 +399,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) return NULL; } - addrman.Attempt(addrConnect); + addrman.Attempt(addrConnect, fCountFailure); // Add node CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); @@ -416,7 +416,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) } else if (!proxyConnectionFailed) { // If connecting to the node failed, and failure is not caused by a problem connecting to // the proxy, mark this as an attempt. - addrman.Attempt(addrConnect); + addrman.Attempt(addrConnect, fCountFailure); } return NULL; @@ -1533,7 +1533,7 @@ void static ProcessOneShot() CAddress addr; CSemaphoreGrant grant(*semOutbound, true); if (grant) { - if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true)) + if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true)) AddOneShot(strDest); } } @@ -1549,7 +1549,7 @@ void ThreadOpenConnections() BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"]) { CAddress addr; - OpenNetworkConnection(addr, NULL, strAddr.c_str()); + OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { MilliSleep(500); @@ -1633,7 +1633,7 @@ void ThreadOpenConnections() } if (addrConnect.IsValid()) - OpenNetworkConnection(addrConnect, &grant); + OpenNetworkConnection(addrConnect, (int)setConnected.size() >= min(nMaxConnections - 1, 2), &grant); } } @@ -1655,7 +1655,7 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(const std::string& strAddNode, lAddresses) { CAddress addr; CSemaphoreGrant grant(*semOutbound); - OpenNetworkConnection(addr, &grant, strAddNode.c_str()); + OpenNetworkConnection(addr, false, &grant, strAddNode.c_str()); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes @@ -1694,7 +1694,7 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(std::vector& vserv, lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); - OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); + OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), false, &grant); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes @@ -1702,7 +1702,7 @@ void ThreadOpenAddedConnections() } // if successful, this moves the passed grant to the constructed node -bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot) +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot) { // // Initiate outbound network connection @@ -1716,7 +1716,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu } else if (FindNode(std::string(pszDest))) return false; - CNode* pnode = ConnectNode(addrConnect, pszDest); + CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure); boost::this_thread::interruption_point(); if (!pnode) diff --git a/src/net.h b/src/net.h index 998ee4926..3332496c0 100644 --- a/src/net.h +++ b/src/net.h @@ -83,7 +83,7 @@ CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); -bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index e09af8965..8f62d636d 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -219,7 +219,7 @@ UniValue addnode(const UniValue& params, bool fHelp) if (strCommand == "onetry") { CAddress addr; - OpenNetworkConnection(addr, NULL, strNode.c_str()); + OpenNetworkConnection(addr, false, NULL, strNode.c_str()); return NullUniValue; } From 6182d10503ae3af222a7e4575724dce7ef563fec Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 19 Apr 2015 13:39:38 -0700 Subject: [PATCH 0670/1223] Do not increment nAttempts by more than one for every Good connection. This slows the increase of the nAttempts in addrman while partitioned, even if the node hasn't yet noticed the partitioning. --- src/addrman.cpp | 8 +++++++- src/addrman.h | 8 ++++++++ src/net.cpp | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 0a1745c10..00f6fe99e 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -197,6 +197,9 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId) void CAddrMan::Good_(const CService& addr, int64_t nTime) { int nId; + + nLastGood = nTime; + CAddrInfo* pinfo = Find(addr, &nId); // if not found, bail out @@ -327,7 +330,10 @@ void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) // update info info.nLastTry = nTime; - if (fCountFailure) info.nAttempts++; + if (fCountFailure && info.nLastCountAttempt < nLastGood) { + info.nLastCountAttempt = nTime; + info.nAttempts++; + } } CAddrInfo CAddrMan::Select_(bool newOnly) diff --git a/src/addrman.h b/src/addrman.h index 65ca79fa0..c5923e941 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -29,6 +29,9 @@ public: //! last try whatsoever by us (memory only) int64_t nLastTry; + //! last counted attempt (memory only) + int64_t nLastCountAttempt; + private: //! where knowledge about this address first came from CNetAddr source; @@ -66,6 +69,7 @@ public: { nLastSuccess = 0; nLastTry = 0; + nLastCountAttempt = 0; nAttempts = 0; nRefCount = 0; fInTried = false; @@ -200,6 +204,9 @@ private: //! list of "new" buckets int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; + //! last time Good was called (memory only) + int64_t nLastGood; + protected: //! secret key to randomize bucket select with uint256 nKey; @@ -458,6 +465,7 @@ public: nIdCount = 0; nTried = 0; nNew = 0; + nLastGood = 1; //Initially at 1 so that "never" is strictly worse. } CAddrMan() diff --git a/src/net.cpp b/src/net.cpp index f30321869..c15a4692e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1633,7 +1633,7 @@ void ThreadOpenConnections() } if (addrConnect.IsValid()) - OpenNetworkConnection(addrConnect, (int)setConnected.size() >= min(nMaxConnections - 1, 2), &grant); + OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant); } } From 52b02ecd6d7ce918676c76c725678cf0ae2561d2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 26 May 2016 18:44:14 +0200 Subject: [PATCH 0671/1223] Use global ::fRelayTxes instead of CNode one --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 44cdfd2ae..a0c670e59 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -471,7 +471,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, strSubVersion, nBestHeight, fRelayTxes); + nLocalHostNonce, strSubVersion, nBestHeight, ::fRelayTxes); } From e871f8338ad180428ff997b80a476d9719d8073f Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 26 May 2016 14:19:07 -0400 Subject: [PATCH 0672/1223] Tests: add timeout to sync_blocks() and sync_mempools() Previously these functions would infinitely loop if sync failed; now they have a default timeout of 60 seconds, after which an AssertionError is raised. sync_blocks() has also been improved and now compares the tip hash of each node, rather than just using block count. --- qa/rpc-tests/test_framework/util.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 3948b664e..fc66ef287 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -121,30 +121,34 @@ def hex_str_to_bytes(hex_str): def str_to_b64str(string): return b64encode(string.encode('utf-8')).decode('ascii') -def sync_blocks(rpc_connections, wait=1): +def sync_blocks(rpc_connections, wait=1, timeout=60): """ - Wait until everybody has the same block count + Wait until everybody has the same tip """ - while True: - counts = [ x.getblockcount() for x in rpc_connections ] - if counts == [ counts[0] ]*len(counts): - break + while timeout > 0: + tips = [ x.getbestblockhash() for x in rpc_connections ] + if tips == [ tips[0] ]*len(tips): + return True time.sleep(wait) + timeout -= wait + raise AssertionError("Block sync failed") -def sync_mempools(rpc_connections, wait=1): +def sync_mempools(rpc_connections, wait=1, timeout=60): """ Wait until everybody has the same transactions in their memory pools """ - while True: + while timeout > 0: pool = set(rpc_connections[0].getrawmempool()) num_match = 1 for i in range(1, len(rpc_connections)): if set(rpc_connections[i].getrawmempool()) == pool: num_match = num_match+1 if num_match == len(rpc_connections): - break + return True time.sleep(wait) + timeout -= wait + raise AssertionError("Mempool sync failed") bitcoind_processes = {} From 5fac1f33fb5afad4cbcb51b7c85ab2cd759846e1 Mon Sep 17 00:00:00 2001 From: Yuri Zhykin Date: Fri, 27 May 2016 05:32:58 +0300 Subject: [PATCH 0673/1223] bench: Added base58 encoding/decoding benchmarks --- src/Makefile.bench.include | 3 +- src/bench/base58.cpp | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/bench/base58.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 65fd24e05..4067ceb39 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -9,7 +9,8 @@ bench_bench_bitcoin_SOURCES = \ bench/bench.h \ bench/Examples.cpp \ bench/rollingbloom.cpp \ - bench/crypto_hash.cpp + bench/crypto_hash.cpp \ + bench/base58.cpp bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/bench/base58.cpp b/src/bench/base58.cpp new file mode 100644 index 000000000..1279c3e7d --- /dev/null +++ b/src/bench/base58.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2016 the Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" + +#include "main.h" +#include "base58.h" + +#include +#include + + +static void Base58Encode(benchmark::State& state) +{ + unsigned char buff[32] = { + 17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147, + 227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90, + 200, 24 + }; + unsigned char* b = buff; + while (state.KeepRunning()) { + EncodeBase58(b, b + 32); + } +} + + +static void Base58CheckEncode(benchmark::State& state) +{ + unsigned char buff[32] = { + 17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147, + 227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90, + 200, 24 + }; + unsigned char* b = buff; + std::vector vch; + vch.assign(b, b + 32); + while (state.KeepRunning()) { + EncodeBase58Check(vch); + } +} + + +static void Base58Decode(benchmark::State& state) +{ + const char* addr = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"; + std::vector vch; + while (state.KeepRunning()) { + DecodeBase58(addr, vch); + } +} + + +BENCHMARK(Base58Encode); +BENCHMARK(Base58CheckEncode); +BENCHMARK(Base58Decode); From 13c455823f6d74c9632bc85191a0bebad973da1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 27 May 2016 07:46:36 +0200 Subject: [PATCH 0674/1223] Remove unused local variable shadowing upper local --- src/test/sighash_tests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 04c6fa962..e43b2ff6c 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -195,7 +195,6 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) nHashType = test[3].get_int(); sigHashHex = test[4].get_str(); - uint256 sh; CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); stream >> tx; From 88f14b999cb70f6c556633f2889e698a05305158 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 27 May 2016 13:30:36 +0200 Subject: [PATCH 0675/1223] Include signal.h for sig_atomic_t in WIN32 --- src/util.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/util.h b/src/util.h index 88a00d3ca..c6f8af4cd 100644 --- a/src/util.h +++ b/src/util.h @@ -28,9 +28,7 @@ #include #include -#ifndef WIN32 #include -#endif static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; From 723779c6504453cfb5ccdacf864e7e2f09bb6c32 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 27 May 2016 14:14:44 -0400 Subject: [PATCH 0676/1223] build: Enumerate ctaes rather than globbing --- src/Makefile.am | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 31917f135..cb8a99fe9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -410,6 +410,12 @@ libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) endif # +CTAES_DIST = crypto/ctaes/bench.c +CTAES_DIST += crypto/ctaes/ctaes.c +CTAES_DIST += crypto/ctaes/ctaes.h +CTAES_DIST += crypto/ctaes/README.md +CTAES_DIST += crypto/ctaes/test.c + CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a CLEANFILES += $(EXTRA_LIBRARIES) CLEANFILES += *.gcda *.gcno @@ -427,7 +433,7 @@ CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb crypto/ctaes +EXTRA_DIST = leveldb $(CTAES_DIST) clean-local: -$(MAKE) -C leveldb clean From 619d5691c20bee5d08be2ce85aafa2cb570dbca4 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 27 May 2016 13:30:08 +0200 Subject: [PATCH 0677/1223] Benchmark SipHash --- src/bench/crypto_hash.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 6b753f630..168006154 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -6,6 +6,8 @@ #include "bench.h" #include "bloom.h" +#include "hash.h" +#include "uint256.h" #include "utiltime.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" @@ -39,6 +41,16 @@ static void SHA256(benchmark::State& state) CSHA256().Write(begin_ptr(in), in.size()).Finalize(hash); } +static void SHA256_32b(benchmark::State& state) +{ + std::vector in(32,0); + while (state.KeepRunning()) { + for (int i = 0; i < 1000000; i++) { + CSHA256().Write(begin_ptr(in), in.size()).Finalize(&in[0]); + } + } +} + static void SHA512(benchmark::State& state) { uint8_t hash[CSHA512::OUTPUT_SIZE]; @@ -47,7 +59,20 @@ static void SHA512(benchmark::State& state) CSHA512().Write(begin_ptr(in), in.size()).Finalize(hash); } +static void SipHash_32b(benchmark::State& state) +{ + uint256 x; + while (state.KeepRunning()) { + for (int i = 0; i < 1000000; i++) { + *((uint64_t*)x.begin()) = SipHashUint256(0, i, x); + } + } +} + BENCHMARK(RIPEMD160); BENCHMARK(SHA1); BENCHMARK(SHA256); BENCHMARK(SHA512); + +BENCHMARK(SHA256_32b); +BENCHMARK(SipHash_32b); From fa2637a3beb8677067015df3d9d7b394fa837c2f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 16 Apr 2016 12:25:12 +0200 Subject: [PATCH 0678/1223] Always require OS randomness when generating secret keys --- src/Makefile.am | 3 ++- src/init.cpp | 2 -- src/key.cpp | 3 +-- src/main.cpp | 1 - src/random.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++- src/random.h | 11 ++++++---- src/wallet/wallet.cpp | 8 ++------ 7 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 3c056386f..f630ad4aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -374,7 +374,8 @@ endif bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBUNIVALUE) \ - $(LIBBITCOIN_UTIL) + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CRYPTO) bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # diff --git a/src/init.cpp b/src/init.cpp index 9b6943c58..98c089412 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1401,8 +1401,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!strErrors.str().empty()) return InitError(strErrors.str()); - RandAddSeedPerfmon(); - //// debug print LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); LogPrintf("nBestHeight = %d\n", chainActive.Height()); diff --git a/src/key.cpp b/src/key.cpp index 6a3d9aa14..79023566c 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -124,9 +124,8 @@ bool CKey::Check(const unsigned char *vch) { } void CKey::MakeNewKey(bool fCompressedIn) { - RandAddSeedPerfmon(); do { - GetRandBytes(vch, sizeof(vch)); + GetStrongRandBytes(vch, sizeof(vch)); } while (!Check(vch)); fValid = true; fCompressed = fCompressedIn; diff --git a/src/main.cpp b/src/main.cpp index ed157b53d..ffc57d48b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4547,7 +4547,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams) { - RandAddSeedPerfmon(); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { diff --git a/src/random.cpp b/src/random.cpp index 6155c0d8c..8ad0a9b00 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -5,9 +5,11 @@ #include "random.h" +#include "crypto/sha512.h" #include "support/cleanse.h" #ifdef WIN32 #include "compat.h" // for Windows API +#include #endif #include "serialize.h" // for begin_ptr(vec) #include "util.h" // for LogPrint() @@ -43,7 +45,7 @@ void RandAddSeed() memory_cleanse((void*)&nCounter, sizeof(nCounter)); } -void RandAddSeedPerfmon() +static void RandAddSeedPerfmon() { RandAddSeed(); @@ -83,6 +85,29 @@ void RandAddSeedPerfmon() #endif } +/** Get 32 bytes of system entropy. */ +static void GetOSRand(unsigned char *ent32) +{ +#ifdef WIN32 + HCRYPTPROV hProvider; + int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + assert(ret); + ret = CryptGenRandom(hProvider, 32, ent32); + assert(ret); + CryptReleaseContext(hProvider, 0); +#else + int f = open("/dev/urandom", O_RDONLY); + assert(f != -1); + int have = 0; + do { + ssize_t n = read(f, ent32 + have, 32 - have); + assert(n > 0 && n <= 32 - have); + have += n; + } while (have < 32); + close(f); +#endif +} + void GetRandBytes(unsigned char* buf, int num) { if (RAND_bytes(buf, num) != 1) { @@ -91,6 +116,27 @@ void GetRandBytes(unsigned char* buf, int num) } } +void GetStrongRandBytes(unsigned char* out, int num) +{ + assert(num <= 32); + CSHA512 hasher; + unsigned char buf[64]; + + // First source: OpenSSL's RNG + RandAddSeedPerfmon(); + GetRandBytes(buf, 32); + hasher.Write(buf, 32); + + // Second source: OS RNG + GetOSRand(buf); + hasher.Write(buf, 32); + + // Produce output + hasher.Finalize(buf); + memcpy(out, buf, num); + memory_cleanse(buf, 64); +} + uint64_t GetRand(uint64_t nMax) { if (nMax == 0) diff --git a/src/random.h b/src/random.h index 1a2d3e8ee..31b80bd56 100644 --- a/src/random.h +++ b/src/random.h @@ -10,11 +10,8 @@ #include -/** - * Seed OpenSSL PRNG with additional entropy data - */ +/* Seed OpenSSL PRNG with additional entropy data */ void RandAddSeed(); -void RandAddSeedPerfmon(); /** * Functions to gather random data via the OpenSSL PRNG @@ -24,6 +21,12 @@ uint64_t GetRand(uint64_t nMax); int GetRandInt(int nMax); uint256 GetRandHash(); +/** + * Function to gather random data from multiple sources, failing whenever any + * of those source fail to provide a result. + */ +void GetStrongRandBytes(unsigned char* buf, int num); + /** * Seed insecure_rand using the random pool. * @param Deterministic Use a deterministic seed diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5d1a43119..da0d6f272 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -509,16 +509,14 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) return false; CKeyingMaterial vMasterKey; - RandAddSeedPerfmon(); vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); - GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + GetStrongRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); CMasterKey kMasterKey; - RandAddSeedPerfmon(); kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); - GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); CCrypter crypter; int64_t nStartTime = GetTimeMillis(); @@ -3147,8 +3145,6 @@ bool CWallet::InitLoadWallet() if (fFirstRun) { // Create new keyUser and set as default key - RandAddSeedPerfmon(); - CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); From 628cf1440aca8b5b259458a4ed41cc138cae34fa Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 23 Apr 2016 18:07:35 +0200 Subject: [PATCH 0679/1223] Don't use assert for catching randomness failures --- src/random.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/random.cpp b/src/random.cpp index 8ad0a9b00..d9a8cc145 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -15,6 +15,7 @@ #include "util.h" // for LogPrint() #include "utilstrencodings.h" // for GetTime() +#include #include #ifndef WIN32 @@ -24,6 +25,12 @@ #include #include +static void RandFailure() +{ + LogPrintf("Failed to read randomness, aborting\n"); + abort(); +} + static inline int64_t GetPerformanceCounter() { int64_t nCounter = 0; @@ -91,17 +98,25 @@ static void GetOSRand(unsigned char *ent32) #ifdef WIN32 HCRYPTPROV hProvider; int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - assert(ret); + if (!ret) { + RandFailure(); + } ret = CryptGenRandom(hProvider, 32, ent32); - assert(ret); + if (!ret) { + RandFailure(); + } CryptReleaseContext(hProvider, 0); #else int f = open("/dev/urandom", O_RDONLY); - assert(f != -1); + if (f == -1) { + RandFailure(); + } int have = 0; do { ssize_t n = read(f, ent32 + have, 32 - have); - assert(n > 0 && n <= 32 - have); + if (n <= 0 || n + have > 32) { + RandFailure(); + } have += n; } while (have < 32); close(f); @@ -111,8 +126,7 @@ static void GetOSRand(unsigned char *ent32) void GetRandBytes(unsigned char* buf, int num) { if (RAND_bytes(buf, num) != 1) { - LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL)); - assert(false); + RandFailure(); } } From 1a8c4d575d9ae15c954a850a2516ef4a75eabf7a Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 27 May 2016 16:01:14 +0800 Subject: [PATCH 0680/1223] [Doc] Add benchmarking notes --- doc/README.md | 1 + doc/benchmarking.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 doc/benchmarking.md diff --git a/doc/README.md b/doc/README.md index 357334dfb..c30f29452 100644 --- a/doc/README.md +++ b/doc/README.md @@ -57,6 +57,7 @@ The Bitcoin repo's [root README](/README.md) contains relevant information on th - [Shared Libraries](shared-libraries.md) - [BIPS](bips.md) - [Dnsseed Policy](dnsseed-policy.md) +- [Benchmarking](benchmarking.md) ### Resources * Discuss on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Development & Technical Discussion board](https://bitcointalk.org/index.php?board=6.0). diff --git a/doc/benchmarking.md b/doc/benchmarking.md new file mode 100644 index 000000000..0ba75afcd --- /dev/null +++ b/doc/benchmarking.md @@ -0,0 +1,30 @@ +Benchmarking +============ + +Bitcoin Core has an internal benchmarking framework, with benchmarks +for cryptographic algorithms such as SHA1, SHA256, SHA512 and RIPEMD160. As well as the rolling bloom filter. + +After compiling bitcoin-core, the benchmarks can be run with: +`src/bench/bench_bitcoin` + +The output will look similar to: +``` +#Benchmark,count,min,max,average +RIPEMD160,448,0.001245033173334,0.002638196945190,0.002461894814457 +RollingBloom-refresh,1,0.000635000000000,0.000635000000000,0.000635000000000 +RollingBloom-refresh,1,0.000108000000000,0.000108000000000,0.000108000000000 +RollingBloom-refresh,1,0.000107000000000,0.000107000000000,0.000107000000000 +RollingBloom-refresh,1,0.000204000000000,0.000204000000000,0.000204000000000 +SHA1,640,0.000909024336207,0.001938136418660,0.001843086257577 +SHA256,256,0.002209486499909,0.008500099182129,0.004300644621253 +SHA512,384,0.001319904176016,0.002813005447388,0.002615700786312 +Sleep100ms,10,0.205592155456543,0.210056066513062,0.104166316986084 +Trig,67108864,0.000000014997003,0.000000015448112,0.000000015188842 +``` + +More benchmarks are needed for, in no particular order: +- Script Validation +- CCoinDBView caching +- Coins database +- Memory pool +- Wallet coin selection From bd0f41387783ee91623d7fac15e89e57db37df82 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Mon, 30 May 2016 11:43:53 +0200 Subject: [PATCH 0681/1223] Reduce unnecessary hashing in signrawtransaction --- src/rpc/rawtransaction.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index bec7ebe55..1bc31c4e3 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -743,6 +743,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // Script verification errors UniValue vErrors(UniValue::VARR); + // Use CTransaction for the constant parts of the + // transaction to avoid rehashing. + const CTransaction txConst(mergedTx); // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; @@ -760,10 +763,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // ... and merge in other signatures: BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); + txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, txin.scriptSig, txv.vin[i].scriptSig); } ScriptError serror = SCRIPT_ERR_OK; - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) { + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i), &serror)) { TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); } } From e4f73c76b3a408037fdf32d9700d57f3d0e77a47 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 30 May 2016 20:43:46 +0800 Subject: [PATCH 0682/1223] [Doc] Update implemented BIPs list --- doc/bips.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/bips.md b/doc/bips.md index b8efabbcf..b4b62e781 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -1,5 +1,6 @@ -BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): +BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): +* [`BIP 9`](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki): The changes allowing multiple soft-forks to be deployed in parallel have been implemented since **v0.12.1** ([PR #7575](https://github.com/bitcoin/bitcoin/pull/7575)) * [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). * [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). * [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). @@ -16,8 +17,11 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). * [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). +* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)). * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). +* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)). +* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)). * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). From b682960a28137966306e0a3646c96fa5f4b811ff Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Mon, 23 May 2016 14:23:07 -0500 Subject: [PATCH 0683/1223] Adding P2SH(p2pkh) script test case Fixing formatting Adding test case into automatically generated test case set Clean up commits removing extra whitespace from eol Removing extra whitespace on macro line --- src/test/data/script_tests.json | 7 +++++++ src/test/script_tests.cpp | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 757d94b52..0bdac182e 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1310,6 +1310,13 @@ "EVAL_FALSE", "P2SH(P2PK), bad redeemscript" ], +[ + "0x47 0x30440220781ba4f59a7b207a10db87628bc2168df4d59b844b397d2dbc9a5835fb2f2b7602206ed8fbcc1072fe2dfc5bb25909269e5dc42ffcae7ec2bc81d59692210ff30c2b01 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x19 0x76a91491b24bf9f5288532960ac687abb035127b1d28a588ac", + "HASH160 0x14 0x7f67f0521934a57d3039f77f9f32cf313f3ac74b EQUAL", + "P2SH", + "OK", + "P2SH(P2PKH)" +], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 5e9711a4a..39089f103 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -427,7 +427,10 @@ BOOST_AUTO_TEST_CASE(script_build) tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE)); - + + tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey0.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH)", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem()); tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true ).PushSig(keys.key0).DamagePush(10).PushRedeem()); From 63ff57db4beb2e92b3d8ed396da016f29f790195 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 29 May 2016 01:36:52 +0000 Subject: [PATCH 0684/1223] Avoid integer division in the benchmark inner-most loop. Previously the benchmark code used an integer division (%) with a non-constant in the inner-loop. This is quite slow on many processors, especially ones like ARM that lack a hardware divide. Even on fairly recent x86_64 like haswell an integer division can take something like 100 cycles-- making it comparable to the runtime of siphash. This change avoids the division by using bitmasking instead. This was especially easy since the count was only increased by doubling. This change also restarts the timing when the execution time was very low this avoids mintimes of zero in cases where one execution ends up below the timer resolution. It also reduces the impact of the overhead on the final result. The formatting of the prints is changed to not use scientific notation make it more machine readable (in particular, gnuplot croaks on the non-fixedpoint, and it doesn't sort correctly). This also hoists out all the floating point divisions out of the semi-hot path because it was easy to do so. It might be prudent to break out the critical test into a macro just to guarantee that it gets inlined. It might also make sense to just save out the intermediate counts and times and get the floating point completely out of the timing loop (because e.g. on hardware without a fast hardware FPU like some ARM it will still be slow enough to distort the results). I haven't done either of these in this commit. --- src/bench/bench.cpp | 35 ++++++++++++++++++++++++----------- src/bench/bench.h | 7 ++++--- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 6ee3cdc27..227546a7a 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -5,6 +5,7 @@ #include "bench.h" #include +#include #include using namespace benchmark; @@ -25,7 +26,7 @@ BenchRunner::BenchRunner(std::string name, BenchFunction func) void BenchRunner::RunAll(double elapsedTimeForOne) { - std::cout << "Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << "\n"; + std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << "\n"; for (std::map::iterator it = benchmarks.begin(); it != benchmarks.end(); ++it) { @@ -38,22 +39,34 @@ BenchRunner::RunAll(double elapsedTimeForOne) bool State::KeepRunning() { + if (count & countMask) { + ++count; + return true; + } double now; if (count == 0) { - beginTime = now = gettimedouble(); + lastTime = beginTime = now = gettimedouble(); } else { - // timeCheckCount is used to avoid calling gettime most of the time, - // so benchmarks that run very quickly get consistent results. - if ((count+1)%timeCheckCount != 0) { - ++count; - return true; // keep going - } now = gettimedouble(); - double elapsedOne = (now - lastTime)/timeCheckCount; + double elapsed = now - lastTime; + double elapsedOne = elapsed * countMaskInv; if (elapsedOne < minTime) minTime = elapsedOne; if (elapsedOne > maxTime) maxTime = elapsedOne; - if (elapsedOne*timeCheckCount < maxElapsed/16) timeCheckCount *= 2; + if (elapsed*128 < maxElapsed) { + // If the execution was much too fast (1/128th of maxElapsed), increase the count mask by 8x and restart timing. + // The restart avoids including the overhead of this code in the measurement. + countMask = ((countMask<<3)|7) & ((1LL<<60)-1); + countMaskInv = 1./(countMask+1); + count = 0; + minTime = std::numeric_limits::max(); + maxTime = std::numeric_limits::min(); + return true; + } + if (elapsed*16 < maxElapsed) { + countMask = ((countMask<<1)|1) & ((1LL<<60)-1); + countMaskInv = 1./(countMask+1); + } } lastTime = now; ++count; @@ -64,7 +77,7 @@ bool State::KeepRunning() // Output results double average = (now-beginTime)/count; - std::cout << name << "," << count << "," << minTime << "," << maxTime << "," << average << "\n"; + std::cout << std::fixed << std::setprecision(15) << name << "," << count << "," << minTime << "," << maxTime << "," << average << "\n"; return false; } diff --git a/src/bench/bench.h b/src/bench/bench.h index 5ce13c642..f13b145aa 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -40,14 +40,15 @@ namespace benchmark { std::string name; double maxElapsed; double beginTime; - double lastTime, minTime, maxTime; + double lastTime, minTime, maxTime, countMaskInv; int64_t count; - int64_t timeCheckCount; + int64_t countMask; public: State(std::string _name, double _maxElapsed) : name(_name), maxElapsed(_maxElapsed), count(0) { minTime = std::numeric_limits::max(); maxTime = std::numeric_limits::min(); - timeCheckCount = 1; + countMask = 1; + countMaskInv = 1./(countMask + 1); } bool KeepRunning(); }; From 16698cb77e455ae1e2fffd8d0225d2486232a366 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 31 May 2016 05:30:35 +0300 Subject: [PATCH 0685/1223] PR #7772 is not enough to fix the issue with QCompleter, use event filter instead of `connect` --- src/qt/rpcconsole.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b11648e46..11f3e49a0 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -327,6 +327,14 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event) return true; } break; + case Qt::Key_Return: + case Qt::Key_Enter: + // forward these events to lineEdit + if(obj == autoCompleter->popup()) { + QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt)); + return true; + } + break; default: // Typing in messages widget brings focus to line edit, and redirects key there // Exclude most combinations and keys that emit no text, except paste shortcuts @@ -458,9 +466,7 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); - - // clear the lineEdit after activating from QCompleter - connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection); + autoCompleter->popup()->installEventFilter(this); } } From f19025106de47a92396f9fb98e6d3bbc568c40b5 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 2 Jan 2016 12:34:08 +0100 Subject: [PATCH 0686/1223] [Wallet] Add simplest BIP32/deterministic key generation implementation --- src/wallet/wallet.cpp | 86 +++++++++++++++++++++++++++++++++++++++-- src/wallet/wallet.h | 12 ++++++ src/wallet/walletdb.cpp | 17 ++++++++ src/wallet/walletdb.h | 32 +++++++++++++++ 4 files changed, 143 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index da0d6f272..fdb46472a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -91,7 +91,48 @@ CPubKey CWallet::GenerateNewKey() bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets CKey secret; - secret.MakeNewKey(fCompressed); + + // Create new metadata + int64_t nCreationTime = GetTime(); + CKeyMetadata metadata(nCreationTime); + + // use HD key derivation if HD was enabled during wallet creation + if (!hdChain.masterKeyID.IsNull()) { + // for now we use a fixed keypath scheme of m/0'/0'/k + CKey key; //master key seed (256bit) + CExtKey masterKey; //hd master key + CExtKey accountKey; //key at m/0' + CExtKey externalChainChildKey; //key at m/0'/0' + CExtKey childKey; //key at m/0'/0'/' + + // try to get the master key + if (!GetKey(hdChain.masterKeyID, key)) + throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); + + masterKey.SetMaster(key.begin(), key.size()); + + // derive m/0' + // use hardened derivation (child keys > 0x80000000 are hardened after bip32) + masterKey.Derive(accountKey, 0 | 0x80000000); + + // derive m/0'/0' + accountKey.Derive(externalChainChildKey, 0 | 0x80000000); + + // derive child key at next index, skip keys already known to the wallet + do + { + externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | 0x80000000); + // increment childkey index + hdChain.nExternalChainCounter++; + } while(HaveKey(childKey.key.GetPubKey().GetID())); + secret = childKey.key; + + // update the chain model in the database + if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) + throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); + } else { + secret.MakeNewKey(fCompressed); + } // Compressed public keys were introduced in version 0.6.0 if (fCompressed) @@ -100,9 +141,7 @@ CPubKey CWallet::GenerateNewKey() CPubKey pubkey = secret.GetPubKey(); assert(secret.VerifyPubKey(pubkey)); - // Create new metadata - int64_t nCreationTime = GetTime(); - mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime); + mapKeyMetadata[pubkey.GetID()] = metadata; if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) nTimeFirstKey = nCreationTime; @@ -1049,6 +1088,37 @@ CAmount CWallet::GetChange(const CTransaction& tx) const return nChange; } +bool CWallet::SetHDMasterKey(const CKey& key) +{ + LOCK(cs_wallet); + + // store the key as normal "key"/"ckey" object + // in the database + // key metadata is not required + CPubKey pubkey = key.GetPubKey(); + if (!AddKeyPubKey(key, pubkey)) + throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + + // store the keyid (hash160) together with + // the child index counter in the database + // as a hdchain object + CHDChain newHdChain; + newHdChain.masterKeyID = pubkey.GetID(); + SetHDChain(newHdChain, false); + + return true; +} + +bool CWallet::SetHDChain(const CHDChain& chain, bool memonly) +{ + LOCK(cs_wallet); + if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain)) + throw runtime_error("AddHDChain(): writing chain failed"); + + hdChain = chain; + return true; +} + int64_t CWalletTx::GetTxTime() const { int64_t n = nTimeSmart; @@ -3058,6 +3128,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after bip32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); @@ -3145,6 +3216,13 @@ bool CWallet::InitLoadWallet() if (fFirstRun) { // Create new keyUser and set as default key + if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET)) { + // generate a new master key + CKey key; + key.MakeNewKey(true); + if (!walletInstance->SetHDMasterKey(key)) + throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); + } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b2180a5a2..a819c0326 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -57,6 +57,9 @@ static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; +//! if set, all keys will be derived by using BIP32 +static const bool DEFAULT_USE_HD_WALLET = true; + extern const char * DEFAULT_WALLET_DAT; class CBlockIndex; @@ -574,6 +577,9 @@ private: void SyncMetaData(std::pair); + /* the hd chain data model (external chain counters) */ + CHDChain hdChain; + public: /* * Main wallet lock. @@ -887,6 +893,12 @@ public: static bool ParameterInteraction(); bool BackupWallet(const std::string& strDest); + + /* Set the hd chain model (chain child index counters) */ + bool SetHDChain(const CHDChain& chain, bool memonly); + + /* Set the current hd master key (will reset the chain child index counters) */ + bool SetHDMasterKey(const CKey& key); }; /** A key allocated from the key pool. */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index b5037c9a6..7bfd49095 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -599,6 +599,16 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, return false; } } + else if (strType == "hdchain") + { + CHDChain chain; + ssValue >> chain; + if (!pwallet->SetHDChain(chain, true)) + { + strErr = "Error reading wallet database: SetHDChain failed"; + return false; + } + } } catch (...) { return false; @@ -1003,3 +1013,10 @@ bool CWalletDB::EraseDestData(const std::string &address, const std::string &key nWalletDBUpdated++; return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key))); } + + +bool CWalletDB::WriteHDChain(const CHDChain& chain) +{ + nWalletDBUpdated++; + return Write(std::string("hdchain"), chain); +} diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 00c10ea70..71b0ff26d 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -40,6 +40,35 @@ enum DBErrors DB_NEED_REWRITE }; +/* simple hd chain data model */ +class CHDChain +{ +public: + uint32_t nExternalChainCounter; + CKeyID masterKeyID; //!< master key hash160 + + static const int CURRENT_VERSION = 1; + int nVersion; + + CHDChain() { SetNull(); } + ADD_SERIALIZE_METHODS; + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nExternalChainCounter); + READWRITE(masterKeyID); + } + + void SetNull() + { + nVersion = CHDChain::CURRENT_VERSION; + nExternalChainCounter = 0; + masterKeyID.SetNull(); + } +}; + class CKeyMetadata { public: @@ -134,6 +163,9 @@ public: static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, const std::string& filename); + //! write the hdchain model (external chain child index counter) + bool WriteHDChain(const CHDChain& chain); + private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); From 4d8993b3469915d8c9ba4cd3b918f16782edf0de Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 21 May 2016 09:45:32 +0000 Subject: [PATCH 0687/1223] Defer inserting into maprelay until just before relaying. This reduces the rate of not founds by better matching the far end expectations, it also improves privacy by removing the ability to use getdata to probe for a node having a txn before it has been relayed. --- src/main.cpp | 43 ++++++++++++++++++++++++++++++------------- src/net.cpp | 15 --------------- src/net.h | 3 --- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c2905784f..f9b8ab37e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,6 +80,10 @@ uint64_t nPruneTarget = 0; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT; +std::map mapRelay; +std::deque > vRelayExpiration; +CCriticalSection cs_mapRelay; + CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; @@ -4501,27 +4505,28 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } else if (inv.IsKnownType()) { + CTransaction tx; // Send stream from relay memory - bool pushed = false; + bool push = false; { LOCK(cs_mapRelay); map::iterator mi = mapRelay.find(inv.hash); if (mi != mapRelay.end()) { - pfrom->PushMessage(inv.GetCommand(), (*mi).second); - pushed = true; + tx = (*mi).second; + push = true; } } - if (!pushed && inv.type == MSG_TX) { - CTransaction tx; + if (!push && inv.type == MSG_TX) { int64_t txtime; // To protect privacy, do not answer getdata using the mempool when // that TX couldn't have been INVed in reply to a MEMPOOL request. if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) { - pfrom->PushMessage(NetMsgType::TX, tx); - pushed = true; + push = true; } } - if (!pushed) { + if (push) { + pfrom->PushMessage(inv.GetCommand(), tx); + } else { vNotFound.push_back(inv); } } @@ -5958,14 +5963,26 @@ bool SendMessages(CNode* pto) if (filterrate && feeRate.GetFeePerK() < filterrate) { continue; } - if (pto->pfilter) { - CTransaction tx; - if (!mempool.lookup(hash, tx)) continue; - if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue; - } + CTransaction tx; + if (!mempool.lookup(hash, tx)) continue; + if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue; // Send vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; + { + LOCK(cs_mapRelay); + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + auto ret = mapRelay.insert(std::make_pair(hash, tx)); + if (ret.second) { + vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash)); + } + } if (vInv.size() == MAX_INV_SZ) { pto->PushMessage(NetMsgType::INV, vInv); vInv.clear(); diff --git a/src/net.cpp b/src/net.cpp index 78a914ebd..c09e3aedb 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -90,9 +90,6 @@ std::string strSubVersion; std::vector vNodes; CCriticalSection cs_vNodes; -std::map mapRelay; -std::deque > vRelayExpiration; -CCriticalSection cs_mapRelay; limitedmap mapAlreadyAskedFor(MAX_INV_SZ); static std::deque vOneShots; @@ -2081,18 +2078,6 @@ instance_of_cnetcleanup; void RelayTransaction(const CTransaction& tx) { CInv inv(MSG_TX, tx.GetHash()); - { - LOCK(cs_mapRelay); - // Expire old relay messages - while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) - { - mapRelay.erase(vRelayExpiration.front().second); - vRelayExpiration.pop_front(); - } - - mapRelay.insert(std::make_pair(inv.hash, tx)); - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv.hash)); - } LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { diff --git a/src/net.h b/src/net.h index 0b4cd0bcb..403653e8c 100644 --- a/src/net.h +++ b/src/net.h @@ -162,9 +162,6 @@ extern int nMaxConnections; extern std::vector vNodes; extern CCriticalSection cs_vNodes; -extern std::map mapRelay; -extern std::deque > vRelayExpiration; -extern CCriticalSection cs_mapRelay; extern limitedmap mapAlreadyAskedFor; extern std::vector vAddedNodes; From 8c9e681ff8bae61c803cdcc1d05d69cbea5da7bf Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Tue, 31 May 2016 14:21:40 -0400 Subject: [PATCH 0688/1223] Tests: Rework blockstore to avoid re-serialization. --- qa/rpc-tests/test_framework/blockstore.py | 59 +++++++++++++++-------- qa/rpc-tests/test_framework/mininode.py | 13 +++++ 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 4bc279032..6120dd574 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -13,20 +13,31 @@ class BlockStore(object): self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') self.currentBlock = 0 self.headers_map = dict() - + def close(self): self.blockDB.close() + def erase(self, blockhash): + del self.blockDB[repr(blockhash)] + + # lookup an entry and return the item as raw bytes def get(self, blockhash): - serialized_block = None + value = None try: - serialized_block = self.blockDB[repr(blockhash)] + value = self.blockDB[repr(blockhash)] except KeyError: return None - f = BytesIO(serialized_block) - ret = CBlock() - ret.deserialize(f) - ret.calc_sha256() + return value + + # lookup an entry and return it as a CBlock + def get_block(self, blockhash): + ret = None + serialized_block = self.get(blockhash) + if serialized_block is not None: + f = BytesIO(serialized_block) + ret = CBlock() + ret.deserialize(f) + ret.calc_sha256() return ret def get_header(self, blockhash): @@ -75,13 +86,16 @@ class BlockStore(object): def add_header(self, header): self.headers_map[header.sha256] = header + # lookup the hashes in "inv", and return p2p messages for delivering + # blocks found. def get_blocks(self, inv): responses = [] for i in inv: if (i.type == 2): # MSG_BLOCK - block = self.get(i.hash) - if block is not None: - responses.append(msg_block(block)) + data = self.get(i.hash) + if data is not None: + # Use msg_generic to avoid re-serialization + responses.append(msg_generic(b"block", data)) return responses def get_locator(self, current_tip=None): @@ -90,11 +104,11 @@ class BlockStore(object): r = [] counter = 0 step = 1 - lastBlock = self.get(current_tip) + lastBlock = self.get_block(current_tip) while lastBlock is not None: r.append(lastBlock.hashPrevBlock) for i in range(step): - lastBlock = self.get(lastBlock.hashPrevBlock) + lastBlock = self.get_block(lastBlock.hashPrevBlock) if lastBlock is None: break counter += 1 @@ -111,16 +125,23 @@ class TxStore(object): def close(self): self.txDB.close() + # lookup an entry and return the item as raw bytes def get(self, txhash): - serialized_tx = None + value = None try: - serialized_tx = self.txDB[repr(txhash)] + value = self.txDB[repr(txhash)] except KeyError: return None - f = BytesIO(serialized_tx) - ret = CTransaction() - ret.deserialize(f) - ret.calc_sha256() + return value + + def get_transaction(self, txhash): + ret = None + serialized_tx = self.get(txhash) + if serialized_tx is not None: + f = BytesIO(serialized_tx) + ret = CTransaction() + ret.deserialize(f) + ret.calc_sha256() return ret def add_transaction(self, tx): @@ -136,5 +157,5 @@ class TxStore(object): if (i.type == 1): # MSG_TX tx = self.get(i.hash) if tx is not None: - responses.append(msg_tx(tx)) + responses.append(msg_generic(b"tx", tx)) return responses diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 1617daa20..e85399c96 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -556,6 +556,7 @@ class CBlock(CBlockHeader): self.nNonce += 1 self.rehash() + def __repr__(self): return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \ % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, @@ -836,6 +837,18 @@ class msg_block(object): def __repr__(self): return "msg_block(block=%s)" % (repr(self.block)) +# for cases where a user needs tighter control over what is sent over the wire +# note that the user must supply the name of the command, and the data +class msg_generic(object): + def __init__(self, command, data=None): + self.command = command + self.data = data + + def serialize(self): + return self.data + + def __repr__(self): + return "msg_generic()" class msg_getaddr(object): command = b"getaddr" From c2dd5a3c39156749e8ee24772d1fcb01404f2b6f Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Wed, 1 Jun 2016 12:29:03 -0400 Subject: [PATCH 0689/1223] FIX: correctly measure size of priority block --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 1eab8f949..99eb0a2eb 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -352,7 +352,7 @@ void BlockAssembler::addPriorityTxs() // If now that this txs is added we've surpassed our desired priority size // or have dropped below the AllowFreeThreshold, then we're done adding priority txs - if (nBlockSize + iter->GetTxSize() >= nBlockPrioritySize || !AllowFree(actualPriority)) { + if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) { return; } From 16cf85fa2c2da7ff73b2c72afcbb5de26a2bede2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 1 Jun 2016 19:18:06 +0200 Subject: [PATCH 0690/1223] Revert "Include signal.h for sig_atomic_t in WIN32" This reverts commit 88f14b999cb70f6c556633f2889e698a05305158. --- src/util.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util.h b/src/util.h index c6f8af4cd..88a00d3ca 100644 --- a/src/util.h +++ b/src/util.h @@ -28,7 +28,9 @@ #include #include +#ifndef WIN32 #include +#endif static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; From a886dbf8e7b6b007153a53e8d8d1fd63b7fc9ee2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 30 May 2016 15:39:37 +0200 Subject: [PATCH 0691/1223] Use std::atomic for fRequestShutdown and fReopenDebugLog --- src/init.cpp | 2 +- src/util.cpp | 2 +- src/util.h | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 98c089412..9a2250185 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -123,7 +123,7 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; // shutdown thing. // -volatile sig_atomic_t fRequestShutdown = false; +std::atomic fRequestShutdown(false); void StartShutdown() { diff --git a/src/util.cpp b/src/util.cpp index 80f219301..9a9209c62 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -113,7 +113,7 @@ string strMiscWarning; bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; bool fLogIPs = DEFAULT_LOGIPS; -volatile sig_atomic_t fReopenDebugLog = false; +std::atomic fReopenDebugLog(false); CTranslationInterface translationInterface; /** Init OpenSSL library multithreading support */ diff --git a/src/util.h b/src/util.h index 88a00d3ca..ac4b94778 100644 --- a/src/util.h +++ b/src/util.h @@ -18,6 +18,7 @@ #include "tinyformat.h" #include "utiltime.h" +#include #include #include #include @@ -28,10 +29,6 @@ #include #include -#ifndef WIN32 -#include -#endif - static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; @@ -54,7 +51,7 @@ extern std::string strMiscWarning; extern bool fLogTimestamps; extern bool fLogTimeMicros; extern bool fLogIPs; -extern volatile sig_atomic_t fReopenDebugLog; +extern std::atomic fReopenDebugLog; extern CTranslationInterface translationInterface; extern const char * const BITCOIN_CONF_FILENAME; From c022e5b15dd0b26bb6ef77a382279987c2efa93f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 1 Jun 2016 20:29:39 +0200 Subject: [PATCH 0692/1223] [Wallet] use constant for bip32 hardened key limit --- src/wallet/wallet.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fdb46472a..1c212d014 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -42,6 +42,7 @@ bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; const char * DEFAULT_WALLET_DAT = "wallet.dat"; +const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) @@ -112,16 +113,19 @@ CPubKey CWallet::GenerateNewKey() masterKey.SetMaster(key.begin(), key.size()); // derive m/0' - // use hardened derivation (child keys > 0x80000000 are hardened after bip32) - masterKey.Derive(accountKey, 0 | 0x80000000); + // use hardened derivation (child keys >= 0x80000000 are hardened after bip32) + masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT); // derive m/0'/0' - accountKey.Derive(externalChainChildKey, 0 | 0x80000000); + accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT); // derive child key at next index, skip keys already known to the wallet do { - externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | 0x80000000); + // always derive hardened keys + // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range + // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649 + externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT); // increment childkey index hdChain.nExternalChainCounter++; } while(HaveKey(childKey.key.GetPubKey().GetID())); From 0cb0f2626e1553426e16a52fc6928d35824827f5 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 1 Jun 2016 18:05:09 -0400 Subject: [PATCH 0693/1223] build: out-of-tree fixups Don't glob the leveldb for dist. That means we need to enumerate the headers. --- Makefile.am | 10 ------- src/Makefile.am | 7 ++--- src/Makefile.leveldb.include | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5783c1fdd..bfdf76568 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,18 +53,8 @@ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info dist-hook: - -$(MAKE) -C $(top_distdir)/src/leveldb clean - -$(MAKE) -C $(top_distdir)/src/secp256k1 distclean -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - -distcheck-hook: - $(MKDIR_P) $(top_distdir)/_build/src/leveldb - cp -rf $(top_srcdir)/src/leveldb/* $(top_distdir)/_build/src/leveldb/ - -$(MAKE) -C $(top_distdir)/_build/src/leveldb clean - -distcleancheck: - @: - $(BITCOIN_WIN_INSTALLER): all-recursive $(MKDIR_P) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release diff --git a/src/Makefile.am b/src/Makefile.am index ea49efe92..c833272ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -417,8 +417,8 @@ CTAES_DIST += crypto/ctaes/ctaes.h CTAES_DIST += crypto/ctaes/README.md CTAES_DIST += crypto/ctaes/test.c -CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a -CLEANFILES += $(EXTRA_LIBRARIES) +CLEANFILES = $(EXTRA_LIBRARIES) + CLEANFILES += *.gcda *.gcno CLEANFILES += compat/*.gcda compat/*.gcno CLEANFILES += consensus/*.gcda consensus/*.gcno @@ -434,10 +434,9 @@ CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb $(CTAES_DIST) +EXTRA_DIST = $(CTAES_DIST) clean-local: - -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean -$(MAKE) -C univalue clean -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 88bb0c193..4b3cd6364 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -26,6 +26,61 @@ leveldb_libleveldb_a_CPPFLAGS = $(AM_CPPFLAGS) $(LEVELDB_CPPFLAGS_INT) $(LEVELDB leveldb_libleveldb_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) leveldb_libleveldb_a_SOURCES= +leveldb_libleveldb_a_SOURCES += leveldb/port/atomic_pointer.h +leveldb_libleveldb_a_SOURCES += leveldb/port/port_example.h +leveldb_libleveldb_a_SOURCES += leveldb/port/port_posix.h +leveldb_libleveldb_a_SOURCES += leveldb/port/win/stdint.h +leveldb_libleveldb_a_SOURCES += leveldb/port/port.h +leveldb_libleveldb_a_SOURCES += leveldb/port/port_win.h +leveldb_libleveldb_a_SOURCES += leveldb/port/thread_annotations.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/db.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/options.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/comparator.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/filter_policy.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/slice.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/table_builder.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/env.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/c.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/iterator.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/cache.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/dumpfile.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/table.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/write_batch.h +leveldb_libleveldb_a_SOURCES += leveldb/include/leveldb/status.h +leveldb_libleveldb_a_SOURCES += leveldb/db/log_format.h +leveldb_libleveldb_a_SOURCES += leveldb/db/memtable.h +leveldb_libleveldb_a_SOURCES += leveldb/db/version_set.h +leveldb_libleveldb_a_SOURCES += leveldb/db/write_batch_internal.h +leveldb_libleveldb_a_SOURCES += leveldb/db/filename.h +leveldb_libleveldb_a_SOURCES += leveldb/db/version_edit.h +leveldb_libleveldb_a_SOURCES += leveldb/db/dbformat.h +leveldb_libleveldb_a_SOURCES += leveldb/db/builder.h +leveldb_libleveldb_a_SOURCES += leveldb/db/log_writer.h +leveldb_libleveldb_a_SOURCES += leveldb/db/db_iter.h +leveldb_libleveldb_a_SOURCES += leveldb/db/skiplist.h +leveldb_libleveldb_a_SOURCES += leveldb/db/db_impl.h +leveldb_libleveldb_a_SOURCES += leveldb/db/table_cache.h +leveldb_libleveldb_a_SOURCES += leveldb/db/snapshot.h +leveldb_libleveldb_a_SOURCES += leveldb/db/log_reader.h +leveldb_libleveldb_a_SOURCES += leveldb/table/filter_block.h +leveldb_libleveldb_a_SOURCES += leveldb/table/block_builder.h +leveldb_libleveldb_a_SOURCES += leveldb/table/block.h +leveldb_libleveldb_a_SOURCES += leveldb/table/two_level_iterator.h +leveldb_libleveldb_a_SOURCES += leveldb/table/merger.h +leveldb_libleveldb_a_SOURCES += leveldb/table/format.h +leveldb_libleveldb_a_SOURCES += leveldb/table/iterator_wrapper.h +leveldb_libleveldb_a_SOURCES += leveldb/util/crc32c.h +leveldb_libleveldb_a_SOURCES += leveldb/util/arena.h +leveldb_libleveldb_a_SOURCES += leveldb/util/random.h +leveldb_libleveldb_a_SOURCES += leveldb/util/posix_logger.h +leveldb_libleveldb_a_SOURCES += leveldb/util/hash.h +leveldb_libleveldb_a_SOURCES += leveldb/util/histogram.h +leveldb_libleveldb_a_SOURCES += leveldb/util/coding.h +leveldb_libleveldb_a_SOURCES += leveldb/util/testutil.h +leveldb_libleveldb_a_SOURCES += leveldb/util/mutexlock.h +leveldb_libleveldb_a_SOURCES += leveldb/util/logging.h +leveldb_libleveldb_a_SOURCES += leveldb/util/testharness.h + leveldb_libleveldb_a_SOURCES += leveldb/db/builder.cc leveldb_libleveldb_a_SOURCES += leveldb/db/c.cc leveldb_libleveldb_a_SOURCES += leveldb/db/dbformat.cc @@ -76,3 +131,4 @@ endif leveldb_libmemenv_a_CPPFLAGS = $(leveldb_libleveldb_a_CPPFLAGS) leveldb_libmemenv_a_CXXFLAGS = $(leveldb_libleveldb_a_CXXFLAGS) leveldb_libmemenv_a_SOURCES = leveldb/helpers/memenv/memenv.cc +leveldb_libmemenv_a_SOURCES += leveldb/helpers/memenv/memenv.h From fc4ad0c7fcf2e5841756c9d1003f95c879ee5cd2 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 1 Jun 2016 18:06:40 -0400 Subject: [PATCH 0694/1223] build: more out-of-tree fixups - clear the __pycache__ during 'make clean' - Copy the qrc locale file to a temp location and remove it when finished (rcc expects everything to be in the same path) --- src/Makefile.am | 1 + src/Makefile.qt.include | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c833272ff..5e33c6a86 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -441,6 +441,7 @@ clean-local: -$(MAKE) -C univalue clean -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno -rm -f config.h + -rm -rf test/__pycache__ .rc.o: @test -f $(WINDRES) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 3b3991944..29e3a264c 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -400,9 +400,10 @@ translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) - @test -f $(@D)/$( $@ + @rm $(@D)/temp_$( Date: Wed, 1 Jun 2016 18:47:21 -0400 Subject: [PATCH 0695/1223] build: a few ugly hacks to get the rpc tests working out-of-tree - Link pull-tester/rpc-tests.py to the build dir - Add the build-dir's config to the python path so that tests can find it - The tests themselves are in srcdir - Clean up __pycache__ in 'make clean' --- Makefile.am | 1 + configure.ac | 1 + qa/pull-tester/rpc-tests.py | 3 ++- qa/pull-tester/tests_config.py.in | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index bfdf76568..9957968f8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -228,3 +228,4 @@ CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) clean-local: rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ qa/tmp/ cache/ $(OSX_APP) + rm -rf qa/pull-tester/__pycache__ diff --git a/configure.ac b/configure.ac index a1c04daf5..7f9ff20cd 100644 --- a/configure.ac +++ b/configure.ac @@ -1060,6 +1060,7 @@ AC_SUBST(MINIUPNPC_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) +AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a dnl result, they leak into secp256k1's configure and crazy things happen. diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index f810f89a5..57a576f1c 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -29,6 +29,7 @@ import subprocess import tempfile import re +sys.path.append("qa/pull-tester/") from tests_config import * BOLD = ("","") @@ -37,7 +38,7 @@ if os.name == 'posix': # terminal via ANSI escape sequences: BOLD = ('\033[0m', '\033[1m') -RPC_TESTS_DIR = BUILDDIR + '/qa/rpc-tests/' +RPC_TESTS_DIR = SRCDIR + '/qa/rpc-tests/' #If imported values are not defined then set to zero (or disabled) if 'ENABLE_WALLET' not in vars(): diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in index 2356b5200..a0d0a3d98 100644 --- a/qa/pull-tester/tests_config.py.in +++ b/qa/pull-tester/tests_config.py.in @@ -3,6 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +SRCDIR="@abs_top_srcdir@" BUILDDIR="@abs_top_builddir@" EXEEXT="@EXEEXT@" From 2b2d52ea3a2c48ce9a221a51bb0c8eef2068582b Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 3 May 2016 20:42:42 +0800 Subject: [PATCH 0696/1223] [depends] Freetype 2.6.3 Update FreeType, and change the download location to gnu.org. This is the other official download location listed on freetype.org --- depends/packages/freetype.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index f7d6e0f9f..7cea28ff0 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -1,8 +1,8 @@ package=freetype -$(package)_version=2.5.3 -$(package)_download_path=http://downloads.sourceforge.net/$(package) +$(package)_version=2.6.3 +$(package)_download_path=http://download.savannah.gnu.org/releases/$(package) $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=c0848b29d52ef3ca27ad92e08351f023c5e24ce8cea7d8fe69fc96358e65f75e +$(package)_sha256_hash=371e707aa522acf5b15ce93f11183c725b8ed1ee8546d7b3af549863045863a2 define $(package)_set_vars $(package)_config_opts=--without-zlib --without-png --disable-static From 0385202befb3416c5d4a39c1665865de7b1e44df Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 3 May 2016 20:51:29 +0800 Subject: [PATCH 0697/1223] [depends] ccache 3.2.5 --- depends/packages/native_ccache.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index cc76f9a79..9216e1759 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.2.4 +$(package)_version=3.2.5 $(package)_download_path=http://samba.org/ftp/ccache $(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=ffeb967edb549e67da0bd5f44f729a2022de9fdde65dfd80d2a7204d7f75332e +$(package)_sha256_hash=7a553809e90faf9de3a23ee9c5b5f786cfd4836bf502744bedb824a24bee1097 define $(package)_set_vars $(package)_config_opts= From bd3cbd53330e001603bfd4be4edfbdb9c952bb36 Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 3 May 2016 20:52:10 +0800 Subject: [PATCH 0698/1223] [depends] ZeroMQ 4.1.4 --- depends/packages/zeromq.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index b3f18db05..f8901f72c 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,11 +1,11 @@ package=zeromq -$(package)_version=4.0.7 +$(package)_version=4.1.4 $(package)_download_path=http://download.zeromq.org $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03 +$(package)_sha256_hash=e99f44fde25c2e4cb84ce440f87ca7d3fe3271c2b8cfbc67d55e4de25e6fe378 define $(package)_set_vars - $(package)_config_opts=--without-documentation --disable-shared + $(package)_config_opts=--without-documentation --disable-shared --without-libsodium $(package)_config_opts_linux=--with-pic $(package)_cxxflags=-std=c++11 endef @@ -15,11 +15,11 @@ define $(package)_config_cmds endef define $(package)_build_cmds - $(MAKE) -C src + $(MAKE) libzmq.la endef define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install + $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-pkgconfigDATA endef define $(package)_postprocess_cmds From 87b8175d999e10082049afd1fb6440cf54d86f1e Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 3 May 2016 20:52:34 +0800 Subject: [PATCH 0699/1223] [depends] Latest config.guess & config.sub --- depends/config.guess | 37 +++++++++++++++++++++---------------- depends/config.sub | 6 ++++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/depends/config.guess b/depends/config.guess index 373a659a0..c4bd827a7 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-02-11' +timestamp='2016-05-15' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -386,7 +389,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 @@ -684,7 +687,7 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac @@ -701,7 +704,7 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w @@ -900,7 +903,7 @@ EOF exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -1276,6 +1279,9 @@ EOF SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1291,7 +1297,7 @@ EOF if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in @@ -1386,7 +1392,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1405,18 +1411,17 @@ esac cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/depends/config.sub b/depends/config.sub index 6223dde93..6d86a1e2f 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-01-01' +timestamp='2016-05-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -1399,7 +1399,7 @@ case $os in | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos*) + | -onefs* | -tirtos* | -phoenix*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1531,6 +1531,8 @@ case $os in ;; -nacl*) ;; + -ios) + ;; -none) ;; *) From 3e0587bf816b9912126ed74ba173edf3d601d2ad Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 10 May 2016 12:50:56 +0800 Subject: [PATCH 0700/1223] [depends] miniupnpc 2.0 --- depends/packages/miniupnpc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 45fa03631..e34cf7be2 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=1.9.20160209 +$(package)_version=2.0 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=572171eacc1d72537ce47b6f4571260757ab7bcfdaf54c3a55c7f88594d94b6f +$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" From 6a4cf16e2bea6e35507fd90846fa4f2441ba93af Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 12 May 2016 19:44:45 +0800 Subject: [PATCH 0701/1223] [depends] expat 2.1.1 --- depends/packages/expat.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 1ac443537..bd2927563 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.1.0 -$(package)_download_path=http://sourceforge.net/projects/expat/files/expat/$($(package)_version) -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=823705472f816df21c8f6aa026dd162b280806838bb55b3432b0fb1fcca7eb86 +$(package)_version=2.1.1 +$(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version) +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=aff584e5a2f759dcfc6d48671e9529f6afe1e30b0cd6a4cec200cbe3f793de67 define $(package)_set_vars $(package)_config_opts=--disable-static From 92e37a368900542700480143af278f66cbe558db Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 1 Jun 2016 22:19:29 -0400 Subject: [PATCH 0702/1223] build: fix out-of-tree 'make deploy' for osx The plist is generated, lives in builddir. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 9957968f8..b93748e32 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,7 @@ OSX_DSSTORE_GEN=$(top_srcdir)/contrib/macdeploy/custom_dsstore.py OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns -OSX_PLIST=$(top_srcdir)/share/qt/Info.plist #not installed +OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) From 142ffc7e6136607b9a31709f31256f360b26588b Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 1 Jun 2016 19:24:29 -0400 Subject: [PATCH 0703/1223] travis: use out-of-tree build --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index bc2c7faf7..f5e306f0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,10 +72,8 @@ script: - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - - make distdir PACKAGE=bitcoin VERSION=$HOST - - cd bitcoin-$HOST - - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) + - mkdir build && cd build + - ../configure $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi From 9dfaa1cb70670eb0a4c82a7ddfcba71ba5ebea94 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Thu, 2 Jun 2016 06:00:59 -0700 Subject: [PATCH 0704/1223] Improve CWallet API with new AccountMove function. --- src/wallet/rpcwallet.cpp | 28 +--------------------------- src/wallet/wallet.cpp | 34 ++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 1 + 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b9f086b09..f7d5210eb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -804,33 +804,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) if (params.size() > 4) strComment = params[4].get_str(); - CWalletDB walletdb(pwalletMain->strWalletFile); - if (!walletdb.TxnBegin()) - throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); - - int64_t nNow = GetAdjustedTime(); - - // Debit - CAccountingEntry debit; - debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb); - debit.strAccount = strFrom; - debit.nCreditDebit = -nAmount; - debit.nTime = nNow; - debit.strOtherAccount = strTo; - debit.strComment = strComment; - pwalletMain->AddAccountingEntry(debit, walletdb); - - // Credit - CAccountingEntry credit; - credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb); - credit.strAccount = strTo; - credit.nCreditDebit = nAmount; - credit.nTime = nNow; - credit.strOtherAccount = strFrom; - credit.strComment = strComment; - pwalletMain->AddAccountingEntry(credit, walletdb); - - if (!walletdb.TxnCommit()) + if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); return true; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index da0d6f272..482eb6aa6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -606,6 +606,40 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) return nRet; } +bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment) +{ + CWalletDB walletdb(strWalletFile); + if (!walletdb.TxnBegin()) + return false; + + int64_t nNow = GetAdjustedTime(); + + // Debit + CAccountingEntry debit; + debit.nOrderPos = IncOrderPosNext(&walletdb); + debit.strAccount = strFrom; + debit.nCreditDebit = -nAmount; + debit.nTime = nNow; + debit.strOtherAccount = strTo; + debit.strComment = strComment; + AddAccountingEntry(debit, walletdb); + + // Credit + CAccountingEntry credit; + credit.nOrderPos = IncOrderPosNext(&walletdb); + credit.strAccount = strTo; + credit.nCreditDebit = nAmount; + credit.nTime = nNow; + credit.strOtherAccount = strFrom; + credit.strComment = strComment; + AddAccountingEntry(credit, walletdb); + + if (!walletdb.TxnCommit()) + return false; + + return true; +} + void CWallet::MarkDirty() { { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b2180a5a2..9fb2eba23 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -718,6 +718,7 @@ public: * @return next transaction order id */ int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); + bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = ""); void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); From 595b22e5c0bf1c3e8ee73aea2f28397c12046a60 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 14 Mar 2016 18:55:19 +0100 Subject: [PATCH 0705/1223] Stop treating importaddress'ed scripts as change Before this, if someone imported a scriptPubKey directly (in hex form) using importaddress, outputs sending to it would be treated as change, as the corresponding CTxDestination was not added to the address book. Fix this by trying to detect scriptPubKeys that are in fact convertible to a CTxDestination and add them anyway. Add a warning to the RPC help to warn against importing raw non-standard scripts. --- src/wallet/rpcdump.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index bb40cf724..70a8462da 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -167,6 +167,11 @@ void ImportScript(const CScript& script, const string& strLabel, bool isRedeemSc if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } else { + CTxDestination destination; + if (ExtractDestination(script, destination)) { + pwalletMain->SetAddressBook(destination, strLabel, "receive"); + } } } @@ -195,6 +200,8 @@ UniValue importaddress(const UniValue& params, bool fHelp) "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" "\nNote: This call can take minutes to complete if rescan is true.\n" "If you have the full public key, you should call importpubkey instead of this.\n" + "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" + "as change, and not show up in many RPCs.\n" "\nExamples:\n" "\nImport a script with rescan\n" + HelpExampleCli("importaddress", "\"myscript\"") + From f45f51e3ae4fca24bc49474ca61c3262186c447d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 13 May 2016 04:49:19 +0200 Subject: [PATCH 0706/1223] Fix interrupted HTTP RPC connection workaround for Python 3.5+ --- qa/rpc-tests/test_framework/authproxy.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index e5f7ab365..95b2be658 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -124,6 +124,11 @@ class AuthServiceProxy(object): return self._get_response() else: raise + except BrokenPipeError: + # Python 3.5+ raises this instead of BadStatusLine when the connection was reset + self.__conn.close() + self.__conn.request(method, path, postdata, headers) + return self._get_response() def __call__(self, *args): AuthServiceProxy.__id_count += 1 From 291f8aa5daf80eed56d6cefa3d410652b412150a Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Thu, 2 Jun 2016 14:42:09 -0400 Subject: [PATCH 0707/1223] Continuing port of java comptool --- qa/rpc-tests/p2p-fullblocktest.py | 1097 +++++++++++++++++++-- qa/rpc-tests/test_framework/blocktools.py | 23 +- qa/rpc-tests/test_framework/mininode.py | 1 - 3 files changed, 1010 insertions(+), 111 deletions(-) diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index aa0501c5e..19b90d4db 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -9,7 +9,8 @@ from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.blocktools import * import time from test_framework.key import CECKey -from test_framework.script import CScript, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE +from test_framework.script import * +import struct class PreviousSpendableOutput(object): def __init__(self, tx = CTransaction(), n = -1): @@ -24,10 +25,36 @@ We use the testing framework in which we expect a particular answer from each test. ''' +def hash160(s): + return hashlib.new('ripemd160', sha256(s)).digest() + +# Use this class for tests that require behavior other than normal "mininode" behavior. +# For now, it is used to serialize a bloated varint (b64). +class CBrokenBlock(CBlock): + def __init__(self, header=None): + super(CBrokenBlock, self).__init__(header) + + def initialize(self, base_block): + self.vtx = copy.deepcopy(base_block.vtx) + self.hashMerkleRoot = self.calc_merkle_root() + + def serialize(self): + r = b"" + r += super(CBlock, self).serialize() + r += struct.pack(" b1 (0) -> b2 (1) - out0 = get_spendable_output() - block(1, spend=out0) + block(1, spend=out[0]) save_spendable_output() yield accepted() - out1 = get_spendable_output() - b2 = block(2, spend=out1) + block(2, spend=out[1]) yield accepted() - + save_spendable_output() # so fork like this: - # + # # genesis -> b1 (0) -> b2 (1) # \-> b3 (1) - # + # # Nothing should happen at this point. We saw b2 first so it takes priority. tip(1) - b3 = block(3, spend=out1) - txout_b3 = PreviousSpendableOutput(b3.vtx[1], 1) + b3 = block(3, spend=out[1]) + txout_b3 = PreviousSpendableOutput(b3.vtx[1], 0) yield rejected() # Now we add another block to make the alternative chain longer. - # + # # genesis -> b1 (0) -> b2 (1) # \-> b3 (1) -> b4 (2) - out2 = get_spendable_output() - block(4, spend=out2) + block(4, spend=out[2]) yield accepted() @@ -197,46 +232,41 @@ class FullBlockTest(ComparisonTestFramework): # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b3 (1) -> b4 (2) tip(2) - block(5, spend=out2) + block(5, spend=out[2]) save_spendable_output() yield rejected() - out3 = get_spendable_output() - block(6, spend=out3) + block(6, spend=out[3]) yield accepted() - # Try to create a fork that double-spends # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b7 (2) -> b8 (4) # \-> b3 (1) -> b4 (2) tip(5) - block(7, spend=out2) + block(7, spend=out[2]) yield rejected() - out4 = get_spendable_output() - block(8, spend=out4) + block(8, spend=out[4]) yield rejected() - # Try to create a block that has too much fee # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b9 (4) # \-> b3 (1) -> b4 (2) tip(6) - block(9, spend=out4, additional_coinbase_value=1) + block(9, spend=out[4], additional_coinbase_value=1) yield rejected(RejectResult(16, b'bad-cb-amount')) - # Create a fork that ends in a block with too much fee (the one that causes the reorg) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b10 (3) -> b11 (4) # \-> b3 (1) -> b4 (2) tip(5) - block(10, spend=out3) + block(10, spend=out[3]) yield rejected() - block(11, spend=out4, additional_coinbase_value=1) + block(11, spend=out[4], additional_coinbase_value=1) yield rejected(RejectResult(16, b'bad-cb-amount')) @@ -246,19 +276,17 @@ class FullBlockTest(ComparisonTestFramework): # (b12 added last) # \-> b3 (1) -> b4 (2) tip(5) - b12 = block(12, spend=out3) + b12 = block(12, spend=out[3]) save_spendable_output() - #yield TestInstance([[b12, False]]) - b13 = block(13, spend=out4) + b13 = block(13, spend=out[4]) # Deliver the block header for b12, and the block b13. # b13 should be accepted but the tip won't advance until b12 is delivered. yield TestInstance([[CBlockHeader(b12), None], [b13, False]]) save_spendable_output() - out5 = get_spendable_output() # b14 is invalid, but the node won't know that until it tries to connect # Tip still can't advance because b12 is missing - block(14, spend=out5, additional_coinbase_value=1) + block(14, spend=out[5], additional_coinbase_value=1) yield rejected() yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. @@ -267,18 +295,18 @@ class FullBlockTest(ComparisonTestFramework): # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6) # \-> b3 (1) -> b4 (2) - + # Test that a block with a lot of checksigs is okay - lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50 - 1)) + lots_of_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS - 1)) tip(13) - block(15, spend=out5, script=lots_of_checksigs) + block(15, spend=out[5], script=lots_of_checksigs) yield accepted() + save_spendable_output() # Test that a block with too many checksigs is rejected - out6 = get_spendable_output() - too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50)) - block(16, spend=out6, script=too_many_checksigs) + too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS)) + block(16, spend=out[6], script=too_many_checksigs) yield rejected(RejectResult(16, b'bad-blk-sigops')) @@ -299,7 +327,7 @@ class FullBlockTest(ComparisonTestFramework): block(18, spend=txout_b3) yield rejected() - block(19, spend=out6) + block(19, spend=out[6]) yield rejected() # Attempt to spend a coinbase at depth too low @@ -307,8 +335,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7) # \-> b3 (1) -> b4 (2) tip(15) - out7 = get_spendable_output() - block(20, spend=out7) + block(20, spend=out[7]) yield rejected(RejectResult(16, b'bad-txns-premature-spend-of-coinbase')) # Attempt to spend a coinbase at depth too low (on a fork this time) @@ -317,10 +344,10 @@ class FullBlockTest(ComparisonTestFramework): # \-> b21 (6) -> b22 (5) # \-> b3 (1) -> b4 (2) tip(13) - block(21, spend=out6) + block(21, spend=out[6]) yield rejected() - block(22, spend=out5) + block(22, spend=out[5]) yield rejected() # Create a block on either side of MAX_BLOCK_SIZE and make sure its accepted/rejected @@ -329,21 +356,21 @@ class FullBlockTest(ComparisonTestFramework): # \-> b24 (6) -> b25 (7) # \-> b3 (1) -> b4 (2) tip(15) - b23 = block(23, spend=out6) - old_hash = b23.sha256 + b23 = block(23, spend=out[6]) tx = CTransaction() script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69 script_output = CScript([b'\x00' * script_length]) tx.vout.append(CTxOut(0, script_output)) - tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1))) + tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 0))) b23 = update_block(23, [tx]) # Make sure the math above worked out to produce a max-sized block assert_equal(len(b23.serialize()), MAX_BLOCK_SIZE) yield accepted() + save_spendable_output() # Make the next block one byte bigger and check that it fails tip(15) - b24 = block(24, spend=out6) + b24 = block(24, spend=out[6]) script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69 script_output = CScript([b'\x00' * (script_length+1)]) tx.vout = [CTxOut(0, script_output)] @@ -351,7 +378,7 @@ class FullBlockTest(ComparisonTestFramework): assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1) yield rejected(RejectResult(16, b'bad-blk-length')) - b25 = block(25, spend=out7) + block(25, spend=out[7]) yield rejected() # Create blocks with a coinbase input script size out of range @@ -360,7 +387,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> ... (6) -> ... (7) # \-> b3 (1) -> b4 (2) tip(15) - b26 = block(26, spend=out6) + b26 = block(26, spend=out[6]) b26.vtx[0].vin[0].scriptSig = b'\x00' b26.vtx[0].rehash() # update_block causes the merkle root to get updated, even with no new @@ -369,23 +396,20 @@ class FullBlockTest(ComparisonTestFramework): yield rejected(RejectResult(16, b'bad-cb-length')) # Extend the b26 chain to make sure bitcoind isn't accepting b26 - b27 = block(27, spend=out7) - yield rejected() + b27 = block(27, spend=out[7]) + yield rejected(RejectResult(16, b'bad-prevblk')) # Now try a too-large-coinbase script tip(15) - b28 = block(28, spend=out6) + b28 = block(28, spend=out[6]) b28.vtx[0].vin[0].scriptSig = b'\x00' * 101 b28.vtx[0].rehash() b28 = update_block(28, []) yield rejected(RejectResult(16, b'bad-cb-length')) - # Extend the b28 chain to make sure bitcoind isn't accepted b28 - b29 = block(29, spend=out7) - # TODO: Should get a reject message back with "bad-prevblk", except - # there's a bug that prevents this from being detected. Just note - # failure for now, and add the reject result later. - yield rejected() + # Extend the b28 chain to make sure bitcoind isn't accepting b28 + b29 = block(29, spend=out[7]) + yield rejected(RejectResult(16, b'bad-prevblk')) # b30 has a max-sized coinbase scriptSig. tip(23) @@ -394,6 +418,867 @@ class FullBlockTest(ComparisonTestFramework): b30.vtx[0].rehash() b30 = update_block(30, []) yield accepted() + save_spendable_output() + + # b31 - b35 - check sigops of OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY / OP_CHECKSIGVERIFY + # + # genesis -> ... -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) + # \-> b36 (11) + # \-> b34 (10) + # \-> b32 (9) + # + + # MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end. + lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS-1) // 20) + [OP_CHECKSIG] * 19) + b31 = block(31, spend=out[8], script=lots_of_multisigs) + assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS) + yield accepted() + save_spendable_output() + + # this goes over the limit because the coinbase has one sigop + too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20)) + b32 = block(32, spend=out[9], script=too_many_multisigs) + assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + + # CHECKMULTISIGVERIFY + tip(31) + lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS-1) // 20) + [OP_CHECKSIG] * 19) + block(33, spend=out[9], script=lots_of_multisigs) + yield accepted() + save_spendable_output() + + too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20)) + block(34, spend=out[10], script=too_many_multisigs) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + + # CHECKSIGVERIFY + tip(33) + lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1)) + b35 = block(35, spend=out[10], script=lots_of_checksigs) + yield accepted() + save_spendable_output() + + too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS)) + block(36, spend=out[11], script=too_many_checksigs) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + + # Check spending of a transaction in a block which failed to connect + # + # b6 (3) + # b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) + # \-> b37 (11) + # \-> b38 (11/37) + # + + # save 37's spendable output, but then double-spend out11 to invalidate the block + tip(35) + b37 = block(37, spend=out[11]) + txout_b37 = PreviousSpendableOutput(b37.vtx[1], 0) + tx = create_and_sign_tx(out[11].tx, out[11].n, 0) + b37 = update_block(37, [tx]) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + # attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid + tip(35) + block(38, spend=txout_b37) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + # Check P2SH SigOp counting + # + # + # 13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b41 (12) + # \-> b40 (12) + # + # b39 - create some P2SH outputs that will require 6 sigops to spend: + # + # redeem_script = COINBASE_PUBKEY, (OP_2DUP+OP_CHECKSIGVERIFY) * 5, OP_CHECKSIG + # p2sh_script = OP_HASH160, ripemd160(sha256(script)), OP_EQUAL + # + tip(35) + b39 = block(39) + b39_outputs = 0 + b39_sigops_per_output = 6 + + # Build the redeem script, hash it, use hash to create the p2sh script + redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY]*5 + [OP_CHECKSIG]) + redeem_script_hash = hash160(redeem_script) + p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL]) + + # Create a transaction that spends one satoshi to the p2sh_script, the rest to OP_TRUE + # This must be signed because it is spending a coinbase + spend = out[11] + tx = create_tx(spend.tx, spend.n, 1, p2sh_script) + tx.vout.append(CTxOut(spend.tx.vout[spend.n].nValue - 1, CScript([OP_TRUE]))) + self.sign_tx(tx, spend.tx, spend.n) + tx.rehash() + b39 = update_block(39, [tx]) + b39_outputs += 1 + + # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE + tx_new = None + tx_last = tx + total_size=len(b39.serialize()) + while(total_size < MAX_BLOCK_SIZE): + tx_new = create_tx(tx_last, 1, 1, p2sh_script) + tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) + tx_new.rehash() + total_size += len(tx_new.serialize()) + if total_size >= MAX_BLOCK_SIZE: + break + b39.vtx.append(tx_new) # add tx to block + tx_last = tx_new + b39_outputs += 1 + + b39 = update_block(39, []) + yield accepted() + save_spendable_output() + + + # Test sigops in P2SH redeem scripts + # + # b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops. + # The first tx has one sigop and then at the end we add 2 more to put us just over the max. + # + # b41 does the same, less one, so it has the maximum sigops permitted. + # + tip(39) + b40 = block(40, spend=out[12]) + sigops = get_legacy_sigopcount_block(b40) + numTxes = (MAX_BLOCK_SIGOPS - sigops) // b39_sigops_per_output + assert_equal(numTxes <= b39_outputs, True) + + lastOutpoint = COutPoint(b40.vtx[1].sha256, 0) + new_txs = [] + for i in range(1, numTxes+1): + tx = CTransaction() + tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) + tx.vin.append(CTxIn(lastOutpoint, b'')) + # second input is corresponding P2SH output from b39 + tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b'')) + # Note: must pass the redeem_script (not p2sh_script) to the signature hash function + (sighash, err) = SignatureHash(redeem_script, tx, 1, SIGHASH_ALL) + sig = self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL])) + scriptSig = CScript([sig, redeem_script]) + + tx.vin[1].scriptSig = scriptSig + tx.rehash() + new_txs.append(tx) + lastOutpoint = COutPoint(tx.sha256, 0) + + b40_sigops_to_fill = MAX_BLOCK_SIGOPS - (numTxes * b39_sigops_per_output + sigops) + 1 + tx = CTransaction() + tx.vin.append(CTxIn(lastOutpoint, b'')) + tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill))) + tx.rehash() + new_txs.append(tx) + update_block(40, new_txs) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + # same as b40, but one less sigop + tip(39) + b41 = block(41, spend=None) + update_block(41, b40.vtx[1:-1]) + b41_sigops_to_fill = b40_sigops_to_fill - 1 + tx = CTransaction() + tx.vin.append(CTxIn(lastOutpoint, b'')) + tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b41_sigops_to_fill))) + tx.rehash() + update_block(41, [tx]) + yield accepted() + + # Fork off of b39 to create a constant base again + # + # b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) + # \-> b41 (12) + # + tip(39) + block(42, spend=out[12]) + yield rejected() + save_spendable_output() + + block(43, spend=out[13]) + yield accepted() + save_spendable_output() + + + # Test a number of really invalid scenarios + # + # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14) + # \-> ??? (15) + + # The next few blocks are going to be created "by hand" since they'll do funky things, such as having + # the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works. + height = self.block_heights[self.tip.sha256] + 1 + coinbase = create_coinbase(height, self.coinbase_pubkey) + b44 = CBlock() + b44.nTime = self.tip.nTime + 1 + b44.hashPrevBlock = self.tip.sha256 + b44.nBits = 0x207fffff + b44.vtx.append(coinbase) + b44.hashMerkleRoot = b44.calc_merkle_root() + b44.solve() + self.tip = b44 + self.block_heights[b44.sha256] = height + self.blocks[44] = b44 + yield accepted() + + # A block with a non-coinbase as the first tx + non_coinbase = create_tx(out[15].tx, out[15].n, 1) + b45 = CBlock() + b45.nTime = self.tip.nTime + 1 + b45.hashPrevBlock = self.tip.sha256 + b45.nBits = 0x207fffff + b45.vtx.append(non_coinbase) + b45.hashMerkleRoot = b45.calc_merkle_root() + b45.calc_sha256() + b45.solve() + self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256]+1 + self.tip = b45 + self.blocks[45] = b45 + yield rejected(RejectResult(16, b'bad-cb-missing')) + + # A block with no txns + tip(44) + b46 = CBlock() + b46.nTime = b44.nTime+1 + b46.hashPrevBlock = b44.sha256 + b46.nBits = 0x207fffff + b46.vtx = [] + b46.hashMerkleRoot = 0 + b46.solve() + self.block_heights[b46.sha256] = self.block_heights[b44.sha256]+1 + self.tip = b46 + assert 46 not in self.blocks + self.blocks[46] = b46 + s = ser_uint256(b46.hashMerkleRoot) + yield rejected(RejectResult(16, b'bad-blk-length')) + + # A block with invalid work + tip(44) + b47 = block(47, solve=False) + target = uint256_from_compact(b47.nBits) + while b47.sha256 < target: #changed > to < + b47.nNonce += 1 + b47.rehash() + yield rejected(RejectResult(16, b'high-hash')) + + # A block with timestamp > 2 hrs in the future + tip(44) + b48 = block(48, solve=False) + b48.nTime = int(time.time()) + 60 * 60 * 3 + b48.solve() + yield rejected(RejectResult(16, b'time-too-new')) + + # A block with an invalid merkle hash + tip(44) + b49 = block(49) + b49.hashMerkleRoot += 1 + b49.solve() + yield rejected(RejectResult(16, b'bad-txnmrklroot')) + + # A block with an incorrect POW limit + tip(44) + b50 = block(50) + b50.nBits = b50.nBits - 1 + b50.solve() + yield rejected(RejectResult(16, b'bad-diffbits')) + + # A block with two coinbase txns + tip(44) + b51 = block(51) + cb2 = create_coinbase(51, self.coinbase_pubkey) + b51 = update_block(51, [cb2]) + yield rejected(RejectResult(16, b'bad-cb-multiple')) + + # A block w/ duplicate txns + # Note: txns have to be in the right position in the merkle tree to trigger this error + tip(44) + b52 = block(52, spend=out[15]) + tx = create_tx(b52.vtx[1], 0, 1) + b52 = update_block(52, [tx, tx]) + yield rejected(RejectResult(16, b'bad-txns-duplicate')) + + # Test block timestamps + # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) + # \-> b54 (15) + # + tip(43) + block(53, spend=out[14]) + yield rejected() # rejected since b44 is at same height + save_spendable_output() + + # invalid timestamp (b35 is 5 blocks back, so its time is MedianTimePast) + b54 = block(54, spend=out[15]) + b54.nTime = b35.nTime - 1 + b54.solve() + yield rejected(RejectResult(16, b'time-too-old')) + + # valid timestamp + tip(53) + b55 = block(55, spend=out[15]) + b55.nTime = b35.nTime + update_block(55, []) + yield accepted() + save_spendable_output() + + + # Test CVE-2012-2459 + # + # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16) + # \-> b57 (16) + # \-> b56p2 (16) + # \-> b56 (16) + # + # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without + # affecting the merkle root of a block, while still invalidating it. + # See: src/consensus/merkle.h + # + # b57 has three txns: coinbase, tx, tx1. The merkle root computation will duplicate tx. + # Result: OK + # + # b56 copies b57 but duplicates tx1 and does not recalculate the block hash. So it has a valid merkle + # root but duplicate transactions. + # Result: Fails + # + # b57p2 has six transactions in its merkle tree: + # - coinbase, tx, tx1, tx2, tx3, tx4 + # Merkle root calculation will duplicate as necessary. + # Result: OK. + # + # b56p2 copies b57p2 but adds both tx3 and tx4. The purpose of the test is to make sure the code catches + # duplicate txns that are not next to one another with the "bad-txns-duplicate" error (which indicates + # that the error was caught early, avoiding a DOS vulnerability.) + + # b57 - a good block with 2 txs, don't submit until end + tip(55) + b57 = block(57) + tx = create_and_sign_tx(out[16].tx, out[16].n, 1) + tx1 = create_tx(tx, 0, 1) + b57 = update_block(57, [tx, tx1]) + + # b56 - copy b57, add a duplicate tx + tip(55) + b56 = copy.deepcopy(b57) + self.blocks[56] = b56 + assert_equal(len(b56.vtx),3) + b56 = update_block(56, [tx1]) + assert_equal(b56.hash, b57.hash) + yield rejected(RejectResult(16, b'bad-txns-duplicate')) + + # b57p2 - a good block with 6 tx'es, don't submit until end + tip(55) + b57p2 = block("57p2") + tx = create_and_sign_tx(out[16].tx, out[16].n, 1) + tx1 = create_tx(tx, 0, 1) + tx2 = create_tx(tx1, 0, 1) + tx3 = create_tx(tx2, 0, 1) + tx4 = create_tx(tx3, 0, 1) + b57p2 = update_block("57p2", [tx, tx1, tx2, tx3, tx4]) + + # b56p2 - copy b57p2, duplicate two non-consecutive tx's + tip(55) + b56p2 = copy.deepcopy(b57p2) + self.blocks["b56p2"] = b56p2 + assert_equal(b56p2.hash, b57p2.hash) + assert_equal(len(b56p2.vtx),6) + b56p2 = update_block("b56p2", [tx3, tx4]) + yield rejected(RejectResult(16, b'bad-txns-duplicate')) + + tip("57p2") + yield accepted() + + tip(57) + yield rejected() #rejected because 57p2 seen first + save_spendable_output() + + # Test a few invalid tx types + # + # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) + # \-> ??? (17) + # + + # tx with prevout.n out of range + tip(57) + b58 = block(58, spend=out[17]) + tx = CTransaction() + assert(len(out[17].tx.vout) < 42) + tx.vin.append(CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) + tx.vout.append(CTxOut(0, b"")) + tx.calc_sha256() + b58 = update_block(58, [tx]) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + # tx with output value > input value out of range + tip(57) + b59 = block(59) + tx = create_and_sign_tx(out[17].tx, out[17].n, 51*COIN) + b59 = update_block(59, [tx]) + yield rejected(RejectResult(16, b'bad-txns-in-belowout')) + + # reset to good chain + tip(57) + b60 = block(60, spend=out[17]) + yield accepted() + save_spendable_output() + + # Test BIP30 + # + # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) + # \-> b61 (18) + # + # Blocks are not allowed to contain a transaction whose id matches that of an earlier, + # not-fully-spent transaction in the same chain. To test, make identical coinbases; + # the second one should be rejected. + # + tip(60) + b61 = block(61, spend=out[18]) + b61.vtx[0].vin[0].scriptSig = b60.vtx[0].vin[0].scriptSig #equalize the coinbases + b61.vtx[0].rehash() + b61 = update_block(61, []) + assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize()) + yield rejected(RejectResult(16, b'bad-txns-BIP30')) + + + # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests) + # + # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) + # \-> b62 (18) + # + tip(60) + b62 = block(62) + tx = CTransaction() + tx.nLockTime = 0xffffffff #this locktime is non-final + assert(out[18].n < len(out[18].tx.vout)) + tx.vin.append(CTxIn(COutPoint(out[18].tx.sha256, out[18].n))) # don't set nSequence + tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) + assert(tx.vin[0].nSequence < 0xffffffff) + tx.calc_sha256() + b62 = update_block(62, [tx]) + yield rejected(RejectResult(16, b'bad-txns-nonfinal')) + + + # Test a non-final coinbase is also rejected + # + # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) + # \-> b63 (-) + # + tip(60) + b63 = block(63) + b63.vtx[0].nLockTime = 0xffffffff + b63.vtx[0].vin[0].nSequence = 0xDEADBEEF + b63.vtx[0].rehash() + b63 = update_block(63, []) + yield rejected(RejectResult(16, b'bad-txns-nonfinal')) + + + # This checks that a block with a bloated VARINT between the block_header and the array of tx is rejected + # (previous behavior was that it was accepted.) It also checks that if you subsequently send that block + # with correct encoding, it should be accepted (i.e., the receiving node should not reject it on the + # basis that it's the same as an already-rejected block, which would be a DoS vulnerability.) + # + # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) + # \ + # b64a (18) + # b64a is a bloated block (non-canonical varint) + # b64 is a good block (same as b64 but w/ canonical varint) + # + tip(60) + regular_block = block("64a", spend=out[18]) + + # make it a "broken_block," with non-canonical serialization + b64a = CBrokenBlock(regular_block) + b64a.initialize(regular_block) + self.blocks["64a"] = b64a + self.tip = b64a + tx = CTransaction() + + # use canonical serialization to calculate size + script_length = MAX_BLOCK_SIZE - len(b64a.normal_serialize()) - 69 + script_output = CScript([b'\x00' * script_length]) + tx.vout.append(CTxOut(0, script_output)) + tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0))) + b64a = update_block("64a", [tx]) + assert_equal(len(b64a.serialize()), MAX_BLOCK_SIZE + 8) + yield rejected() + + # comptool workaround: to make sure b64 is delivered, manually erase b64a from blockstore + self.test.block_store.erase(b64a.sha256) + + tip(60) + b64 = CBlock(b64a) + b64.vtx = copy.deepcopy(b64a.vtx) + assert_equal(b64.hash, b64a.hash) + assert_equal(len(b64.serialize()), MAX_BLOCK_SIZE) + self.blocks[64] = b64 + update_block(64, []) + yield accepted() + save_spendable_output() + + # Spend an output created in the block itself + # + # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) + # + tip(64) + b65 = block(65) + tx1 = create_and_sign_tx(out[19].tx, out[19].n, out[19].tx.vout[0].nValue) + tx2 = create_and_sign_tx(tx1, 0, 0) + update_block(65, [tx1, tx2]) + yield accepted() + save_spendable_output() + + # Attempt to spend an output created later in the same block + # + # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) + # \-> b66 (20) + tip(65) + b66 = block(66) + tx1 = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue) + tx2 = create_and_sign_tx(tx1, 0, 1) + update_block(66, [tx2, tx1]) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + + # Attempt to double-spend a transaction created in a block + # + # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) + # \-> b67 (20) + # + # + tip(65) + b67 = block(67) + tx1 = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue) + tx2 = create_and_sign_tx(tx1, 0, 1) + tx3 = create_and_sign_tx(tx1, 0, 2) + update_block(67, [tx1, tx2, tx3]) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + # More tests of block subsidy + # + # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) + # \-> b68 (20) + # + # b68 - coinbase with an extra 10 satoshis, + # creates a tx that has 9 satoshis from out[20] go to fees + # this fails because the coinbase is trying to claim 1 satoshi too much in fees + # + # b69 - coinbase with extra 10 satoshis, and a tx that gives a 10 satoshi fee + # this succeeds + # + tip(65) + b68 = block(68, additional_coinbase_value=10) + tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-9) + update_block(68, [tx]) + yield rejected(RejectResult(16, b'bad-cb-amount')) + + tip(65) + b69 = block(69, additional_coinbase_value=10) + tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-10) + update_block(69, [tx]) + yield accepted() + save_spendable_output() + + # Test spending the outpoint of a non-existent transaction + # + # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) + # \-> b70 (21) + # + tip(69) + block(70, spend=out[21]) + bogus_tx = CTransaction() + bogus_tx.sha256 = uint256_from_str(b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff)) + tx.vout.append(CTxOut(1, b"")) + update_block(70, [tx]) + yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) + + + # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) + # + # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) + # \-> b71 (21) + # + # b72 is a good block. + # b71 is a copy of 72, but re-adds one of its transactions. However, it has the same hash as b71. + # + tip(69) + b72 = block(72) + tx1 = create_and_sign_tx(out[21].tx, out[21].n, 2) + tx2 = create_and_sign_tx(tx1, 0, 1) + b72 = update_block(72, [tx1, tx2]) # now tip is 72 + b71 = copy.deepcopy(b72) + b71.vtx.append(tx2) # add duplicate tx2 + self.block_heights[b71.sha256] = self.block_heights[b69.sha256] + 1 # b71 builds off b69 + self.blocks[71] = b71 + + assert_equal(len(b71.vtx), 4) + assert_equal(len(b72.vtx), 3) + assert_equal(b72.sha256, b71.sha256) + + tip(71) + yield rejected(RejectResult(16, b'bad-txns-duplicate')) + tip(72) + yield accepted() + save_spendable_output() + + + # Test some invalid scripts and MAX_BLOCK_SIGOPS + # + # -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) + # \-> b** (22) + # + + # b73 - tx with excessive sigops that are placed after an excessively large script element. + # The purpose of the test is to make sure those sigops are counted. + # + # script is a bytearray of size 20,526 + # + # bytearray[0-19,998] : OP_CHECKSIG + # bytearray[19,999] : OP_PUSHDATA4 + # bytearray[20,000-20,003]: 521 (max_script_element_size+1, in little-endian format) + # bytearray[20,004-20,525]: unread data (script_element) + # bytearray[20,526] : OP_CHECKSIG (this puts us over the limit) + # + tip(72) + b73 = block(73) + size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1 + a = bytearray([OP_CHECKSIG] * size) + a[MAX_BLOCK_SIGOPS - 1] = int("4e",16) # OP_PUSHDATA4 + + element_size = MAX_SCRIPT_ELEMENT_SIZE + 1 + a[MAX_BLOCK_SIGOPS] = element_size % 256 + a[MAX_BLOCK_SIGOPS+1] = element_size // 256 + a[MAX_BLOCK_SIGOPS+2] = 0 + a[MAX_BLOCK_SIGOPS+3] = 0 + + tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) + b73 = update_block(73, [tx]) + assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS+1) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + # b74/75 - if we push an invalid script element, all prevous sigops are counted, + # but sigops after the element are not counted. + # + # The invalid script element is that the push_data indicates that + # there will be a large amount of data (0xffffff bytes), but we only + # provide a much smaller number. These bytes are CHECKSIGS so they would + # cause b75 to fail for excessive sigops, if those bytes were counted. + # + # b74 fails because we put MAX_BLOCK_SIGOPS+1 before the element + # b75 succeeds because we put MAX_BLOCK_SIGOPS before the element + # + # + tip(72) + b74 = block(74) + size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561 + a = bytearray([OP_CHECKSIG] * size) + a[MAX_BLOCK_SIGOPS] = 0x4e + a[MAX_BLOCK_SIGOPS+1] = 0xfe + a[MAX_BLOCK_SIGOPS+2] = 0xff + a[MAX_BLOCK_SIGOPS+3] = 0xff + a[MAX_BLOCK_SIGOPS+4] = 0xff + tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) + b74 = update_block(74, [tx]) + yield rejected(RejectResult(16, b'bad-blk-sigops')) + + tip(72) + b75 = block(75) + size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 + a = bytearray([OP_CHECKSIG] * size) + a[MAX_BLOCK_SIGOPS-1] = 0x4e + a[MAX_BLOCK_SIGOPS] = 0xff + a[MAX_BLOCK_SIGOPS+1] = 0xff + a[MAX_BLOCK_SIGOPS+2] = 0xff + a[MAX_BLOCK_SIGOPS+3] = 0xff + tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) + b75 = update_block(75, [tx]) + yield accepted() + save_spendable_output() + + # Check that if we push an element filled with CHECKSIGs, they are not counted + tip(75) + b76 = block(76) + size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + a = bytearray([OP_CHECKSIG] * size) + a[MAX_BLOCK_SIGOPS-1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs + tx = create_and_sign_tx(out[23].tx, 0, 1, CScript(a)) + b76 = update_block(76, [tx]) + yield accepted() + save_spendable_output() + + # Test transaction resurrection + # + # -> b77 (24) -> b78 (25) -> b79 (26) + # \-> b80 (25) -> b81 (26) -> b82 (27) + # + # b78 creates a tx, which is spent in b79. After b82, both should be in mempool + # + # The tx'es must be unsigned and pass the node's mempool policy. It is unsigned for the + # rather obscure reason that the Python signature code does not distinguish between + # Low-S and High-S values (whereas the bitcoin code has custom code which does so); + # as a result of which, the odds are 50% that the python code will use the right + # value and the transaction will be accepted into the mempool. Until we modify the + # test framework to support low-S signing, we are out of luck. + # + # To get around this issue, we construct transactions which are not signed and which + # spend to OP_TRUE. If the standard-ness rules change, this test would need to be + # updated. (Perhaps to spend to a P2SH OP_TRUE script) + # + tip(76) + block(77) + tx77 = create_and_sign_tx(out[24].tx, out[24].n, 10*COIN) + update_block(77, [tx77]) + yield accepted() + save_spendable_output() + + block(78) + tx78 = create_tx(tx77, 0, 9*COIN) + update_block(78, [tx78]) + yield accepted() + + block(79) + tx79 = create_tx(tx78, 0, 8*COIN) + update_block(79, [tx79]) + yield accepted() + + # mempool should be empty + assert_equal(len(self.nodes[0].getrawmempool()), 0) + + tip(77) + block(80, spend=out[25]) + yield rejected() + save_spendable_output() + + block(81, spend=out[26]) + yield rejected() # other chain is same length + save_spendable_output() + + block(82, spend=out[27]) + yield accepted() # now this chain is longer, triggers re-org + save_spendable_output() + + # now check that tx78 and tx79 have been put back into the peer's mempool + mempool = self.nodes[0].getrawmempool() + assert_equal(len(mempool), 2) + assert(tx78.hash in mempool) + assert(tx79.hash in mempool) + + + # Test invalid opcodes in dead execution paths. + # + # -> b81 (26) -> b82 (27) -> b83 (28) + # + b83 = block(83) + op_codes = [OP_IF, OP_INVALIDOPCODE, OP_ELSE, OP_TRUE, OP_ENDIF] + script = CScript(op_codes) + tx1 = create_and_sign_tx(out[28].tx, out[28].n, out[28].tx.vout[0].nValue, script) + + tx2 = create_and_sign_tx(tx1, 0, 0, CScript([OP_TRUE])) + tx2.vin[0].scriptSig = CScript([OP_FALSE]) + tx2.rehash() + + update_block(83, [tx1, tx2]) + yield accepted() + save_spendable_output() + + + # Reorg on/off blocks that have OP_RETURN in them (and try to spend them) + # + # -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) + # \-> b85 (29) -> b86 (30) \-> b89a (32) + # + # + b84 = block(84) + tx1 = create_tx(out[29].tx, out[29].n, 0, CScript([OP_RETURN])) + tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) + tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) + tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) + tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) + tx1.calc_sha256() + self.sign_tx(tx1, out[29].tx, out[29].n) + tx1.rehash() + tx2 = create_tx(tx1, 1, 0, CScript([OP_RETURN])) + tx2.vout.append(CTxOut(0, CScript([OP_RETURN]))) + tx3 = create_tx(tx1, 2, 0, CScript([OP_RETURN])) + tx3.vout.append(CTxOut(0, CScript([OP_TRUE]))) + tx4 = create_tx(tx1, 3, 0, CScript([OP_TRUE])) + tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) + tx5 = create_tx(tx1, 4, 0, CScript([OP_RETURN])) + + update_block(84, [tx1,tx2,tx3,tx4,tx5]) + yield accepted() + save_spendable_output() + + tip(83) + block(85, spend=out[29]) + yield rejected() + + block(86, spend=out[30]) + yield accepted() + + tip(84) + block(87, spend=out[30]) + yield rejected() + save_spendable_output() + + block(88, spend=out[31]) + yield accepted() + save_spendable_output() + + # trying to spend the OP_RETURN output is rejected + block("89a", spend=out[32]) + tx = create_tx(tx1, 0, 0, CScript([OP_TRUE])) + update_block("89a", [tx]) + yield rejected() + + + # Test re-org of a week's worth of blocks (1088 blocks) + # This test takes a minute or two and can be accomplished in memory + # + tip(88) + LARGE_REORG_SIZE = 1088 + test1 = TestInstance(sync_every_block=False) + spend=out[32] + for i in range(89, LARGE_REORG_SIZE + 89): + b = block(i, spend) + tx = CTransaction() + script_length = MAX_BLOCK_SIZE - len(b.serialize()) - 69 + script_output = CScript([b'\x00' * script_length]) + tx.vout.append(CTxOut(0, script_output)) + tx.vin.append(CTxIn(COutPoint(b.vtx[1].sha256, 0))) + b = update_block(i, [tx]) + assert_equal(len(b.serialize()), MAX_BLOCK_SIZE) + test1.blocks_and_transactions.append([self.tip, True]) + save_spendable_output() + spend = get_spendable_output() + + yield test1 + chain1_tip = i + + # now create alt chain of same length + tip(88) + test2 = TestInstance(sync_every_block=False) + for i in range(89, LARGE_REORG_SIZE + 89): + block("alt"+str(i)) + test2.blocks_and_transactions.append([self.tip, False]) + yield test2 + + # extend alt chain to trigger re-org + block("alt" + str(chain1_tip + 1)) + yield accepted() + + # ... and re-org back to the first chain + tip(chain1_tip) + block(chain1_tip + 1) + yield rejected() + block(chain1_tip + 2) + yield accepted() + + chain1_tip += 2 if __name__ == '__main__': diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 44232153a..26cc39631 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -56,12 +56,27 @@ def create_coinbase(height, pubkey = None): coinbase.calc_sha256() return coinbase -# Create a transaction with an anyone-can-spend output, that spends the -# nth output of prevtx. -def create_transaction(prevtx, n, sig, value): +# Create a transaction. +# If the scriptPubKey is not specified, make it anyone-can-spend. +def create_transaction(prevtx, n, sig, value, scriptPubKey=CScript()): tx = CTransaction() assert(n < len(prevtx.vout)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) - tx.vout.append(CTxOut(value, b"")) + tx.vout.append(CTxOut(value, scriptPubKey)) tx.calc_sha256() return tx + +def get_legacy_sigopcount_block(block, fAccurate=True): + count = 0 + for tx in block.vtx: + count += get_legacy_sigopcount_tx(tx, fAccurate) + return count + +def get_legacy_sigopcount_tx(tx, fAccurate=True): + count = 0 + for i in tx.vout: + count += i.scriptPubKey.GetSigOpCount(fAccurate) + for j in tx.vin: + # scriptSig might be of type bytes, so convert to CScript for the moment + count += CScript(j.scriptSig).GetSigOpCount(fAccurate) + return count diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index e85399c96..c0b59f385 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -556,7 +556,6 @@ class CBlock(CBlockHeader): self.nNonce += 1 self.rehash() - def __repr__(self): return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \ % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, From 12c5a16c4e635799cfb6cadbca79dfa83555da72 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Thu, 2 Jun 2016 14:43:18 -0400 Subject: [PATCH 0708/1223] Catch exceptions from non-canonical encoding and print only to log --- src/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ed157b53d..885b1b56f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5567,6 +5567,11 @@ bool ProcessMessages(CNode* pfrom) // Allow exceptions from over-long size LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); } + else if (strstr(e.what(), "non-canonical ReadCompactSize()")) + { + // Allow exceptions from non-canonical encoding + LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); + } else { PrintExceptionContinue(&e, "ProcessMessages()"); From 9805f4af7ecb6becf8a146bd845fb131ffa625c9 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Sat, 30 Apr 2016 21:45:26 -0700 Subject: [PATCH 0709/1223] mapNextTx: use pointer as key, simplify value Saves about 10% of application memory usage once the mempool warms up. Since the mempool is DynamicUsage-regulated, this will translate to a larger mempool in the same amount of space. Map value type: eliminate the vin index; no users of the map need to know which input of the transaction is spending the prevout. Map key type: replace the COutPoint with a pointer to a COutPoint. A COutPoint is 36 bytes, but each COutPoint is accessible from the same map entry's value. A trivial DereferencingComparator functor allows indirect map keys, but the resulting syntax is misleading: `map.find(&outpoint)`. Implement an indirectmap that acts as a wrapper to a map that uses a DereferencingComparator, supporting a syntax that accurately reflect the container's semantics: inserts and iterators use pointers since they store pointers and need them to remain constant and dereferenceable, but lookup functions take const references. --- src/Makefile.am | 1 + src/indirectmap.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 5 +++-- src/memusage.h | 16 +++++++++++++++ src/txmempool.cpp | 46 ++++++++++++++++++++--------------------- src/txmempool.h | 17 ++-------------- 6 files changed, 96 insertions(+), 41 deletions(-) create mode 100644 src/indirectmap.h diff --git a/src/Makefile.am b/src/Makefile.am index 3c056386f..ad61e4f10 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,6 +94,7 @@ BITCOIN_CORE_H = \ core_memusage.h \ httprpc.h \ httpserver.h \ + indirectmap.h \ init.h \ key.h \ keystore.h \ diff --git a/src/indirectmap.h b/src/indirectmap.h new file mode 100644 index 000000000..28e1e8ded --- /dev/null +++ b/src/indirectmap.h @@ -0,0 +1,52 @@ +#ifndef BITCOIN_INDIRECTMAP_H +#define BITCOIN_INDIRECTMAP_H + +template +struct DereferencingComparator { bool operator()(const T a, const T b) const { return *a < *b; } }; + +/* Map whose keys are pointers, but are compared by their dereferenced values. + * + * Differs from a plain std::map > in + * that methods that take a key for comparison take a K rather than taking a K* + * (taking a K* would be confusing, since it's the value rather than the address + * of the object for comparison that matters due to the dereferencing comparator). + * + * Objects pointed to by keys must not be modified in any way that changes the + * result of DereferencingComparator. + */ +template +class indirectmap { +private: + typedef std::map > base; + base m; +public: + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + typedef typename base::size_type size_type; + typedef typename base::value_type value_type; + + // passthrough (pointer interface) + std::pair insert(const value_type& value) { return m.insert(value); } + + // pass address (value interface) + iterator find(const K& key) { return m.find(&key); } + const_iterator find(const K& key) const { return m.find(&key); } + iterator lower_bound(const K& key) { return m.lower_bound(&key); } + const_iterator lower_bound(const K& key) const { return m.lower_bound(&key); } + size_type erase(const K& key) { return m.erase(&key); } + size_type count(const K& key) const { return m.count(&key); } + + // passthrough + bool empty() const { return m.empty(); } + size_type size() const { return m.size(); } + size_type max_size() const { return m.max_size(); } + void clear() { m.clear(); } + iterator begin() { return m.begin(); } + iterator end() { return m.end(); } + const_iterator begin() const { return m.begin(); } + const_iterator end() const { return m.end(); } + const_iterator cbegin() const { return m.cbegin(); } + const_iterator cend() const { return m.cend(); } +}; + +#endif // BITCOIN_INDIRECTMAP_H diff --git a/src/main.cpp b/src/main.cpp index 11ccab253..13da2137e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1049,9 +1049,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C LOCK(pool.cs); // protect pool.mapNextTx BOOST_FOREACH(const CTxIn &txin, tx.vin) { - if (pool.mapNextTx.count(txin.prevout)) + auto itConflicting = pool.mapNextTx.find(txin.prevout); + if (itConflicting != pool.mapNextTx.end()) { - const CTransaction *ptxConflicting = pool.mapNextTx[txin.prevout].ptx; + const CTransaction *ptxConflicting = itConflicting->second; if (!setConflicts.count(ptxConflicting->GetHash())) { // Allow opt-out of transaction replacement by setting diff --git a/src/memusage.h b/src/memusage.h index 49760e64c..9c98e5c2c 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_MEMUSAGE_H #define BITCOIN_MEMUSAGE_H +#include "indirectmap.h" + #include #include @@ -106,6 +108,20 @@ static inline size_t IncrementalDynamicUsage(const std::map& m) return MallocUsage(sizeof(stl_tree_node >)); } +// indirectmap has underlying map with pointer as key + +template +static inline size_t DynamicUsage(const indirectmap& m) +{ + return MallocUsage(sizeof(stl_tree_node >)) * m.size(); +} + +template +static inline size_t IncrementalDynamicUsage(const indirectmap& m) +{ + return MallocUsage(sizeof(stl_tree_node >)); +} + // Boost data structures template diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52c779311..d7fb77661 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -147,11 +147,11 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes if (it == mapTx.end()) { continue; } - std::map::iterator iter = mapNextTx.lower_bound(COutPoint(hash, 0)); + auto iter = mapNextTx.lower_bound(COutPoint(hash, 0)); // First calculate the children, and update setMemPoolChildren to // include them, and update their setMemPoolParents to include this tx. - for (; iter != mapNextTx.end() && iter->first.hash == hash; ++iter) { - const uint256 &childHash = iter->second.ptx->GetHash(); + for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) { + const uint256 &childHash = iter->second->GetHash(); txiter childIter = mapTx.find(childHash); assert(childIter != mapTx.end()); // We can skip updating entries we've encountered before or that @@ -365,11 +365,11 @@ void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins) { LOCK(cs); - std::map::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0)); + auto it = mapNextTx.lower_bound(COutPoint(hashTx, 0)); // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx - while (it != mapNextTx.end() && it->first.hash == hashTx) { - coins.Spend(it->first.n); // and remove those outputs from coins + while (it != mapNextTx.end() && it->first->hash == hashTx) { + coins.Spend(it->first->n); // and remove those outputs from coins it++; } } @@ -414,7 +414,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, const CTransaction& tx = newit->GetTx(); std::set setParentTransactions; for (unsigned int i = 0; i < tx.vin.size(); i++) { - mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); + mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx)); setParentTransactions.insert(tx.vin[i].prevout.hash); } // Don't bother worrying about child transactions of this one. @@ -500,10 +500,10 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, std::list::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); + auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); if (it == mapNextTx.end()) continue; - txiter nextit = mapTx.find(it->second.ptx->GetHash()); + txiter nextit = mapTx.find(it->second->GetHash()); assert(nextit != mapTx.end()); txToRemove.insert(nextit); } @@ -561,9 +561,9 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list list result; LOCK(cs); BOOST_FOREACH(const CTxIn &txin, tx.vin) { - std::map::iterator it = mapNextTx.find(txin.prevout); + auto it = mapNextTx.find(txin.prevout); if (it != mapNextTx.end()) { - const CTransaction &txConflict = *it->second.ptx; + const CTransaction &txConflict = *it->second; if (txConflict != tx) { removeRecursive(txConflict, removed); @@ -671,10 +671,10 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(coins && coins->IsAvailable(txin.prevout.n)); } // Check whether its inputs are marked in mapNextTx. - std::map::const_iterator it3 = mapNextTx.find(txin.prevout); + auto it3 = mapNextTx.find(txin.prevout); assert(it3 != mapNextTx.end()); - assert(it3->second.ptx == &tx); - assert(it3->second.n == i); + assert(it3->first == &txin.prevout); + assert(it3->second == &tx); i++; } assert(setParentCheck == GetMemPoolParents(it)); @@ -701,10 +701,10 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const // Check children against mapNextTx CTxMemPool::setEntries setChildrenCheck; - std::map::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); + auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; - for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { - txiter childit = mapTx.find(iter->second.ptx->GetHash()); + for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) { + txiter childit = mapTx.find(iter->second->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); @@ -738,14 +738,12 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const stepsSinceLastRemove = 0; } } - for (std::map::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) { - uint256 hash = it->second.ptx->GetHash(); + for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { + uint256 hash = it->second->GetHash(); indexed_transaction_set::const_iterator it2 = mapTx.find(hash); const CTransaction& tx = it2->GetTx(); assert(it2 != mapTx.end()); - assert(&tx == it->second.ptx); - assert(tx.vin.size() > it->second.n); - assert(it->first == it->second.ptx->vin[it->second.n].prevout); + assert(&tx == it->second); } assert(totalTxSize == checkTotal); @@ -1044,8 +1042,8 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe BOOST_FOREACH(const CTxIn& txin, tx.vin) { if (exists(txin.prevout.hash)) continue; - std::map::iterator it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0)); - if (it == mapNextTx.end() || it->first.hash != txin.prevout.hash) + auto it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0)); + if (it == mapNextTx.end() || it->first->hash != txin.prevout.hash) pvNoSpendsRemaining->push_back(txin.prevout.hash); } } diff --git a/src/txmempool.h b/src/txmempool.h index de4ba0b37..7ad5579a0 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -11,6 +11,7 @@ #include "amount.h" #include "coins.h" +#include "indirectmap.h" #include "primitives/transaction.h" #include "sync.h" @@ -305,20 +306,6 @@ struct ancestor_score {}; class CBlockPolicyEstimator; -/** An inpoint - a combination of a transaction and an index n into its vin */ -class CInPoint -{ -public: - const CTransaction* ptx; - uint32_t n; - - CInPoint() { SetNull(); } - CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } - void SetNull() { ptx = NULL; n = (uint32_t) -1; } - bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } - size_t DynamicMemoryUsage() const { return 0; } -}; - /** * CTxMemPool stores valid-according-to-the-current-best-chain * transactions that may be included in the next block. @@ -477,7 +464,7 @@ private: void UpdateChild(txiter entry, txiter child, bool add); public: - std::map mapNextTx; + indirectmap mapNextTx; std::map > mapDeltas; /** Create a new CTxMemPool. From e39dc698adf46dc3306526971ca6f0f6401f30ca Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 3 Jun 2016 10:05:51 -0400 Subject: [PATCH 0710/1223] comment nit: miners don't vote --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c98f42d7c..527d4f570 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1886,8 +1886,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // such nodes as they are not following the protocol. That // said during an upgrade careful thought should be taken // as to the correct behavior - we may want to continue - // peering with non-upgraded nodes even after a soft-fork - // super-majority vote has passed. + // peering with non-upgraded nodes even after soft-fork + // super-majority signaling has occurred. return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError()))); } } From 340012d9c978901d23ccedad5805c6630c49e756 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 3 Jun 2016 14:00:38 -0400 Subject: [PATCH 0711/1223] build: add temporary fix for "bad magic number" error in out-of-tree builds This was caused by an pyc files hanging around from previous python2 invocations, when the matching .py missing from that path. This should not be a problem with python3's tagged caches. --- Makefile.am | 3 +++ src/Makefile.test.include | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Makefile.am b/Makefile.am index b93748e32..b10d08506 100644 --- a/Makefile.am +++ b/Makefile.am @@ -224,6 +224,9 @@ EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc- CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) +# This file is problematic for out-of-tree builds if it exists. +DISTCLEANFILES = qa/pull-tester/tests_config.pyc + .INTERMEDIATE: $(COVERAGE_INFO) clean-local: diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 77cf1001e..ff3351fe7 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -123,6 +123,9 @@ CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES) CLEANFILES += $(CLEAN_BITCOIN_TEST) +# This file is problematic for out-of-tree builds if it exists. +DISTCLEANFILES += test/buildenv.pyc + bitcoin_test: $(TEST_BINARY) bitcoin_test_check: $(TEST_BINARY) FORCE From 1b9e6d3c1a0f0e7eeff5ddb2e0386911fe9ab2b6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 30 May 2016 16:50:14 +0200 Subject: [PATCH 0712/1223] Add support for unique_ptr and shared_ptr to memusage --- src/memusage.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/memusage.h b/src/memusage.h index 9c98e5c2c..3810bfad0 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -72,6 +72,15 @@ private: X x; }; +struct stl_shared_counter +{ + /* Various platforms use different sized counters here. + * Conservatively assume that they won't be larger than size_t. */ + void* class_type; + size_t use_count; + size_t weak_count; +}; + template static inline size_t DynamicUsage(const std::vector& v) { @@ -122,6 +131,21 @@ static inline size_t IncrementalDynamicUsage(const indirectmap& m) return MallocUsage(sizeof(stl_tree_node >)); } +template +static inline size_t DynamicUsage(const std::unique_ptr& p) +{ + return p ? MallocUsage(sizeof(X)) : 0; +} + +template +static inline size_t DynamicUsage(const std::shared_ptr& p) +{ + // A shared_ptr can either use a single continuous memory block for both + // the counter and the storage (when using std::make_shared), or separate. + // We can't observe the difference, however, so assume the worst. + return p ? MallocUsage(sizeof(X)) + MallocUsage(sizeof(stl_shared_counter)) : 0; +} + // Boost data structures template From 8d39d7a2cf1559e0ba40681b0ab90f13ea6c0618 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 30 May 2016 17:06:24 +0200 Subject: [PATCH 0713/1223] Switch CTransaction storage in mempool to std::shared_ptr --- src/main.cpp | 32 +++++++--------- src/txmempool.cpp | 96 ++++++++++++++++++++++++++++++++--------------- src/txmempool.h | 28 ++++++++++++-- 3 files changed, 103 insertions(+), 53 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 527d4f570..d71f35bf7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4519,10 +4519,11 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } if (!push && inv.type == MSG_TX) { - int64_t txtime; + auto txinfo = mempool.info(inv.hash); // To protect privacy, do not answer getdata using the mempool when // that TX couldn't have been INVed in reply to a MEMPOOL request. - if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) { + if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) { + tx = *txinfo.tx; push = true; } } @@ -5900,8 +5901,7 @@ bool SendMessages(CNode* pto) // Respond to BIP35 mempool requests if (fSendTrickle && pto->fSendMempool) { - std::vector vtxid; - mempool.queryHashes(vtxid); + auto vtxinfo = mempool.infoAll(); pto->fSendMempool = false; CAmount filterrate = 0; { @@ -5911,20 +5911,16 @@ bool SendMessages(CNode* pto) LOCK(pto->cs_filter); - BOOST_FOREACH(const uint256& hash, vtxid) { + for (const auto& txinfo : vtxinfo) { + const uint256& hash = txinfo.tx->GetHash(); CInv inv(MSG_TX, hash); pto->setInventoryTxToSend.erase(hash); if (filterrate) { - CFeeRate feeRate; - mempool.lookupFeeRate(hash, feeRate); - if (feeRate.GetFeePerK() < filterrate) + if (txinfo.feeRate.GetFeePerK() < filterrate) continue; } if (pto->pfilter) { - CTransaction tx; - bool fInMemPool = mempool.lookup(hash, tx); - if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... - if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue; + if (!pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue; } pto->filterInventoryKnown.insert(hash); vInv.push_back(inv); @@ -5970,16 +5966,14 @@ bool SendMessages(CNode* pto) continue; } // Not in the mempool anymore? don't bother sending it. - CFeeRate feeRate; - if (!mempool.lookupFeeRate(hash, feeRate)) { + auto txinfo = mempool.info(hash); + if (!txinfo.tx) { continue; } - if (filterrate && feeRate.GetFeePerK() < filterrate) { + if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) { continue; } - CTransaction tx; - if (!mempool.lookup(hash, tx)) continue; - if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue; + if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue; // Send vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; @@ -5992,7 +5986,7 @@ bool SendMessages(CNode* pto) vRelayExpiration.pop_front(); } - auto ret = mapRelay.insert(std::make_pair(hash, tx)); + auto ret = mapRelay.insert(std::make_pair(hash, *txinfo.tx)); if (ret.second) { vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash)); } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index f44e45036..d39c9577f 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -23,18 +23,18 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp): - tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), + tx(std::make_shared(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp) { - nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - nModSize = tx.CalculateModifiedSize(nTxSize); - nUsageSize = RecursiveDynamicUsage(tx); + nTxSize = ::GetSerializeSize(_tx, SER_NETWORK, PROTOCOL_VERSION); + nModSize = _tx.CalculateModifiedSize(nTxSize); + nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; nModFeesWithDescendants = nFee; - CAmount nValueIn = tx.GetValueOut()+nFee; + CAmount nValueIn = _tx.GetValueOut()+nFee; assert(inChainInputValue <= nValueIn); feeDelta = 0; @@ -768,50 +768,86 @@ bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb namespace { class DepthAndScoreComparator { - CTxMemPool *mp; public: - DepthAndScoreComparator(CTxMemPool *mempool) : mp(mempool) {} - bool operator()(const uint256& a, const uint256& b) { return mp->CompareDepthAndScore(a, b); } + bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b) + { + uint64_t counta = a->GetCountWithAncestors(); + uint64_t countb = b->GetCountWithAncestors(); + if (counta == countb) { + return CompareTxMemPoolEntryByScore()(*a, *b); + } + return counta < countb; + } }; } +std::vector CTxMemPool::GetSortedDepthAndScore() const +{ + std::vector iters; + AssertLockHeld(cs); + + iters.reserve(mapTx.size()); + + for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) { + iters.push_back(mi); + } + std::sort(iters.begin(), iters.end(), DepthAndScoreComparator()); + return iters; +} + void CTxMemPool::queryHashes(vector& vtxid) { + LOCK(cs); + auto iters = GetSortedDepthAndScore(); + vtxid.clear(); - - LOCK(cs); vtxid.reserve(mapTx.size()); - for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) - vtxid.push_back(mi->GetTx().GetHash()); - std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this)); + for (auto it : iters) { + vtxid.push_back(it->GetTx().GetHash()); + } } - -bool CTxMemPool::lookup(uint256 hash, CTransaction& result, int64_t& time) const +std::vector CTxMemPool::infoAll() const { LOCK(cs); - indexed_transaction_set::const_iterator i = mapTx.find(hash); - if (i == mapTx.end()) return false; - result = i->GetTx(); - time = i->GetTime(); - return true; + auto iters = GetSortedDepthAndScore(); + + std::vector ret; + ret.reserve(mapTx.size()); + for (auto it : iters) { + ret.push_back(TxMempoolInfo{it->GetSharedTx(), it->GetTime(), CFeeRate(it->GetFee(), it->GetTxSize())}); + } + + return ret; } -bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const -{ - int64_t time; - return CTxMemPool::lookup(hash, result, time); -} - -bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const +std::shared_ptr CTxMemPool::get(const uint256& hash) const { LOCK(cs); indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) - return false; - feeRate = CFeeRate(i->GetFee(), i->GetTxSize()); - return true; + return nullptr; + return i->GetSharedTx(); +} + +bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const +{ + auto tx = get(hash); + if (tx) { + result = *tx; + return true; + } + return false; +} + +TxMempoolInfo CTxMemPool::info(const uint256& hash) const +{ + LOCK(cs); + indexed_transaction_set::const_iterator i = mapTx.find(hash); + if (i == mapTx.end()) + return TxMempoolInfo(); + return TxMempoolInfo{i->GetSharedTx(), i->GetTime(), CFeeRate(i->GetFee(), i->GetTxSize())}; } CFeeRate CTxMemPool::estimateFee(int nBlocks) const diff --git a/src/txmempool.h b/src/txmempool.h index 3cf84159c..2f407fe00 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -7,6 +7,7 @@ #define BITCOIN_TXMEMPOOL_H #include +#include #include #include "amount.h" @@ -75,7 +76,7 @@ class CTxMemPool; class CTxMemPoolEntry { private: - CTransaction tx; + std::shared_ptr tx; CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups size_t nTxSize; //!< ... and avoid recomputing tx size size_t nModSize; //!< ... and modified size for priority @@ -112,7 +113,8 @@ public: unsigned int nSigOps, LockPoints lp); CTxMemPoolEntry(const CTxMemPoolEntry& other); - const CTransaction& GetTx() const { return this->tx; } + const CTransaction& GetTx() const { return *this->tx; } + std::shared_ptr GetSharedTx() const { return this->tx; } /** * Fast calculation of lower bound of current priority as update * from entry priority. Only inputs that were originally in-chain will age. @@ -307,6 +309,21 @@ struct ancestor_score {}; class CBlockPolicyEstimator; +/** + * Information about a mempool transaction. + */ +struct TxMempoolInfo +{ + /** The transaction itself */ + std::shared_ptr tx; + + /** Time the transaction entered the mempool. */ + int64_t nTime; + + /** Feerate of the transaction. */ + CFeeRate feeRate; +}; + /** * CTxMemPool stores valid-according-to-the-current-best-chain * transactions that may be included in the next block. @@ -464,6 +481,8 @@ private: void UpdateParent(txiter entry, txiter parent, bool add); void UpdateChild(txiter entry, txiter child, bool add); + std::vector GetSortedDepthAndScore() const; + public: indirectmap mapNextTx; std::map > mapDeltas; @@ -589,8 +608,9 @@ public: } bool lookup(uint256 hash, CTransaction& result) const; - bool lookup(uint256 hash, CTransaction& result, int64_t& time) const; - bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const; + std::shared_ptr get(const uint256& hash) const; + TxMempoolInfo info(const uint256& hash) const; + std::vector infoAll() const; /** Estimate fee rate needed to get into the next nBlocks * If no answer can be given at nBlocks, return an estimate From f0fdda0181e1b05b66541bf235c6702c41664170 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Tue, 26 Apr 2016 17:21:22 -0700 Subject: [PATCH 0714/1223] IsInitialBlockDownload: usually avoid locking Optimistically test the latch bool before taking the lock. For all IsInitialBlockDownload calls after the first to return false, this avoids the need to lock cs_main. --- src/main.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d2b7c6bc4..aed8a7c42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,7 @@ #include "validationinterface.h" #include "versionbits.h" +#include #include #include @@ -1574,18 +1575,24 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) bool IsInitialBlockDownload() { const CChainParams& chainParams = Params(); + + // Once this function has returned false, it must remain false. + static std::atomic latchToFalse{false}; + // Optimization: pre-test latch before taking the lock. + if (latchToFalse.load(std::memory_order_relaxed)) + return false; + LOCK(cs_main); + if (latchToFalse.load(std::memory_order_relaxed)) + return false; if (fImporting || fReindex) return true; if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) return true; - static bool lockIBDState = false; - if (lockIBDState) - return false; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge); if (!state) - lockIBDState = true; + latchToFalse.store(true, std::memory_order_relaxed); return state; } From dbfb426b96fbd79fb76734c6b747ef8ee10ad5ab Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 May 2016 19:51:45 +0200 Subject: [PATCH 0715/1223] Optimize the relay map to use shared_ptr's * Switch mapRelay to use shared_ptr * Switch the relay code to copy mempool shared_ptr's, rather than copying the transaction itself. * Change vRelayExpiration to store mapRelay iterators rather than hashes (smaller and faster). --- src/main.cpp | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d71f35bf7..bf0f0d896 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,9 +80,6 @@ uint64_t nPruneTarget = 0; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT; -std::map mapRelay; -std::deque > vRelayExpiration; -CCriticalSection cs_mapRelay; CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; @@ -215,6 +212,12 @@ namespace { /** Number of peers from which we're downloading blocks. */ int nPeersWithValidatedDownloads = 0; + + /** Relay map, protected by cs_main. */ + typedef std::map> MapRelay; + MapRelay mapRelay; + /** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */ + std::deque> vRelayExpiration; } // anon namespace ////////////////////////////////////////////////////////////////////////////// @@ -4505,31 +4508,24 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } } - else if (inv.IsKnownType()) + else if (inv.type == MSG_TX) { - CTransaction tx; // Send stream from relay memory bool push = false; - { - LOCK(cs_mapRelay); - map::iterator mi = mapRelay.find(inv.hash); - if (mi != mapRelay.end()) { - tx = (*mi).second; - push = true; - } - } - if (!push && inv.type == MSG_TX) { + auto mi = mapRelay.find(inv.hash); + if (mi != mapRelay.end()) { + pfrom->PushMessage(NetMsgType::TX, *mi->second); + push = true; + } else { auto txinfo = mempool.info(inv.hash); // To protect privacy, do not answer getdata using the mempool when // that TX couldn't have been INVed in reply to a MEMPOOL request. if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) { - tx = *txinfo.tx; + pfrom->PushMessage(NetMsgType::TX, *txinfo.tx); push = true; } } - if (push) { - pfrom->PushMessage(inv.GetCommand(), tx); - } else { + if (!push) { vNotFound.push_back(inv); } } @@ -5978,7 +5974,6 @@ bool SendMessages(CNode* pto) vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; { - LOCK(cs_mapRelay); // Expire old relay messages while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) { @@ -5986,9 +5981,9 @@ bool SendMessages(CNode* pto) vRelayExpiration.pop_front(); } - auto ret = mapRelay.insert(std::make_pair(hash, *txinfo.tx)); + auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx))); if (ret.second) { - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash)); + vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, ret.first)); } } if (vInv.size() == MAX_INV_SZ) { From e9b4780b292122fd727426471f025ec3d3eb7b08 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 May 2016 20:34:27 +0200 Subject: [PATCH 0716/1223] Optimization: don't check the mempool at all if no mempool req ever --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index bf0f0d896..68368e402 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4516,7 +4516,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam if (mi != mapRelay.end()) { pfrom->PushMessage(NetMsgType::TX, *mi->second); push = true; - } else { + } else if (pfrom->timeLastMempoolReq) { auto txinfo = mempool.info(inv.hash); // To protect privacy, do not answer getdata using the mempool when // that TX couldn't have been INVed in reply to a MEMPOOL request. From c2a4724642400bc9200aeef4c725b5c07eee9d90 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 May 2016 20:35:44 +0200 Subject: [PATCH 0717/1223] Optimization: use usec in expiration and reuse nNow --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 68368e402..db0580bda 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5975,7 +5975,7 @@ bool SendMessages(CNode* pto) nRelayedTransactions++; { // Expire old relay messages - while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow) { mapRelay.erase(vRelayExpiration.front().second); vRelayExpiration.pop_front(); @@ -5983,7 +5983,7 @@ bool SendMessages(CNode* pto) auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx))); if (ret.second) { - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, ret.first)); + vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first)); } } if (vInv.size() == MAX_INV_SZ) { From e6b141acf9dcc0a12f49d53c0bb8a892bae72217 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 6 Jun 2016 10:23:51 +0200 Subject: [PATCH 0718/1223] qt: translation strings update --- src/qt/bitcoinstrings.cpp | 108 ++-- src/qt/locale/bitcoin_en.ts | 1032 +++++++++++++++++++---------------- 2 files changed, 620 insertions(+), 520 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 41f1d5841..23be8e016 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -1,26 +1,35 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include -// Automatically generated by extract_strings.py +// Automatically generated by extract_strings_qt.py #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #else #define UNUSED #endif static const char UNUSED *bitcoin_strings[] = { +QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin Core"), +QT_TRANSLATE_NOOP("bitcoin-core", "The %s developers"), QT_TRANSLATE_NOOP("bitcoin-core", "" "(1 = keep tx meta data e.g. account owner and payment request information, 2 " "= drop tx meta data)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"-fallbackfee is set very high! This is the transaction fee you may pay when " +"fee estimates are not available."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "-maxtxfee is set very high! Fees this large could be paid on a single " "transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" "-paytxfee is set very high! This is the transaction fee you will pay if you " "send a transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"A fee rate (in %s/kB) that will be used when fee estimation has insufficient " +"data (default: %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Accept relayed transactions received from whitelisted peers even when not " +"relaying transactions (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Allow JSON-RPC connections from specified source. Valid for are a " "single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or " "a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"), @@ -35,8 +44,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "notation for IPv6. This option can be specified multiple times (default: " "bind to all interfaces)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Cannot obtain a lock on data directory %s. Bitcoin Core is probably already " -"running."), +"Cannot obtain a lock on data directory %s. %s is probably already running."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Create new files with system default permissions, instead of umask 077 (only " "effective with disabled wallet functionality)"), @@ -52,8 +60,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Do not keep transactions in the mempool longer than hours (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Error reading wallet.dat! All keys read correctly, but transaction data or " -"address book entries might be missing or incorrect."), +"Error reading %s! All keys read correctly, but transaction data or address " +"book entries might be missing or incorrect."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Listening for incoming connections failed (listen returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -72,6 +80,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Fees (in %s/kB) smaller than this are considered zero fee for transaction " "creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Force relay of transactions from whitelisted peers even they violate local " +"relay policy (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "If is not supplied or if = 1, output all debugging " @@ -86,18 +97,22 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Maximum allowed median peer time offset adjustment. Local perspective of " +"time may be influenced by peers forward or backward by this amount. " +"(default: %u seconds)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Maximum size of data in data carrier transactions we relay and mine " "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Maximum total fees (in %s) to use in a single wallet transaction; setting " -"this too low may abort large transactions (default: %s)"), +"Maximum total fees (in %s) to use in a single wallet transaction or raw " +"transaction; setting this too low may abort large transactions (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Output debugging information (default: %u, supplying is optional)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Please check that your computer's date and time are correct! If your clock " -"is wrong Bitcoin Core will not work properly."), +"is wrong, %s will not work properly."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Prune configured below the minimum of %d MiB. Please use a higher number."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -123,11 +138,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Set the number of threads for coin generation if enabled (-1 = all cores, " -"default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Support filtering of blocks and transaction with bloom filters (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Tell other nodes to filter invs to us by our mempool min fee (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "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 " @@ -148,12 +162,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = " "no limit (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Unable to bind to %s on this computer. Bitcoin Core is probably already " -"running."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Unsupported argument -socks found. Setting SOCKS version isn't possible " "anymore, only SOCKS5 proxies are supported."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/" +"or -whitelistforcerelay."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Use UPnP to map the listening port (default: 1 when listening and no -proxy)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " @@ -172,13 +186,16 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: The network does not appear to fully agree! Some miners appear to " "be experiencing issues."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: Unknown block versions being mined! It's possible unknown rules are " +"in effect"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; " +"if your balance or transactions are incorrect you should restore from a " +"backup."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: We do not appear to fully agree with our peers! You may need to " "upgrade, or other nodes may need to upgrade."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as " -"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect " -"you should restore from a backup."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Whitelist peers connecting from the given netmask or IP address. Can be " "specified multiple times."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -187,6 +204,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "You need to rebuild the database using -reindex to go back to unpruned " "mode. This will redownload the entire blockchain"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"You need to rebuild the database using -reindex-chainstate to change -txindex"), +QT_TRANSLATE_NOOP("bitcoin-core", "%s corrupt, salvage failed"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"), @@ -194,24 +214,22 @@ QT_TRANSLATE_NOOP("bitcoin-core", " can be:"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."), QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Always relay transactions received from whitelisted peers (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat on startup"), +QT_TRANSLATE_NOOP("bitcoin-core", "Append comment to the user agent string"), +QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Automatically create Tor hidden service (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"), -QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -%s address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Change index out of range"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"), QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"), +QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) %i-%i"), QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"), QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"), @@ -221,12 +239,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash block in
"), QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash transaction in
"), QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw block in
"), QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw transaction in
"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable transaction replacement in the memory pool (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet corrupted"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet requires newer version of %s"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"), QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."), QT_TRANSLATE_NOOP("bitcoin-core", "Error"), @@ -234,34 +253,34 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see d QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"), QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."), QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"), QT_TRANSLATE_NOOP("bitcoin-core", "Information"), -QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."), +QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. %s is shutting down."), QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -%s=: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -fallbackfee=: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s' (must be at least %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most unconnectable transactions in memory (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below megabytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading banlist..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Location of the auth cookie (default: data dir)"), QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most connections to peers (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, *1000 bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, *1000 bytes (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Minimum bytes per sigop in transactions we relay and mine (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."), @@ -269,12 +288,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network (ipv4, QT_TRANSLATE_NOOP("bitcoin-core", "Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Print this help message and exit"), +QT_TRANSLATE_NOOP("bitcoin-core", "Print version and exit"), QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."), QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."), QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."), QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"), -QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild chain state and block index from the blk*.dat files on disk"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild chain state from the currently indexed blocks"), QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."), QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"), @@ -299,7 +320,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)") QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), -QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Tor control port password (default: empty)"), @@ -309,6 +329,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"), 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 start HTTP server. See debug log for details."), QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -benchmark ignored, use -debug=bench."), @@ -321,13 +342,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet %s resides outside data directory %s"), -QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin Core to complete"), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet debugging/testing options:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart %s to complete"), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning"), -QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"), +QT_TRANSLATE_NOOP("bitcoin-core", "Warning: unknown new rules activated (versionbit %i)"), QT_TRANSLATE_NOOP("bitcoin-core", "Whether to operate in a blocks only mode (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"), QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."), QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), }; diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 00411741f..5549ccd4f 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -165,7 +165,7 @@ Repeat new passphrase - + Encrypt wallet Encrypt wallet @@ -195,7 +195,7 @@ Change passphrase - + Confirm wallet encryption Confirm wallet encryption @@ -210,12 +210,7 @@ Are you sure you wish to encrypt your wallet? - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - - - - + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. @@ -232,7 +227,7 @@ Wallet encrypted - + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. @@ -242,7 +237,12 @@ - + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + @@ -299,17 +299,17 @@ BitcoinGUI - + Sign &message... Sign &message... - + Synchronizing with network... Synchronizing with network... - + &Overview &Overview @@ -344,7 +344,17 @@ Quit application - + + &About %1 + + + + + Show information about %1 + + + + About &Qt About &Qt @@ -358,6 +368,11 @@ &Options... &Options... + + + Modify configuration options for %1 + + &Encrypt Wallet... @@ -374,7 +389,7 @@ &Change Passphrase... - + &Sending addresses... @@ -389,27 +404,17 @@ - - Bitcoin Core client - - - - - Importing blocks from disk... - Importing blocks from disk... - - - + Reindexing blocks on disk... Reindexing blocks on disk... - + Send coins to a Bitcoin address Send coins to a Bitcoin address - + Backup wallet to another location Backup wallet to another location @@ -434,12 +439,12 @@ &Verify message... - + Bitcoin Bitcoin - + Wallet Wallet @@ -454,12 +459,7 @@ &Receive - - Show information about Bitcoin Core - - - - + &Show / Hide &Show / Hide @@ -484,7 +484,7 @@ Verify messages to ensure they were signed with specified Bitcoin addresses - + &File &File @@ -504,27 +504,12 @@ Tabs toolbar - - Bitcoin Core - Bitcoin Core - - - + Request payments (generates QR codes and bitcoin: URIs) - - &About Bitcoin Core - - - - - Modify configuration options for Bitcoin Core - - - - + Show the list of used sending addresses and labels @@ -543,13 +528,8 @@ &Command-line options - - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - - - + %n active connection(s) to Bitcoin network %n active connection to Bitcoin network @@ -557,7 +537,17 @@ - + + Indexing blocks on disk... + + + + + Processing blocks on disk... + + + + No block source available... No block source available... @@ -643,12 +633,22 @@ Up to date - + + Show the %1 help message to get a list with possible Bitcoin command-line options + + + + + %1 client + + + + Catching up... Catching up... - + Date: %1 @@ -698,14 +698,6 @@ Wallet is <b>encrypted</b> and currently <b>locked</b> - - ClientModel - - - Network Alert - Network Alert - - CoinControlDialog @@ -870,7 +862,7 @@ - + highest @@ -935,12 +927,7 @@ - - This label turns red if any recipient receives an amount smaller than %1. - - - - + Can vary +/- %1 satoshi(s) per input. @@ -971,7 +958,12 @@ - + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + + + + (no label) (no label) @@ -1058,7 +1050,7 @@ FreespaceChecker - + A new data directory will be created. A new data directory will be created. @@ -1086,12 +1078,7 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - - - + version version @@ -1103,7 +1090,7 @@ - About Bitcoin Core + About %1 @@ -1166,17 +1153,17 @@ - Welcome to Bitcoin Core. + Welcome to %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + As this is the first time the program is launched, you can choose where %1 will store its data. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. @@ -1190,12 +1177,7 @@ Use a custom data directory: - - Bitcoin Core - Bitcoin Core - - - + Error: Specified data directory "%1" cannot be created. @@ -1262,7 +1244,17 @@ &Main - + + Automatically start %1 after logging in to the system. + + + + + &Start %1 on system login + + + + Size of &database cache @@ -1293,17 +1285,12 @@ - + 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. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - - - - + 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 |. @@ -1329,22 +1316,12 @@ &Reset Options - + &Network &Network - - Automatically start Bitcoin Core after logging in to the system. - - - - - &Start Bitcoin Core on system login - - - - + (0 = auto, <0 = leave that many cores free) @@ -1455,6 +1432,16 @@ + &Hide the icon from the system tray. + + + + + Hide tray icon + + + + Show only a tray icon after minimizing the window. Show only a tray icon after minimizing the window. @@ -1479,7 +1466,12 @@ User Interface &language: - + + The user interface language can be set here. This setting will take effect after restarting %1. + + + + &Unit to show amounts in: &Unit to show amounts in: @@ -1489,12 +1481,12 @@ Choose the default subdivision unit to show in the interface and when sending coins. - + Whether to show coin control features or not. - + &OK &OK @@ -1504,7 +1496,7 @@ &Cancel - + default default @@ -1514,23 +1506,23 @@ - + Confirm options reset Confirm options reset - + Client restart required to activate changes. - + Client will be shut down. Do you want to proceed? - + This change would require a client restart. @@ -1781,12 +1773,12 @@ QObject - + Amount Amount - + Enter a Bitcoin address (e.g. %1) @@ -1807,7 +1799,7 @@ - + %1 s @@ -1862,16 +1854,15 @@ + - - - + - - + + @@ -1892,7 +1883,7 @@ N/A - + Client version Client version @@ -1913,26 +1904,26 @@ - Using OpenSSL version - Using OpenSSL version - - - Using BerkeleyDB version - + + Datadir + + + + Startup time Startup time - + Network Network - + Name @@ -1962,41 +1953,36 @@ - + Memory usage - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - - - - - + + Received - - + + Sent - + &Peers - + Banned peers - - - + + + Select a peer to view detailed information. @@ -2031,13 +2017,28 @@ - - + + User Agent - + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + + + + + Decrease font size + + + + + Increase font size + + + + Services @@ -2082,12 +2083,12 @@ - + Last block time Last block time - + &Open &Open @@ -2097,7 +2098,7 @@ &Console - + &Network Traffic @@ -2112,7 +2113,7 @@ - + In: @@ -2122,22 +2123,17 @@ - - Build date - Build date - - - + Debug log file Debug log file - + Clear console Clear console - + &Disconnect Node @@ -2175,8 +2171,8 @@ - - Welcome to the Bitcoin Core RPC console. + + Welcome to the %1 RPC console. @@ -2190,7 +2186,7 @@ Type <b>help</b> for an overview of available commands. - + %1 B @@ -2444,9 +2440,14 @@ Message - - Amount - Amount + + (no amount requested) + + + + + Requested + @@ -2458,17 +2459,12 @@ (no message) - - - (no amount) - - SendCoinsDialog - + Send Coins Send Coins @@ -2615,17 +2611,7 @@ - - Send as zero-fee transaction if possible - - - - - (confirmation may take longer) - - - - + Send to multiple recipients at once Send to multiple recipients at once @@ -2640,12 +2626,12 @@ - + Dust: - + Clear &All Clear &All @@ -2678,7 +2664,7 @@ - + Copy quantity @@ -2713,7 +2699,7 @@ - + Total Amount %1 @@ -2758,12 +2744,12 @@ - + Pay only the required fee of %1 - + Estimated to begin confirmation within %n block(s). Estimated to begin confirmation within %n block. @@ -2796,12 +2782,12 @@ - + Copy dust - + Are you sure you want to send? @@ -2920,11 +2906,20 @@ + + SendConfirmationDialog + + + + Yes + + + ShutdownWindow - Bitcoin Core is shutting down... + %1 is shutting down... @@ -3117,16 +3112,6 @@ SplashScreen - - - Bitcoin Core - Bitcoin Core - - - - The Bitcoin Core developers - - [testnet] @@ -3149,14 +3134,29 @@ Open until %1 - - conflicted - + + %1/offline + %1/offline - %1/offline - %1/offline + 0/unconfirmed, %1 + + + + + in memory pool + + + + + not in memory pool + + + + + abandoned + @@ -3231,12 +3231,12 @@ - + Credit Credit - + matures in %n more block(s) matures in %n more block @@ -3251,12 +3251,12 @@ - + Debit Debit - + Total debit @@ -3277,12 +3277,12 @@ - + Message Message - + Comment Comment @@ -3291,6 +3291,11 @@ Transaction ID Transaction ID + + + Output index + + Merchant @@ -3334,12 +3339,12 @@ false - + , has not been successfully broadcast yet , has not been successfully broadcast yet - + Open for %n more block(s) Open for %n more block @@ -3347,7 +3352,12 @@ - + + conflicted with a transaction with %1 confirmations + + + + unknown unknown @@ -3355,15 +3365,15 @@ TransactionDescDialog - - Transaction details - Transaction details - - - + This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction + + + Details for %1 + + TransactionTableModel @@ -3378,12 +3388,12 @@ Type - + Immature (%1 confirmations, will be available after %2) - + Open for %n more block(s) Open for %n more block @@ -3396,7 +3406,7 @@ Open until %1 - + Confirmed (%1 confirmations) Confirmed (%1 confirmations) @@ -3411,7 +3421,7 @@ Generated but not accepted - + Offline @@ -3425,6 +3435,11 @@ Unconfirmed + + + Abandoned + + Confirming (%1 of %2 recommended confirmations) @@ -3471,7 +3486,12 @@ (n/a) - + + (no label) + (no label) + + + Transaction status. Hover over this field to show number of confirmations. Transaction status. Hover over this field to show number of confirmations. @@ -3576,6 +3596,11 @@ + Abandon transaction + + + + Copy address Copy address @@ -3599,6 +3624,11 @@ Copy raw transaction + + + Copy full transaction details + + Edit label @@ -3610,7 +3640,7 @@ Show transaction details - + Export Transaction History @@ -3675,7 +3705,7 @@ ID - + Range: Range: @@ -3688,7 +3718,7 @@ UnitDisplayStatusBarControl - + Unit to show amounts in. Click to select another unit. @@ -3755,47 +3785,37 @@ bitcoin-core - + Options: Options: - + Specify data directory Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - - - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - - - - + Prune configured below the minimum of %d MiB. Please use a higher number. @@ -3815,7 +3835,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -3825,7 +3845,7 @@ - + Pruning blockstore... @@ -3840,17 +3860,47 @@ - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + + Bitcoin Core + Bitcoin Core + + + + The %s developers + + + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + + + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + + + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind to given address and always listen on it. Use [host]:port notation for IPv6 - + + Cannot obtain a lock on data directory %s. %s is probably already running. + + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup @@ -3860,17 +3910,47 @@ - - Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - - - - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + + + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + + + + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + + + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + + + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + + + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + + + + + Tell other nodes to filter invs to us by our mempool min fee (default: %u) + + + + 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 @@ -3880,12 +3960,7 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - - - - + Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -3905,22 +3980,27 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. - + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - - - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. - + + You need to rebuild the database using -reindex-chainstate to change -txindex + + + + + %s corrupt, salvage failed + + + + -maxmempool must be at least %d MB @@ -3930,12 +4010,32 @@ - + + Append comment to the user agent string + + + + + Attempt to recover private keys from a corrupt wallet on startup + + + + Block creation options: Block creation options: - + + Cannot resolve -%s address: '%s' + + + + + Change index out of range + + + + Connect only to the specified node(s) Connect only to the specified node(s) @@ -3945,7 +4045,12 @@ - + + Copyright (C) %i-%i + + + + Corrupted block database detected Corrupted block database detected @@ -3984,6 +4089,11 @@ Enable publish raw transaction in <address> + + + Enable transaction replacement in the memory pool (default: %u) + + Error initializing block database @@ -3994,13 +4104,28 @@ Error initializing wallet database environment %s! Error initializing wallet database environment %s! + + + Error loading %s + + + + + Error loading %s: Wallet corrupted + + + + + Error loading %s: Wallet requires newer version of %s + + Error loading block database Error loading block database - + Error opening block database Error opening block database @@ -4015,7 +4140,7 @@ Failed to listen on any port. Use -listen=0 if you want this. - + Importing... @@ -4025,17 +4150,47 @@ Incorrect or no genesis block found. Wrong datadir for network? - + + Initialization sanity check failed. %s is shutting down. + + + + Invalid -onion address: '%s' - + + Invalid amount for -%s=<amount>: '%s' + + + + + Invalid amount for -fallbackfee=<amount>: '%s' + + + + Keep the transaction memory pool below <n> megabytes (default: %u) - + + Loading banlist... + + + + + Location of the auth cookie (default: data dir) + + + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + + + + Not enough file descriptors available. Not enough file descriptors available. @@ -4046,6 +4201,16 @@ + Print this help message and exit + + + + + Print version and exit + + + + Prune cannot be configured with a negative value. @@ -4055,7 +4220,17 @@ - + + Rebuild chain state and block index from the blk*.dat files on disk + + + + + Rebuild chain state from the currently indexed blocks + + + + Set database cache size in megabytes (%d to %d, default: %d) @@ -4070,7 +4245,12 @@ Specify wallet file (within data directory) - + + Unable to bind to %s on this computer. %s is probably already running. + + + + Unsupported argument -benchmark ignored, use -debug=bench. @@ -4110,22 +4290,22 @@ Wallet %s resides outside data directory %s - + + Wallet debugging/testing options: + + + + + Wallet needed to be rewritten: restart %s to complete + + + + Wallet options: - - Warning: This version is obsolete; upgrade required! - - - - - You need to rebuild the database using -reindex to change -txindex - You need to rebuild the database using -reindex to change -txindex - - - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -4140,12 +4320,7 @@ - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - - - - + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) @@ -4170,7 +4345,7 @@ - + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) @@ -4180,7 +4355,7 @@ - + Maximum size of data in data carrier transactions we relay and mine (default: %u) @@ -4200,12 +4375,7 @@ - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - - - - + The transaction amount is too small to send after the fee has been deducted @@ -4215,7 +4385,7 @@ - + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -4225,7 +4395,7 @@ - + (default: %u) @@ -4235,52 +4405,22 @@ - - Activating best chain... - - - - - Always relay transactions received from whitelisted peers (default: %d) - - - - - Attempt to recover private keys from a corrupt wallet.dat on startup - - - - + Automatically create Tor hidden service (default: %d) - - Cannot resolve -whitebind address: '%s' - - - - + Connect through SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - - - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - - - - + Error reading from database, shutting down. - + Imports blocks from external blk000??.dat file on startup @@ -4290,32 +4430,12 @@ Information - - Initialization sanity check failed. Bitcoin Core is shutting down. - - - - - Invalid amount for -maxtxfee=<amount>: '%s' - - - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Invalid amount for -minrelaytxfee=<amount>: '%s' - - - - Invalid amount for -mintxfee=<amount>: '%s' - Invalid amount for -mintxfee=<amount>: '%s' - - - + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) - + Invalid netmask specified in -whitelist: '%s' @@ -4325,7 +4445,7 @@ - + Need to specify a port with -whitebind: '%s' @@ -4335,22 +4455,12 @@ - + RPC server options: - - Rebuild block chain index from current blk000??.dat files on startup - - - - - Receive and display P2P network alerts (default: %u) - - - - + Reducing -maxconnections from %d to %d, because of system limitations. @@ -4390,7 +4500,7 @@ - + This is experimental software. @@ -4430,7 +4540,7 @@ - + Upgrade wallet to latest format on startup @@ -4440,22 +4550,22 @@ Username for JSON-RPC connections - - Wallet needed to be rewritten: restart Bitcoin Core to complete - - - - + Warning Warning - + + Warning: unknown new rules activated (versionbit %i) + + + + Whether to operate in a blocks only mode (default: %u) - + Zapping all transactions from wallet... @@ -4465,47 +4575,32 @@ - - wallet.dat corrupt, salvage failed - wallet.dat corrupt, salvage failed - - - + Password for JSON-RPC connections Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - - This help message - This help message - - - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect - + Loading addresses... Loading addresses... - - Error loading wallet.dat: Wallet corrupted - Error loading wallet.dat: Wallet corrupted - - - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) - + -maxtxfee is set very high! Fees this large could be paid on a single transaction. @@ -4515,22 +4610,17 @@ - + Do not keep transactions in the mempool longer than <n> hours (default: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - - - - + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) - + How thorough the block verification of -checkblocks is (0-4, default: %u) @@ -4540,7 +4630,7 @@ - + Number of seconds to keep misbehaving peers from reconnecting (default: %u) @@ -4550,12 +4640,12 @@ - + Support filtering of blocks and transaction with bloom filters (default: %u) - + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. @@ -4565,10 +4655,15 @@ - + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) @@ -4580,27 +4675,27 @@ - + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + + + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + + + + (default: %s) - + Always query for peer addresses via DNS lookup (default: %u) - - Error loading wallet.dat - Error loading wallet.dat - - - - Generate coins (default: %u) - - - - + How many blocks to check at startup (default: %u, 0 = all) @@ -4615,7 +4710,7 @@ Invalid -proxy address: '%s' - + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) @@ -4625,7 +4720,7 @@ - + Maintain at most <n> connections to peers (default: %u) @@ -4645,12 +4740,12 @@ - + Prepend debug output with timestamp (default: %u) - + Relay and mine data carrier transactions (default: %u) @@ -4695,72 +4790,57 @@ - + Threshold for disconnecting misbehaving peers (default: %u) - + Unknown network specified in -onlynet: '%s' Unknown network specified in -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Cannot resolve -bind address: '%s' - - - - Cannot resolve -externalip address: '%s' - Cannot resolve -externalip address: '%s' - - - - Invalid amount for -paytxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' - - - + Insufficient funds Insufficient funds - + Loading block index... Loading block index... - + Add a node to connect to and attempt to keep the connection open Add a node to connect to and attempt to keep the connection open - + Loading wallet... Loading wallet... - + Cannot downgrade wallet Cannot downgrade wallet - + Cannot write default address Cannot write default address - + Rescanning... Rescanning... - + Done loading Done loading - + Error Error From 2e494489c35499dbe7891d4c07b4c35b178341d1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 17 Mar 2016 12:49:16 +0100 Subject: [PATCH 0719/1223] tor: Change auth order to only use HASHEDPASSWORD if -torpassword Change authentication order to make it more clear (see #7700). - If the `-torpassword` option is provided, force use of `HASHEDPASSWORD` auth. - Give error message if `-torpassword` provided, but `HASHEDPASSWORD` auth is not available. - Give error message if only `HASHEDPASSWORD` available, but `-torpassword` not given. --- src/torcontrol.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 1c7bc2dbe..6fabe54af 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -574,7 +574,15 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl * password: "password" */ std::string torpassword = GetArg("-torpassword", ""); - if (methods.count("NULL")) { + if (!torpassword.empty()) { + if (methods.count("HASHEDPASSWORD")) { + LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n"); + boost::replace_all(torpassword, "\"", "\\\""); + conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); + } else { + LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n"); + } + } else if (methods.count("NULL")) { LogPrint("tor", "tor: Using NULL authentication\n"); conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2)); } else if (methods.count("SAFECOOKIE")) { @@ -595,13 +603,7 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl } } } else if (methods.count("HASHEDPASSWORD")) { - if (!torpassword.empty()) { - LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n"); - boost::replace_all(torpassword, "\"", "\\\""); - conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); - } else { - LogPrintf("tor: Password authentication required, but no password provided with -torpassword\n"); - } + LogPrintf("tor: The only supported authentication mechanism left is password, but no password provided with -torpassword\n"); } else { LogPrintf("tor: No supported authentication method\n"); } From 152ab236ea1c1106340196f45918fd84f57a0b63 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Thu, 2 Jun 2016 23:16:42 -0700 Subject: [PATCH 0720/1223] Improve CWallet API with new GetAccountPubkey function. Remove one more caller that is passing CWalletDB. --- src/wallet/rpcwallet.cpp | 34 ++++------------------------------ src/wallet/wallet.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/wallet/wallet.h | 1 + 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 42b37ea77..5e6afcd7c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -146,38 +146,12 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) { - CWalletDB walletdb(pwalletMain->strWalletFile); - - CAccount account; - walletdb.ReadAccount(strAccount, account); - - if (!bForceNew) { - if (!account.vchPubKey.IsValid()) - bForceNew = true; - else { - // Check if the current key has been used - CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); - for (map::iterator it = pwalletMain->mapWallet.begin(); - it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); - ++it) - BOOST_FOREACH(const CTxOut& txout, (*it).second.vout) - if (txout.scriptPubKey == scriptPubKey) { - bForceNew = true; - break; - } - } + CPubKey pubKey; + if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) { + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); } - // Generate a new key - if (bForceNew) { - if (!pwalletMain->GetKeyFromPool(account.vchPubKey)) - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - - pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive"); - walletdb.WriteAccount(strAccount, account); - } - - return CBitcoinAddress(account.vchPubKey.GetID()); + return CBitcoinAddress(pubKey.GetID()); } UniValue getaccountaddress(const UniValue& params, bool fHelp) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fb56e7c1d..f3d165472 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -640,6 +640,44 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun return true; } +bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew) +{ + CWalletDB walletdb(strWalletFile); + + CAccount account; + walletdb.ReadAccount(strAccount, account); + + if (!bForceNew) { + if (!account.vchPubKey.IsValid()) + bForceNew = true; + else { + // Check if the current key has been used + CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); + for (map::iterator it = mapWallet.begin(); + it != mapWallet.end() && account.vchPubKey.IsValid(); + ++it) + BOOST_FOREACH(const CTxOut& txout, (*it).second.vout) + if (txout.scriptPubKey == scriptPubKey) { + bForceNew = true; + break; + } + } + } + + // Generate a new key + if (bForceNew) { + if (!GetKeyFromPool(account.vchPubKey)) + return false; + + SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive"); + walletdb.WriteAccount(strAccount, account); + } + + pubKey = account.vchPubKey; + + return true; +} + void CWallet::MarkDirty() { { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3077bf461..683c90144 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -719,6 +719,7 @@ public: */ int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = ""); + bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false); void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); From d3df40e51a29bd98830043dd19829126390d1bc4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 23 Apr 2016 23:30:20 +0000 Subject: [PATCH 0721/1223] Implement BIP 9 GBT changes - BIP9DeploymentInfo struct for static deployment info - VersionBitsDeploymentInfo: Avoid C++11ism by commenting parameter names - getblocktemplate: Make sure to set deployments in the version if it is LOCKED_IN - In this commit, all rules are considered required for clients to support --- src/consensus/params.h | 1 + src/main.cpp | 2 +- src/main.h | 2 ++ src/rpc/mining.cpp | 50 ++++++++++++++++++++++++++++++++++++++++-- src/versionbits.cpp | 11 ++++++++++ src/versionbits.h | 7 ++++++ 6 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/consensus/params.h b/src/consensus/params.h index 4f3480b89..6c4cc4947 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -16,6 +16,7 @@ enum DeploymentPos { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. + // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp MAX_VERSION_BITS_DEPLOYMENTS }; diff --git a/src/main.cpp b/src/main.cpp index f74cb3057..623d77985 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2122,7 +2122,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const } // Protected by cs_main -static VersionBitsCache versionbitscache; +VersionBitsCache versionbitscache; int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) { diff --git a/src/main.h b/src/main.h index 6936b5379..404a787e4 100644 --- a/src/main.h +++ b/src/main.h @@ -551,6 +551,8 @@ extern CBlockTreeDB *pblocktree; */ int GetSpendHeight(const CCoinsViewCache& inputs); +extern VersionBitsCache versionbitscache; + /** * Determine what nVersion a new block should use. */ diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index c33082fca..277696fe0 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -7,6 +7,7 @@ #include "chain.h" #include "chainparams.h" #include "consensus/consensus.h" +#include "consensus/params.h" #include "consensus/validation.h" #include "core_io.h" #include "init.h" @@ -260,6 +261,13 @@ static UniValue BIP22ValidationResult(const CValidationState& state) return "valid?"; } +std::string gbt_vb_name(const Consensus::DeploymentPos pos) { + const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; + std::string s = vbinfo.name; + s.insert(s.begin(), '!'); + return s; +} + UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -267,7 +275,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) "getblocktemplate ( \"jsonrequestobject\" )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" - "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n" + "For full specification, see BIPs 22 and 9:\n" + " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" + " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" "\nArguments:\n" "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n" @@ -283,6 +293,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"version\" : n, (numeric) The block version\n" + " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" + " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" + " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" + " ,...\n" + " },\n" + " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" @@ -458,9 +474,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) pindexPrev = pindexPrevNew; } CBlock* pblock = &pblocktemplate->block; // pointer for convenience + const Consensus::Params& consensusParams = Params().GetConsensus(); // Update nTime - UpdateTime(pblock, Params().GetConsensus(), pindexPrev); + UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); @@ -511,7 +528,36 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); + + UniValue aRules(UniValue::VARR); + UniValue vbavailable(UniValue::VOBJ); + for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) { + Consensus::DeploymentPos pos = Consensus::DeploymentPos(i); + ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); + switch (state) { + case THRESHOLD_DEFINED: + case THRESHOLD_FAILED: + // Not exposed to GBT at all + break; + case THRESHOLD_LOCKED_IN: + // Ensure bit is set in block version + pblock->nVersion |= VersionBitsMask(consensusParams, pos); + // FALL THROUGH to get vbavailable set... + case THRESHOLD_STARTED: + // Add to vbavailable (and it's presumably in version already) + vbavailable.push_back(Pair(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit)); + break; + case THRESHOLD_ACTIVE: + // Add to rules only + aRules.push_back(gbt_vb_name(pos)); + break; + } + } result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("rules", aRules)); + result.push_back(Pair("vbavailable", vbavailable)); + result.push_back(Pair("vbrequired", int(0))); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); diff --git a/src/versionbits.cpp b/src/versionbits.cpp index fbb60c0fc..041ca2adb 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -4,6 +4,17 @@ #include "versionbits.h" +#include "consensus/params.h" + +const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { + { + /*.name =*/ "testdummy", + }, + { + /*.name =*/ "csv", + } +}; + ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const { int nPeriod = Period(params); diff --git a/src/versionbits.h b/src/versionbits.h index 04f473827..d80594202 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -30,6 +30,13 @@ enum ThresholdState { // will either be NULL or a block with (height + 1) % Period() == 0. typedef std::map ThresholdConditionCache; +struct BIP9DeploymentInfo { + /** Deployment name */ + const char *name; +}; + +extern const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[]; + /** * Abstract class that implements BIP9-style threshold logic, and caches results. */ From 72cd6b20cae3d1eda2f917f1608a8ae7f1e606f7 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 May 2016 08:39:34 +0000 Subject: [PATCH 0722/1223] qa/rpc-tests: bip9-softforks: Add tests for getblocktemplate versionbits updates --- qa/rpc-tests/bip9-softforks.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index cbb1b7d4c..1b1f5dd0d 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -85,7 +85,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): raise IndexError ('key:"%s" not found' % key) - def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature): + def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno): # generate some coins for later self.coinbase_blocks = self.nodes[0].generate(2) self.height = 3 # height of the next block to build @@ -94,6 +94,11 @@ class BIP9SoftForksTest(ComparisonTestFramework): self.last_block_time = time.time() assert_equal(self.get_bip9_status(bipName)['status'], 'defined') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName not in tmpl['rules']) + assert(bipName not in tmpl['vbavailable']) + assert_equal(tmpl['vbrequired'], 0) + assert_equal(tmpl['version'], 0x20000000) # Test 1 # Advance from DEFINED to STARTED @@ -101,6 +106,11 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName not in tmpl['rules']) + assert_equal(tmpl['vbavailable'][bipName], bitno) + assert_equal(tmpl['vbrequired'], 0) + assert(tmpl['version'] & activated_version) # Test 2 # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 @@ -112,6 +122,11 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName not in tmpl['rules']) + assert_equal(tmpl['vbavailable'][bipName], bitno) + assert_equal(tmpl['vbrequired'], 0) + assert(tmpl['version'] & activated_version) # Test 3 # 108 out of 144 signal bit 1 to achieve LOCKED_IN @@ -123,6 +138,8 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName not in tmpl['rules']) # Test 4 # 143 more version 536870913 blocks (waiting period-1) @@ -130,6 +147,8 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName not in tmpl['rules']) # Test 5 # Check that the new rule is enforced @@ -153,6 +172,11 @@ class BIP9SoftForksTest(ComparisonTestFramework): yield TestInstance([[block, True]]) assert_equal(self.get_bip9_status(bipName)['status'], 'active') + tmpl = self.nodes[0].getblocktemplate({}) + assert(bipName in tmpl['rules']) + assert(bipName not in tmpl['vbavailable']) + assert_equal(tmpl['vbrequired'], 0) + assert(not (tmpl['version'] & (1 << bitno))) # Test 6 # Check that the new sequence lock rules are enforced @@ -187,9 +211,9 @@ class BIP9SoftForksTest(ComparisonTestFramework): def get_tests(self): for test in itertools.chain( - self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing), - self.test_BIP('csv', 536870913, self.mtp_invalidate, self.donothing), - self.test_BIP('csv', 536870913, self.donothing, self.csv_invalidate) + self.test_BIP('csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0), + self.test_BIP('csv', 0x20000001, self.mtp_invalidate, self.donothing, 0), + self.test_BIP('csv', 0x20000001, self.donothing, self.csv_invalidate, 0) ): yield test From 98790608a43e60b8025346034d28ff1f58cebab0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 1 Jun 2016 16:47:36 +0000 Subject: [PATCH 0723/1223] getblocktemplate: Explicitly handle the distinction between GBT-affecting softforks vs not --- src/rpc/mining.cpp | 32 ++++++++++++++++++++++++++++++-- src/versionbits.cpp | 2 ++ src/versionbits.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 277696fe0..9558b4c20 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -264,7 +264,9 @@ static UniValue BIP22ValidationResult(const CValidationState& state) std::string gbt_vb_name(const Consensus::DeploymentPos pos) { const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; std::string s = vbinfo.name; - s.insert(s.begin(), '!'); + if (!vbinfo.gbt_force) { + s.insert(s.begin(), '!'); + } return s; } @@ -342,6 +344,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) std::string strMode = "template"; UniValue lpval = NullUniValue; + std::set setClientRules; if (params.size() > 0) { const UniValue& oparam = params[0].get_obj(); @@ -385,6 +388,14 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } + + const UniValue& aClientRules = find_value(oparam, "rules"); + if (aClientRules.isArray()) { + for (unsigned int i = 0; i < aClientRules.size(); ++i) { + const UniValue& v = aClientRules[i]; + setClientRules.insert(v.get_str()); + } + } } if (strMode != "template") @@ -544,13 +555,30 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) pblock->nVersion |= VersionBitsMask(consensusParams, pos); // FALL THROUGH to get vbavailable set... case THRESHOLD_STARTED: - // Add to vbavailable (and it's presumably in version already) + { + const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; vbavailable.push_back(Pair(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit)); + if (setClientRules.find(vbinfo.name) == setClientRules.end()) { + if (!vbinfo.gbt_force) { + // If the client doesn't support this, don't indicate it in the [default] version + pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); + } + } break; + } case THRESHOLD_ACTIVE: + { // Add to rules only + const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; aRules.push_back(gbt_vb_name(pos)); + if (setClientRules.find(vbinfo.name) == setClientRules.end()) { + // Not supported by the client; make sure it's safe to proceed + if (!vbinfo.gbt_force) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); + } + } break; + } } } result.push_back(Pair("version", pblock->nVersion)); diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 041ca2adb..c06c9907b 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -9,9 +9,11 @@ const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { { /*.name =*/ "testdummy", + /*.gbt_force =*/ true, }, { /*.name =*/ "csv", + /*.gbt_force =*/ true, } }; diff --git a/src/versionbits.h b/src/versionbits.h index d80594202..ede2dcdda 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -33,6 +33,8 @@ typedef std::map ThresholdConditionCache; struct BIP9DeploymentInfo { /** Deployment name */ const char *name; + /** Whether GBT clients can safely ignore this rule in simplified usage */ + bool gbt_force; }; extern const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[]; From 12c708a4b3a799478fbb3f93fda696706177a824 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 1 Jun 2016 16:51:54 +0000 Subject: [PATCH 0724/1223] getblocktemplate: Use version/force mutation to support pre-BIP9 clients --- src/rpc/mining.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 9558b4c20..5a06d15c5 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -345,6 +345,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) std::string strMode = "template"; UniValue lpval = NullUniValue; std::set setClientRules; + int64_t nMaxVersionPreVB = -1; if (params.size() > 0) { const UniValue& oparam = params[0].get_obj(); @@ -395,6 +396,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } + } else { + // NOTE: It is important that this NOT be read if versionbits is supported + const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); + if (uvMaxVersion.isNum()) { + nMaxVersionPreVB = uvMaxVersion.get_int64(); + } } } @@ -529,13 +536,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static UniValue aMutable(UniValue::VARR); - if (aMutable.empty()) - { - aMutable.push_back("time"); - aMutable.push_back("transactions"); - aMutable.push_back("prevblock"); - } + UniValue aMutable(UniValue::VARR); + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); @@ -574,6 +578,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { + // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } @@ -586,6 +591,14 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("vbavailable", vbavailable)); result.push_back(Pair("vbrequired", int(0))); + if (nMaxVersionPreVB >= 2) { + // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here + // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks + // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated + // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated + aMutable.push_back("version/force"); + } + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); From faf82e8fc819b2f1f8b60983ac72cb111c47e8ba Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 3 Jun 2016 19:07:08 +0200 Subject: [PATCH 0725/1223] [rpc] fundrawtransaction: Fix help text and interface --- qa/rpc-tests/fundrawtransaction.py | 2 +- src/wallet/rpcwallet.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 5c11d3ab1..3040752dc 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -681,7 +681,7 @@ class RawTransactionsTest(BitcoinTestFramework): inputs = [] outputs = {self.nodes[2].getnewaddress() : 1} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = self.nodes[3].fundrawtransaction(rawtx, ) + result = self.nodes[3].fundrawtransaction(rawtx) # 1000 sat via settxfee result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000}) result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000}) assert_equal(result['fee']*2, result2['fee']) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5e6afcd7c..68895ac52 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2369,13 +2369,13 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" - " \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n" + " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (satoshis per KB)\n" " }\n" " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" - " \"fee\": n, (numeric) Fee the resulting transaction pays\n" + " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n" " \"changepos\": n (numeric) The position of the added change output, or -1\n" "}\n" "\"hex\" \n" From d3d02d51453943bfe3a9edb944eb48f9f1e01aca Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Mon, 6 Jun 2016 14:42:34 -0700 Subject: [PATCH 0726/1223] drop vAddrToSend after sending big addr message We send a newly-accepted peer a 1000-entry addr message, and then only use vAddrToSend for small messages. Deallocate vAddrToSend after it's been used for the big message to save about 40 kB per connected inbound peer. --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index fc8e72a7d..5fff4187a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5713,6 +5713,9 @@ bool SendMessages(CNode* pto) pto->vAddrToSend.clear(); if (!vAddr.empty()) pto->PushMessage(NetMsgType::ADDR, vAddr); + // we only send the big addr message once + if (pto->vAddrToSend.capacity() > 40) + pto->vAddrToSend.shrink_to_fit(); } CNodeState &state = *State(pto->GetId()); From fa51a1d2b73580e240a4750144ceb14022deeae2 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 6 Jun 2016 17:20:58 +0200 Subject: [PATCH 0727/1223] [init] Make feefilter option debug option --- src/init.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 9a2250185..3a260d16d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -319,7 +319,8 @@ std::string HelpMessage(HelpMessageMode mode) } strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); - strUsage += HelpMessageOpt("-feefilter", strprintf(_("Tell other nodes to filter invs to us by our mempool min fee (default: %u)"), DEFAULT_FEEFILTER)); + if (showDebug) + strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file on startup")); strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); strUsage += HelpMessageOpt("-maxmempool=", strprintf(_("Keep the transaction memory pool below megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE)); From 8b78486d02ed3c1c217d79ebca78a70d73e0d570 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 2 Jun 2016 13:52:09 +0200 Subject: [PATCH 0728/1223] Log/report in 10% steps during VerifyDB --- src/main.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 162c8b986..a71269821 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3873,10 +3873,18 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, CBlockIndex* pindexFailure = NULL; int nGoodTransactions = 0; CValidationState state; + int reportDone = 0; + LogPrintf("[0%]..."); for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { boost::this_thread::interruption_point(); - uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))))); + int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))); + if (reportDone < percentageDone/10) { + // report every 10% step + LogPrintf("[%d%%]...", percentageDone); + reportDone = percentageDone/10; + } + uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone); if (pindex->nHeight < chainActive.Height()-nCheckDepth) break; if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) { @@ -3934,6 +3942,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, } } + LogPrintf("[DONE].\n"); LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions); return true; From fa7f4f577cbab2b4bc03b5427704c2ec16680c34 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 6 Jun 2016 17:50:50 +0200 Subject: [PATCH 0729/1223] [rpc] fundrawtransaction feeRate: Use BTC/kB Also introduce UniValueType UniValueType is a wrapper for UniValue::VType which allows setting a typeAny flag. This flag indicates the type does not matter. (Used by RPCTypeCheckObj) --- qa/rpc-tests/fundrawtransaction.py | 6 +++--- src/rpc/rawtransaction.cpp | 15 +++++++++++++-- src/rpc/server.cpp | 14 ++++++-------- src/rpc/server.h | 15 ++++++++++++--- src/wallet/rpcwallet.cpp | 20 ++++++++++++++++---- 5 files changed, 50 insertions(+), 20 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 3040752dc..998f822af 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -681,9 +681,9 @@ class RawTransactionsTest(BitcoinTestFramework): inputs = [] outputs = {self.nodes[2].getnewaddress() : 1} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) - result = self.nodes[3].fundrawtransaction(rawtx) # 1000 sat via settxfee - result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000}) - result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000}) + result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee) + result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}) + result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee}) assert_equal(result['fee']*2, result2['fee']) assert_equal(result['fee']*10, result3['fee']) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 483fe746c..f92ddb282 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -675,7 +675,12 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) UniValue prevOut = p.get_obj(); - RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); + RPCTypeCheckObj(prevOut, + { + {"txid", UniValueType(UniValue::VSTR)}, + {"vout", UniValueType(UniValue::VNUM)}, + {"scriptPubKey", UniValueType(UniValue::VSTR)}, + }); uint256 txid = ParseHashO(prevOut, "txid"); @@ -703,7 +708,13 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { - RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); + RPCTypeCheckObj(prevOut, + { + {"txid", UniValueType(UniValue::VSTR)}, + {"vout", UniValueType(UniValue::VNUM)}, + {"scriptPubKey", UniValueType(UniValue::VSTR)}, + {"redeemScript", UniValueType(UniValue::VSTR)}, + }); UniValue v = find_value(prevOut, "redeemScript"); if (!v.isNull()) { vector rsData(ParseHexV(v, "redeemScript")); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index d06a9142b..23149baa6 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -88,20 +88,18 @@ void RPCTypeCheck(const UniValue& params, } void RPCTypeCheckObj(const UniValue& o, - const map& typesExpected, - bool fAllowNull, - bool fStrict) + const map& typesExpected, + bool fAllowNull, + bool fStrict) { - BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) - { + for (const auto& t : typesExpected) { const UniValue& v = find_value(o, t.first); if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); - if (!((v.type() == t.second) || (fAllowNull && (v.isNull())))) - { + if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) { string err = strprintf("Expected type %s for %s, got %s", - uvTypeName(t.second), t.first, uvTypeName(v.type())); + uvTypeName(t.second.type), t.first, uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } } diff --git a/src/rpc/server.h b/src/rpc/server.h index b47133661..b5ccc153d 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -32,6 +32,15 @@ namespace RPCServer class CBlockIndex; class CNetAddr; +/** Wrapper for UniValue::VType, which includes typeAny: + * Used to denote don't care type. Only used by RPCTypeCheckObj */ +struct UniValueType { + UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} + UniValueType() : typeAny(true) {} + bool typeAny; + UniValue::VType type; +}; + class JSONRequest { public: @@ -60,17 +69,17 @@ bool RPCIsInWarmup(std::string *statusOut); /** * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that * the right number of arguments are passed, just that any passed are the correct type. - * Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); */ void RPCTypeCheck(const UniValue& params, const std::list& typesExpected, bool fAllowNull=false); /* Check for expected keys/value types in an Object. - Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type)); */ void RPCTypeCheckObj(const UniValue& o, - const std::map& typesExpected, bool fAllowNull=false, bool fStrict=false); + const std::map& typesExpected, + bool fAllowNull = false, + bool fStrict = false); /** Opaque base class for timers returned by NewTimerFunc. * This provides no methods at the moment, but makes sure that delete diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 68895ac52..1300e39aa 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2069,7 +2069,11 @@ UniValue lockunspent(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); const UniValue& o = output.get_obj(); - RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); + RPCTypeCheckObj(o, + { + {"txid", UniValueType(UniValue::VSTR)}, + {"vout", UniValueType(UniValue::VNUM)}, + }); string txid = find_value(o, "txid").get_str(); if (!IsHex(txid)) @@ -2369,7 +2373,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" - " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (satoshis per KB)\n" + " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n" " }\n" " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" @@ -2409,7 +2413,15 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) UniValue options = params[1]; - RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true); + RPCTypeCheckObj(options, + { + {"changeAddress", UniValueType(UniValue::VSTR)}, + {"changePosition", UniValueType(UniValue::VNUM)}, + {"includeWatching", UniValueType(UniValue::VBOOL)}, + {"lockUnspents", UniValueType(UniValue::VBOOL)}, + {"feeRate", UniValueType()}, // will be checked below + }, + true, true); if (options.exists("changeAddress")) { CBitcoinAddress address(options["changeAddress"].get_str()); @@ -2431,7 +2443,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (options.exists("feeRate")) { - feeRate = CFeeRate(options["feeRate"].get_real()); + feeRate = CFeeRate(AmountFromValue(options["feeRate"])); overrideEstimatedFeerate = true; } } From 288d85ddf2e0a0c9d25a23db56052883170466d0 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 7 Jun 2016 13:44:56 +0200 Subject: [PATCH 0730/1223] Get rid of CTxMempool::lookup() entirely --- src/main.cpp | 4 +++- src/test/policyestimator_tests.cpp | 18 +++++++++--------- src/txmempool.cpp | 16 +++------------- src/txmempool.h | 1 - 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index db0580bda..b581ece09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1445,8 +1445,10 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P LOCK(cs_main); - if (mempool.lookup(hash, txOut)) + std::shared_ptr ptx = mempool.get(hash); + if (ptx) { + txOut = *ptx; return true; } diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 644c3da21..2b00e6f56 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -74,9 +74,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // 9/10 blocks add 2nd highest and so on until ... // 1/10 blocks add lowest fee/pri transactions while (txHashes[9-h].size()) { - CTransaction btx; - if (mpool.lookup(txHashes[9-h].back(), btx)) - block.push_back(btx); + std::shared_ptr ptx = mpool.get(txHashes[9-h].back()); + if (ptx) + block.push_back(*ptx); txHashes[9-h].pop_back(); } } @@ -160,9 +160,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // Estimates should still not be below original for (int j = 0; j < 10; j++) { while(txHashes[j].size()) { - CTransaction btx; - if (mpool.lookup(txHashes[j].back(), btx)) - block.push_back(btx); + std::shared_ptr ptx = mpool.get(txHashes[j].back()); + if (ptx) + block.push_back(*ptx); txHashes[j].pop_back(); } } @@ -181,9 +181,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); - CTransaction btx; - if (mpool.lookup(hash, btx)) - block.push_back(btx); + std::shared_ptr ptx = mpool.get(hash); + if (ptx) + block.push_back(*ptx); } } mpool.removeForBlock(block, ++blocknum, dummyConflicted); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d39c9577f..205ffd637 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -831,16 +831,6 @@ std::shared_ptr CTxMemPool::get(const uint256& hash) const return i->GetSharedTx(); } -bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const -{ - auto tx = get(hash); - if (tx) { - result = *tx; - return true; - } - return false; -} - TxMempoolInfo CTxMemPool::info(const uint256& hash) const { LOCK(cs); @@ -960,9 +950,9 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { // If an entry in the mempool exists, always return that one, as it's guaranteed to never // conflict with the underlying cache, and it cannot have pruned entries (as it contains full) // transactions. First checking the underlying cache risks returning a pruned entry instead. - CTransaction tx; - if (mempool.lookup(txid, tx)) { - coins = CCoins(tx, MEMPOOL_HEIGHT); + shared_ptr ptx = mempool.get(txid); + if (ptx) { + coins = CCoins(*ptx, MEMPOOL_HEIGHT); return true; } return (base->GetCoins(txid, coins) && !coins.IsPruned()); diff --git a/src/txmempool.h b/src/txmempool.h index 2f407fe00..f0e9b2e2c 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -607,7 +607,6 @@ public: return (mapTx.count(hash) != 0); } - bool lookup(uint256 hash, CTransaction& result) const; std::shared_ptr get(const uint256& hash) const; TxMempoolInfo info(const uint256& hash) const; std::vector infoAll() const; From 053930ffc41ba33fe7ce26bde7097951fe0b8462 Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Mon, 23 May 2016 00:21:05 -0700 Subject: [PATCH 0731/1223] Avoid recalculating vchKeyedNetGroup in eviction logic. Lazy calculate vchKeyedNetGroup in CNode::GetKeyedNetGroup. --- src/net.cpp | 43 +++++++++---------------------------------- src/net.h | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index c09e3aedb..eb62ee8a0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -14,6 +14,7 @@ #include "clientversion.h" #include "consensus/consensus.h" #include "crypto/common.h" +#include "crypto/sha256.h" #include "hash.h" #include "primitives/transaction.h" #include "scheduler.h" @@ -838,6 +839,7 @@ struct NodeEvictionCandidate int64_t nTimeConnected; int64_t nMinPingUsecTime; CAddress addr; + std::vector vchKeyedNetGroup; }; static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) @@ -850,36 +852,8 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons return a.nTimeConnected > b.nTimeConnected; } -class CompareNetGroupKeyed -{ - std::vector vchSecretKey; -public: - CompareNetGroupKeyed() - { - vchSecretKey.resize(32, 0); - GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); - } - - bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) - { - std::vector vchGroupA, vchGroupB; - CSHA256 hashA, hashB; - std::vector vchA(32), vchB(32); - - vchGroupA = a.addr.GetGroup(); - vchGroupB = b.addr.GetGroup(); - - hashA.Write(begin_ptr(vchGroupA), vchGroupA.size()); - hashB.Write(begin_ptr(vchGroupB), vchGroupB.size()); - - hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); - hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); - - hashA.Finalize(begin_ptr(vchA)); - hashB.Finalize(begin_ptr(vchB)); - - return vchA < vchB; - } +static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { + return a.vchKeyedNetGroup < b.vchKeyedNetGroup; }; /** Try to find a connection to evict when the node is full. @@ -902,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr}; + NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->vchKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } } @@ -912,9 +886,8 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { // Protect connections with certain characteristics // Deterministically select 4 peers to protect by netgroup. - // An attacker cannot predict which netgroups will be protected. - static CompareNetGroupKeyed comparerNetGroupKeyed; - std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed); + // An attacker cannot predict which netgroups will be protected + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed); vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); if (vEvictionCandidates.empty()) return false; @@ -2392,6 +2365,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa lastSentFeeFilter = 0; nextSendTimeFeeFilter = 0; + CalculateKeyedNetGroup(); + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; diff --git a/src/net.h b/src/net.h index 403653e8c..019a3f7ee 100644 --- a/src/net.h +++ b/src/net.h @@ -9,6 +9,8 @@ #include "amount.h" #include "bloom.h" #include "compat.h" +#include "crypto/common.h" +#include "crypto/sha256.h" #include "limitedmap.h" #include "netbase.h" #include "protocol.h" @@ -362,6 +364,8 @@ public: CBloomFilter* pfilter; int nRefCount; NodeId id; + + std::vector vchKeyedNetGroup; protected: // Denial-of-service detection/prevention @@ -450,6 +454,22 @@ private: CNode(const CNode&); void operator=(const CNode&); + void CalculateKeyedNetGroup() { + static std::vector vchSecretKey; + if (vchSecretKey.empty()) { + vchSecretKey.resize(32, 0); + GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); + } + + std::vector vchNetGroup(this->addr.GetGroup()); + + CSHA256 hash; + hash.Write(begin_ptr(vchNetGroup), vchNetGroup.size()); + hash.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); + + vchKeyedNetGroup.resize(32, 0); + hash.Finalize(begin_ptr(vchKeyedNetGroup)); + } public: NodeId GetId() const { From 9bf156bb9ee4915fa7e8f84589d65f6598563c97 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 22 May 2016 11:06:18 +0200 Subject: [PATCH 0732/1223] Support SipHash with arbitrary byte writes --- src/hash.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/hash.h | 21 ++++++++++++++++++++- src/test/hash_tests.cpp | 17 +++++++++++++---- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/hash.cpp b/src/hash.cpp index a518314a5..20a83342d 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -100,12 +100,15 @@ CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) v[2] = 0x6c7967656e657261ULL ^ k0; v[3] = 0x7465646279746573ULL ^ k1; count = 0; + tmp = 0; } CSipHasher& CSipHasher::Write(uint64_t data) { uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; + assert(count % 8 == 0); + v3 ^= data; SIPROUND; SIPROUND; @@ -116,7 +119,35 @@ CSipHasher& CSipHasher::Write(uint64_t data) v[2] = v2; v[3] = v3; - count++; + count += 8; + return *this; +} + +CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size) +{ + uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; + uint64_t t = tmp; + int c = count; + + while (size--) { + t |= ((uint64_t)(*(data++))) << (8 * (c % 8)); + c++; + if ((c & 7) == 0) { + v3 ^= t; + SIPROUND; + SIPROUND; + v0 ^= t; + t = 0; + } + } + + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + count = c; + tmp = t; + return *this; } @@ -124,10 +155,12 @@ uint64_t CSipHasher::Finalize() const { uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; - v3 ^= ((uint64_t)count) << 59; + uint64_t t = tmp | (((uint64_t)count) << 56); + + v3 ^= t; SIPROUND; SIPROUND; - v0 ^= ((uint64_t)count) << 59; + v0 ^= t; v2 ^= 0xFF; SIPROUND; SIPROUND; diff --git a/src/hash.h b/src/hash.h index 600dabec5..db4e130ae 100644 --- a/src/hash.h +++ b/src/hash.h @@ -171,19 +171,38 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector Date: Wed, 25 May 2016 15:38:32 +0200 Subject: [PATCH 0733/1223] Use 64-bit SipHash of netgroups in eviction --- src/net.cpp | 39 ++++++++++++++++++++++++++------------- src/net.h | 22 +++------------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index eb62ee8a0..0bc501601 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -839,7 +839,7 @@ struct NodeEvictionCandidate int64_t nTimeConnected; int64_t nMinPingUsecTime; CAddress addr; - std::vector vchKeyedNetGroup; + uint64_t nKeyedNetGroup; }; static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) @@ -853,7 +853,7 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons } static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { - return a.vchKeyedNetGroup < b.vchKeyedNetGroup; + return a.nKeyedNetGroup < b.nKeyedNetGroup; }; /** Try to find a connection to evict when the node is full. @@ -876,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->vchKeyedNetGroup}; + NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } } @@ -908,24 +908,24 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { // Identify the network group with the most connections and youngest member. // (vEvictionCandidates is already sorted by reverse connect time) - std::vector naMostConnections; + uint64_t naMostConnections; unsigned int nMostConnections = 0; int64_t nMostConnectionsTime = 0; - std::map, std::vector > mapAddrCounts; + std::map > mapAddrCounts; BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) { - mapAddrCounts[node.addr.GetGroup()].push_back(node); - int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected; - size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size(); + mapAddrCounts[node.nKeyedNetGroup].push_back(node); + int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected; + size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size(); if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { nMostConnections = groupsize; nMostConnectionsTime = grouptime; - naMostConnections = node.addr.GetGroup(); + naMostConnections = node.nKeyedNetGroup; } } // Reduce to the network group with the most connections - vEvictionCandidates = mapAddrCounts[naMostConnections]; + vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]); // Do not disconnect peers if there is only one unprotected connection from their network group. // This step excessively favors netgroup diversity, and should be removed once more protective criteria are established. @@ -2318,6 +2318,8 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), + addr(addrIn), + nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)), addrKnown(5000, 0.001), filterInventoryKnown(50000, 0.000001) { @@ -2330,7 +2332,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nRecvBytes = 0; nTimeConnected = GetTime(); nTimeOffset = 0; - addr = addrIn; addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; nVersion = 0; strSubVer = ""; @@ -2365,8 +2366,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa lastSentFeeFilter = 0; nextSendTimeFeeFilter = 0; - CalculateKeyedNetGroup(); - BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; @@ -2599,3 +2598,17 @@ bool CBanDB::Read(banmap_t& banSet) int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); } + +/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad) +{ + static uint64_t k0 = 0, k1 = 0; + while (k0 == 0 && k1 == 0) { + // Make sure this only runs on the first invocation. + GetRandBytes((unsigned char*)&k0, sizeof(k0)); + GetRandBytes((unsigned char*)&k1, sizeof(k1)); + } + + std::vector vchNetGroup(ad.GetGroup()); + + return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize(); +} diff --git a/src/net.h b/src/net.h index 019a3f7ee..8df3cb421 100644 --- a/src/net.h +++ b/src/net.h @@ -9,8 +9,6 @@ #include "amount.h" #include "bloom.h" #include "compat.h" -#include "crypto/common.h" -#include "crypto/sha256.h" #include "limitedmap.h" #include "netbase.h" #include "protocol.h" @@ -337,7 +335,7 @@ public: int64_t nLastRecv; int64_t nTimeConnected; int64_t nTimeOffset; - CAddress addr; + const CAddress addr; std::string addrName; CService addrLocal; int nVersion; @@ -365,7 +363,7 @@ public: int nRefCount; NodeId id; - std::vector vchKeyedNetGroup; + const uint64_t nKeyedNetGroup; protected: // Denial-of-service detection/prevention @@ -454,22 +452,8 @@ private: CNode(const CNode&); void operator=(const CNode&); - void CalculateKeyedNetGroup() { - static std::vector vchSecretKey; - if (vchSecretKey.empty()) { - vchSecretKey.resize(32, 0); - GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); - } + static uint64_t CalculateKeyedNetGroup(const CAddress& ad); - std::vector vchNetGroup(this->addr.GetGroup()); - - CSHA256 hash; - hash.Write(begin_ptr(vchNetGroup), vchNetGroup.size()); - hash.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); - - vchKeyedNetGroup.resize(32, 0); - hash.Finalize(begin_ptr(vchKeyedNetGroup)); - } public: NodeId GetId() const { From 888483098e60f2a944f1d246bbfec4d14a2975f8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 7 Jun 2016 16:29:03 +0200 Subject: [PATCH 0734/1223] Use C++11 thread-safe static initializers --- src/coins.cpp | 6 +----- src/coins.h | 2 +- src/main.cpp | 7 ++----- src/net.cpp | 8 ++------ 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index b7dd293d6..39db7dedf 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -56,11 +56,7 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); } -SaltedTxidHasher::SaltedTxidHasher() -{ - GetRandBytes((unsigned char*)&k0, sizeof(k0)); - GetRandBytes((unsigned char*)&k1, sizeof(k1)); -} +SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits::max())), k1(GetRand(std::numeric_limits::max())) {} CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { } diff --git a/src/coins.h b/src/coins.h index 1dd908700..033651a43 100644 --- a/src/coins.h +++ b/src/coins.h @@ -269,7 +269,7 @@ class SaltedTxidHasher { private: /** Salt */ - uint64_t k0, k1; + const uint64_t k0, k1; public: SaltedTxidHasher(); diff --git a/src/main.cpp b/src/main.cpp index bf6e6d04b..da140cffa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4784,11 +4784,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_vNodes); // Use deterministic randomness to send to the same nodes for 24 hours // at a time so the addrKnowns of the chosen nodes prevent repeats - static uint64_t salt0 = 0, salt1 = 0; - while (salt0 == 0 && salt1 == 0) { - GetRandBytes((unsigned char*)&salt0, sizeof(salt0)); - GetRandBytes((unsigned char*)&salt1, sizeof(salt1)); - } + static const uint64_t salt0 = GetRand(std::numeric_limits::max()); + static const uint64_t salt1 = GetRand(std::numeric_limits::max()); uint64_t hashAddr = addr.GetHash(); multimap mapMix; const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60)); diff --git a/src/net.cpp b/src/net.cpp index 0bc501601..e29053cf5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2601,12 +2601,8 @@ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { /* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad) { - static uint64_t k0 = 0, k1 = 0; - while (k0 == 0 && k1 == 0) { - // Make sure this only runs on the first invocation. - GetRandBytes((unsigned char*)&k0, sizeof(k0)); - GetRandBytes((unsigned char*)&k1, sizeof(k1)); - } + static const uint64_t k0 = GetRand(std::numeric_limits::max()); + static const uint64_t k1 = GetRand(std::numeric_limits::max()); std::vector vchNetGroup(ad.GetGroup()); From ae357d5ab940dea5e2640361ae17fd8722a93c9f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 7 Jun 2016 17:37:35 +0200 Subject: [PATCH 0735/1223] [Bitcoin-Tx] Add tests for sequence number support --- src/test/data/bitcoin-util-test.json | 13 +++++++++++++ src/test/data/txcreatedata_seq0.hex | 1 + src/test/data/txcreatedata_seq1.hex | 1 + 3 files changed, 15 insertions(+) create mode 100644 src/test/data/txcreatedata_seq0.hex create mode 100644 src/test/data/txcreatedata_seq1.hex diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 3bf80ca43..5cb383de8 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -86,5 +86,18 @@ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "output_cmp": "txcreatedata2.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], + "output_cmp": "txcreatedata_seq0.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], + "output_cmp": "txcreatedata_seq1.hex" } ] diff --git a/src/test/data/txcreatedata_seq0.hex b/src/test/data/txcreatedata_seq0.hex new file mode 100644 index 000000000..db02b5e4a --- /dev/null +++ b/src/test/data/txcreatedata_seq0.hex @@ -0,0 +1 @@ +01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000 diff --git a/src/test/data/txcreatedata_seq1.hex b/src/test/data/txcreatedata_seq1.hex new file mode 100644 index 000000000..4cedcd975 --- /dev/null +++ b/src/test/data/txcreatedata_seq1.hex @@ -0,0 +1 @@ +01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000 From 86efa30ae3fd36aa77b19ff0f70bb89be9ec308e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 7 Jun 2016 19:57:54 +0200 Subject: [PATCH 0736/1223] [Bitcoin-Tx] fix missing test fixtures, fix 32bit atoi issue --- src/Makefile.test.include | 4 +++- src/bitcoin-tx.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 77cf1001e..2d7791232 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -17,7 +17,9 @@ EXTRA_DIST += \ test/data/txcreate2.hex \ test/data/txcreatedata1.hex \ test/data/txcreatedata2.hex \ - test/data/txcreatesign.hex + test/data/txcreatesign.hex \ + test/data/txcreatedata_seq0.hex \ + test/data/txcreatedata_seq1.hex JSON_TEST_FILES = \ test/data/script_tests.json \ diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index d5e2fc279..f9ea94b9f 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -206,7 +206,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) // extract the optional sequence number uint32_t nSequenceIn=std::numeric_limits::max(); if (vStrInputParts.size() > 2) - nSequenceIn = atoi(vStrInputParts[2]); + nSequenceIn = std::stoul(vStrInputParts[2]); // append to transaction input list CTxIn txin(txid, vout, CScript(), nSequenceIn); From c2715d3ab8d83be5bc256380b84d5467e85a4330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Tue, 7 Jun 2016 21:22:48 +0200 Subject: [PATCH 0737/1223] Do not shadow local variables --- src/test/base58_tests.cpp | 4 ++-- src/test/miner_tests.cpp | 4 ++-- src/test/pmt_tests.cpp | 4 ++-- src/test/prevector_tests.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index e5a2e28b2..01eb2aee9 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -79,7 +79,7 @@ class TestAddrTypeVisitor : public boost::static_visitor private: std::string exp_addrType; public: - TestAddrTypeVisitor(const std::string &exp_addrType) : exp_addrType(exp_addrType) { } + TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { } bool operator()(const CKeyID &id) const { return (exp_addrType == "pubkey"); @@ -100,7 +100,7 @@ class TestPayloadVisitor : public boost::static_visitor private: std::vector exp_payload; public: - TestPayloadVisitor(std::vector &exp_payload) : exp_payload(exp_payload) { } + TestPayloadVisitor(std::vector &_exp_payload) : exp_payload(_exp_payload) { } bool operator()(const CKeyID &id) const { uint160 exp_key(exp_payload); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 469862518..3f5f0ee98 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -385,8 +385,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) SetMockTime(0); mempool.clear(); - BOOST_FOREACH(CTransaction *tx, txFirst) - delete tx; + BOOST_FOREACH(CTransaction *_tx, txFirst) + delete _tx; fCheckpointsEnabled = true; } diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 2f3f60788..74ffe0cc7 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -37,8 +37,8 @@ BOOST_AUTO_TEST_CASE(pmt_test1) seed_insecure_rand(false); static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095}; - for (int n = 0; n < 12; n++) { - unsigned int nTx = nTxCounts[n]; + for (int i = 0; i < 12; i++) { + unsigned int nTx = nTxCounts[i]; // build a block with some dummy transactions CBlock block; diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index b39b90353..d1407c1da 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -192,8 +192,8 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (((r >> 21) % 32) == 7) { int values[4]; int num = 1 + (insecure_rand() % 4); - for (int i = 0; i < num; i++) { - values[i] = insecure_rand(); + for (int k = 0; k < num; k++) { + values[k] = insecure_rand(); } test.insert_range(insecure_rand() % (test.size() + 1), values, values + num); } From b676f38791edd4a276f7c7937ffdd98c0cd2cf08 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 7 Jun 2016 15:45:02 -0400 Subject: [PATCH 0738/1223] depends: allow for CONFIG_SITE to be used rather than stealing prefix This does not break any existing prefix behavior, only makes new behavior work. For example: CONFIG_SITE=$PWD/depends/x86_64-pc-linux-gnu/share/config.site ./configure --prefix=/ --- depends/config.site.in | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/depends/config.site.in b/depends/config.site.in index 984ddb1e6..e731537bf 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -1,24 +1,26 @@ +depends_prefix="`dirname ${ac_site_file}`/.." + cross_compiling=maybe host_alias=@HOST@ ac_tool_prefix=${host_alias}- if test -z $with_boost; then - with_boost=$prefix + with_boost=$depends_prefix fi if test -z $with_qt_plugindir; then - with_qt_plugindir=$prefix/plugins + with_qt_plugindir=$depends_prefix/plugins fi if test -z $with_qt_translationdir; then - with_qt_translationdir=$prefix/translations + with_qt_translationdir=$depends_prefix/translations fi if test -z $with_qt_bindir; then - with_qt_bindir=$prefix/native/bin + with_qt_bindir=$depends_prefix/native/bin fi if test -z $with_protoc_bindir; then - with_protoc_bindir=$prefix/native/bin + with_protoc_bindir=$depends_prefix/native/bin fi if test -z $with_comparison_tool; then - with_comparison_tool=$prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar + with_comparison_tool=$depends_prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar fi @@ -41,32 +43,32 @@ fi if test x@host_os@ = xmingw32; then if test -z $with_qt_incdir; then - with_qt_incdir=$prefix/include + with_qt_incdir=$depends_prefix/include fi if test -z $with_qt_libdir; then - with_qt_libdir=$prefix/lib + with_qt_libdir=$depends_prefix/lib fi fi -PATH=$prefix/native/bin:$PATH +PATH=$depends_prefix/native/bin:$PATH PKG_CONFIG="`which pkg-config` --static" # These two need to remain exported because pkg-config does not see them # otherwise. That means they must be unexported at the end of configure.ac to # avoid ruining the cache. Sigh. -export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig -export PKG_CONFIG_PATH=$prefix/share/pkgconfig +export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig +export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig -CPPFLAGS="-I$prefix/include/ $CPPFLAGS" -LDFLAGS="-L$prefix/lib $LDFLAGS" +CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" +LDFLAGS="-L$depends_prefix/lib $LDFLAGS" CC="@CC@" CXX="@CXX@" OBJC="${CC}" OBJCXX="${CXX}" -CCACHE=$prefix/native/bin/ccache -PYTHONPATH=$prefix/native/lib/python/dist-packages:$PYTHONPATH +CCACHE=$depends_prefix/native/bin/ccache +PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH if test -n "@AR@"; then AR=@AR@ From ad38204e6e114d383af0f17b18c216cae10d7686 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 7 Jun 2016 14:51:51 -0400 Subject: [PATCH 0739/1223] gitian: use CONFIG_SITE rather than hijacking the prefix --- contrib/gitian-descriptors/gitian-linux.yml | 6 +++--- contrib/gitian-descriptors/gitian-osx.yml | 6 +++--- contrib/gitian-descriptors/gitian-win.yml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 13941f5d5..2ea6769ef 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -74,7 +74,7 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist SOURCEDIST=`echo bitcoin-*.tar.gz` DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` @@ -95,11 +95,11 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security make ${MAKEOPTS} -C src check-symbols - make install-strip + make install-strip DESTDIR=${INSTALLPATH} cd installed find . -name "lib*.la" -delete find . -name "lib*.a" -delete diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index c430932f9..b37b35d76 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -90,7 +90,7 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist SOURCEDIST=`echo bitcoin-*.tar.gz` DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` @@ -112,9 +112,9 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} - make install-strip + make install-strip DESTDIR=${INSTALLPATH} make osx_volname make deploydir diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 9f7322f0b..6504a64b3 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -101,7 +101,7 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ make dist SOURCEDIST=`echo bitcoin-*.tar.gz` DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` @@ -125,11 +125,11 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security make deploy - make install-strip + make install-strip DESTDIR=${INSTALLPATH} cp -f bitcoin-*setup*.exe $OUTDIR/ cd installed mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ From 7e7eb2724e1d66b9d6675433798f312a71789a8f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 7 Jun 2016 22:09:28 -0400 Subject: [PATCH 0740/1223] gitian: create debug packages for linux/windows The -debug tarballs/zips contain detached debugging symbols. To use them, place in the same dir as the target binary, and invoke gdb as usual. Also, because the debug symbols add a substantial space requirement, the build dirs are now deleted when they're no longer needed. --- contrib/gitian-descriptors/gitian-linux.yml | 19 ++++++++++++++----- contrib/gitian-descriptors/gitian-win.yml | 18 +++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 2ea6769ef..cfd254cf1 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -26,9 +26,12 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu" - CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests LDFLAGS=-static-libstdc++" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="" - FAKETIME_PROGS="date ar ranlib nm strip" + FAKETIME_PROGS="date ar ranlib nm strip objcopy" + HOST_CFLAGS="-O2 -g" + HOST_CXXFLAGS="-O2 -g" + HOST_LDFLAGS=-static-libstdc++ export QT_RCC_TEST=1 export GZIP="-9n" @@ -95,20 +98,26 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security make ${MAKEOPTS} -C src check-symbols - make install-strip DESTDIR=${INSTALLPATH} + make install DESTDIR=${INSTALLPATH} cd installed find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME}/bin -type f -executable -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME}/lib -type f -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz cd ../../ + rm -rf distsrc-${i} done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src + mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux64-debug.tar.gz + mv ${OUTDIR}/${DISTNAME}-i686-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux32-debug.tar.gz mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 6504a64b3..bb57d2faf 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -30,8 +30,10 @@ script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" CONFIGFLAGS="--enable-reduce-exports --disable-gui-tests" - FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip" + FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip objcopy" FAKETIME_PROGS="date makensis zip" + HOST_CFLAGS="-O2 -g" + HOST_CXXFLAGS="-O2 -g" export QT_RCC_TEST=1 export GZIP="-9n" @@ -125,22 +127,28 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security make deploy - make install-strip DESTDIR=${INSTALLPATH} + make install DESTDIR=${INSTALLPATH} cp -f bitcoin-*setup*.exe $OUTDIR/ cd installed mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip - cd ../.. + find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip + find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip + cd ../../ + rm -rf distsrc-${i} done cd $OUTDIR rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz + mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip + mv ${OUTDIR}/${DISTNAME}-i686-*-debug.zip ${OUTDIR}/${DISTNAME}-win32-debug.zip mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip From e012f3cea0ca4096dd4dd59a356a973c43651912 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 8 Jun 2016 10:23:25 +0200 Subject: [PATCH 0741/1223] util: Add ParseUInt32 and ParseUInt64 Add error and range-checking parsers for unsigned 32 and 64 bit numbers. The 32-bit variant is required for parsing sequence numbers from the command line in `bitcoin-tx` (see #8164 for discussion). I've thrown in the 64-bit variant as a bonus, as I'm sure it will be needed at some point. Also adds tests, and updates `developer-notes.md`. --- doc/developer-notes.md | 2 +- src/test/util_tests.cpp | 63 ++++++++++++++++++++++++++++++++++++++++ src/utilstrencodings.cpp | 34 ++++++++++++++++++++++ src/utilstrencodings.h | 14 +++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index add2fb500..e40b73ffa 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -323,7 +323,7 @@ Strings and formatting buffer overflows and surprises with `\0` characters. Also some C string manipulations tend to act differently depending on platform, or even the user locale -- Use `ParseInt32`, `ParseInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing +- Use `ParseInt32`, `ParseInt64`, `ParseUInt32`, `ParseUInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing - *Rationale*: These functions do overflow checking, and avoid pesky locale issues diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index b99f952a0..e467a4171 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -376,6 +376,69 @@ BOOST_AUTO_TEST_CASE(test_ParseInt64) BOOST_CHECK(!ParseInt64("32482348723847471234", NULL)); } +BOOST_AUTO_TEST_CASE(test_ParseUInt32) +{ + uint32_t n; + // Valid values + BOOST_CHECK(ParseUInt32("1234", NULL)); + BOOST_CHECK(ParseUInt32("0", &n) && n == 0); + BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234); + BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal + BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647); + BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648); + BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295); + // Invalid values + BOOST_CHECK(!ParseUInt32("", &n)); + BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseUInt32(" -1", &n)); + BOOST_CHECK(!ParseUInt32("1 ", &n)); + BOOST_CHECK(!ParseUInt32("1a", &n)); + BOOST_CHECK(!ParseUInt32("aap", &n)); + BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex + BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseUInt32(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseUInt32("-2147483648", &n)); + BOOST_CHECK(!ParseUInt32("4294967296", &n)); + BOOST_CHECK(!ParseUInt32("-1234", &n)); + BOOST_CHECK(!ParseUInt32("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseUInt32("32482348723847471234", NULL)); +} + +BOOST_AUTO_TEST_CASE(test_ParseUInt64) +{ + uint64_t n; + // Valid values + BOOST_CHECK(ParseUInt64("1234", NULL)); + BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL); + BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL); + BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal + BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL); + BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL); + BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL); + BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL); + // Invalid values + BOOST_CHECK(!ParseUInt64("", &n)); + BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseUInt64(" -1", &n)); + BOOST_CHECK(!ParseUInt64("1 ", &n)); + BOOST_CHECK(!ParseUInt64("1a", &n)); + BOOST_CHECK(!ParseUInt64("aap", &n)); + BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseUInt64(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseUInt64("-9223372036854775809", NULL)); + BOOST_CHECK(!ParseUInt64("18446744073709551616", NULL)); + BOOST_CHECK(!ParseUInt64("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseUInt64("-2147483648", &n)); + BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n)); + BOOST_CHECK(!ParseUInt64("-1234", &n)); +} + BOOST_AUTO_TEST_CASE(test_ParseDouble) { double n; diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 0f9334cbe..5ffdb3be1 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -461,6 +461,40 @@ bool ParseInt64(const std::string& str, int64_t *out) n <= std::numeric_limits::max(); } +bool ParseUInt32(const std::string& str, uint32_t *out) +{ + if (!ParsePrechecks(str)) + return false; + if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range + return false; + char *endp = NULL; + errno = 0; // strtoul will not set errno if valid + unsigned long int n = strtoul(str.c_str(), &endp, 10); + if(out) *out = (uint32_t)n; + // Note that strtoul returns a *unsigned long int*, so even if it doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit + // platforms the size of these types may be different. + return endp && *endp == 0 && !errno && + n <= std::numeric_limits::max(); +} + +bool ParseUInt64(const std::string& str, uint64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range + return false; + char *endp = NULL; + errno = 0; // strtoull will not set errno if valid + unsigned long long int n = strtoull(str.c_str(), &endp, 10); + if(out) *out = (uint64_t)n; + // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *uint64_t*. + return endp && *endp == 0 && !errno && + n <= std::numeric_limits::max(); +} + + bool ParseDouble(const std::string& str, double *out) { if (!ParsePrechecks(str)) diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index d40613cfc..5744f78c6 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -70,6 +70,20 @@ bool ParseInt32(const std::string& str, int32_t *out); */ bool ParseInt64(const std::string& str, int64_t *out); +/** + * Convert decimal string to unsigned 32-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseUInt32(const std::string& str, uint32_t *out); + +/** + * Convert decimal string to unsigned 64-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseUInt64(const std::string& str, uint64_t *out); + /** * Convert string to double with strict parse error feedback. * @returns true if the entire string could be parsed as valid double, From cdf7dff4248ec4050e535079227dd57cbfb610e4 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 8 Jun 2016 13:25:50 +0200 Subject: [PATCH 0742/1223] OSX diskimages need 0775 folder permissions Avoids endless Gatekeeper warnings (#7085) --- contrib/gitian-descriptors/gitian-osx-signer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index fac61aa3d..8b2b1467c 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -34,5 +34,5 @@ script: | tar -xf ${UNSIGNED} OSX_VOLNAME="$(cat osx_volname)" ./detached-sig-apply.sh ${UNSIGNED} signature/osx - ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} From 77f63a4fcd0517a6804bde7285e1859d5a087d77 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Jun 2016 15:34:18 +0200 Subject: [PATCH 0743/1223] Fix two warnings for comparison between signed and unsigned --- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1300e39aa..2d4e95911 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2457,7 +2457,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (origTx.vout.size() == 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); - if (changePosition != -1 && (changePosition < 0 || changePosition > origTx.vout.size())) + if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > origTx.vout.size())) throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); CMutableTransaction tx(origTx); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f3d165472..9faf21591 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2232,7 +2232,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Insert change txn at random position: nChangePosInOut = GetRandInt(txNew.vout.size()+1); } - else if (nChangePosInOut > txNew.vout.size()) + else if ((unsigned int)nChangePosInOut > txNew.vout.size()) { strFailReason = _("Change index out of range"); return false; From 6fa950a57334e93e70d806532ee517cbd75a2338 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 8 Jun 2016 15:34:25 +0200 Subject: [PATCH 0744/1223] [RPC] Fix createrawtx sequence number unsigned int parsing --- qa/rpc-tests/rawtransactions.py | 14 ++++++++++++++ src/rpc/rawtransaction.cpp | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index aa403f058..ab6d2e8de 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -143,6 +143,20 @@ class RawTransactionsTest(BitcoinTestFramework): rawtx = self.nodes[0].createrawtransaction(inputs, outputs) decrawtx= self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['vin'][0]['sequence'], 1000) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}] + outputs = { self.nodes[0].getnewaddress() : 1 } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['vin'][0]['sequence'], 4294967294) if __name__ == '__main__': RawTransactionsTest().main() diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 992914f88..9723e394d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -388,8 +388,13 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) // set the sequence number if passed in the parameters object const UniValue& sequenceObj = find_value(o, "sequence"); - if (sequenceObj.isNum()) - nSequence = sequenceObj.get_int(); + if (sequenceObj.isNum()) { + int64_t seqNr64 = sequenceObj.get_int64(); + if (seqNr64 < 0 || seqNr64 > std::numeric_limits::max()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range"); + else + nSequence = (uint32_t)seqNr64; + } CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); From eebc23218758d89bce0b7cb0eced9fd654cd3d15 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 8 Jun 2016 15:49:27 +0200 Subject: [PATCH 0745/1223] test: Add more test vectors for siphash Add full test vectors from spec, test per byte and per 8 bytes. Builds on #8086. --- src/test/hash_tests.cpp | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index f62080c1d..82d61209b 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -47,6 +47,38 @@ BOOST_AUTO_TEST_CASE(murmurhash3) #undef T } +/* + SipHash-2-4 output with + k = 00 01 02 ... + and + in = (empty string) + in = 00 (1 byte) + in = 00 01 (2 bytes) + in = 00 01 02 (3 bytes) + ... + in = 00 01 02 ... 3e (63 bytes) + + from: https://131002.net/siphash/siphash24.c +*/ +uint64_t siphash_4_2_testvec[] = { + 0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d, + 0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137, + 0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7, + 0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5, + 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd, + 0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8, + 0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad, + 0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342, + 0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae, + 0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c, + 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95, + 0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb, + 0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a, + 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499, + 0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93, + 0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572 +}; + BOOST_AUTO_TEST_CASE(siphash) { CSipHasher hasher(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL); @@ -74,6 +106,22 @@ BOOST_AUTO_TEST_CASE(siphash) BOOST_CHECK_EQUAL(hasher.Finalize(), 0xe612a3cb9ecba951ull); BOOST_CHECK_EQUAL(SipHashUint256(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL, uint256S("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")), 0x7127512f72f27cceull); + + // Check test vectors from spec, one byte at a time + CSipHasher hasher2(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL); + for (uint8_t x=0; x Date: Wed, 8 Jun 2016 15:09:01 -0400 Subject: [PATCH 0746/1223] Tests: Edit bloated varint test and add option for 'barely expensive' tests --- qa/rpc-tests/p2p-fullblocktest.py | 90 +++++++++++++++++-------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index 19b90d4db..17fd40ef1 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -65,6 +65,10 @@ class FullBlockTest(ComparisonTestFramework): self.tip = None self.blocks = {} + def add_options(self, parser): + super().add_options(parser) + parser.add_option("--runbarelyexpensive", dest="runbarelyexpensive", default=True) + def run_test(self): self.test = TestManager(self, self.options.tmpdir) self.test.add_all_connections(self.nodes) @@ -875,10 +879,13 @@ class FullBlockTest(ComparisonTestFramework): yield rejected(RejectResult(16, b'bad-txns-nonfinal')) - # This checks that a block with a bloated VARINT between the block_header and the array of tx is rejected - # (previous behavior was that it was accepted.) It also checks that if you subsequently send that block - # with correct encoding, it should be accepted (i.e., the receiving node should not reject it on the - # basis that it's the same as an already-rejected block, which would be a DoS vulnerability.) + # This checks that a block with a bloated VARINT between the block_header and the array of tx such that + # the block is > MAX_BLOCK_SIZE with the bloated varint, but <= MAX_BLOCK_SIZE without the bloated varint, + # does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not + # care whether the bloated block is accepted or rejected; it only cares that the second block is accepted. + # + # What matters is that the receiving node should not reject the bloated block, and then reject the canonical + # block on the basis that it's the same as an already-rejected block (which would be a consensus failure.) # # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) # \ @@ -903,7 +910,7 @@ class FullBlockTest(ComparisonTestFramework): tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0))) b64a = update_block("64a", [tx]) assert_equal(len(b64a.serialize()), MAX_BLOCK_SIZE + 8) - yield rejected() + yield TestInstance([[self.tip, None]]) # comptool workaround: to make sure b64 is delivered, manually erase b64a from blockstore self.test.block_store.erase(b64a.sha256) @@ -941,7 +948,6 @@ class FullBlockTest(ComparisonTestFramework): update_block(66, [tx2, tx1]) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) - # Attempt to double-spend a transaction created in a block # # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) @@ -1239,46 +1245,48 @@ class FullBlockTest(ComparisonTestFramework): # Test re-org of a week's worth of blocks (1088 blocks) # This test takes a minute or two and can be accomplished in memory # - tip(88) - LARGE_REORG_SIZE = 1088 - test1 = TestInstance(sync_every_block=False) - spend=out[32] - for i in range(89, LARGE_REORG_SIZE + 89): - b = block(i, spend) - tx = CTransaction() - script_length = MAX_BLOCK_SIZE - len(b.serialize()) - 69 - script_output = CScript([b'\x00' * script_length]) - tx.vout.append(CTxOut(0, script_output)) - tx.vin.append(CTxIn(COutPoint(b.vtx[1].sha256, 0))) - b = update_block(i, [tx]) - assert_equal(len(b.serialize()), MAX_BLOCK_SIZE) - test1.blocks_and_transactions.append([self.tip, True]) - save_spendable_output() - spend = get_spendable_output() + if self.options.runbarelyexpensive: + tip(88) + LARGE_REORG_SIZE = 1088 + test1 = TestInstance(sync_every_block=False) + spend=out[32] + for i in range(89, LARGE_REORG_SIZE + 89): + b = block(i, spend) + tx = CTransaction() + script_length = MAX_BLOCK_SIZE - len(b.serialize()) - 69 + script_output = CScript([b'\x00' * script_length]) + tx.vout.append(CTxOut(0, script_output)) + tx.vin.append(CTxIn(COutPoint(b.vtx[1].sha256, 0))) + b = update_block(i, [tx]) + assert_equal(len(b.serialize()), MAX_BLOCK_SIZE) + test1.blocks_and_transactions.append([self.tip, True]) + save_spendable_output() + spend = get_spendable_output() - yield test1 - chain1_tip = i + yield test1 + chain1_tip = i - # now create alt chain of same length - tip(88) - test2 = TestInstance(sync_every_block=False) - for i in range(89, LARGE_REORG_SIZE + 89): - block("alt"+str(i)) - test2.blocks_and_transactions.append([self.tip, False]) - yield test2 + # now create alt chain of same length + tip(88) + test2 = TestInstance(sync_every_block=False) + for i in range(89, LARGE_REORG_SIZE + 89): + block("alt"+str(i)) + test2.blocks_and_transactions.append([self.tip, False]) + yield test2 - # extend alt chain to trigger re-org - block("alt" + str(chain1_tip + 1)) - yield accepted() + # extend alt chain to trigger re-org + block("alt" + str(chain1_tip + 1)) + yield accepted() - # ... and re-org back to the first chain - tip(chain1_tip) - block(chain1_tip + 1) - yield rejected() - block(chain1_tip + 2) - yield accepted() + # ... and re-org back to the first chain + tip(chain1_tip) + block(chain1_tip + 1) + yield rejected() + block(chain1_tip + 2) + yield accepted() + + chain1_tip += 2 - chain1_tip += 2 if __name__ == '__main__': From 74c134748291bff8b94244456ae6b97f8e587645 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 8 Jun 2016 20:21:18 +0200 Subject: [PATCH 0747/1223] gitian: Add --disable-bench to config flags for windows Forgot to do this in #7776. --- contrib/gitian-descriptors/gitian-win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index bb57d2faf..65f76e8df 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -29,7 +29,7 @@ files: [] script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" - CONFIGFLAGS="--enable-reduce-exports --disable-gui-tests" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip objcopy" FAKETIME_PROGS="date makensis zip" HOST_CFLAGS="-O2 -g" From 0d53a9e72f9694e84344f230317aa2485bc07960 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 9 Jun 2016 05:20:30 +0000 Subject: [PATCH 0748/1223] Update luke-jr's PGP key Same key, extended expiration date --- contrib/gitian-keys/luke-jr-key.pgp | Bin 6518 -> 6518 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/gitian-keys/luke-jr-key.pgp b/contrib/gitian-keys/luke-jr-key.pgp index 4406e6d5be02c1e9006c6ecccc1e4c7c0dbad60c..a2d34e75e1c16c17cb721633038813800dbe45b3 100644 GIT binary patch delta 4256 zcmV;R5MS^1GWIgCSpPuXaZYryc63(9iU(Tx20xYcM|Car2&hw#M@uO#ed*5hz8;cSsDztB~^ z*!uHEl#~<~71CNpe~!bQCp#C;=KD$swx5#N`r*45vmMoJxL zkSOQrZbx$%#-j&_%lcP@giqL3o#Q>8Ar&VkSHLfMwmxWb=XD9Map0F>t%>OU{8A7o zUPIhv`)f&I&a7A4IYfc#X$81#C`27-;90TWk}YJ-HSVdKY3oZOh>6kucK{fOOiWI~ z_RKci>?>cQn>T+OC$WQru;(z9K3Mh_N4inqmErkq#)wY}k9ZUc(tXMfRnQjIgjG>n zjg5_on&%vHALEzf!+*6$G&|_AvGZ95y3_oH-EN*g%?-3apUoo~iJ@38TV6y3k<=;k zlbwyC{m)7|3D0UHJH^J|uYtYHb|@r8Eqi%`24&WnaHClwU_$BJ^E+}n~bSB$Yc60a+Q8RpuN0lop!#|`Ho?X zBzNPZ40V5xz7}~^G`7SvJ#+_UU|n~(QdG-Ol;DK_d9B^X+ma#*3;5**q-ylNEYc{~ zSVacA4OFmHeM)fj*sJjl2_5M5h?8i`1GUuF#i9l`-mJb-DKvHwC%F9vLiYo;`kD)0 z6fIEZwmlQrN?I;~;G567g46t0swL7nbyBCPLGMQqS518NDkjl!AB1IKl+lf5CyZjsN5f7c$I< zkhp(7$ZxW2Sb>y&IkvNu4hj%tqxsUNc@0@PjYv!jg-9Jbp%x`NBP+BvMOh=LM15MS zD$jg8sEMKxhne|WI9jtO`|&dAn^oUar@iuuXOjKL4~68FUjZ4%Nbw%}FfK)x+DO2M zAs&Q+w?Kcg;G%Ts&gJ;RX?L?KtZ=)}dCY$y3hEJf;)8QnU{jcA5bjD|MReBv*9C=% zQI={Y9(9bRhg?n)b8$t}5wNf{w$CcNMYg~Sb);###P!T&s~gwX96Cw44L%NbykJ?B zUzQxHPE@6(1T)HibSp)MLIZue@Da6frI5bE3TvAsH{gZPDPJdTe`hNup3C?cN0162Z zy#kaZA@qo!9y%ZXEkZ|!HwpDX#?3Tv9_G_=yzA;kD||Wd(YnW-k=v>fP|y~2;}jYm z>CBeKY8sMW6bg~T|GSt)W2^@-CHNS<&7Ym!aV``ExM*INh7vZEXy zlq)Z2a=m~Yw@3c#FWy7WW9xlZPXFn#e6m(W$ar`(Kl}a;DI0mhR3d4$-1Sz_nE_Lwz&Nn z?h;M(2N~#-TG@7A5|kb=#_G`5fdwTWWy1`A+JAw#yTBNBh)b*Bf_PDIB`dw4>G;lF z_?(O2)lt=jvj0CUQObiZ*8b{*ulnU2;a?6_5!jkA21~IR^xbM=S0FLQRCfL%N6&qq znUsht{ExkDFA??`n|T#<8N|N14q{XyXMn~t3gsY|H-{Oq>&2aGOA;$i^$eEh5`}bF}FtLYF%=DElK;9i?>rOc&^0AL4L&g zJ#ns|0smsA`tu-a&;r$@6Uyhwnp?(oxPM`e7fKD3jp#icfol{R2UX>$(4XHmBGJ#% zUC1<+vpC-W%c|OkO8Z7zz*veXNGHTP!3oCZl4*j2N7=_ZVxlU{VUnfQE&V^9a9+p_ zpNAw9+OKq~`m-4I;X;695Ts-bJ|A-@JM12Tl&@8f{ zZ7+o#Q6hUYSTt%SEvA)9<>LT^MkRb|^dsBPF>Wz7ijmpgAfd<57ee@=X7{rU0wZwjv{+uUO4hP``Hgs9&}5zcr~Q(o=Y;6~}0x$a|OB zSR^2$liLhQe^*%ge+3B%&Th~E3JDOs0+b{n^oXAWw;%s%Uhkllnyop5uuYm82iz5p zWIa%!JoBJNszDLC-(5V-p**5OO^84mh!oenpJ0Ud$sZ_?l5s8Ky1EKcwZXQ%XbBvi zxY4VuPW0U(Jo?Uy)N}n}TRERT{9p2ss)3nDGu3)yf3c~EJii4Leyvvf+ydK*zv@m~ zlDMTt9hfS|VuWQ_$vCS(OaOa-`YY+wgAhQ&dgkEzqqMrY_Cg7<=Wl@~<%e6V2nKKT z1YyZ;tthN|twnlZAdfK+QGsEa-=94jh2~!m57Q0|jSuj{<3jSXNImlfdSpB>Ts6TA*Y?gP6;MEq=Lu>& zc`6fSle~VPO5BGQ_A14kg6}2msLn7lweDGT3IXbIf=ZF(E8Vb#50&zvKjOkx6g-xFE!6G^l2INY4_H z9;+KWNdyk_-1LS7s~JfB4H-*>_~C&C>k$%%a~_G=r%7KF@A-_TYp`+u*Xu^ym&h+V zfA^wD7>J$pEeo^;;0AZT2`UKuTQ6%*>B6)V8W|Wbd}^;QDmaos28Bl>F!Uu!HLu|d z))sq!!uRX2!fYmdrdsg;dPhWiPzzGdz>m#Wo;Ps46J{8goSaO11`mEWCP}4DO-&*+ z2)D=p_R3Qn%|OMgtk(lZ5`c~2&^A^We~Ucd5khQ93XYS)7Er$WLo#mkQ^=SPwoj5S z9e?@1-leD%tfAnxw2rjdX>j3WZ+DMw!iR}^C1>HaK;NBW1UcbDqj}#5y?(b(%)qSp z3)d)Ec|6sQ_QheJw^{C(LmiE;p~xnp^kkN@5)~{X*68+WtiXMy70^~mr@18oe}1l@ zXk^w*VP7Es`F1Dvm_JGjN+D@rh8dcE%a}U^RMCU4lOwJPj(_6Ju|S^lCV>(9#mMM? z`A)IaVf69+Asnt{shDPnD_lHAc%zA7)i*UxSf&Y5&DU9i4)jOkfot}|y%gjj^5$-m#sBj&A=ay(Zi1zJpK32FT zBBK~rOmv$A7Ws4dbh!;tLZx>APwMQ9R57pZ$uS0;o4F(Qakls=UlO-BA`{T`OiE@! zkd>In@(2T*B5~798s9RZsH%|54WQQbQs_~$J`o-Se^*%ghXn}<&TifS3JDOs0+b{n z^oXBUp&$TGI1I5A>xR;5_?^b4*2IjwY^nw(% z{=u#Rm~bT<1lTht!wQ8~m}={V7L6vjhrcy%TgCJgNgb)C7ob0lk|JBqFnI5Su$~jQ2?%wq@d0_A`<58X*f0;oM86VpAiMbRjR!sY5FjbDD5X=&hSq8)F14cYp zI0|W8&C|9pyuDj@@@B{*_Wki2@GRU-A)+V?K}x*{K1X@y>&zz|NgU27Hw5dgtpV`- zB%#xe3`P$dH(t|!!dG?Bx}8PBju`M8x6dEBs*QXg16Bg(d;4uq3$3JKe?G9i@XBn0 zWPV2~7*t+1VK_}B%tq-jd1RP#YYj*3!Lj>uvGa|ev2Clf+M_VK&xhti(tR_5X+Qr6 zUwklqugS5yXV%#$Y>^ia*2`{x6qx;=^-#=I>g(?TZcGLSC7|?r)>ovtzH~=RF<@`p zhJ4T0(Z3@xfS&KS^e~*=B0AqWhV-{;@6zWx7tufpiP;b3t^WF)as&FX0p2Z2k|Kwc CqBzt5 delta 4256 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 A(f|Me From d096d22446a1d126ea78170f37a148ce0ca43df2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 9 Jun 2016 11:09:21 +0200 Subject: [PATCH 0749/1223] build: Get rid of `CLIENT_DATE` Putting the build date in the executable is a practice that has no place in these days, now that deterministic building is increasingly common. Continues #7732 which did this for the GUI. --- share/genbuild.sh | 7 ------- src/clientversion.cpp | 9 --------- src/clientversion.h | 1 - src/init.cpp | 2 +- src/wallet/rpcdump.cpp | 2 +- 5 files changed, 2 insertions(+), 19 deletions(-) diff --git a/share/genbuild.sh b/share/genbuild.sh index a15cb34e4..1ef77d706 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -15,7 +15,6 @@ fi DESC="" SUFFIX="" -LAST_COMMIT_DATE="" if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then # clean 'dirty' status of touched files that haven't been modified git diff >/dev/null 2>/dev/null @@ -29,9 +28,6 @@ if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/ # otherwise generate suffix from git, i.e. string like "59887e8-dirty" SUFFIX=$(git rev-parse --short HEAD) git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX-dirty" - - # get a string like "2012-04-10 16:27:19 +0200" - LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")" fi if [ -n "$DESC" ]; then @@ -45,7 +41,4 @@ fi # only update build.h if necessary if [ "$INFO" != "$NEWINFO" ]; then echo "$NEWINFO" >"$FILE" - if [ -n "$LAST_COMMIT_DATE" ]; then - echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE" - fi fi diff --git a/src/clientversion.cpp b/src/clientversion.cpp index aae0569bb..bfe9e16f8 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -67,16 +67,7 @@ const std::string CLIENT_NAME("Satoshi"); #endif #endif -#ifndef BUILD_DATE -#ifdef GIT_COMMIT_DATE -#define BUILD_DATE GIT_COMMIT_DATE -#else -#define BUILD_DATE __DATE__ ", " __TIME__ -#endif -#endif - const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); -const std::string CLIENT_DATE(BUILD_DATE); static std::string FormatVersion(int nVersion) { diff --git a/src/clientversion.h b/src/clientversion.h index 6f255d69c..47263d534 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -59,7 +59,6 @@ static const int CLIENT_VERSION = extern const std::string CLIENT_NAME; extern const std::string CLIENT_BUILD; -extern const std::string CLIENT_DATE; std::string FormatFullVersion(); diff --git a/src/init.cpp b/src/init.cpp index 3a260d16d..ec4ce6b6d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -748,7 +748,7 @@ void InitLogging() fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS); LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); + LogPrintf("Bitcoin version %s\n", FormatFullVersion()); } /** Initialize bitcoin. diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index bb40cf724..14c2e31d9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -590,7 +590,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) std::sort(vKeyBirth.begin(), vKeyBirth.end()); // produce output - file << strprintf("# Wallet dump created by Bitcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE); + file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD); file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime())); file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); From 31444491f2e07c5ffd4d50827b54830ee3958a4d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Jun 2016 18:07:45 +0200 Subject: [PATCH 0750/1223] Add git and github tips and tricks to developer notes --- doc/developer-notes.md | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index add2fb500..0caad3b7a 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -381,3 +381,51 @@ GUI - *Rationale*: Model classes pass through events and data from the core, they should not interact with the user. That's where View classes come in. The converse also holds: try to not directly access core data structures from Views. + +Git and github tips +--------------------- + +- For resolving merge/rebase conflicts, it can be useful to enable diff3 style using + `git config merge.conflictstyle diff3`. Instead of + + <<< + yours + === + theirs + >>> + + you will see + + <<< + yours + ||| + original + === + theirs + >>> + + This may make it much clearer what caused the conflict. In this style, you can often just look + at what changed between *original* and *theirs*, and mechanically apply that to *yours* (or the other way around). + +- When reviewing patches which change indentation in C++ files, use `git diff -w` and `git show -w`. This makes + the diff algorithm ignore whitespace changes. This feature is also available on github.com, by adding `?w=1` + at the end of any URL which shows a diff. + +- When reviewing patches that change symbol names in many places, use `git diff --word-diff`. This will instead + of showing the patch as deleted/added *lines*, show deleted/added *words*. + +- When reviewing patches that move code around, try using + `git diff --patience commit~:old/file.cpp commit:new/file/name.cpp`, and ignoring everything except the + moved body of code which should show up as neither `+` or `-` lines. In case it was not a pure move, this may + even work when combined with the `-w` or `--word-diff` options described above. + +- When looking at other's pull requests, it may make sense to add the following section to your `.git/config` + file: + + [remote "upstream-pull"] + fetch = +refs/pull/*:refs/remotes/upstream-pull/* + url = git@github.com:bitcoin/bitcoin.git + + This will add an `upstream-pull` remote to your git repository, which can be fetched using `git fetch --all` + or `git fetch upstream-pull`. Afterwards, you can use `upstream-pull/NUMBER/head` in arguments to `git show`, + `git checkout` and anywhere a commit id would be acceptable to see the changes from pull request NUMBER. From 0dfd86956dcd2ac8a2223437e9bbd4f29bd35fce Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 14:48:22 -0500 Subject: [PATCH 0751/1223] Add getmempooldescendants RPC call --- src/rpc/blockchain.cpp | 67 +++++++++++++++++++++++++++++++++++++++++- src/rpc/client.cpp | 1 + 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6c005068d..e53ed1c1b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -302,7 +302,7 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" "\nResult (for verbose=false):\n" - "[ (json array of string)\n" + "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" " ,...\n" "]\n" @@ -356,6 +356,70 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } } +UniValue getmempooldescendants(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) { + throw runtime_error( + "getmempooldescendants txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool descendants.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of strings)\n" + " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempooldescendants", "\"mytxid\"") + + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = params[1].get_bool(); + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setDescendants; + mempool.CalculateDescendants(it, setDescendants); + // CTxMemPool::CalculateDescendants will include the given tx + setDescendants.erase(it); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + o.push_back(descendantIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + const CTxMemPoolEntry &e = *descendantIt; + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1081,6 +1145,7 @@ static const CRPCCommand commands[] = { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, + { "blockchain", "getmempooldescendants", &getmempooldescendants, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 3dfc27fff..d0675fdb4 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -103,6 +103,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "setban", 2 }, { "setban", 3 }, { "getmempoolancestors", 1 }, + { "getmempooldescendants", 1 }, }; class CRPCConvertTable From b09b8135ae1c4df103c68543c931e479fbb907ab Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 14:57:58 -0500 Subject: [PATCH 0752/1223] Add getmempoolentry RPC call --- src/rpc/blockchain.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e53ed1c1b..6a07bb8c4 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -420,6 +420,39 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } } +UniValue getmempoolentry(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) { + throw runtime_error( + "getmempoolentry txid\n" + "\nReturns mempool data for given transaction\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "\nResult:\n" + "{ (json object)\n" + + EntryDescriptionString() + + "}\n" + "\nExamples\n" + + HelpExampleCli("getmempoolentry", "\"mytxid\"") + + HelpExampleRpc("getmempoolentry", "\"mytxid\"") + ); + } + + uint256 hash = ParseHashV(params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + const CTxMemPoolEntry &e = *it; + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + return info; +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1146,6 +1179,7 @@ static const CRPCCommand commands[] = { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true }, { "blockchain", "getmempooldescendants", &getmempooldescendants, true }, + { "blockchain", "getmempoolentry", &getmempoolentry, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "gettxout", &gettxout, true }, From a9b8390222a19496922c05d0c3f31bd6f75e1ac6 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 4 Jan 2016 15:15:15 -0500 Subject: [PATCH 0753/1223] Add test coverage for new RPC calls --- qa/rpc-tests/mempool_packages.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 7ac85c1b6..35a7e2326 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -61,7 +61,14 @@ class MempoolPackagesTest(BitcoinTestFramework): descendant_fees = 0 descendant_size = 0 + descendants = [] + ancestors = list(chain) for x in reversed(chain): + # Check that getmempoolentry is consistent with getrawmempool + entry = self.nodes[0].getmempoolentry(x) + assert_equal(entry, mempool[x]) + + # Check that the descendant calculations are correct assert_equal(mempool[x]['descendantcount'], descendant_count) descendant_fees += mempool[x]['fee'] assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) @@ -70,6 +77,27 @@ class MempoolPackagesTest(BitcoinTestFramework): assert_equal(mempool[x]['descendantsize'], descendant_size) descendant_count += 1 + # Check that getmempooldescendants is correct + assert_equal(sorted(descendants), sorted(self.nodes[0].getmempooldescendants(x))) + descendants.append(x) + + # Check that getmempoolancestors is correct + ancestors.remove(x) + assert_equal(sorted(ancestors), sorted(self.nodes[0].getmempoolancestors(x))) + + # Check that getmempoolancestors/getmempooldescendants correctly handle verbose=true + v_ancestors = self.nodes[0].getmempoolancestors(chain[-1], True) + assert_equal(len(v_ancestors), len(chain)-1) + for x in v_ancestors.keys(): + assert_equal(mempool[x], v_ancestors[x]) + assert(chain[-1] not in v_ancestors.keys()) + + v_descendants = self.nodes[0].getmempooldescendants(chain[0], True) + assert_equal(len(v_descendants), len(chain)-1) + for x in v_descendants.keys(): + assert_equal(mempool[x], v_descendants[x]) + assert(chain[0] not in v_descendants.keys()) + # Check that descendant modified fees includes fee deltas from # prioritisetransaction self.nodes[0].prioritisetransaction(chain[-1], 0, 1000) From 7f6eda80438be452a0b6e079737fb6fe00bb26b7 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 17 May 2016 08:42:35 -0400 Subject: [PATCH 0754/1223] Add ancestor statistics to mempool entry RPC output --- src/rpc/blockchain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6a07bb8c4..1bb365d36 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -195,6 +195,9 @@ std::string EntryDescriptionString() " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n" + " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n" + " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" " ... ]\n"; @@ -214,6 +217,9 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + info.push_back(Pair("ancestorcount", e.GetCountWithAncestors())); + info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors())); + info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors())); const CTransaction& tx = e.GetTx(); set setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) From 176e19b571f722437043d2aa80a69ae21852c70d Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 17 May 2016 09:01:12 -0400 Subject: [PATCH 0755/1223] Mention new RPC's in release notes --- doc/release-notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 7d44b8cda..be619e41c 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -80,6 +80,13 @@ The following outputs are affected by this change: - REST `/rest/block/` (JSON format when including extended tx details) - `bitcoin-tx -json` +New mempool information RPC calls +--------------------------------- + +RPC calls have been added to output detailed statistics for individual mempool +entries, as well as to calculate the in-mempool ancestors or descendants of a +transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. + ### ZMQ Each ZMQ notification now contains an up-counting sequence number that allows From 654a21162252294b7dbd6c982fec88008af7335e Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Wed, 8 Jun 2016 13:26:18 -0700 Subject: [PATCH 0756/1223] developer notes: updates for C++11 - boost::scoped_ptr is obsolete - std::vector::data replaces begin_ptr / end_ptr --- doc/developer-notes.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index add2fb500..94bd86203 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -265,7 +265,7 @@ General C++ the `.h` to the `.cpp` should not result in build errors - Use the RAII (Resource Acquisition Is Initialization) paradigm where possible. For example by using - `scoped_pointer` for allocations in a function. + `unique_ptr` for allocations in a function. - *Rationale*: This avoids memory and resource leaks, and ensures exception safety @@ -284,10 +284,9 @@ C++ data structures - *Rationale*: Behavior is undefined. In C++ parlor this means "may reformat the universe", in practice this has resulted in at least one hard-to-debug crash bug -- Watch out for vector out-of-bounds exceptions. `&vch[0]` is illegal for an - empty vector, `&vch[vch.size()]` is always illegal. Use `begin_ptr(vch)` and - `end_ptr(vch)` to get the begin and end pointer instead (defined in - `serialize.h`) +- Watch out for out-of-bounds vector access. `&vch[vch.size()]` is illegal, + including `&vch[0]` for an empty vector. Use `vch.data()` and `vch.data() + + vch.size()` instead. - Vector bounds checking is only enabled in debug mode. Do not rely on it From 966151e71dc33cb5b97cf4243efd18afb4cf279d Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Thu, 9 Jun 2016 13:55:12 -0400 Subject: [PATCH 0757/1223] Add README for verify-commits --- contrib/verify-commits/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 contrib/verify-commits/README.md diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md new file mode 100644 index 000000000..e9e3f65da --- /dev/null +++ b/contrib/verify-commits/README.md @@ -0,0 +1,26 @@ +Tooling for verification of PGP signed commits +---------------------------------------------- + +This is an incomplete work in progress, but currently includes a pre-push hook +script (`pre-push-hook.sh`) for maintainers to ensure that their own commits +are PGP signed (nearly always merge commits), as well as a script to verify +commits against a trusted keys list. + + +Using verify-commits.sh safely +------------------------------ + +Remember that you can't use an untrusted script to verify itself. This means +that checking out code, then running `verify-commits.sh` against `HEAD` is +_not_ safe, because the version of `verify-commits.sh` that you just ran could +be backdoored. Instead, you need to use a trusted version of verify-commits +prior to checkout to make sure you're checking out only code signed by trusted +keys: + + git fetch origin && \ + ./contrib/verify-commits/verify-commits.sh origin/master && \ + git checkout origin/master + +Note that the above isn't a good UI/UX yet, and needs significant improvements +to make it more convenient and reduce the chance of errors; pull-reqs +improving this process would be much appreciated. From d1a3d570e5f4e59683cde9ccc0ac10d012ef7070 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 9 Jun 2016 17:49:16 -0400 Subject: [PATCH 0758/1223] bulid: fix "make translate" when out-of-tree --- src/Makefile.qt.include | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 29e3a264c..9381cca9f 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -390,13 +390,13 @@ QT_QM=$(QT_TS:.ts=.qm) SECONDARY: $(QT_QM) -qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) +$(srcdir)/qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^ -translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) +translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" - $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts qt/locale/bitcoin_en.ts + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/bitcoin_en.ts $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) From ac8d0418ed2891311cb786f32d39a54242aa2759 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 10 Jun 2016 10:12:00 +0200 Subject: [PATCH 0759/1223] qt: translations update --- src/qt/bitcoinstrings.cpp | 2 -- src/qt/locale/bitcoin_en.ts | 25 ++++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 23be8e016..9e53f1959 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -140,8 +140,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Support filtering of blocks and transaction with bloom filters (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Tell other nodes to filter invs to us by our mempool min fee (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "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 " diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 5549ccd4f..b90221f2c 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -3785,7 +3785,7 @@ bitcoin-core - + Options: Options: @@ -3810,7 +3810,7 @@ Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -3835,7 +3835,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -3865,7 +3865,7 @@ Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -3946,11 +3946,6 @@ - Tell other nodes to filter invs to us by our mempool min fee (default: %u) - - - - 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 @@ -4305,7 +4300,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -4375,7 +4370,7 @@ - + The transaction amount is too small to send after the fee has been deducted @@ -4580,12 +4575,12 @@ Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect @@ -4595,7 +4590,7 @@ Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -4645,7 +4640,7 @@ - + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. From 980e7eb98c81af5acc843cdd697ad277489252ad Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 9 Jun 2016 18:13:33 -0400 Subject: [PATCH 0760/1223] depends: only build qt on linux for x86_64/x86 --- depends/Makefile | 10 +++++++--- depends/packages/packages.mk | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/depends/Makefile b/depends/Makefile index 3ddfc85a4..dedb0674c 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -89,13 +89,17 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) -qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) -qt_native_packages_$(NO_QT) = $(qt_native_packages) +qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) upnp_packages_$(NO_UPNP) = $(upnp_packages) packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) -native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) $(qt_native_packages_) +native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) + +ifneq ($(qt_packages_),) +native_packages += $(qt_native_packages) +endif + all_packages = $(packages) $(native_packages) meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 59b009b66..ac43ef4a2 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -6,7 +6,9 @@ native_packages := native_ccache native_comparisontool qt_native_packages = native_protobuf qt_packages = qrencode protobuf -qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +qt_x86_64_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +qt_i686_linux_packages:=$(qt_x86_64_linux_packages) + qt_darwin_packages=qt qt_mingw32_packages=qt From 17c0131fad62bfc966da93b7e42c7f0e07948b51 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 10 Jun 2016 11:04:16 +0200 Subject: [PATCH 0761/1223] [Docs] Add release notes and bip update for Bip32/HD wallets --- doc/bips.md | 1 + doc/release-notes.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/doc/bips.md b/doc/bips.md index b8efabbcf..266544d7a 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -9,6 +9,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)). * [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)). * [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)). +* [`BIP 32`](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki): Hierarchical Deterministic Wallets has been implemented since **v0.13.0** ([PR #8035](https://github.com/bitcoin/bitcoin/pull/8035)). * [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)). * [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)). * [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)). diff --git a/doc/release-notes.md b/doc/release-notes.md index 7d44b8cda..72f69446f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -112,6 +112,24 @@ feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawik ### Wallet +Hierarchical Deterministic Key Generation +----------------------------------------- +Newly created wallets will use hierarchical deterministic key generation +according to BIP32 (keypath m/0'/0'/k'). +Existing wallets will still use traditional key generation. + +Backups of HD wallets, regardless of when they have been created, can +therefore be used to re-generate all possible private keys, even the +ones which haven't already been generated during the time of the backup. + +HD key generation for new wallets can be disabled by `-usehd=0`. Keep in +mind that this flag only has affect on newly created wallets. +You can't disable HD key generation once you have created a HD wallet. + +There is no distinction between internal (change) and external keys. + +[Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + ### GUI ### Tests From 9d253620874087d96d64d0c4c771a582d9774657 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 10 Jun 2016 02:56:42 -0400 Subject: [PATCH 0762/1223] build: add armhf/aarch64 gitian builds - create a script to handle split debug. This will also eventually need to check targets, and use dsymutil for osx. - update config.guess/config.sub for bdb for aarch64. - temporarily disable symbol checks for arm/aarch64 - quit renaming to linux32/linux64 and use the host directly This also adds a hack to work around an Ubuntu bug in the gcc-multilib package: https://bugs.launchpad.net/ubuntu/+source/gcc-defaults-armhf-cross/+bug/1347820 The problem is that gcc-multilib conflicts with the aarch toolchain. gcc-multilib installs a symlink that points /usr/include/asm -> /usr/include/x86_64-linux-gnu/asm. Without this link, gcc -m32 can't find asm/errno.h (and others), since /usr/include/x86_64-linux-gnu isn't in its default include path. But /usr/include/i386-linux-gnu is (though it doesn't exist on disk). So work around the problem by linking /usr/include/i386-linux-gnu/asm -> /usr/include/x86_64-linux-gnu/asm. The symlink fix is actually quite reasonable, but echoing the password into sudo is nasty, and should probably be addressed in gitian itself. It makes more sense to enable passwordless sudo for the build user by default. --- configure.ac | 2 + contrib/devtools/split-debug.sh.in | 10 +++++ contrib/gitian-descriptors/gitian-linux.yml | 45 +++++++++++++++------ depends/packages/bdb.mk | 3 +- 4 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 contrib/devtools/split-debug.sh.in diff --git a/configure.ac b/configure.ac index 7f9ff20cd..97af58bd7 100644 --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,7 @@ AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) AC_PATH_TOOL(READELF, readelf) AC_PATH_TOOL(CPPFILT, c++filt) +AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) @@ -1060,6 +1061,7 @@ AC_SUBST(MINIUPNPC_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) +AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a diff --git a/contrib/devtools/split-debug.sh.in b/contrib/devtools/split-debug.sh.in new file mode 100644 index 000000000..deda49cc5 --- /dev/null +++ b/contrib/devtools/split-debug.sh.in @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ $# -ne 3 ]; + then echo "usage: $0 " +fi + +@OBJCOPY@ --enable-deterministic-archives -p --only-keep-debug $1 $3 +@OBJCOPY@ --enable-deterministic-archives -p --strip-debug $1 $2 +@STRIP@ --enable-deterministic-archives -p -s $2 +@OBJCOPY@ --enable-deterministic-archives -p --add-gnu-debuglink=$3 $2 diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index cd289b2f6..fb629578d 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -7,7 +7,17 @@ architectures: - "amd64" packages: - "curl" -- "g++-multilib" +- "g++-aarch64-linux-gnu" +- "g++-4.8-aarch64-linux-gnu" +- "gcc-4.8-aarch64-linux-gnu" +- "binutils-aarch64-linux-gnu" +- "g++-arm-linux-gnueabihf" +- "g++-4.8-arm-linux-gnueabihf" +- "gcc-4.8-arm-linux-gnueabihf" +- "binutils-arm-linux-gnueabihf" +- "g++-4.8-multilib" +- "gcc-4.8-multilib" +- "binutils-gold" - "git-core" - "pkg-config" - "autoconf" @@ -15,7 +25,6 @@ packages: - "automake" - "faketime" - "bsdmainutils" -- "binutils-gold" - "ca-certificates" - "python" remotes: @@ -23,11 +32,18 @@ remotes: "dir": "bitcoin" files: [] script: | + + #unlock sudo + echo "ubuntu" | sudo -S true + + sudo mkdir -p /usr/include/i386-linux-gnu/ + sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/i386-linux-gnu/asm + WRAP_DIR=$HOME/wrapped - HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu" + HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="" - FAKETIME_PROGS="date ar ranlib nm strip objcopy" + FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ @@ -111,14 +127,24 @@ script: | CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security - make ${MAKEOPTS} -C src check-symbols + + #TODO: This is a quick hack that disables symbol checking for arm. + # Instead, we should investigate why these are popping up. + # For aarch64, we'll need to bump up the min GLIBC version, as the abi + # support wasn't introduced until 2.17. + case $i in + aarch64-*) : ;; + arm-*) : ;; + *) make ${MAKEOPTS} -C src check-symbols ;; + esac + make install DESTDIR=${INSTALLPATH} cd installed find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find ${DISTNAME}/bin -type f -executable -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; - find ${DISTNAME}/lib -type f -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME}/bin -type f -executable -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; + find ${DISTNAME}/lib -type f -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \; find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz cd ../../ @@ -126,8 +152,3 @@ script: | done mkdir -p $OUTDIR/src mv $SOURCEDIST $OUTDIR/src - mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux64-debug.tar.gz - mv ${OUTDIR}/${DISTNAME}-i686-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux32-debug.tar.gz - mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz - mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz - diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 200d57314..6c9876c2c 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -14,7 +14,8 @@ endef define $(package)_preprocess_cmds sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \ - sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c + sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub dist endef define $(package)_config_cmds From 60ab9b200654ef0914459711cf2b22be16be3dc2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 10 Jun 2016 15:19:51 +0200 Subject: [PATCH 0763/1223] Squashed 'src/univalue/' changes from 2740c4f..f32df99 f32df99 Merge branch '2016_04_unicode' into bitcoin 280b191 Merge remote-tracking branch 'jgarzik/master' into bitcoin c9a716c Handle UTF-8 bed8dd9 Version 1.0.2. 5e7985a Merge pull request #14 from laanwj/2015_11_escape_plan git-subtree-dir: src/univalue git-subtree-split: f32df99e96d99ab49e5eeda16cac93747d388245 --- Makefile.am | 9 ++- configure.ac | 6 +- lib/univalue_read.cpp | 37 +++++------- lib/univalue_utffilter.h | 119 +++++++++++++++++++++++++++++++++++++++ lib/univalue_write.cpp | 11 +--- test/fail38.json | 1 + test/fail39.json | 1 + test/fail40.json | 1 + test/fail41.json | 1 + test/round2.json | 1 + test/unitester.cpp | 31 ++++++++++ 11 files changed, 181 insertions(+), 37 deletions(-) create mode 100644 lib/univalue_utffilter.h create mode 100644 test/fail38.json create mode 100644 test/fail39.json create mode 100644 test/fail40.json create mode 100644 test/fail41.json create mode 100644 test/round2.json diff --git a/Makefile.am b/Makefile.am index 34fe9e3f1..6c1ec81e6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 .INTERMEDIATE: $(GENBIN) include_HEADERS = include/univalue.h -noinst_HEADERS = lib/univalue_escapes.h +noinst_HEADERS = lib/univalue_escapes.h lib/univalue_utffilter.h lib_LTLIBRARIES = libunivalue.la @@ -73,6 +73,10 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail35.json \ $(TEST_DATA_DIR)/fail36.json \ $(TEST_DATA_DIR)/fail37.json \ + $(TEST_DATA_DIR)/fail38.json \ + $(TEST_DATA_DIR)/fail39.json \ + $(TEST_DATA_DIR)/fail40.json \ + $(TEST_DATA_DIR)/fail41.json \ $(TEST_DATA_DIR)/fail3.json \ $(TEST_DATA_DIR)/fail4.json \ $(TEST_DATA_DIR)/fail5.json \ @@ -83,6 +87,7 @@ TEST_FILES = \ $(TEST_DATA_DIR)/pass1.json \ $(TEST_DATA_DIR)/pass2.json \ $(TEST_DATA_DIR)/pass3.json \ - $(TEST_DATA_DIR)/round1.json + $(TEST_DATA_DIR)/round1.json \ + $(TEST_DATA_DIR)/round2.json EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/configure.ac b/configure.ac index 0515b632b..93d3ba945 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ m4_define([libunivalue_major_version], [1]) m4_define([libunivalue_minor_version], [1]) -m4_define([libunivalue_micro_version], [1]) -m4_define([libunivalue_interface_age], [1]) +m4_define([libunivalue_micro_version], [2]) +m4_define([libunivalue_interface_age], [2]) # If you need a modifier for the version number. # Normally empty, but can be used to make "fixup" releases. m4_define([libunivalue_extraversion], []) @@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.1], +AC_INIT([univalue], [1.0.2], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used diff --git a/lib/univalue_read.cpp b/lib/univalue_read.cpp index c7516b962..95bac6958 100644 --- a/lib/univalue_read.cpp +++ b/lib/univalue_read.cpp @@ -6,6 +6,7 @@ #include #include #include "univalue.h" +#include "univalue_utffilter.h" using namespace std; @@ -174,41 +175,31 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, raw++; // skip " string valStr; + JSONUTF8StringFilter writer(valStr); while (*raw) { - if (*raw < 0x20) + if ((unsigned char)*raw < 0x20) return JTOK_ERR; else if (*raw == '\\') { raw++; // skip backslash switch (*raw) { - case '"': valStr += "\""; break; - case '\\': valStr += "\\"; break; - case '/': valStr += "/"; break; - case 'b': valStr += "\b"; break; - case 'f': valStr += "\f"; break; - case 'n': valStr += "\n"; break; - case 'r': valStr += "\r"; break; - case 't': valStr += "\t"; break; + case '"': writer.push_back('\"'); break; + case '\\': writer.push_back('\\'); break; + case '/': writer.push_back('/'); break; + case 'b': writer.push_back('\b'); break; + case 'f': writer.push_back('\f'); break; + case 'n': writer.push_back('\n'); break; + case 'r': writer.push_back('\r'); break; + case 't': writer.push_back('\t'); break; case 'u': { unsigned int codepoint; if (hatoui(raw + 1, raw + 1 + 4, codepoint) != raw + 1 + 4) return JTOK_ERR; - - if (codepoint <= 0x7f) - valStr.push_back((char)codepoint); - else if (codepoint <= 0x7FF) { - valStr.push_back((char)(0xC0 | (codepoint >> 6))); - valStr.push_back((char)(0x80 | (codepoint & 0x3F))); - } else if (codepoint <= 0xFFFF) { - valStr.push_back((char)(0xE0 | (codepoint >> 12))); - valStr.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F))); - valStr.push_back((char)(0x80 | (codepoint & 0x3F))); - } - + writer.push_back_u(codepoint); raw += 4; break; } @@ -226,11 +217,13 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, } else { - valStr += *raw; + writer.push_back(*raw); raw++; } } + if (!writer.finalize()) + return JTOK_ERR; tokenVal = valStr; consumed = (raw - rawStart); return JTOK_STRING; diff --git a/lib/univalue_utffilter.h b/lib/univalue_utffilter.h new file mode 100644 index 000000000..0e330dce9 --- /dev/null +++ b/lib/univalue_utffilter.h @@ -0,0 +1,119 @@ +// Copyright 2016 Wladimir J. van der Laan +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef UNIVALUE_UTFFILTER_H +#define UNIVALUE_UTFFILTER_H + +#include + +/** + * Filter that generates and validates UTF-8, as well as collates UTF-16 + * surrogate pairs as specified in RFC4627. + */ +class JSONUTF8StringFilter +{ +public: + JSONUTF8StringFilter(std::string &s): + str(s), is_valid(true), codepoint(0), state(0), surpair(0) + { + } + // Write single 8-bit char (may be part of UTF-8 sequence) + void push_back(unsigned char ch) + { + if (state == 0) { + if (ch < 0x80) // 7-bit ASCII, fast direct pass-through + str.push_back(ch); + else if (ch < 0xc0) // Mid-sequence character, invalid in this state + is_valid = false; + else if (ch < 0xe0) { // Start of 2-byte sequence + codepoint = (ch & 0x1f) << 6; + state = 6; + } else if (ch < 0xf0) { // Start of 3-byte sequence + codepoint = (ch & 0x0f) << 12; + state = 12; + } else if (ch < 0xf8) { // Start of 4-byte sequence + codepoint = (ch & 0x07) << 18; + state = 18; + } else // Reserved, invalid + is_valid = false; + } else { + if ((ch & 0xc0) != 0x80) // Not a continuation, invalid + is_valid = false; + state -= 6; + codepoint |= (ch & 0x3f) << state; + if (state == 0) + push_back_u(codepoint); + } + } + // Write codepoint directly, possibly collating surrogate pairs + void push_back_u(unsigned int codepoint) + { + if (state) // Only accept full codepoints in open state + is_valid = false; + if (codepoint >= 0xD800 && codepoint < 0xDC00) { // First half of surrogate pair + if (surpair) // Two subsequent surrogate pair openers - fail + is_valid = false; + else + surpair = codepoint; + } else if (codepoint >= 0xDC00 && codepoint < 0xE000) { // Second half of surrogate pair + if (surpair) { // Open surrogate pair, expect second half + // Compute code point from UTF-16 surrogate pair + append_codepoint(0x10000 | ((surpair - 0xD800)<<10) | (codepoint - 0xDC00)); + surpair = 0; + } else // Second half doesn't follow a first half - fail + is_valid = false; + } else { + if (surpair) // First half of surrogate pair not followed by second - fail + is_valid = false; + else + append_codepoint(codepoint); + } + } + // Check that we're in a state where the string can be ended + // No open sequences, no open surrogate pairs, etc + bool finalize() + { + if (state || surpair) + is_valid = false; + return is_valid; + } +private: + std::string &str; + bool is_valid; + // Current UTF-8 decoding state + unsigned int codepoint; + int state; // Top bit to be filled in for next UTF-8 byte, or 0 + + // Keep track of the following state to handle the following section of + // RFC4627: + // + // To escape an extended character that is not in the Basic Multilingual + // Plane, the character is represented as a twelve-character sequence, + // encoding the UTF-16 surrogate pair. So, for example, a string + // containing only the G clef character (U+1D11E) may be represented as + // "\uD834\uDD1E". + // + // Two subsequent \u.... may have to be replaced with one actual codepoint. + unsigned int surpair; // First half of open UTF-16 surrogate pair, or 0 + + void append_codepoint(unsigned int codepoint) + { + if (codepoint <= 0x7f) + str.push_back((char)codepoint); + else if (codepoint <= 0x7FF) { + str.push_back((char)(0xC0 | (codepoint >> 6))); + str.push_back((char)(0x80 | (codepoint & 0x3F))); + } else if (codepoint <= 0xFFFF) { + str.push_back((char)(0xE0 | (codepoint >> 12))); + str.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F))); + str.push_back((char)(0x80 | (codepoint & 0x3F))); + } else if (codepoint <= 0x1FFFFF) { + str.push_back((char)(0xF0 | (codepoint >> 18))); + str.push_back((char)(0x80 | ((codepoint >> 12) & 0x3F))); + str.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F))); + str.push_back((char)(0x80 | (codepoint & 0x3F))); + } + } +}; + +#endif diff --git a/lib/univalue_write.cpp b/lib/univalue_write.cpp index ceb4cc916..cfbdad328 100644 --- a/lib/univalue_write.cpp +++ b/lib/univalue_write.cpp @@ -8,8 +8,6 @@ #include "univalue.h" #include "univalue_escapes.h" -// TODO: Using UTF8 - using namespace std; static string json_escape(const string& inS) @@ -23,15 +21,8 @@ static string json_escape(const string& inS) if (escStr) outS += escStr; - - else if (ch < 0x80) + else outS += ch; - - else { // TODO handle UTF-8 properly - char tmpesc[16]; - sprintf(tmpesc, "\\u%04x", ch); - outS += tmpesc; - } } return outS; diff --git a/test/fail38.json b/test/fail38.json new file mode 100644 index 000000000..b245e2e46 --- /dev/null +++ b/test/fail38.json @@ -0,0 +1 @@ +["\ud834"] diff --git a/test/fail39.json b/test/fail39.json new file mode 100644 index 000000000..7c9e263f2 --- /dev/null +++ b/test/fail39.json @@ -0,0 +1 @@ +["\udd61"] diff --git a/test/fail40.json b/test/fail40.json new file mode 100644 index 000000000..664dc9e24 --- /dev/null +++ b/test/fail40.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/test/fail41.json b/test/fail41.json new file mode 100644 index 000000000..0de342a2b --- /dev/null +++ b/test/fail41.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/test/round2.json b/test/round2.json new file mode 100644 index 000000000..b766cccc6 --- /dev/null +++ b/test/round2.json @@ -0,0 +1 @@ +["a§■𐎒𝅘𝅥𝅯"] diff --git a/test/unitester.cpp b/test/unitester.cpp index 5a052fe92..05f3842cd 100644 --- a/test/unitester.cpp +++ b/test/unitester.cpp @@ -22,6 +22,7 @@ string srcdir(JSON_TEST_SRC); static bool test_failed = false; #define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } } +#define f_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", __func__); } } static std::string rtrim(std::string s) { @@ -108,6 +109,10 @@ static const char *filenames[] = { "fail35.json", "fail36.json", "fail37.json", + "fail38.json", // invalid unicode: only first half of surrogate pair + "fail39.json", // invalid unicode: only second half of surrogate pair + "fail40.json", // invalid unicode: broken UTF-8 + "fail41.json", // invalid unicode: unfinished UTF-8 "fail3.json", "fail4.json", // extra comma "fail5.json", @@ -119,14 +124,40 @@ static const char *filenames[] = { "pass2.json", "pass3.json", "round1.json", // round-trip test + "round2.json", // unicode }; +// Test \u handling +void unescape_unicode_test() +{ + UniValue val; + bool testResult; + // Escaped ASCII (quote) + testResult = val.read("[\"\\u0022\"]"); + f_assert(testResult); + f_assert(val[0].get_str() == "\""); + // Escaped Basic Plane character, two-byte UTF-8 + testResult = val.read("[\"\\u0191\"]"); + f_assert(testResult); + f_assert(val[0].get_str() == "\xc6\x91"); + // Escaped Basic Plane character, three-byte UTF-8 + testResult = val.read("[\"\\u2191\"]"); + f_assert(testResult); + f_assert(val[0].get_str() == "\xe2\x86\x91"); + // Escaped Supplementary Plane character U+1d161 + testResult = val.read("[\"\\ud834\\udd61\"]"); + f_assert(testResult); + f_assert(val[0].get_str() == "\xf0\x9d\x85\xa1"); +} + int main (int argc, char *argv[]) { for (unsigned int fidx = 0; fidx < ARRAY_SIZE(filenames); fidx++) { runtest_file(filenames[fidx]); } + unescape_unicode_test(); + return test_failed ? 1 : 0; } From a406fcb6cacdc49ce11fc6147df58c0c827a7a06 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 15:17:41 +0200 Subject: [PATCH 0764/1223] test: add ensure_ascii setting to AuthServiceProxy Add a setting ensure_ascii to AuthServiceProxy. This setting, defaulting to True (backwards compatible), is passed through to json.dumps. If set to False, non-ASCII characters >0x80 are not escaped. This is useful for testing server input processing, as well as slightly more bandwidth friendly in case of heavy unicode usage. --- qa/rpc-tests/test_framework/authproxy.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 95b2be658..d095a56ce 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -67,9 +67,11 @@ def EncodeDecimal(o): class AuthServiceProxy(object): __id_count = 0 - def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): + # ensure_ascii: escape unicode as \uXXXX, passed to json.dumps + def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None, ensure_ascii=True): self.__service_url = service_url self._service_name = service_name + self.ensure_ascii = ensure_ascii # can be toggled on the fly by tests self.__url = urlparse.urlparse(service_url) if self.__url.port is None: port = 80 @@ -134,12 +136,12 @@ class AuthServiceProxy(object): AuthServiceProxy.__id_count += 1 log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name, - json.dumps(args, default=EncodeDecimal))) + json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) postdata = json.dumps({'version': '1.1', 'method': self._service_name, 'params': args, - 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) - response = self._request('POST', self.__url.path, postdata) + 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal, ensure_ascii=self.ensure_ascii) + response = self._request('POST', self.__url.path, postdata.encode('utf-8')) if response['error'] is not None: raise JSONRPCException(response['error']) elif 'result' not in response: @@ -149,9 +151,9 @@ class AuthServiceProxy(object): return response['result'] def _batch(self, rpc_call_list): - postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) + postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal, ensure_ascii=self.ensure_ascii) log.debug("--> "+postdata) - return self._request('POST', self.__url.path, postdata) + return self._request('POST', self.__url.path, postdata.encode('utf-8')) def _get_response(self): http_response = self.__conn.getresponse() @@ -167,7 +169,7 @@ class AuthServiceProxy(object): responsedata = http_response.read().decode('utf8') response = json.loads(responsedata, parse_float=decimal.Decimal) if "error" in response and response["error"] is None: - log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) + log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) else: log.debug("<-- "+responsedata) return response From 6bbb4ef39989ff75167da48faec581b55ba51240 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 28 Apr 2016 15:18:01 +0200 Subject: [PATCH 0765/1223] test: test utf-8 for labels in wallet --- qa/rpc-tests/wallet.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 9dda712f4..ba84f0d56 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -314,6 +314,20 @@ class WalletTest (BitcoinTestFramework): balance_nodes = [self.nodes[i].getbalance() for i in range(3)] block_count = self.nodes[0].getblockcount() + # Check modes: + # - True: unicode escaped as \u.... + # - False: unicode directly as UTF-8 + for mode in [True, False]: + self.nodes[0].ensure_ascii = mode + # unicode check: Basic Multilingual Plane, Supplementary Plane respectively + for s in [u'рыба', u'𝅘𝅥𝅯']: + addr = self.nodes[0].getaccountaddress(s) + label = self.nodes[0].getaccount(addr) + assert_equal(label, s) + assert(s in self.nodes[0].listaccounts().keys()) + self.nodes[0].ensure_ascii = True # restore to default + + # maintenance tests maintenance = [ '-rescan', '-reindex', From 7982fce64c61c53d1e2e8cc6a8724f878701796d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 16 Apr 2016 15:21:47 +0200 Subject: [PATCH 0766/1223] doc: Mention full UTF-8 support in release notes --- doc/release-notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 7d44b8cda..0d457714d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -43,6 +43,11 @@ RPC low-level changes 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been fixed, but this means that the output will be different than from previous versions. +- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, + wallet labels have always been malformed because they weren't taken into account + properly in JSON RPC processing. This is no longer the case. This also affects + the GUI debug console. + C++11 and Python 3 ------------------- From 1b0bcc5f9573406bff1c3ffaf73826b0142d23cc Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 10 Jun 2016 16:07:14 +0200 Subject: [PATCH 0767/1223] Track orphan by prev COutPoint rather than prev hash --- src/main.cpp | 58 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6d006e878..17867c869 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,12 +88,21 @@ CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CTxMemPool mempool(::minRelayTxFee); FeeFilterRounder filterRounder(::minRelayTxFee); +struct IteratorComparator +{ + template + bool operator()(const I& a, const I& b) + { + return &(*a) < &(*b); + } +}; + struct COrphanTx { CTransaction tx; NodeId fromPeer; }; map mapOrphanTransactions GUARDED_BY(cs_main); -map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main); +map::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** @@ -632,31 +641,33 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c return false; } - mapOrphanTransactions[hash].tx = tx; - mapOrphanTransactions[hash].fromPeer = peer; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); + auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer}); + assert(ret.second); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first); + } - LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(), + LogPrint("mempool", "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(), mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size()); return true; } -void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { map::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) - return; + return 0; BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin) { - map >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash); + auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout); if (itPrev == mapOrphanTransactionsByPrev.end()) continue; - itPrev->second.erase(hash); + itPrev->second.erase(it); if (itPrev->second.empty()) mapOrphanTransactionsByPrev.erase(itPrev); } mapOrphanTransactions.erase(it); + return 1; } void EraseOrphansFor(NodeId peer) @@ -668,8 +679,7 @@ void EraseOrphansFor(NodeId peer) map::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid if (maybeErase->second.fromPeer == peer) { - EraseOrphanTx(maybeErase->second.tx.GetHash()); - ++nErased; + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); } } if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer); @@ -5019,7 +5029,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - vector vWorkQueue; + deque vWorkQueue; vector vEraseQueue; CTransaction tx; vRecv >> tx; @@ -5038,7 +5048,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); RelayTransaction(tx); - vWorkQueue.push_back(inv.hash); + for (unsigned int i = 0; i < tx.vout.size(); i++) { + vWorkQueue.emplace_back(inv.hash, i); + } LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n", pfrom->id, @@ -5047,18 +5059,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Recursively process any orphan transactions that depended on this one set setMisbehaving; - for (unsigned int i = 0; i < vWorkQueue.size(); i++) - { - map >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]); + while (!vWorkQueue.empty()) { + auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front()); + vWorkQueue.pop_front(); if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - for (set::iterator mi = itByPrev->second.begin(); + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - const uint256& orphanHash = *mi; - const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx; - NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer; + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + NodeId fromPeer = (*mi)->second.fromPeer; bool fMissingInputs2 = false; // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get @@ -5071,7 +5083,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); RelayTransaction(orphanTx); - vWorkQueue.push_back(orphanHash); + for (unsigned int i = 0; i < orphanTx.vout.size(); i++) { + vWorkQueue.emplace_back(orphanHash, i); + } vEraseQueue.push_back(orphanHash); } else if (!fMissingInputs2) From db0ffe80a0919653f058ab0f1fc735f46bb902f3 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 10 Jun 2016 20:41:49 +0000 Subject: [PATCH 0768/1223] This eliminates the primary leak that causes the orphan map to always grow to its maximum size. This does not go so far as to attempt to connect orphans made connectable by a new block. Keeping the orphan map less full helps improve the reliability of relaying chains of transactions. --- src/main.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 17867c869..c80a4ac92 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2345,6 +2345,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); + std::vector vOrphanErase; std::vector prevheights; CAmount nFees = 0; int nInputs = 0; @@ -2377,6 +2378,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin prevheights[j] = view.AccessCoins(tx.vin[j].prevout.hash)->nHeight; } + // Which orphan pool entries must we evict? + for (size_t j = 0; j < tx.vin.size(); j++) { + auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + vOrphanErase.push_back(orphanHash); + } + } + if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); @@ -2464,6 +2476,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); + // Erase orphan transactions include or precluded by this block + if (vOrphanErase.size()) { + int nErased = 0; + BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) { + nErased += EraseOrphanTx(orphanHash); + } + LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased); + } + int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5; LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); From fa61756842d78beeac8e7cffa88767fa3f710510 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 12 Jun 2016 14:10:55 +0200 Subject: [PATCH 0769/1223] [gitian] set correct PATH for wrappers --- contrib/gitian-descriptors/gitian-linux.yml | 6 ++++-- contrib/gitian-descriptors/gitian-osx.yml | 6 ++++-- contrib/gitian-descriptors/gitian-win.yml | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index cd289b2f6..28b7e6d35 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -68,11 +68,11 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd bitcoin BASEPREFIX=`pwd`/depends @@ -82,8 +82,10 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 8436cd612..536fcfb10 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -77,11 +77,11 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd bitcoin BASEPREFIX=`pwd`/depends @@ -95,8 +95,10 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 1d3a876df..32b57b316 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -94,12 +94,12 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" create_per-host_linker_wrapper "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd bitcoin BASEPREFIX=`pwd`/depends @@ -109,9 +109,11 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh From b0938a00203a32cd932c78bc2782d113d2d78f06 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 12 Jun 2016 20:33:20 +0800 Subject: [PATCH 0770/1223] [trivial][doc] Use Debian 8.5 in the gitian-build guide --- doc/gitian-building.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 791f209bb..7796a5fc9 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -1,7 +1,7 @@ Gitian building ================ -*Setup instructions for a Gitian build of Bitcoin using a Debian VM or physical system.* +*Setup instructions for a Gitian build of Bitcoin Core using a Debian VM or physical system.* Gitian is the deterministic build process that is used to build the Bitcoin Core executables. It provides a way to be reasonably sure that the @@ -26,7 +26,7 @@ Table of Contents - [Installing Gitian](#installing-gitian) - [Setting up the Gitian image](#setting-up-the-gitian-image) - [Getting and building the inputs](#getting-and-building-the-inputs) -- [Building Bitcoin](#building-bitcoin) +- [Building Bitcoin Core](#building-bitcoin-core) - [Building an alternative repository](#building-an-alternative-repository) - [Signing externally](#signing-externally) - [Uploading signatures](#uploading-signatures) @@ -95,11 +95,11 @@ After creating the VM, we need to configure it. - Click `Ok` twice to save. -Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.4.0/amd64/iso-cd/debian-8.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.5.0/amd64/iso-cd/debian-8.5.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "7a6b418e6a4ee3ca75dda04d79ed96c9e2c33bb0c703ca7e40c6374ab4590748 debian-8.4.0-amd64-netinst.iso" | sha256sum -c + echo "ad4e8c27c561ad8248d5ebc1d36eb172f884057bfeb2c22ead823f59fa8c3dff debian-8.5.0-amd64-netinst.iso" | sha256sum -c # (must return OK) Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded iso. @@ -342,10 +342,10 @@ manual intervention. Also optionally follow the next step: 'Seed the Gitian sour and offline git repositories' which will fetch the remaining files required for building offline. -Building Bitcoin +Building Bitcoin Core ---------------- -To build Bitcoin (for Linux, OS X and Windows) just follow the steps under 'perform +To build Bitcoin Core (for Linux, OS X and Windows) just follow the steps under 'perform Gitian builds' in [doc/release-process.md](release-process.md#perform-gitian-builds) in the bitcoin repository. This may take some time as it will build all the dependencies needed for each descriptor. From 01a99046de63dac4dbf1ddce9fc711ff1f05049a Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 13 Jun 2016 19:28:39 +0800 Subject: [PATCH 0771/1223] [trivial] Ignore split-debug.sh --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a8722aa59..ce40019dc 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ share/BitcoindComparisonTool.jar /doc/doxygen/ libbitcoinconsensus.pc +contrib/devtools/split-debug.sh From 0e209f9bf940ec2f6215885cf30deaa7355086e9 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 13 Jun 2016 19:33:02 +0800 Subject: [PATCH 0772/1223] [trivial] Sync ax_pthread with upstream draft --- build-aux/m4/ax_pthread.m4 | 506 ++++++++++++++++++------------------- 1 file changed, 253 insertions(+), 253 deletions(-) diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index d218d1af7..4c4051ea3 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -82,7 +82,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 22 +#serial 23 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -100,22 +100,22 @@ ax_pthread_ok=no # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then - ax_pthread_save_CC="$CC" - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) - AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = "xno"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - CC="$ax_pthread_save_CC" - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -152,50 +152,50 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread -- case $host_os in - freebsd*) + freebsd*) - # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) - # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - ax_pthread_flags="-kthread lthread $ax_pthread_flags" - ;; + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; - hpux*) + hpux*) - # From the cc(1) man page: "[-mt] Sets various -D flags to enable - # multi-threading and also sets -lpthread." + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." - ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; - openedition*) + openedition*) - # IBM z/OS requires a feature-test macro to be defined in order to - # enable POSIX threads at all, so give the user a hint if this is - # not set. (We don't define these ourselves, as they can affect - # other portions of the system API in unpredictable ways.) + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) - AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], - [ -# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) - AX_PTHREAD_ZOS_MISSING -# endif - ], - [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) - ;; + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; - solaris*) + solaris*) - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (N.B.: The stubs are missing - # pthread_cleanup_push, or rather a function called by this macro, - # so we could check for that, but who knows whether they'll stub - # that too in a future libc.) So we'll check first for the - # standard Solaris way of linking pthreads (-mt -lpthread). + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) @@ -208,17 +208,17 @@ AS_IF([test "x$GCC" = "xyes"], # correctly enabled case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) - ax_pthread_check_macro="_REENTRANT" - ;; + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - aix* | freebsd*) - ax_pthread_check_macro="_THREAD_SAFE" - ;; + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - *) - ax_pthread_check_macro="--" - ;; + *) + ax_pthread_check_macro="--" + ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], @@ -231,13 +231,13 @@ AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" @@ -249,222 +249,222 @@ ax_pthread_clang_warning=no if test "x$ax_pthread_clang" = "xyes"; then - # Clang takes -pthread; it has never supported any other flag + # Clang takes -pthread; it has never supported any other flag - # (Note 1: This will need to be revisited if a system that Clang - # supports has POSIX threads in a separate library. This tends not - # to be the way of modern systems, but it's conceivable.) + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) - # (Note 2: On some systems, notably Darwin, -pthread is not needed - # to get POSIX threads support; the API is always present and - # active. We could reasonably leave PTHREAD_CFLAGS empty. But - # -pthread does define _REENTRANT, and while the Darwin headers - # ignore this macro, third-party headers might not.) + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= - ax_pthread_ok=yes + ax_pthread_ok=yes - # However, older versions of Clang make a point of warning the user - # that, in an invocation where only linking and no compilation is - # taking place, the -pthread option has no effect ("argument unused - # during compilation"). They expect -pthread to be passed in only - # when source code is being compiled. - # - # Problem is, this is at odds with the way Automake and most other - # C build frameworks function, which is that the same flags used in - # compilation (CFLAGS) are also used in linking. Many systems - # supported by AX_PTHREAD require exactly this for POSIX threads - # support, and in fact it is often not straightforward to specify a - # flag that is used only in the compilation phase and not in - # linking. Such a scenario is extremely rare in practice. - # - # Even though use of the -pthread flag in linking would only print - # a warning, this can be a nuisance for well-run software projects - # that build with -Werror. So if the active version of Clang has - # this misfeature, we search for an option to squash it. + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. - AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown - # Create an alternate version of $ac_link that compiles and - # links in two steps (.c -> .o, .o -> exe) instead of one - # (.c -> exe), because the warning occurs only in the second - # step - ax_pthread_save_ac_link="$ac_link" - ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` - ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" - ax_pthread_save_CFLAGS="$CFLAGS" - for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do - AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) - CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" - ac_link="$ax_pthread_save_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [ac_link="$ax_pthread_2step_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [break]) - ]) - done - ac_link="$ax_pthread_save_ac_link" - CFLAGS="$ax_pthread_save_CFLAGS" - AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - ]) + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) - case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in - no | unknown) ;; - *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; - esac + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_CACHE_CHECK([for joinable pthread attribute], - [ax_cv_PTHREAD_JOINABLE_ATTR], - [ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $ax_pthread_attr; return attr /* ; */])], - [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], - []) - done - ]) - AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ - test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ - test "x$ax_pthread_joinable_attr_defined" != "xyes"], - [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], - [$ax_cv_PTHREAD_JOINABLE_ATTR], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - ax_pthread_joinable_attr_defined=yes - ]) + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) - AC_CACHE_CHECK([whether more special flags are required for pthreads], - [ax_cv_PTHREAD_SPECIAL_FLAGS], - [ax_cv_PTHREAD_SPECIAL_FLAGS=no - case $host_os in - solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" - ;; - esac - ]) - AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ - test "x$ax_pthread_special_flags_added" != "xyes"], - [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" - ax_pthread_special_flags_added=yes]) + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ - test "x$ax_pthread_prio_inherit_defined" != "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) - ax_pthread_prio_inherit_defined=yes - ]) + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - # More AIX lossage: compile with *_r variant - if test "x$GCC" != "xyes"; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -475,11 +475,11 @@ AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : else - ax_pthread_ok=no - $2 + ax_pthread_ok=no + $2 fi AC_LANG_POP ])dnl AX_PTHREAD From 1c2a1bac0ad6901868c1a4003c7cbddcdf46a29b Mon Sep 17 00:00:00 2001 From: Francesco 'makevoid' Canessa Date: Thu, 3 Mar 2016 10:54:31 +0000 Subject: [PATCH 0773/1223] Add address label to request payment QR Code (QT) In the Receive 'Tab' of the QT wallet, when 'Show'ing a previously requested payment, add a label underneath the QR Code showing the bitcoin address where the funds will go to. This way the user can be sure that the QR code scanner app the user using is reading the correct bitcoin address, preventing funds to be stolen. Includes fix for HiDPI screens by @jonasschnelli. --- src/qt/forms/receiverequestdialog.ui | 2 +- src/qt/guiconstants.h | 2 +- src/qt/receiverequestdialog.cpp | 22 +++++++++++++++++----- src/qt/receiverequestdialog.h | 1 + 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index 1e484dd9a..4163f4189 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -22,7 +22,7 @@ 300 - 300 + 320 diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 4b2c10dd4..bab9923d2 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -43,7 +43,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80; static const int MAX_URI_LENGTH = 255; /* QRCodeDialog -- size of exported QR Code image */ -#define EXPORT_IMAGE_SIZE 256 +#define QR_IMAGE_SIZE 300 /* Number of frames in spinner animation */ #define SPINNER_FRAMES 36 diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index a1e9156ee..b13ea3df7 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -45,7 +45,7 @@ QImage QRImageWidget::exportImage() { if(!pixmap()) return QImage(); - return pixmap()->toImage().scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE); + return pixmap()->toImage(); } void QRImageWidget::mousePressEvent(QMouseEvent *event) @@ -166,20 +166,32 @@ void ReceiveRequestDialog::update() ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); return; } - QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); - myImage.fill(0xffffff); + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); unsigned char *p = code->data; for (int y = 0; y < code->width; y++) { for (int x = 0; x < code->width; x++) { - myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); p++; } } QRcode_free(code); - ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE+20, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(12); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(QR_IMAGE_SIZE+12); + painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, info.address); + painter.end(); + + ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage)); ui->btnSaveAs->setEnabled(true); } } diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 4cab4caff..676745a85 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -10,6 +10,7 @@ #include #include #include +#include class OptionsModel; From 3764dec36c815267174951a4c64e17c07ee6302f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 18:58:00 +0100 Subject: [PATCH 0774/1223] Keep addrman's nService bits consistent with outbound observations --- src/addrman.cpp | 18 ++++++++++++++++++ src/addrman.h | 11 +++++++++++ src/main.cpp | 4 ++++ 3 files changed, 33 insertions(+) diff --git a/src/addrman.cpp b/src/addrman.cpp index 00f6fe99e..d1e98d8ac 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -502,6 +502,24 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) info.nTime = nTime; } +void CAddrMan::SetServices_(const CService& addr, uint64_t nServices) +{ + CAddrInfo* pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nServices = nServices; +} + int CAddrMan::RandomInt(int nMax){ return GetRandInt(nMax); } diff --git a/src/addrman.h b/src/addrman.h index c5923e941..7e36e2228 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -256,6 +256,9 @@ protected: //! Mark an entry as currently-connected-to. void Connected_(const CService &addr, int64_t nTime); + //! Update an entry's service bits. + void SetServices_(const CService &addr, uint64_t nServices); + public: /** * serialized format: @@ -589,6 +592,14 @@ public: } } + void SetServices(const CService &addr, uint64_t nServices) + { + LOCK(cs); + Check(); + SetServices_(addr, nServices); + Check(); + } + }; #endif // BITCOIN_ADDRMAN_H diff --git a/src/main.cpp b/src/main.cpp index 6092e7a12..ac89945bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4612,6 +4612,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CAddress addrFrom; uint64_t nNonce = 1; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (!pfrom->fInbound) + { + addrman.SetServices(pfrom->addr, pfrom->nServices); + } if (pfrom->nVersion < MIN_PEER_PROTO_VERSION) { // disconnect from peers older than this proto version From fc83f181530fb566726e5f3f4197fc5586d77fd8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 19:09:22 +0100 Subject: [PATCH 0775/1223] Verify that outbound connections have expected services --- src/main.cpp | 9 +++++++++ src/net.cpp | 5 +++++ src/net.h | 1 + 3 files changed, 15 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ac89945bf..7818056d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4616,6 +4616,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { addrman.SetServices(pfrom->addr, pfrom->nServices); } + if (pfrom->nServicesExpected & ~pfrom->nServices) + { + LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, pfrom->nServices, pfrom->nServicesExpected); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD, + strprintf("Expected to offer services %08x", pfrom->nServicesExpected)); + pfrom->fDisconnect = true; + return false; + } + if (pfrom->nVersion < MIN_PEER_PROTO_VERSION) { // disconnect from peers older than this proto version diff --git a/src/net.cpp b/src/net.cpp index 173eba57c..a0c2bd509 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -71,6 +71,9 @@ namespace { const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; +/** Services this node implementation cares about */ +static const uint64_t nRelevantServices = NODE_NETWORK; + // // Global state variables // @@ -409,6 +412,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure vNodes.push_back(pnode); } + pnode->nServicesExpected = addrConnect.nServices & nRelevantServices; pnode->nTimeConnected = GetTime(); return pnode; @@ -2325,6 +2329,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa filterInventoryKnown(50000, 0.000001) { nServices = 0; + nServicesExpected = 0; hSocket = hSocketIn; nRecvVersion = INIT_PROTO_VERSION; nLastSend = 0; diff --git a/src/net.h b/src/net.h index 5c1f7e3e8..445d25bf8 100644 --- a/src/net.h +++ b/src/net.h @@ -317,6 +317,7 @@ class CNode public: // socket uint64_t nServices; + uint64_t nServicesExpected; SOCKET hSocket; CDataStream ssSend; size_t nSendSize; // total size of all vSendMsg entries From 5e7ab16d29ac66a5a5753dd4f59b6fb12e60654e Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 26 Mar 2016 13:31:25 +0100 Subject: [PATCH 0776/1223] Only store and connect to NODE_NETWORK nodes --- src/main.cpp | 3 +++ src/net.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 7818056d2..bcaf095ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4785,6 +4785,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { boost::this_thread::interruption_point(); + if (!(addr.nServices & NODE_NETWORK)) + continue; + if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; pfrom->AddAddressKnown(addr); diff --git a/src/net.cpp b/src/net.cpp index a0c2bd509..395e1fe42 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1596,6 +1596,10 @@ void ThreadOpenConnections() if (IsLimited(addr)) continue; + // only connect to full nodes + if (!(addr.nServices & NODE_NETWORK)) + continue; + // only consider very recently tried nodes after 30 failed attempts if (nANow - addr.nLastTry < 600 && nTries < 30) continue; From 15bf863219abe968ebe9e59fed4806c9fd07a58b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 25 May 2016 17:18:37 +0200 Subject: [PATCH 0777/1223] Don't require services in -addnode --- src/net.cpp | 15 ++++--- src/protocol.cpp | 2 +- src/protocol.h | 2 +- src/test/DoS_tests.cpp | 8 ++-- src/test/addrman_tests.cpp | 92 +++++++++++++++++++------------------- src/test/net_tests.cpp | 8 ++-- 6 files changed, 64 insertions(+), 63 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 395e1fe42..80ba7fce2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -162,7 +162,7 @@ static std::vector convertSeed6(const std::vector &vSeedsIn { struct in6_addr ip; memcpy(&ip, i->addr, sizeof(ip)); - CAddress addr(CService(ip, i->port)); + CAddress addr(CService(ip, i->port), NODE_NETWORK); addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek; vSeedsOut.push_back(addr); } @@ -179,9 +179,8 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer) CService addr; if (GetLocal(addr, paddrPeer)) { - ret = CAddress(addr); + ret = CAddress(addr, nLocalServices); } - ret.nServices = nLocalServices; ret.nTime = GetAdjustedTime(); return ret; } @@ -465,7 +464,7 @@ void CNode::PushVersion() int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0); int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); - CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); + CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0), addr.nServices)); CAddress addrMe = GetLocalAddress(&addr); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) @@ -1441,7 +1440,7 @@ void ThreadDNSAddressSeed() } else { std::vector vIPs; std::vector vAdd; - uint64_t requiredServiceBits = NODE_NETWORK; + uint64_t requiredServiceBits = nRelevantServices; if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) @@ -1524,7 +1523,7 @@ void ThreadOpenConnections() ProcessOneShot(); BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"]) { - CAddress addr; + CAddress addr(CService(), 0); OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { @@ -1674,7 +1673,9 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(std::vector& vserv, lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); - OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), false, &grant); + /* We want -addnode to work even for nodes that don't provide all + * wanted services, so pass in nServices=0 to CAddress. */ + OpenNetworkConnection(CAddress(vserv[i % vserv.size()], 0), false, &grant); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes diff --git a/src/protocol.cpp b/src/protocol.cpp index 8c4bd0572..a46051b84 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -141,7 +141,7 @@ CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) void CAddress::Init() { - nServices = NODE_NETWORK; + nServices = 0; nTime = 100000000; } diff --git a/src/protocol.h b/src/protocol.h index 1b049e52a..c3f819aae 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -251,7 +251,7 @@ class CAddress : public CService { public: CAddress(); - explicit CAddress(CService ipIn, uint64_t nServicesIn = NODE_NETWORK); + explicit CAddress(CService ipIn, uint64_t nServicesIn); void Init(); diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 95342498f..dc019d6cf 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -45,7 +45,7 @@ BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { CNode::ClearBanned(); - CAddress addr1(ip(0xa0b0c001)); + CAddress addr1(ip(0xa0b0c001), 0); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned - CAddress addr2(ip(0xa0b0c002)); + CAddress addr2(ip(0xa0b0c002), 0); CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) { CNode::ClearBanned(); mapArgs["-banscore"] = "111"; // because 11 is my favorite number - CAddress addr1(ip(0xa0b0c001)); + CAddress addr1(ip(0xa0b0c001), 0); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() - CAddress addr(ip(0xa0b0c001)); + CAddress addr(ip(0xa0b0c001), 0); CNode dummyNode(INVALID_SOCKET, addr, "", true); dummyNode.nVersion = 1; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 767b653e4..93c3eba7f 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 2: Does Addrman::Add work as expected. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); @@ -76,14 +76,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. CService addr1_dup = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1_dup), source); + addrman.Add(CAddress(addr1_dup, 0), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. CService addr2 = CService("250.1.1.2", 8333); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 2); // Test 6: AddrMan::Clear() should empty the new table. @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); CService addr1_port = CService("250.1.1.1", 8334); - addrman.Add(CAddress(addr1_port), source); + addrman.Add(CAddress(addr1_port, 0), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); // Test 8: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. - addrman.Good(CAddress(addr1_port)); + addrman.Good(CAddress(addr1_port, 0)); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test 9: Select from new with 1 addr in new. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); // Test 10: move addr to tried, select from new expected nothing returned. - addrman.Good(CAddress(addr1)); + addrman.Good(CAddress(addr1, 0)); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(newOnly); BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); @@ -160,21 +160,21 @@ BOOST_AUTO_TEST_CASE(addrman_select) CService addr3 = CService("250.3.2.2", 9999); CService addr4 = CService("250.3.3.3", 9999); - addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333)); + addrman.Add(CAddress(addr2, 0), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3, 0), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4, 0), CService("250.4.1.1", 8333)); // Add three addresses to tried table. CService addr5 = CService("250.4.4.4", 8333); CService addr6 = CService("250.4.5.5", 7777); CService addr7 = CService("250.4.6.6", 8333); - addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr5)); - addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr6)); - addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333)); - addrman.Good(CAddress(addr7)); + addrman.Add(CAddress(addr5, 0), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5, 0)); + addrman.Add(CAddress(addr6, 0), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6, 0)); + addrman.Add(CAddress(addr7, 0), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7, 0)); // Test 11: 6 addrs + 1 addr from last test = 7. BOOST_CHECK(addrman.size() == 7); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) for (unsigned int i = 1; i < 18; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr), source); + addrman.Add(CAddress(addr, 0), source); //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); @@ -207,11 +207,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) //Test 14: new table collision! CService addr1 = CService("250.1.1.18"); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 17); CService addr2 = CService("250.1.1.19"); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 18); } @@ -228,8 +228,8 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) for (unsigned int i = 1; i < 80; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr), source); - addrman.Good(CAddress(addr)); + addrman.Add(CAddress(addr, 0), source); + addrman.Good(CAddress(addr, 0)); //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); @@ -238,11 +238,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) //Test 16: tried table collision! CService addr1 = CService("250.1.1.80"); - addrman.Add(CAddress(addr1), source); + addrman.Add(CAddress(addr1, 0), source); BOOST_CHECK(addrman.size() == 79); CService addr2 = CService("250.1.1.81"); - addrman.Add(CAddress(addr2), source); + addrman.Add(CAddress(addr2, 0), source); BOOST_CHECK(addrman.size() == 80); } @@ -255,9 +255,9 @@ BOOST_AUTO_TEST_CASE(addrman_find) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); - CAddress addr3 = CAddress(CService("251.255.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.1.2.2"); @@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -344,15 +344,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) vector vAddr1 = addrman.GetAddr(); BOOST_CHECK(vAddr1.size() == 0); - CAddress addr1 = CAddress(CService("250.250.2.1", 8333)); + CAddress addr1 = CAddress(CService("250.250.2.1", 8333), 0); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false - CAddress addr2 = CAddress(CService("250.251.2.2", 9999)); + CAddress addr2 = CAddress(CService("250.251.2.2", 9999), 0); addr2.nTime = GetAdjustedTime(); - CAddress addr3 = CAddress(CService("251.252.2.3", 8333)); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333), 0); addr3.nTime = GetAdjustedTime(); - CAddress addr4 = CAddress(CService("252.253.3.4", 8333)); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333), 0); addr4.nTime = GetAdjustedTime(); - CAddress addr5 = CAddress(CService("252.254.4.5", 8333)); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333), 0); addr5.nTime = GetAdjustedTime(); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.2.3.3"); @@ -368,8 +368,8 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 24: Ensure GetAddr works with new and tried addresses. - addrman.Good(CAddress(addr1)); - addrman.Good(CAddress(addr2)); + addrman.Good(CAddress(addr1, 0)); + addrman.Good(CAddress(addr2, 0)); BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. @@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) int octet2 = (i / 256) % 256; int octet3 = (i / (256 * 2)) % 256; string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; - CAddress addr = CAddress(CService(strAddr)); + CAddress addr = CAddress(CService(strAddr), 0); // Ensure that for all addrs in addrman, isTerrible == false. addr.nTime = GetAdjustedTime(); @@ -403,8 +403,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.1.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.1.1", 9999)); + CAddress addr1 = CAddress(CService("250.1.1.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999), 0); CNetAddr source1 = CNetAddr("250.1.1.1"); @@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i))), + CAddress(CService("250.1.1." + boost::to_string(i)), 0), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250." + boost::to_string(j) + ".1.1")), + CAddress(CService("250." + boost::to_string(j) + ".1.1"), 0), CNetAddr("250." + boost::to_string(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -460,8 +460,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); CNetAddr source1 = CNetAddr("250.1.2.1"); @@ -484,7 +484,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i))), + CAddress(CService("250.1.1." + boost::to_string(i)), 0), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetNewBucket(nKey1); buckets.insert(bucket); @@ -497,7 +497,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( CService( - boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1")), + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), 0), CNetAddr("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); @@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) buckets.clear(); for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250.1.1.1")), + CAddress(CService("250.1.1.1"), 0), CNetAddr("250." + boost::to_string(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index b38d61f33..b3d848fcb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -51,7 +51,7 @@ public: int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; - CAddress addr = CAddress(CService("252.1.1.1", 7777)); + CAddress addr = CAddress(CService("252.1.1.1", 7777), 0); CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2")); s << info; } @@ -79,9 +79,9 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) CService addr3 = CService("250.7.3.3", 9999); // Add three addresses to new table. - addrmanUncorrupted.Add(CAddress(addr1), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr2), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr3), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr1, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr2, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr3, 0), CService("252.5.1.1", 8333)); // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); From ee06e04369c37da21e048fda849cce2a1f066f84 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Jun 2016 19:12:22 +0200 Subject: [PATCH 0778/1223] Introduce enum ServiceFlags for service flags --- src/addrman.cpp | 4 +- src/addrman.h | 4 +- src/init.cpp | 4 +- src/main.cpp | 4 +- src/net.cpp | 24 +++++----- src/net.h | 8 ++-- src/protocol.cpp | 4 +- src/protocol.h | 12 +++-- src/test/DoS_tests.cpp | 8 ++-- src/test/addrman_tests.cpp | 92 +++++++++++++++++++------------------- src/test/net_tests.cpp | 8 ++-- 11 files changed, 89 insertions(+), 83 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index d1e98d8ac..cebb1c8e5 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -263,7 +263,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty); // add services - pinfo->nServices |= addr.nServices; + pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices); // do not update if no new information is present if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime)) @@ -502,7 +502,7 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) info.nTime = nTime; } -void CAddrMan::SetServices_(const CService& addr, uint64_t nServices) +void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices) { CAddrInfo* pinfo = Find(addr); diff --git a/src/addrman.h b/src/addrman.h index 7e36e2228..1caf54075 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -257,7 +257,7 @@ protected: void Connected_(const CService &addr, int64_t nTime); //! Update an entry's service bits. - void SetServices_(const CService &addr, uint64_t nServices); + void SetServices_(const CService &addr, ServiceFlags nServices); public: /** @@ -592,7 +592,7 @@ public: } } - void SetServices(const CService &addr, uint64_t nServices) + void SetServices(const CService &addr, ServiceFlags nServices) { LOCK(cs); Check(); diff --git a/src/init.cpp b/src/init.cpp index ec4ce6b6d..c2ba9ae44 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -950,7 +950,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) - nLocalServices |= NODE_BLOOM; + nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); @@ -1361,7 +1361,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // after any wallet rescanning has taken place. if (fPruneMode) { LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); - nLocalServices &= ~NODE_NETWORK; + nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK); if (!fReindex) { uiInterface.InitMessage(_("Pruning blockstore...")); PruneAndFlush(); diff --git a/src/main.cpp b/src/main.cpp index bcaf095ab..c1569545b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4611,7 +4611,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CAddress addrMe; CAddress addrFrom; uint64_t nNonce = 1; - vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + uint64_t nServiceInt; + vRecv >> pfrom->nVersion >> nServiceInt >> nTime >> addrMe; + pfrom->nServices = ServiceFlags(nServiceInt); if (!pfrom->fInbound) { addrman.SetServices(pfrom->addr, pfrom->nServices); diff --git a/src/net.cpp b/src/net.cpp index 80ba7fce2..4661974d2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -72,14 +72,14 @@ namespace { const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; /** Services this node implementation cares about */ -static const uint64_t nRelevantServices = NODE_NETWORK; +static const ServiceFlags nRelevantServices = NODE_NETWORK; // // Global state variables // bool fDiscover = true; bool fListen = true; -uint64_t nLocalServices = NODE_NETWORK; +ServiceFlags nLocalServices = NODE_NETWORK; bool fRelayTxes = true; CCriticalSection cs_mapLocalHost; std::map mapLocalHost; @@ -175,7 +175,7 @@ static std::vector convertSeed6(const std::vector &vSeedsIn // one by discovery. CAddress GetLocalAddress(const CNetAddr *paddrPeer) { - CAddress ret(CService("0.0.0.0",GetListenPort()),0); + CAddress ret(CService("0.0.0.0",GetListenPort()), NODE_NONE); CService addr; if (GetLocal(addr, paddrPeer)) { @@ -411,7 +411,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure vNodes.push_back(pnode); } - pnode->nServicesExpected = addrConnect.nServices & nRelevantServices; + pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices); pnode->nTimeConnected = GetTime(); return pnode; @@ -464,14 +464,14 @@ void CNode::PushVersion() int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0); int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); - CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0), addr.nServices)); + CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0), addr.nServices)); CAddress addrMe = GetLocalAddress(&addr); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, strSubVersion, nBestHeight, ::fRelayTxes); } @@ -1440,7 +1440,7 @@ void ThreadDNSAddressSeed() } else { std::vector vIPs; std::vector vAdd; - uint64_t requiredServiceBits = nRelevantServices; + ServiceFlags requiredServiceBits = nRelevantServices; if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) @@ -1523,7 +1523,7 @@ void ThreadOpenConnections() ProcessOneShot(); BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"]) { - CAddress addr(CService(), 0); + CAddress addr(CService(), NODE_NONE); OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { @@ -1674,8 +1674,8 @@ void ThreadOpenAddedConnections() { CSemaphoreGrant grant(*semOutbound); /* We want -addnode to work even for nodes that don't provide all - * wanted services, so pass in nServices=0 to CAddress. */ - OpenNetworkConnection(CAddress(vserv[i % vserv.size()], 0), false, &grant); + * wanted services, so pass in nServices=NODE_NONE to CAddress. */ + OpenNetworkConnection(CAddress(vserv[i % vserv.size()], NODE_NONE), false, &grant); MilliSleep(500); } MilliSleep(120000); // Retry every 2 minutes @@ -2333,8 +2333,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa addrKnown(5000, 0.001), filterInventoryKnown(50000, 0.000001) { - nServices = 0; - nServicesExpected = 0; + nServices = NODE_NONE; + nServicesExpected = NODE_NONE; hSocket = hSocketIn; nRecvVersion = INIT_PROTO_VERSION; nLastSend = 0; diff --git a/src/net.h b/src/net.h index 445d25bf8..f5fb8faae 100644 --- a/src/net.h +++ b/src/net.h @@ -152,7 +152,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); extern bool fDiscover; extern bool fListen; -extern uint64_t nLocalServices; +extern ServiceFlags nLocalServices; extern bool fRelayTxes; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; @@ -186,7 +186,7 @@ class CNodeStats { public: NodeId nodeid; - uint64_t nServices; + ServiceFlags nServices; bool fRelayTxes; int64_t nLastSend; int64_t nLastRecv; @@ -316,8 +316,8 @@ class CNode { public: // socket - uint64_t nServices; - uint64_t nServicesExpected; + ServiceFlags nServices; + ServiceFlags nServicesExpected; SOCKET hSocket; CDataStream ssSend; size_t nSendSize; // total size of all vSendMsg entries diff --git a/src/protocol.cpp b/src/protocol.cpp index a46051b84..422ef6f63 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -133,7 +133,7 @@ CAddress::CAddress() : CService() Init(); } -CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) +CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn) { Init(); nServices = nServicesIn; @@ -141,7 +141,7 @@ CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn) void CAddress::Init() { - nServices = 0; + nServices = NODE_NONE; nTime = 100000000; } diff --git a/src/protocol.h b/src/protocol.h index c3f819aae..ab0a58178 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -223,7 +223,9 @@ extern const char *FEEFILTER; const std::vector &getAllNetMessageTypes(); /** nServices flags */ -enum { +enum ServiceFlags : uint64_t { + // Nothing + NODE_NONE = 0, // NODE_NETWORK means that the node is capable of serving the block chain. It is currently // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want // network services but don't provide them. @@ -251,7 +253,7 @@ class CAddress : public CService { public: CAddress(); - explicit CAddress(CService ipIn, uint64_t nServicesIn); + explicit CAddress(CService ipIn, ServiceFlags nServicesIn); void Init(); @@ -267,13 +269,15 @@ public: if ((nType & SER_DISK) || (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) READWRITE(nTime); - READWRITE(nServices); + uint64_t nServicesInt = nServices; + READWRITE(nServicesInt); + nServices = (ServiceFlags)nServicesInt; READWRITE(*(CService*)this); } // TODO: make private (improves encapsulation) public: - uint64_t nServices; + ServiceFlags nServices; // disk and network only unsigned int nTime; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index dc019d6cf..4a373fc60 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -45,7 +45,7 @@ BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { CNode::ClearBanned(); - CAddress addr1(ip(0xa0b0c001), 0); + CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned - CAddress addr2(ip(0xa0b0c002), 0); + CAddress addr2(ip(0xa0b0c002), NODE_NONE); CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) { CNode::ClearBanned(); mapArgs["-banscore"] = "111"; // because 11 is my favorite number - CAddress addr1(ip(0xa0b0c001), 0); + CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() - CAddress addr(ip(0xa0b0c001), 0); + CAddress addr(ip(0xa0b0c001), NODE_NONE); CNode dummyNode(INVALID_SOCKET, addr, "", true); dummyNode.nVersion = 1; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 93c3eba7f..b6cec24b5 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 2: Does Addrman::Add work as expected. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); @@ -76,14 +76,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. CService addr1_dup = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1_dup, 0), source); + addrman.Add(CAddress(addr1_dup, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. CService addr2 = CService("250.1.1.2", 8333); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 2); // Test 6: AddrMan::Clear() should empty the new table. @@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CService addr1_port = CService("250.1.1.1", 8334); - addrman.Add(CAddress(addr1_port, 0), source); + addrman.Add(CAddress(addr1_port, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); // Test 8: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. - addrman.Good(CAddress(addr1_port, 0)); + addrman.Good(CAddress(addr1_port, NODE_NONE)); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test 9: Select from new with 1 addr in new. CService addr1 = CService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 1); bool newOnly = true; @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); // Test 10: move addr to tried, select from new expected nothing returned. - addrman.Good(CAddress(addr1, 0)); + addrman.Good(CAddress(addr1, NODE_NONE)); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(newOnly); BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); @@ -160,21 +160,21 @@ BOOST_AUTO_TEST_CASE(addrman_select) CService addr3 = CService("250.3.2.2", 9999); CService addr4 = CService("250.3.3.3", 9999); - addrman.Add(CAddress(addr2, 0), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr3, 0), CService("250.3.1.1", 8333)); - addrman.Add(CAddress(addr4, 0), CService("250.4.1.1", 8333)); + addrman.Add(CAddress(addr2, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4, NODE_NONE), CService("250.4.1.1", 8333)); // Add three addresses to tried table. CService addr5 = CService("250.4.4.4", 8333); CService addr6 = CService("250.4.5.5", 7777); CService addr7 = CService("250.4.6.6", 8333); - addrman.Add(CAddress(addr5, 0), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr5, 0)); - addrman.Add(CAddress(addr6, 0), CService("250.3.1.1", 8333)); - addrman.Good(CAddress(addr6, 0)); - addrman.Add(CAddress(addr7, 0), CService("250.1.1.3", 8333)); - addrman.Good(CAddress(addr7, 0)); + addrman.Add(CAddress(addr5, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5, NODE_NONE)); + addrman.Add(CAddress(addr6, NODE_NONE), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6, NODE_NONE)); + addrman.Add(CAddress(addr7, NODE_NONE), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7, NODE_NONE)); // Test 11: 6 addrs + 1 addr from last test = 7. BOOST_CHECK(addrman.size() == 7); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) for (unsigned int i = 1; i < 18; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr, 0), source); + addrman.Add(CAddress(addr, NODE_NONE), source); //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); @@ -207,11 +207,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) //Test 14: new table collision! CService addr1 = CService("250.1.1.18"); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 17); CService addr2 = CService("250.1.1.19"); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 18); } @@ -228,8 +228,8 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) for (unsigned int i = 1; i < 80; i++) { CService addr = CService("250.1.1." + boost::to_string(i)); - addrman.Add(CAddress(addr, 0), source); - addrman.Good(CAddress(addr, 0)); + addrman.Add(CAddress(addr, NODE_NONE), source); + addrman.Good(CAddress(addr, NODE_NONE)); //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); @@ -238,11 +238,11 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) //Test 16: tried table collision! CService addr1 = CService("250.1.1.80"); - addrman.Add(CAddress(addr1, 0), source); + addrman.Add(CAddress(addr1, NODE_NONE), source); BOOST_CHECK(addrman.size() == 79); CService addr2 = CService("250.1.1.81"); - addrman.Add(CAddress(addr2, 0), source); + addrman.Add(CAddress(addr2, NODE_NONE), source); BOOST_CHECK(addrman.size() == 80); } @@ -255,9 +255,9 @@ BOOST_AUTO_TEST_CASE(addrman_find) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); - CAddress addr3 = CAddress(CService("251.255.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.1.2.2"); @@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) BOOST_CHECK(addrman.size() == 0); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); int nId; @@ -344,15 +344,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) vector vAddr1 = addrman.GetAddr(); BOOST_CHECK(vAddr1.size() == 0); - CAddress addr1 = CAddress(CService("250.250.2.1", 8333), 0); + CAddress addr1 = CAddress(CService("250.250.2.1", 8333), NODE_NONE); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false - CAddress addr2 = CAddress(CService("250.251.2.2", 9999), 0); + CAddress addr2 = CAddress(CService("250.251.2.2", 9999), NODE_NONE); addr2.nTime = GetAdjustedTime(); - CAddress addr3 = CAddress(CService("251.252.2.3", 8333), 0); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333), NODE_NONE); addr3.nTime = GetAdjustedTime(); - CAddress addr4 = CAddress(CService("252.253.3.4", 8333), 0); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333), NODE_NONE); addr4.nTime = GetAdjustedTime(); - CAddress addr5 = CAddress(CService("252.254.4.5", 8333), 0); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333), NODE_NONE); addr5.nTime = GetAdjustedTime(); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.2.3.3"); @@ -368,8 +368,8 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 24: Ensure GetAddr works with new and tried addresses. - addrman.Good(CAddress(addr1, 0)); - addrman.Good(CAddress(addr2, 0)); + addrman.Good(CAddress(addr1, NODE_NONE)); + addrman.Good(CAddress(addr2, NODE_NONE)); BOOST_CHECK(addrman.GetAddr().size() == 1); // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. @@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) int octet2 = (i / 256) % 256; int octet3 = (i / (256 * 2)) % 256; string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; - CAddress addr = CAddress(CService(strAddr), 0); + CAddress addr = CAddress(CService(strAddr), NODE_NONE); // Ensure that for all addrs in addrman, isTerrible == false. addr.nTime = GetAdjustedTime(); @@ -403,8 +403,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.1.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.1.1", 9999), 0); + CAddress addr1 = CAddress(CService("250.1.1.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.1.1"); @@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i)), 0), + CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250." + boost::to_string(j) + ".1.1"), 0), + CAddress(CService("250." + boost::to_string(j) + ".1.1"), NODE_NONE), CNetAddr("250." + boost::to_string(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1); buckets.insert(bucket); @@ -460,8 +460,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CAddress addr1 = CAddress(CService("250.1.2.1", 8333), 0); - CAddress addr2 = CAddress(CService("250.1.2.1", 9999), 0); + CAddress addr1 = CAddress(CService("250.1.2.1", 8333), NODE_NONE); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999), NODE_NONE); CNetAddr source1 = CNetAddr("250.1.2.1"); @@ -484,7 +484,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) set buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(CService("250.1.1." + boost::to_string(i)), 0), + CAddress(CService("250.1.1." + boost::to_string(i)), NODE_NONE), CNetAddr("250.1.1." + boost::to_string(i))); int bucket = infoi.GetNewBucket(nKey1); buckets.insert(bucket); @@ -497,7 +497,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( CService( - boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), 0), + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1"), NODE_NONE), CNetAddr("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); @@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) buckets.clear(); for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( - CAddress(CService("250.1.1.1"), 0), + CAddress(CService("250.1.1.1"), NODE_NONE), CNetAddr("250." + boost::to_string(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index b3d848fcb..d005d6a16 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -51,7 +51,7 @@ public: int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; - CAddress addr = CAddress(CService("252.1.1.1", 7777), 0); + CAddress addr = CAddress(CService("252.1.1.1", 7777), NODE_NONE); CAddrInfo info = CAddrInfo(addr, CNetAddr("252.2.2.2")); s << info; } @@ -79,9 +79,9 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) CService addr3 = CService("250.7.3.3", 9999); // Add three addresses to new table. - addrmanUncorrupted.Add(CAddress(addr1, 0), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr2, 0), CService("252.5.1.1", 8333)); - addrmanUncorrupted.Add(CAddress(addr3, 0), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), CService("252.5.1.1", 8333)); + addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), CService("252.5.1.1", 8333)); // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted); From ecd7fd37c888f8ebc64cf3d92272975b37ae54ca Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 13 Jun 2016 16:01:21 +0200 Subject: [PATCH 0779/1223] Introduce REQUIRED_SERVICES constant --- src/main.cpp | 2 +- src/net.cpp | 2 +- src/net.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c1569545b..62012bf56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4787,7 +4787,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { boost::this_thread::interruption_point(); - if (!(addr.nServices & NODE_NETWORK)) + if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) continue; if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) diff --git a/src/net.cpp b/src/net.cpp index 4661974d2..a390eca77 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1596,7 +1596,7 @@ void ThreadOpenConnections() continue; // only connect to full nodes - if (!(addr.nServices & NODE_NETWORK)) + if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) continue; // only consider very recently tried nodes after 30 failed attempts diff --git a/src/net.h b/src/net.h index f5fb8faae..2aaca4888 100644 --- a/src/net.h +++ b/src/net.h @@ -72,6 +72,8 @@ static const bool DEFAULT_FORCEDNSSEED = false; static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000; static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000; +static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK; + // NOTE: When adjusting this, update rpcnet:setban's help ("24h") static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban From fa26c420bfb7dbad6781f31f222a66ef52f2ae45 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 13 Jun 2016 19:36:01 +0200 Subject: [PATCH 0780/1223] [qa] util: Move check_fee_amount out of wallet.py --- qa/rpc-tests/test_framework/util.py | 9 +++++++++ qa/rpc-tests/wallet.py | 7 +------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index fc66ef287..782df52d6 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -477,6 +477,15 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): return (txid, signresult["hex"], fee) +def assert_fee_amount(fee, tx_size, fee_per_kB): + """Assert the fee was in range""" + target_fee = tx_size * fee_per_kB / 1000 + if fee < target_fee: + raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)"%(str(fee), str(target_fee))) + # allow the wallet's estimation to be at most 2 bytes off + if fee > (tx_size + 2) * fee_per_kB / 1000: + raise AssertionError("Fee of %s BTC too high! (Should be %s BTC)"%(str(fee), str(target_fee))) + def assert_equal(thing1, thing2): if thing1 != thing2: raise AssertionError("%s != %s"%(str(thing1),str(thing2))) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 9dda712f4..0b7eb52f0 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -11,12 +11,7 @@ class WalletTest (BitcoinTestFramework): def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size): """Return curr_balance after asserting the fee was in range""" fee = balance_with_fee - curr_balance - target_fee = fee_per_byte * tx_size - if fee < target_fee: - raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)"%(str(fee), str(target_fee))) - # allow the node's estimation to be at most 2 bytes off - if fee > fee_per_byte * (tx_size + 2): - raise AssertionError("Fee of %s BTC too high! (Should be %s BTC)"%(str(fee), str(target_fee))) + assert_fee_amount(fee, tx_size, fee_per_byte * 1000) return curr_balance def __init__(self): From fae1d063fc8a54067a8527d249d8801a00feef03 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 13 Jun 2016 19:52:01 +0200 Subject: [PATCH 0781/1223] [qa] fundrawtransaction: Fix race, assert amounts --- qa/rpc-tests/fundrawtransaction.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 998f822af..228574e67 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -58,7 +58,6 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) - self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -552,7 +551,6 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[1].walletpassphrase("test", 100) signedTx = self.nodes[1].signrawtransaction(fundedTx['hex']) txId = self.nodes[1].sendrawtransaction(signedTx['hex']) - self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -572,7 +570,6 @@ class RawTransactionsTest(BitcoinTestFramework): for i in range(0,20): self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) - self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -603,7 +600,6 @@ class RawTransactionsTest(BitcoinTestFramework): for i in range(0,20): self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) - self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -677,6 +673,15 @@ class RawTransactionsTest(BitcoinTestFramework): signedtx = self.nodes[0].signrawtransaction(signedtx["hex"]) assert(signedtx["complete"]) self.nodes[0].sendrawtransaction(signedtx["hex"]) + self.nodes[0].generate(1) + self.sync_all() + + ####################### + # Test feeRate option # + ####################### + + # Make sure there is exactly one input so coin selection can't skew the result + assert_equal(len(self.nodes[3].listunspent(1)), 1) inputs = [] outputs = {self.nodes[2].getnewaddress() : 1} @@ -684,8 +689,9 @@ class RawTransactionsTest(BitcoinTestFramework): result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee) result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}) result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee}) - assert_equal(result['fee']*2, result2['fee']) - assert_equal(result['fee']*10, result3['fee']) + result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex']) + assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) + assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) if __name__ == '__main__': RawTransactionsTest().main() From 1111b80df84aa7bc72fbddcc7bafde43f0835d90 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 28 May 2016 15:32:30 +0200 Subject: [PATCH 0782/1223] Rework addnode behaviour * Use CNode::addeName to track whether a connection to a name is already open * A new connection to a previously-connected by-name addednode is only opened when the previous one closes (even if the name starts resolving to something else) * At most one connection is opened per addednode (even if the name resolves to multiple) * Unify the code between ThreadOpenAddedNodeConnections and getaddednodeinfo * Information about open connections is always returned, and the dns argument becomes a dummy * An IP address and inbound/outbound is only reported for the (at most 1) open connection --- src/net.cpp | 113 ++++++++++++++++++++++++++---------------------- src/net.h | 10 +++++ src/rpc/net.cpp | 95 ++++++++++------------------------------ 3 files changed, 94 insertions(+), 124 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index a390eca77..4d27db760 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1616,6 +1616,58 @@ void ThreadOpenConnections() } } +std::vector GetAddedNodeInfo() +{ + std::vector ret; + + std::list lAddresses(0); + { + LOCK(cs_vAddedNodes); + ret.reserve(vAddedNodes.size()); + BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) + lAddresses.push_back(strAddNode); + } + + + // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService + std::map mapConnected; + std::map> mapConnectedByName; + { + LOCK(cs_vNodes); + for (const CNode* pnode : vNodes) { + if (pnode->addr.IsValid()) { + mapConnected[pnode->addr] = pnode->fInbound; + } + if (!pnode->addrName.empty()) { + mapConnectedByName[pnode->addrName] = std::make_pair(pnode->fInbound, static_cast(pnode->addr)); + } + } + } + + BOOST_FOREACH(const std::string& strAddNode, lAddresses) { + CService service(strAddNode, Params().GetDefaultPort()); + if (service.IsValid()) { + // strAddNode is an IP:port + auto it = mapConnected.find(service); + if (it != mapConnected.end()) { + ret.push_back(AddedNodeInfo{strAddNode, service, true, it->second}); + } else { + ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false}); + } + } else { + // strAddNode is a name + auto it = mapConnectedByName.find(strAddNode); + if (it != mapConnectedByName.end()) { + ret.push_back(AddedNodeInfo{strAddNode, it->second.second, true, it->second.first}); + } else { + ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false}); + } + } + } + + return ret; +} + void ThreadOpenAddedConnections() { { @@ -1623,61 +1675,20 @@ void ThreadOpenAddedConnections() vAddedNodes = mapMultiArgs["-addnode"]; } - if (HaveNameProxy()) { - while(true) { - std::list lAddresses(0); - { - LOCK(cs_vAddedNodes); - BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) - lAddresses.push_back(strAddNode); - } - BOOST_FOREACH(const std::string& strAddNode, lAddresses) { - CAddress addr; - CSemaphoreGrant grant(*semOutbound); - OpenNetworkConnection(addr, false, &grant, strAddNode.c_str()); - MilliSleep(500); - } - MilliSleep(120000); // Retry every 2 minutes - } - } - for (unsigned int i = 0; true; i++) { - std::list lAddresses(0); - { - LOCK(cs_vAddedNodes); - BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) - lAddresses.push_back(strAddNode); + std::vector vInfo = GetAddedNodeInfo(); + for (const AddedNodeInfo& info : vInfo) { + if (!info.fConnected) { + CSemaphoreGrant grant(*semOutbound); + // If strAddedNode is an IP/port, decode it immediately, so + // OpenNetworkConnection can detect existing connections to that IP/port. + CService service(info.strAddedNode, Params().GetDefaultPort()); + OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false); + MilliSleep(500); + } } - std::list > lservAddressesToAdd(0); - BOOST_FOREACH(const std::string& strAddNode, lAddresses) { - std::vector vservNode(0); - if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) - lservAddressesToAdd.push_back(vservNode); - } - // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry - // (keeping in mind that addnode entries can have many IPs if fNameLookup) - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - for (std::list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) - BOOST_FOREACH(const CService& addrNode, *(it)) - if (pnode->addr == addrNode) - { - it = lservAddressesToAdd.erase(it); - it--; - break; - } - } - BOOST_FOREACH(std::vector& vserv, lservAddressesToAdd) - { - CSemaphoreGrant grant(*semOutbound); - /* We want -addnode to work even for nodes that don't provide all - * wanted services, so pass in nServices=NODE_NONE to CAddress. */ - OpenNetworkConnection(CAddress(vserv[i % vserv.size()], NODE_NONE), false, &grant); - MilliSleep(500); - } MilliSleep(120000); // Retry every 2 minutes } } diff --git a/src/net.h b/src/net.h index 2aaca4888..54a86d88d 100644 --- a/src/net.h +++ b/src/net.h @@ -818,4 +818,14 @@ public: /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); +struct AddedNodeInfo +{ + std::string strAddedNode; + CService resolvedAddress; + bool fConnected; + bool fInbound; +}; + +std::vector GetAddedNodeInfo(); + #endif // BITCOIN_NET_H diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index cae964e46..b85c7b2e1 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -271,25 +271,22 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "getaddednodeinfo dns ( \"node\" )\n" + "getaddednodeinfo dummy ( \"node\" )\n" "\nReturns information about the given added node, or all added nodes\n" "(note that onetry addnodes are not listed here)\n" - "If dns is false, only a list of added nodes will be provided,\n" - "otherwise connected information will also be available.\n" "\nArguments:\n" - "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n" + "1. dummy (boolean, required) Kept for historical purposes but ignored\n" "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n" "\nResult:\n" "[\n" " {\n" - " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n" + " \"addednode\" : \"192.168.0.201\", (string) The node ip address or name (as provided to addnode)\n" " \"connected\" : true|false, (boolean) If connected\n" - " \"addresses\" : [\n" + " \"addresses\" : [ (list of objects) Only when connected = true\n" " {\n" - " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n" + " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server IP and port we're connected to\n" " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n" " }\n" - " ,...\n" " ]\n" " }\n" " ,...\n" @@ -300,83 +297,35 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"") ); - bool fDns = params[0].get_bool(); + std::vector vInfo = GetAddedNodeInfo(); - list laddedNodes(0); - if (params.size() == 1) - { - LOCK(cs_vAddedNodes); - BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) - laddedNodes.push_back(strAddNode); - } - else - { - string strNode = params[1].get_str(); - LOCK(cs_vAddedNodes); - BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) { - if (strAddNode == strNode) - { - laddedNodes.push_back(strAddNode); + if (params.size() == 2) { + bool found = false; + for (const AddedNodeInfo& info : vInfo) { + if (info.strAddedNode == params[1].get_str()) { + vInfo.assign(1, info); + found = true; break; } } - if (laddedNodes.size() == 0) + if (!found) { throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added."); + } } UniValue ret(UniValue::VARR); - if (!fDns) - { - BOOST_FOREACH (const std::string& strAddNode, laddedNodes) { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addednode", strAddNode)); - ret.push_back(obj); - } - return ret; - } - list > > laddedAddreses(0); - BOOST_FOREACH(const std::string& strAddNode, laddedNodes) { - vector vservNode(0); - if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) - laddedAddreses.push_back(make_pair(strAddNode, vservNode)); - else - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addednode", strAddNode)); - obj.push_back(Pair("connected", false)); - UniValue addresses(UniValue::VARR); - obj.push_back(Pair("addresses", addresses)); - ret.push_back(obj); - } - } - - LOCK(cs_vNodes); - for (list > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) - { + for (const AddedNodeInfo& info : vInfo) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addednode", it->first)); - + obj.push_back(Pair("addednode", info.strAddedNode)); + obj.push_back(Pair("connected", info.fConnected)); UniValue addresses(UniValue::VARR); - bool fConnected = false; - BOOST_FOREACH(const CService& addrNode, it->second) { - bool fFound = false; - UniValue node(UniValue::VOBJ); - node.push_back(Pair("address", addrNode.ToString())); - BOOST_FOREACH(CNode* pnode, vNodes) { - if (pnode->addr == addrNode) - { - fFound = true; - fConnected = true; - node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound")); - break; - } - } - if (!fFound) - node.push_back(Pair("connected", "false")); - addresses.push_back(node); + if (info.fConnected) { + UniValue address(UniValue::VOBJ); + address.push_back(Pair("address", info.resolvedAddress.ToString())); + address.push_back(Pair("connected", info.fInbound ? "inbound" : "outbound")); + addresses.push_back(address); } - obj.push_back(Pair("connected", fConnected)); obj.push_back(Pair("addresses", addresses)); ret.push_back(obj); } From f9f5cfc50637f2cd1540923caf337e2651ec1625 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 28 May 2016 16:22:02 +0200 Subject: [PATCH 0783/1223] Prevent duplicate connections where one is by name and another by ip --- src/net.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 4d27db760..30a6bc896 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -400,6 +400,26 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure return NULL; } + if (pszDest && addrConnect.IsValid()) { + // It is possible that we already have a connection to the IP/port pszDest resolved to. + // In that case, drop the connection that was just created, and return the existing CNode instead. + // Also store the name we used to connect in that CNode, so that future FindNode() calls to that + // name catch this early. + CNode* pnode = FindNode((CService)addrConnect); + if (pnode) + { + pnode->AddRef(); + { + LOCK(cs_vNodes); + if (pnode->addrName.empty()) { + pnode->addrName = std::string(pszDest); + } + } + CloseSocket(hSocket); + return pnode; + } + } + addrman.Attempt(addrConnect, fCountFailure); // Add node From 1a5a4e648873c4cd88b936648ebf2858393e5510 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 28 May 2016 16:44:08 +0200 Subject: [PATCH 0784/1223] Randomize name lookup result in ConnectSocketByName --- src/netbase.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 572ae7087..e2a516986 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -621,10 +621,10 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest proxyType nameProxy; GetNameProxy(nameProxy); - CService addrResolved; - if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy())) { - if (addrResolved.IsValid()) { - addr = addrResolved; + std::vector addrResolved; + if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy(), 256)) { + if (addrResolved.size() > 0) { + addr = addrResolved[GetRand(addrResolved.size())]; return ConnectSocket(addr, hSocketRet, nTimeout); } } From afcd77e17936f7ec9bbf7b47f55a211eccc08364 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 13 Jun 2016 16:27:41 +0200 Subject: [PATCH 0785/1223] Detect -usehd mismatches when wallet.dat already exists --- src/wallet/wallet.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1c212d014..a4ffdfdb5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3236,6 +3236,13 @@ bool CWallet::InitLoadWallet() walletInstance->SetBestChain(chainActive.GetLocator()); } + else if (mapArgs.count("-usehd")) { + bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); + if (!walletInstance->hdChain.masterKeyID.IsNull() && !useHD) + return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); + if (walletInstance->hdChain.masterKeyID.IsNull() && useHD) + return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); + } LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); From ab8be98fdb25b678a8cd7e89adf06d1b1f6bdd62 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Tue, 14 Jun 2016 12:26:59 +0100 Subject: [PATCH 0786/1223] Remove bad chain alert partition check As per meeting 2016-03-31 https://bitcoincore.org/en/meetings/2016/03/31/#bad-chain-alerts The partition checker was producing huge number of false-positives and was disabled in 0.12.1 on the understanding it would either be fixed in 0.13 or removed entirely from master if not. --- src/Makefile.test.include | 1 - src/init.cpp | 6 --- src/main.cpp | 62 ------------------------------ src/main.h | 2 - src/test/alert_tests.cpp | 79 --------------------------------------- 5 files changed, 150 deletions(-) delete mode 100644 src/test/alert_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 41d811fb5..0b6f306f8 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -38,7 +38,6 @@ BITCOIN_TESTS =\ test/arith_uint256_tests.cpp \ test/scriptnum10.h \ test/addrman_tests.cpp \ - test/alert_tests.cpp \ test/amount_tests.cpp \ test/allocator_tests.cpp \ test/base32_tests.cpp \ diff --git a/src/init.cpp b/src/init.cpp index c2ba9ae44..323d1cedc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1416,12 +1416,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) StartNode(threadGroup, scheduler); - // Monitor the chain, and alert if we get blocks much quicker or slower than expected - int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing; - CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload, - boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing); - scheduler.scheduleEvery(f, nPowTargetSpacing); - // ********************************************************* Step 12: finished SetRPCWarmupFinished(); diff --git a/src/main.cpp b/src/main.cpp index 62012bf56..91da3f47a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2118,68 +2118,6 @@ void ThreadScriptCheck() { scriptcheckqueue.Thread(); } -// -// Called periodically asynchronously; alerts if it smells like -// we're being fed a bad chain (blocks being generated much -// too slowly or too quickly). -// -void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, - int64_t nPowTargetSpacing) -{ - if (bestHeader == NULL || initialDownloadCheck()) return; - - static int64_t lastAlertTime = 0; - int64_t now = GetAdjustedTime(); - if (lastAlertTime > now-60*60*24) return; // Alert at most once per day - - const int SPAN_HOURS=4; - const int SPAN_SECONDS=SPAN_HOURS*60*60; - int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing; - - boost::math::poisson_distribution poisson(BLOCKS_EXPECTED); - - std::string strWarning; - int64_t startTime = GetAdjustedTime()-SPAN_SECONDS; - - LOCK(cs); - const CBlockIndex* i = bestHeader; - int nBlocks = 0; - while (i->GetBlockTime() >= startTime) { - ++nBlocks; - i = i->pprev; - if (i == NULL) return; // Ran out of chain, we must not be fully sync'ed - } - - // How likely is it to find that many by chance? - double p = boost::math::pdf(poisson, nBlocks); - - LogPrint("partitioncheck", "%s: Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS); - LogPrint("partitioncheck", "%s: likelihood: %g\n", __func__, p); - - // Aim for one false-positive about every fifty years of normal running: - const int FIFTY_YEARS = 50*365*24*60*60; - double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS); - - if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED) - { - // Many fewer blocks than expected: alert! - strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"), - nBlocks, SPAN_HOURS, BLOCKS_EXPECTED); - } - else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED) - { - // Many more blocks than expected: alert! - strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"), - nBlocks, SPAN_HOURS, BLOCKS_EXPECTED); - } - if (!strWarning.empty()) - { - strMiscWarning = strWarning; - AlertNotify(strWarning); - lastAlertTime = now; - } -} - // Protected by cs_main VersionBitsCache versionbitscache; diff --git a/src/main.h b/src/main.h index 9b99ae7c8..05f7d4d92 100644 --- a/src/main.h +++ b/src/main.h @@ -242,8 +242,6 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); -/** Try to detect Partition (network isolation) attacks against us */ -void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing); /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload(); /** Format a string that describes several potential problems detected by the core. diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp deleted file mode 100644 index 70f1f1227..000000000 --- a/src/test/alert_tests.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// Unit tests for alert system - -#include "chainparams.h" -#include "main.h" // For PartitionCheck - -#include "test/testutil.h" -#include "test/test_bitcoin.h" - -#include - -BOOST_FIXTURE_TEST_SUITE(Alert_tests, TestingSetup) - - -static bool falseFunc() { return false; } - -BOOST_AUTO_TEST_CASE(PartitionAlert) -{ - // Test PartitionCheck - CCriticalSection csDummy; - CBlockIndex indexDummy[100]; - CChainParams& params = Params(CBaseChainParams::MAIN); - int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing; - - // Generate fake blockchain timestamps relative to - // an arbitrary time: - int64_t now = 1427379054; - SetMockTime(now); - for (int i = 0; i < 100; i++) - { - indexDummy[i].phashBlock = NULL; - if (i == 0) indexDummy[i].pprev = NULL; - else indexDummy[i].pprev = &indexDummy[i-1]; - indexDummy[i].nHeight = i; - indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing; - // Other members don't matter, the partition check code doesn't - // use them - } - - strMiscWarning = ""; - - // Test 1: chain with blocks every nPowTargetSpacing seconds, - // as normal, no worries: - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); - - // Test 2: go 3.5 hours without a block, expect a warning: - now += 3*60*60+30*60; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; - - // Test 3: test the "partition alerts only go off once per day" - // code: - now += 60*10; - SetMockTime(now); - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); - - // Test 4: get 2.5 times as many blocks as expected: - now += 60*60*24; // Pretend it is a day later - SetMockTime(now); - int64_t quickSpacing = nPowTargetSpacing*2/5; - for (int i = 0; i < 100; i++) // Tweak chain timestamps: - indexDummy[i].nTime = now - (100-i)*quickSpacing; - PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(!strMiscWarning.empty()); - BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning); - strMiscWarning = ""; - - SetMockTime(0); -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From d80efec3273dfdb88a434474be644cc5c788b617 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Wed, 15 Jun 2016 00:11:39 -0400 Subject: [PATCH 0787/1223] Update petertodd's testnet seed New seed with servicebit filtering support. --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 000511567..442bc6102 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -207,7 +207,7 @@ public: vSeeds.clear(); // nodes with support for servicebits filtering should be at the top vSeeds.push_back(CDNSSeedData("testnetbitcoin.jonasschnelli.ch", "testnet-seed.bitcoin.jonasschnelli.ch", true)); - vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); + vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.tbtc.petertodd.org", true)); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); From 11cc143895e730002749f0881c4c95635fa54bd5 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 11 Jun 2016 00:26:16 +0000 Subject: [PATCH 0788/1223] Adds an expiration time for orphan tx. This prevents higher order orphans and other junk from holding positions in the orphan map. Parents delayed twenty minutes are more are unlikely to ever arrive. The freed space will improve the orphan matching success rate for other transactions. --- src/main.cpp | 23 ++++++++++++++++++++++- src/main.h | 4 ++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index c80a4ac92..44d96d614 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,6 +100,7 @@ struct IteratorComparator struct COrphanTx { CTransaction tx; NodeId fromPeer; + int64_t nTimeExpire; }; map mapOrphanTransactions GUARDED_BY(cs_main); map::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); @@ -641,7 +642,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c return false; } - auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer}); + auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME}); assert(ret.second); BOOST_FOREACH(const CTxIn& txin, tx.vin) { mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first); @@ -689,6 +690,26 @@ void EraseOrphansFor(NodeId peer) unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { unsigned int nEvicted = 0; + static int64_t nNextSweep; + int64_t nNow = GetTime(); + if (nNextSweep <= nNow) { + // Sweep out expired orphan pool entries: + int nErased = 0; + int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL; + map::iterator iter = mapOrphanTransactions.begin(); + while (iter != mapOrphanTransactions.end()) + { + map::iterator maybeErase = iter++; + if (maybeErase->second.nTimeExpire <= nNow) { + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); + } else { + nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime); + } + } + // Sweep again 5 minutes after the next entry that expires in order to batch the linear scan. + nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL; + if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx due to expiration\n", nErased); + } while (mapOrphanTransactions.size() > nMaxOrphans) { // Evict a random orphan: diff --git a/src/main.h b/src/main.h index 9b99ae7c8..191aafe04 100644 --- a/src/main.h +++ b/src/main.h @@ -56,6 +56,10 @@ static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Expiration time for orphan transactions in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; +/** Minimum time between orphan transactions expire time checks in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; /** Default for -limitancestorcount, max number of in-mempool ancestors */ static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25; /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ From 8c99d1b525562ab3b733e9d7ef770882646bad5c Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 13 Jun 2016 17:27:44 +0000 Subject: [PATCH 0789/1223] Treat orphans as implicit inv for parents, discard when parents rejected. An orphan whos parents were rejected is never going to connect, so there is little utility in keeping it. Orphans also helpfully tell us what we're missing, so go ahead and treat it as INVed. --- src/main.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 44d96d614..6a2290bc0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5156,13 +5156,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (fMissingInputs) { - AddOrphanTx(tx, pfrom->GetId()); + bool fRejectedParents = false; // It may be the case that the orphans parents have all been rejected + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (recentRejects->contains(txin.prevout.hash)) { + fRejectedParents = true; + break; + } + } + if (!fRejectedParents) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + CInv inv(MSG_TX, txin.prevout.hash); + pfrom->AddInventoryKnown(inv); + if (!AlreadyHave(inv)) pfrom->AskFor(inv); + } + AddOrphanTx(tx, pfrom->GetId()); - // DoS prevention: do not allow mapOrphanTransactions to grow unbounded - unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); - unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); - if (nEvicted > 0) - LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + // DoS prevention: do not allow mapOrphanTransactions to grow unbounded + unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); + if (nEvicted > 0) + LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + } else { + LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); + } } else { assert(recentRejects); recentRejects->insert(tx.GetHash()); From 54326a6808a7026eef9d3a26f91f93b77f00a793 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 11 Jun 2016 00:28:48 +0000 Subject: [PATCH 0790/1223] Increase maximum orphan size to 100,000 bytes. Although this increases node memory usage in the worst case by perhaps 30MB, the current behavior causes severe issues with dependent tx relay. --- src/main.cpp | 6 +++--- src/test/DoS_tests.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6a2290bc0..d4ab32744 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -633,10 +633,10 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // large transaction with a missing parent then we assume // it will rebroadcast it later, after the parent transaction(s) // have been mined or received. - // 10,000 orphans, each of which is at most 5,000 bytes big is - // at most 500 megabytes of orphans: + // 100 orphans, each of which is at most 99,999 bytes big is + // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz > 5000) + if (sz >= MAX_STANDARD_TX_SIZE) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 95342498f..818128d18 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - tx.vin.resize(500); + tx.vin.resize(2777); for (unsigned int j = 0; j < tx.vin.size(); j++) { tx.vin[j].prevout.n = j; From bc0a895d810107132651c8178e95a981b9f3ff74 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 15 Jun 2016 19:31:28 +0200 Subject: [PATCH 0791/1223] Do not set extra flags for unfiltered DNS seed results --- src/chainparams.cpp | 8 -------- src/chainparams.h | 4 +--- src/net.cpp | 14 +++++++++++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 000511567..8c27a578b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -16,14 +16,6 @@ #include "chainparamsseeds.h" -std::string CDNSSeedData::getHost(uint64_t requiredServiceBits) const { - //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) - if (!supportsServiceBitsFiltering || requiredServiceBits == NODE_NETWORK) - return host; - - return strprintf("x%x.%s", requiredServiceBits, host); -} - static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; diff --git a/src/chainparams.h b/src/chainparams.h index 7168daaf4..638893e9a 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,11 +13,9 @@ #include -class CDNSSeedData { -public: +struct CDNSSeedData { std::string name, host; bool supportsServiceBitsFiltering; - std::string getHost(uint64_t requiredServiceBits) const; CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; diff --git a/src/net.cpp b/src/net.cpp index a390eca77..5e791291c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1415,6 +1415,18 @@ void MapPort(bool) +static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits) +{ + //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) + if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) { + *requiredServiceBits = NODE_NETWORK; + return data.host; + } + + return strprintf("x%x.%s", *requiredServiceBits, data.host); +} + + void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute @@ -1441,7 +1453,7 @@ void ThreadDNSAddressSeed() std::vector vIPs; std::vector vAdd; ServiceFlags requiredServiceBits = nRelevantServices; - if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) + if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { From 5d0ca81f7422b7eac0a5129c6fbccad77e36b85d Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 22 May 2016 05:55:15 +0000 Subject: [PATCH 0792/1223] Add recently accepted blocks and txn to AttemptToEvictConnection. This protects any not-already-protected peers who were the most recent four to relay transactions and most recent four to send blocks to us. --- src/main.cpp | 16 +++++++++++----- src/main.h | 2 +- src/net.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++---- src/net.h | 5 +++++ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6d006e878..24ae61b74 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3449,8 +3449,9 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state } /** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ -static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp) +static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp, bool* fNewBlock) { + if (fNewBlock) *fNewBlock = false; AssertLockHeld(cs_main); CBlockIndex *pindexDummy = NULL; @@ -3479,6 +3480,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha if (!fHasMoreWork) return true; // Don't process less-work chains if (fTooFarAhead) return true; // Block height is too high } + if (fNewBlock) *fNewBlock = true; if ((!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) || !ContextualCheckBlock(block, state, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { @@ -3526,7 +3528,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) { { LOCK(cs_main); @@ -3535,9 +3537,11 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c // Store to disk CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp); + bool fNewBlock = false; + bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp, &fNewBlock); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); + if (fNewBlock) pfrom->nLastBlockTime = GetTime(); } CheckBlockIndex(chainparams.GetConsensus()); if (!ret) @@ -4107,7 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { LOCK(cs_main); CValidationState state; - if (AcceptBlock(block, state, chainparams, NULL, true, dbp)) + if (AcceptBlock(block, state, chainparams, NULL, true, dbp, NULL)) nLoaded++; if (state.IsError()) break; @@ -4140,7 +4144,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB head.ToString()); LOCK(cs_main); CValidationState dummy; - if (AcceptBlock(block, dummy, chainparams, NULL, true, &it->second)) + if (AcceptBlock(block, dummy, chainparams, NULL, true, &it->second, NULL)) { nLoaded++; queue.push_back(block.GetHash()); @@ -5040,6 +5044,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, RelayTransaction(tx); vWorkQueue.push_back(inv.hash); + pfrom->nLastTXTime = GetTime(); + LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n", pfrom->id, tx.GetHash().ToString(), diff --git a/src/main.h b/src/main.h index 9b99ae7c8..e2bfdfdf6 100644 --- a/src/main.h +++ b/src/main.h @@ -215,7 +215,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @param[out] dbp The already known disk position of pblock, or NULL if not yet stored. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ diff --git a/src/net.cpp b/src/net.cpp index 173eba57c..ec547e8c9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -838,6 +838,11 @@ struct NodeEvictionCandidate NodeId id; int64_t nTimeConnected; int64_t nMinPingUsecTime; + int64_t nLastBlockTime; + int64_t nLastTXTime; + bool fNetworkNode; + bool fRelayTxes; + bool fBloomFilter; CAddress addr; uint64_t nKeyedNetGroup; }; @@ -854,7 +859,24 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { return a.nKeyedNetGroup < b.nKeyedNetGroup; -}; +} + +static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) +{ + // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block. + if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime; + if (a.fNetworkNode != b.fNetworkNode) return b.fNetworkNode; + return a.nTimeConnected > b.nTimeConnected; +} + +static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) +{ + // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn. + if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime; + if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes; + if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter; + return a.nTimeConnected > b.nTimeConnected; +} /** Try to find a connection to evict when the node is full. * Extreme care must be taken to avoid opening the node to attacker @@ -864,7 +886,7 @@ static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvict * to forge. In order to partition a node the attacker must be * simultaneously better at all of them than honest peers. */ -static bool AttemptToEvictConnection(bool fPreferNewConnection) { +static bool AttemptToEvictConnection() { std::vector vEvictionCandidates; { LOCK(cs_vNodes); @@ -876,7 +898,9 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup}; + NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, + node->nLastBlockTime, node->nLastTXTime, node->fNetworkNode, + node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } } @@ -899,6 +923,20 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { if (vEvictionCandidates.empty()) return false; + // Protect 4 nodes that most recently sent us transactions. + // An attacker cannot manipulate this metric without performing useful work. + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime); + vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Protect 4 nodes that most recently sent us blocks. + // An attacker cannot manipulate this metric without performing useful work. + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime); + vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + // Protect the half of the remaining nodes which have been connected the longest. // This replicates the non-eviction implicit behavior, and precludes attacks that start later. std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); @@ -999,7 +1037,7 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { if (nInbound >= nMaxInbound) { - if (!AttemptToEvictConnection(whitelisted)) { + if (!AttemptToEvictConnection()) { // No connection to evict, disconnect the new connection LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n"); CloseSocket(hSocket); @@ -2358,6 +2396,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa fSentAddr = false; pfilter = new CBloomFilter(); timeLastMempoolReq = 0; + nLastBlockTime = 0; + nLastTXTime = 0; nPingNonceSent = 0; nPingUsecStart = 0; nPingUsecTime = 0; diff --git a/src/net.h b/src/net.h index 5c1f7e3e8..2f96c58e3 100644 --- a/src/net.h +++ b/src/net.h @@ -416,6 +416,11 @@ public: // Last time a "MEMPOOL" request was serviced. std::atomic timeLastMempoolReq; + + // Block and TXN accept times + std::atomic nLastBlockTime; + std::atomic nLastTXTime; + // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. uint64_t nPingNonceSent; From 6ee7f05622c32431a9815a96b31a6a65a821fdcc Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 10 Jun 2016 03:02:01 +0000 Subject: [PATCH 0793/1223] Allow disconnecting a netgroup with only one member in eviction. With the latest additions there are enough protective measures that we can take the training wheels off. --- src/net.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index ec547e8c9..89eb55ae9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -965,13 +965,6 @@ static bool AttemptToEvictConnection() { // Reduce to the network group with the most connections vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]); - // Do not disconnect peers if there is only one unprotected connection from their network group. - // This step excessively favors netgroup diversity, and should be removed once more protective criteria are established. - if (vEvictionCandidates.size() <= 1) - // unless we prefer the new connection (for whitelisted peers) - if (!fPreferNewConnection) - return false; - // Disconnect from the network group with the most connections NodeId evicted = vEvictionCandidates.front().id; LOCK(cs_vNodes); From fa58e5ee93b8ab7a5a71cd232d829233ee7f2f56 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 16 Jun 2016 10:10:03 +0200 Subject: [PATCH 0794/1223] [doc] Add website links to about dialog --- src/init.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index c2ba9ae44..b572bfc32 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -479,11 +479,20 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { + const std::string URL_SOURCE_CODE = ""; + const std::string URL_WEBSITE = ""; // todo: remove urls from translations on next change return CopyrightHolders(strprintf(_("Copyright (C) %i-%i"), 2009, COPYRIGHT_YEAR) + " ") + "\n" + "\n" + - _("This is experimental software.") + "\n" + + strprintf(_("Please contribute if you find %s useful. " + "Visit %s for further information about the software."), + PACKAGE_NAME, URL_WEBSITE) + "\n" + + strprintf(_("The source code is available from %s."), + URL_SOURCE_CODE) + + "\n" + + "\n" + + _("This is experimental software.") + "\n" + _("Distributed under the MIT software license, see the accompanying file COPYING or .") + "\n" + "\n" + _("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.") + From c82a4e9a63a28fc8c482c7c8e5b7bfcc51a6805a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Sat, 20 Feb 2016 21:02:44 -0500 Subject: [PATCH 0795/1223] Use ancestor-feerate based transaction selection for mining Includes changes by Pieter Wuille --- src/miner.cpp | 206 +++++++++++++++++++++++++++++++++++++++++++++++++- src/miner.h | 118 +++++++++++++++++++++++++++++ 2 files changed, 323 insertions(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 99eb0a2eb..989ad11a2 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -25,6 +25,7 @@ #include "utilmoneystr.h" #include "validationinterface.h" +#include #include #include #include @@ -134,7 +135,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) : pblock->GetBlockTime(); addPriorityTxs(); - addScoreTxs(); + addPackageTxs(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; @@ -177,7 +178,38 @@ bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) return false; } +void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) +{ + for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) { + // Only test txs not already in the block + if (inBlock.count(*iit)) { + testSet.erase(iit++); + } + else { + iit++; + } + } +} +bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps) +{ + if (nBlockSize + packageSize >= nBlockMaxSize) + return false; + if (nBlockSigOps + packageSigOps >= MAX_BLOCK_SIGOPS) + return false; + return true; +} + +// Block size and sigops have already been tested. Check that all transactions +// are final. +bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package) +{ + BOOST_FOREACH (const CTxMemPool::txiter it, package) { + if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) + return false; + } + return true; +} bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { @@ -297,6 +329,178 @@ void BlockAssembler::addScoreTxs() } } +void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, + indexed_modified_transaction_set &mapModifiedTx) +{ + BOOST_FOREACH(const CTxMemPool::txiter it, alreadyAdded) { + CTxMemPool::setEntries descendants; + mempool.CalculateDescendants(it, descendants); + // Insert all descendants (not yet in block) into the modified set + BOOST_FOREACH(CTxMemPool::txiter desc, descendants) { + if (alreadyAdded.count(desc)) + continue; + modtxiter mit = mapModifiedTx.find(desc); + if (mit == mapModifiedTx.end()) { + CTxMemPoolModifiedEntry modEntry(desc); + modEntry.nSizeWithAncestors -= it->GetTxSize(); + modEntry.nModFeesWithAncestors -= it->GetModifiedFee(); + modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount(); + mapModifiedTx.insert(modEntry); + } else { + mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); + } + } + } +} + +// Skip entries in mapTx that are already in a block or are present +// in mapModifiedTx (which implies that the mapTx ancestor state is +// stale due to ancestor inclusion in the block) +// Also skip transactions that we've already failed to add. This can happen if +// we consider a transaction in mapModifiedTx and it fails: we can then +// potentially consider it again while walking mapTx. It's currently +// guaranteed to fail again, but as a belt-and-suspenders check we put it in +// failedTx and avoid re-evaluation, since the re-evaluation would be using +// cached size/sigops/fee values that are not actually correct. +bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) +{ + assert (it != mempool.mapTx.end()); + if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it)) + return true; + return false; +} + +void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries) +{ + // Sort package by ancestor count + // If a transaction A depends on transaction B, then A's ancestor count + // must be greater than B's. So this is sufficient to validly order the + // transactions for block inclusion. + sortedEntries.clear(); + sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end()); + std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount()); +} + +// This transaction selection algorithm orders the mempool based +// on feerate of a transaction including all unconfirmed ancestors. +// Since we don't remove transactions from the mempool as we select them +// for block inclusion, we need an alternate method of updating the feerate +// of a transaction with its not-yet-selected ancestors as we go. +// This is accomplished by walking the in-mempool descendants of selected +// transactions and storing a temporary modified state in mapModifiedTxs. +// Each time through the loop, we compare the best transaction in +// mapModifiedTxs with the next transaction in the mempool to decide what +// transaction package to work on next. +void BlockAssembler::addPackageTxs() +{ + // mapModifiedTx will store sorted packages after they are modified + // because some of their txs are already in the block + indexed_modified_transaction_set mapModifiedTx; + // Keep track of entries that failed inclusion, to avoid duplicate work + CTxMemPool::setEntries failedTx; + + // Start by adding all descendants of previously added txs to mapModifiedTx + // and modifying them for their already included ancestors + UpdatePackagesForAdded(inBlock, mapModifiedTx); + + CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); + CTxMemPool::txiter iter; + while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty()) + { + // First try to find a new transaction in mapTx to evaluate. + if (mi != mempool.mapTx.get().end() && + SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) { + ++mi; + continue; + } + + // Now that mi is not stale, determine which transaction to evaluate: + // the next entry from mapTx, or the best from mapModifiedTx? + bool fUsingModified = false; + + modtxscoreiter modit = mapModifiedTx.get().begin(); + if (mi == mempool.mapTx.get().end()) { + // We're out of entries in mapTx; use the entry from mapModifiedTx + iter = modit->iter; + fUsingModified = true; + } else { + // Try to compare the mapTx entry to the mapModifiedTx entry + iter = mempool.mapTx.project<0>(mi); + if (modit != mapModifiedTx.get().end() && + CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) { + // The best entry in mapModifiedTx has higher score + // than the one from mapTx. + // Switch which transaction (package) to consider + iter = modit->iter; + fUsingModified = true; + } else { + // Either no entry in mapModifiedTx, or it's worse than mapTx. + // Increment mi for the next loop iteration. + ++mi; + } + } + + // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't + // contain anything that is inBlock. + assert(!inBlock.count(iter)); + + uint64_t packageSize = iter->GetSizeWithAncestors(); + CAmount packageFees = iter->GetModFeesWithAncestors(); + unsigned int packageSigOps = iter->GetSigOpCountWithAncestors(); + if (fUsingModified) { + packageSize = modit->nSizeWithAncestors; + packageFees = modit->nModFeesWithAncestors; + packageSigOps = modit->nSigOpCountWithAncestors; + } + + if (packageFees < ::minRelayTxFee.GetFee(packageSize) && nBlockSize >= nBlockMinSize) { + // Everything else we might consider has a lower fee rate + return; + } + + if (!TestPackage(packageSize, packageSigOps)) { + if (fUsingModified) { + // Since we always look at the best entry in mapModifiedTx, + // we must erase failed entries so that we can consider the + // next best entry on the next loop iteration + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); + } + continue; + } + + CTxMemPool::setEntries ancestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + + onlyUnconfirmed(ancestors); + ancestors.insert(iter); + + // Test if all tx's are Final + if (!TestPackageFinality(ancestors)) { + if (fUsingModified) { + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); + } + continue; + } + + // Package can be added. Sort the entries in a valid order. + vector sortedEntries; + SortForBlock(ancestors, iter, sortedEntries); + + for (size_t i=0; i #include +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" class CBlockIndex; class CChainParams; @@ -29,6 +31,104 @@ struct CBlockTemplate std::vector vTxSigOps; }; +// Container for tracking updates to ancestor feerate as we include (parent) +// transactions in a block +struct CTxMemPoolModifiedEntry { + CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) + { + iter = entry; + nSizeWithAncestors = entry->GetSizeWithAncestors(); + nModFeesWithAncestors = entry->GetModFeesWithAncestors(); + nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); + } + + CTxMemPool::txiter iter; + uint64_t nSizeWithAncestors; + CAmount nModFeesWithAncestors; + unsigned int nSigOpCountWithAncestors; +}; + +/** Comparator for CTxMemPool::txiter objects. + * It simply compares the internal memory address of the CTxMemPoolEntry object + * pointed to. This means it has no meaning, and is only useful for using them + * as key in other indexes. + */ +struct CompareCTxMemPoolIter { + bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const + { + return &(*a) < &(*b); + } +}; + +struct modifiedentry_iter { + typedef CTxMemPool::txiter result_type; + result_type operator() (const CTxMemPoolModifiedEntry &entry) const + { + return entry.iter; + } +}; + +// This matches the calculation in CompareTxMemPoolEntryByAncestorFee, +// except operating on CTxMemPoolModifiedEntry. +// TODO: refactor to avoid duplication of this logic. +struct CompareModifiedEntry { + bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) + { + double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors; + double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors; + if (f1 == f2) { + return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter); + } + return f1 > f2; + } +}; + +// A comparator that sorts transactions based on number of ancestors. +// This is sufficient to sort an ancestor package in an order that is valid +// to appear in a block. +struct CompareTxIterByAncestorCount { + bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) + { + if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) + return a->GetCountWithAncestors() < b->GetCountWithAncestors(); + return CTxMemPool::CompareIteratorByHash()(a, b); + } +}; + +typedef boost::multi_index_container< + CTxMemPoolModifiedEntry, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< + modifiedentry_iter, + CompareCTxMemPoolIter + >, + // sorted by modified ancestor fee rate + boost::multi_index::ordered_non_unique< + // Reuse same tag from CTxMemPool's similar index + boost::multi_index::tag, + boost::multi_index::identity, + CompareModifiedEntry + > + > +> indexed_modified_transaction_set; + +typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; +typedef indexed_modified_transaction_set::index::type::iterator modtxscoreiter; + +struct update_for_parent_inclusion +{ + update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} + + void operator() (CTxMemPoolModifiedEntry &e) + { + e.nModFeesWithAncestors -= iter->GetFee(); + e.nSizeWithAncestors -= iter->GetTxSize(); + e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); + } + + CTxMemPool::txiter iter; +}; + /** Generate a new block, without valid proof-of-work */ class BlockAssembler { @@ -74,12 +174,30 @@ private: void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); + /** Add transactions based on feerate including unconfirmed ancestors */ + void addPackageTxs(); // helper function for addScoreTxs and addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ bool isStillDependent(CTxMemPool::txiter iter); + + // helper functions for addPackageTxs() + /** Remove confirmed (inBlock) entries from given set */ + void onlyUnconfirmed(CTxMemPool::setEntries& testSet); + /** Test if a new package would "fit" in the block */ + bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); + /** Test if a set of transactions are all final */ + bool TestPackageFinality(const CTxMemPool::setEntries& package); + /** Return true if given transaction from mapTx has already been evaluated, + * or if the transaction's cached data in mapTx is incorrect. */ + bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); + /** Sort the package in an order that is valid to appear in a block */ + void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries); + /** Add descendants of given transactions to mapModifiedTx with ancestor + * state updated assuming given transactions are inBlock. */ + void UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); }; /** Modify the extranonce in a block */ From 29fac19c93fabfed4163ee9ffa85f9188c9ee6ac Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Sat, 20 Feb 2016 20:58:23 -0500 Subject: [PATCH 0796/1223] Add unit tests for ancestor feerate mining --- src/test/miner_tests.cpp | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 3fb796788..ca8d6d2e0 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -71,6 +71,113 @@ bool TestSequenceLocks(const CTransaction &tx, int flags) return CheckSequenceLocks(tx, flags); } +// Test suite for ancestor feerate transaction selection. +// Implemented as an additional function, rather than a separate test case, +// to allow reusing the blockchain created in CreateNewBlock_validity. +// Note that this test assumes blockprioritysize is 0. +void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector& txFirst) +{ + // Test the ancestor feerate transaction selection. + TestMemPoolEntryHelper entry; + + // Test that a medium fee transaction will be selected after a higher fee + // rate package with a low fee rate parent. + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].prevout.n = 0; + tx.vout.resize(1); + tx.vout[0].nValue = 5000000000LL - 1000; + // This tx has a low fee: 1000 satoshis + uint256 hashParentTx = tx.GetHash(); // save this txid for later use + mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a medium fee: 10000 satoshis + tx.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx.vout[0].nValue = 5000000000LL - 10000; + uint256 hashMediumFeeTx = tx.GetHash(); + mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a high fee, but depends on the first transaction + tx.vin[0].prevout.hash = hashParentTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee + uint256 hashHighFeeTx = tx.GetHash(); + mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + + CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[1].GetHash() == hashParentTx); + BOOST_CHECK(pblocktemplate->block.vtx[2].GetHash() == hashHighFeeTx); + BOOST_CHECK(pblocktemplate->block.vtx[3].GetHash() == hashMediumFeeTx); + + // Test that a package below the min relay fee doesn't get included + tx.vin[0].prevout.hash = hashHighFeeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee + uint256 hashFreeTx = tx.GetHash(); + mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx)); + size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Calculate a fee on child transaction that will put the package just + // below the min relay fee (assuming 1 child tx of the same size). + CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; + + tx.vin[0].prevout.hash = hashFreeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; + uint256 hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + // Verify that the free tx and the low fee tx didn't get selected + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx); + } + + // Test that packages above the min relay fee do get included, even if one + // of the transactions is below the min relay fee + // Remove the low fee transaction and replace with a higher fee transaction + std::list dummy; + mempool.removeRecursive(tx, dummy); + tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee + hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[4].GetHash() == hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[5].GetHash() == hashLowFeeTx); + + // Test that transaction selection properly updates ancestor fee + // calculations as ancestor transactions get included in a block. + // Add a 0-fee transaction that has 2 outputs. + tx.vin[0].prevout.hash = txFirst[2]->GetHash(); + tx.vout.resize(2); + tx.vout[0].nValue = 5000000000LL - 100000000; + tx.vout[1].nValue = 100000000; // 1BTC output + uint256 hashFreeTx2 = tx.GetHash(); + mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); + + // This tx can't be mined by itself + tx.vin[0].prevout.hash = hashFreeTx2; + tx.vout.resize(1); + feeToUse = minRelayTxFee.GetFee(freeTxSize); + tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; + uint256 hashLowFeeTx2 = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + + // Verify that this tx isn't selected. + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx2); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx2); + } + + // This tx will be mineable, and should cause hashLowFeeTx2 to be selected + // as well. + tx.vin[0].prevout.n = 1; + tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee + mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[8].GetHash() == hashLowFeeTx2); +} + // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { @@ -385,6 +492,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) SetMockTime(0); mempool.clear(); + TestPackageSelection(chainparams, scriptPubKey, txFirst); + BOOST_FOREACH(CTransaction *_tx, txFirst) delete _tx; From f25209a3e1e6488d4d44de15b0f113d2302e9aee Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 9 Jun 2016 12:30:38 -0400 Subject: [PATCH 0797/1223] depends: bump OSX toolchain clang: 3.7.1 cctools: 877.8 ld64: 253.9 --- depends/hosts/darwin.mk | 4 ++-- depends/packages/native_cctools.mk | 20 +++++++++++--------- depends/packages/qt.mk | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index dbe6d0079..985649619 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,7 @@ OSX_MIN_VERSION=10.7 -OSX_SDK_VERSION=10.9 +OSX_SDK_VERSION=10.11 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=241.9 +LD64_VERSION=253.9 darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index b5603a8d4..797480c25 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,14 +1,14 @@ package=native_cctools -$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb +$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 $(package)_download_path=https://github.com/theuni/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9 +$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a $(package)_build_subdir=cctools -$(package)_clang_version=3.3 +$(package)_clang_version=3.7.1 $(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7 +$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 $(package)_extra_sources=$($(package)_clang_file_name) define $(package)_fetch_cmds @@ -23,6 +23,7 @@ define $(package)_extract_cmds $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + rm -f toolchain/lib/libc++abi.so* && \ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ chmod +x toolchain/bin/$(host)-dsymutil && \ @@ -30,7 +31,7 @@ define $(package)_extract_cmds endef define $(package)_set_vars -$(package)_config_opts=--target=$(host) --disable-libuuid +$(package)_config_opts=--target=$(host) --disable-lto-support $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ @@ -53,10 +54,11 @@ define $(package)_stage_cmds cd $($(package)_extract_dir)/toolchain && \ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi endef diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index c1fc8e305..a8d343996 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -124,6 +124,7 @@ define $(package)_preprocess_cmds sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \ sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \ sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \ + sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ From f6eb4e2b62d9c01ae32cf5a742dd86a594849343 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sat, 14 May 2016 16:38:44 +0800 Subject: [PATCH 0798/1223] [depends] OpenSSL 1.0.1k - update config_opts --- depends/packages/openssl.mk | 39 ++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index c6452820a..5ee9f17a6 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -6,9 +6,42 @@ $(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fce define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" -$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso -$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2 -$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl2 no-ssl3 +$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl +$(package)_config_opts+=no-camellia +$(package)_config_opts+=no-capieng +$(package)_config_opts+=no-cast +$(package)_config_opts+=no-comp +$(package)_config_opts+=no-dso +$(package)_config_opts+=no-dtls1 +$(package)_config_opts+=no-ec_nistp_64_gcc_128 +$(package)_config_opts+=no-gost +$(package)_config_opts+=no-gmp +$(package)_config_opts+=no-heartbeats +$(package)_config_opts+=no-idea +$(package)_config_opts+=no-jpake +$(package)_config_opts+=no-krb5 +$(package)_config_opts+=no-libunbound +$(package)_config_opts+=no-md2 +$(package)_config_opts+=no-mdc2 +$(package)_config_opts+=no-rc4 +$(package)_config_opts+=no-rc5 +$(package)_config_opts+=no-rdrand +$(package)_config_opts+=no-rfc3779 +$(package)_config_opts+=no-rsax +$(package)_config_opts+=no-sctp +$(package)_config_opts+=no-seed +$(package)_config_opts+=no-sha0 +$(package)_config_opts+=no-shared +$(package)_config_opts+=no-ssl-trace +$(package)_config_opts+=no-ssl2 +$(package)_config_opts+=no-ssl3 +$(package)_config_opts+=no-static_engine +$(package)_config_opts+=no-store +$(package)_config_opts+=no-unit-test +$(package)_config_opts+=no-weak-ssl-ciphers +$(package)_config_opts+=no-whirlpool +$(package)_config_opts+=no-zlib +$(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) $(package)_config_opts_linux=-fPIC -Wa,--noexecstack $(package)_config_opts_x86_64_linux=linux-x86_64 From faa91b12f774d7f459e47f440b7e9fe173d72bb0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 7 Jun 2016 11:22:21 +0200 Subject: [PATCH 0799/1223] [wallet] tests: Don't use floating point --- src/wallet/test/wallet_tests.cpp | 46 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 387b22358..0a4f06ba8 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -27,7 +27,7 @@ typedef set > CoinSet; BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static CWallet wallet; +static const CWallet wallet; static vector vCoins; static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) @@ -188,11 +188,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // empty the wallet and start again, now with fractions of a cent, to test small change avoidance empty_wallet(); - add_coin(0.1*MIN_CHANGE); - add_coin(0.2*MIN_CHANGE); - add_coin(0.3*MIN_CHANGE); - add_coin(0.4*MIN_CHANGE); - add_coin(0.5*MIN_CHANGE); + add_coin(MIN_CHANGE * 1 / 10); + add_coin(MIN_CHANGE * 2 / 10); + add_coin(MIN_CHANGE * 3 / 10); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 5 / 10); // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly @@ -207,8 +207,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // if we add more small coins: - add_coin(0.6*MIN_CHANGE); - add_coin(0.7*MIN_CHANGE); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); // and try again to make 1.0 * MIN_CHANGE BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -229,9 +229,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.7 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin @@ -239,9 +239,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.8 * MIN_CHANGE); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 8 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount @@ -249,17 +249,17 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // test avoiding small change empty_wallet(); - add_coin(0.05 * MIN_CHANGE); - add_coin(1 * MIN_CHANGE); - add_coin(100 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 100); + add_coin(MIN_CHANGE * 1); + add_coin(MIN_CHANGE * 100); // trying to make 100.01 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change - BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -310,7 +310,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // add 75 cents in small change. not enough to make 90 cents, // then try making 90 cents. there are multiple competing "smallest bigger" coins, // one of which should be picked at random - add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + add_coin(5 * CENT); + add_coin(10 * CENT); + add_coin(15 * CENT); + add_coin(20 * CENT); + add_coin(25 * CENT); fails = 0; for (int i = 0; i < RANDOM_REPEATS; i++) From facb6c0bf8a6ef7081d763d9f33b446276a36635 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 22 May 2016 11:37:42 +0200 Subject: [PATCH 0800/1223] [qa] mininode: fail on send_message instead of silent return --- qa/rpc-tests/test_framework/mininode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index c0b59f385..6612b99b8 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1315,7 +1315,7 @@ class NodeConn(asyncore.dispatcher): def send_message(self, message, pushbuf=False): if self.state != "connected" and not pushbuf: - return + raise IOError('Not connected, no pushbuf') self.show_debug_msg("Send %s" % repr(message)) command = message.command data = message.serialize() From fa8ce3b670dd9376d2c13722670b9cc8012011ca Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 16 Apr 2016 19:11:39 +0200 Subject: [PATCH 0801/1223] [qa] assert 'changePosition out of bounds' --- qa/rpc-tests/fundrawtransaction.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 228574e67..3dfb9e402 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -247,6 +247,12 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) change = self.nodes[2].getnewaddress() + try: + rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 2}) + except JSONRPCException as e: + assert('changePosition out of bounds' == e.error['message']) + else: + assert(False) rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) out = dec_tx['vout'][0]; From fa324653ab7a44a89d6a692ce8f953ded8501e17 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 16 Apr 2016 18:36:39 +0200 Subject: [PATCH 0802/1223] [qa] fundrawtransaction: Create get_unspent() --- qa/rpc-tests/fundrawtransaction.py | 93 ++++++------------------------ 1 file changed, 19 insertions(+), 74 deletions(-) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 3dfb9e402..eeb847663 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -6,7 +6,14 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -# Create one-input, one-output, no-fee transaction: + +def get_unspent(listunspent, amount): + for utx in listunspent: + if utx['amount'] == amount: + return utx + raise AssertionError('Could not find unspent with amount={}'.format(amount)) + + class RawTransactionsTest(BitcoinTestFramework): def __init__(self): @@ -71,7 +78,7 @@ class RawTransactionsTest(BitcoinTestFramework): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert(len(dec_tx['vin']) > 0) #test if we have enought inputs + assert(len(dec_tx['vin']) > 0) #test that we have enough inputs ############################## # simple test with two coins # @@ -123,14 +130,7 @@ class RawTransactionsTest(BitcoinTestFramework): ######################################################################### # test a fundrawtransaction with a VIN greater than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 5.0: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 1.0 } @@ -151,14 +151,7 @@ class RawTransactionsTest(BitcoinTestFramework): ##################################################################### # test a fundrawtransaction with which will not get a change output # ##################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 5.0: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance } @@ -180,14 +173,7 @@ class RawTransactionsTest(BitcoinTestFramework): #################################################### # test a fundrawtransaction with an invalid option # #################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 5.0: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } @@ -205,14 +191,7 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################################ # test a fundrawtransaction with an invalid change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 5.0: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } @@ -227,18 +206,10 @@ class RawTransactionsTest(BitcoinTestFramework): assert("changeAddress must be a valid bitcoin address" in e.error['message']) - ############################################################ # test a fundrawtransaction with a provided change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 5.0: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } @@ -259,18 +230,10 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(change, out['scriptPubKey']['addresses'][0]) - ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 1.0: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 1) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 1.0 } @@ -305,17 +268,8 @@ class RawTransactionsTest(BitcoinTestFramework): ########################################### # test a fundrawtransaction with two VINs # ########################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 1.0: - utx = aUtx - if aUtx['amount'] == 5.0: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 1) + utx2 = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 6.0 } @@ -347,17 +301,8 @@ class RawTransactionsTest(BitcoinTestFramework): ######################################################### # test a fundrawtransaction with two VINs and two vOUTs # ######################################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 1.0: - utx = aUtx - if aUtx['amount'] == 5.0: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 1) + utx2 = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 } From fa3b3792522681207b3619edec5f3175be6fc841 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 9 May 2016 21:29:18 +0200 Subject: [PATCH 0803/1223] [qa] pull-tester: Fix assertion and check for run_parallel --- qa/pull-tester/rpc-tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 57a576f1c..988230850 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -191,7 +191,7 @@ def runtests(): if coverage: flags.append(coverage.flag) - if len(test_list) > 1: + if len(test_list) > 1 and run_parallel > 1: # Populate cache subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) @@ -251,7 +251,7 @@ class RPCTestHandler: stdout=subprocess.PIPE, stderr=subprocess.PIPE))) if not self.jobs: - raise IndexError('%s from empty list' % __name__) + raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) From 6194d9a501901f9fa7b20d2a4c34b31357a6441d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 16 Jun 2016 11:29:44 +0200 Subject: [PATCH 0804/1223] Fix bitcoin_qt.m4 and fix-xcb-include-order.patch --- .travis.yml | 2 +- build-aux/m4/bitcoin_qt.m4 | 2 + contrib/devtools/symbol-check.py | 1 + contrib/gitian-descriptors/gitian-osx.yml | 4 +- depends/packages/qt.mk | 88 ++++++++++--------- .../patches/qt/fix-xcb-include-order.patch | 28 +++--- depends/patches/qt/fix_qt_pkgconfig.patch | 11 +++ 7 files changed, 79 insertions(+), 57 deletions(-) create mode 100644 depends/patches/qt/fix_qt_pkgconfig.patch diff --git a/.travis.yml b/.travis.yml index 64227ac2a..a6c51753b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ env: # No wallet - HOST=x86_64-unknown-linux-gnu PACKAGES=" openjdk-7-jre-headless python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" # Cross-Mac - - HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + - HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.11 GOAL="deploy" before_install: - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index efffa4887..210df3c02 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -342,6 +342,8 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test x$TARGET_OS = xdarwin; then PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi + else + QT_LIBS="-lQt5PlatformSupport $QT_LIBS" fi ]) else diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index e26c0fbb9..037b34212 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -68,6 +68,7 @@ b'libX11.so.6', # part of X11 b'libxcb.so.1', # part of X11 b'libfontconfig.so.1', # font support b'libfreetype.so.6', # font parsing +b'libdbus-1.so.3', # inter process communication (notification system) b'libdl.so.2' # programming interface to dynamic linker } diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 536fcfb10..991976d59 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -31,7 +31,7 @@ remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "MacOSX10.9.sdk.tar.gz" +- "MacOSX10.11.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" @@ -87,7 +87,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index a8d343996..c452823a9 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,20 +1,21 @@ PACKAGE=qt -$(package)_version=5.5.0 -$(package)_download_path=http://download.qt.io/official_releases/qt/5.5/$($(package)_version)/submodules +$(package)_version=5.6.1 +$(package)_download_path=http://download.qt.io/official_releases/qt/5.6/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=7e82b1318f88e56a2a9376e069aa608d4fd96b48cb0e1b880ae658b0a1af0561 +$(package)_sha256_hash=0ac67cf8d66d52b995f96c31c4b48117a1afb3db99eaa93e20ccd8f7f55f7fde $(package)_dependencies=openssl $(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch mingw-uuidof.patch pidlist_absolute.patch +$(package)_patches=mac-qmake.conf mingw-uuidof.patch pidlist_absolute.patch fix-xcb-include-order.patch fix_qt_pkgconfig.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=c4bd6db6e426965c6f8824c54e81f68bbd61e2bae1bcadc328c6e81c45902a0d +$(package)_qttranslations_sha256_hash=dcc1534d247babca1840cb6d0a000671801a341ea352d0535474f86adadaf028 + $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=d9e06bd19ecc86afba5e95d45a906d1bc1ad579aa70001e36143c1aaf695bdd6 +$(package)_qttools_sha256_hash=e0f845de28c31230dfa428f0190ccb3b91d1fc02481b1f064698ae4ef8376aa1 $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -22,21 +23,33 @@ $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars $(package)_config_opts_release = -release $(package)_config_opts_debug = -debug -$(package)_config_opts += -opensource -confirm-license +$(package)_config_opts += -bindir $(build_prefix)/bin +$(package)_config_opts += -c++11 +$(package)_config_opts += -confirm-license +$(package)_config_opts += -hostprefix $(build_prefix) +$(package)_config_opts += -no-alsa $(package)_config_opts += -no-audio-backend -$(package)_config_opts += -no-glib -$(package)_config_opts += -no-icu $(package)_config_opts += -no-cups -$(package)_config_opts += -no-iconv -$(package)_config_opts += -no-gif -$(package)_config_opts += -no-freetype -$(package)_config_opts += -no-nis -$(package)_config_opts += -pch -$(package)_config_opts += -no-qml-debug -$(package)_config_opts += -nomake examples -$(package)_config_opts += -nomake tests +$(package)_config_opts += -no-egl +$(package)_config_opts += -no-eglfs $(package)_config_opts += -no-feature-style-windowsmobile $(package)_config_opts += -no-feature-style-windowsce +$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-gif +$(package)_config_opts += -no-glib +$(package)_config_opts += -no-gstreamer +$(package)_config_opts += -no-icu +$(package)_config_opts += -no-iconv +$(package)_config_opts += -no-kms +$(package)_config_opts += -no-linuxfb +$(package)_config_opts += -no-libudev +$(package)_config_opts += -no-mitshm +$(package)_config_opts += -no-mtdev +$(package)_config_opts += -no-nis +$(package)_config_opts += -no-pulseaudio +$(package)_config_opts += -no-openvg +$(package)_config_opts += -no-reduce-relocations +$(package)_config_opts += -no-qml-debug $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -46,36 +59,25 @@ $(package)_config_opts += -no-sql-odbc $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 -$(package)_config_opts += -prefix $(host_prefix) -$(package)_config_opts += -hostprefix $(build_prefix) -$(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++11 +$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -no-xinput2 +$(package)_config_opts += -no-xrender +$(package)_config_opts += -nomake examples +$(package)_config_opts += -nomake tests +$(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked -$(package)_config_opts += -v -$(package)_config_opts += -static -$(package)_config_opts += -silent +$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -pch $(package)_config_opts += -pkg-config +$(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg -$(package)_config_opts += -qt-zlib $(package)_config_opts += -qt-pcre -$(package)_config_opts += -no-pulseaudio -$(package)_config_opts += -no-openvg -$(package)_config_opts += -no-xrender -$(package)_config_opts += -no-alsa -$(package)_config_opts += -no-mtdev -$(package)_config_opts += -no-gstreamer -$(package)_config_opts += -no-mitshm -$(package)_config_opts += -no-kms -$(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-egl -$(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-linuxfb -$(package)_config_opts += -no-xinput2 -$(package)_config_opts += -no-libudev -$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -qt-zlib $(package)_config_opts += -reduce-exports -$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -static +$(package)_config_opts += -silent +$(package)_config_opts += -v ifneq ($(build_os),darwin) $(package)_config_opts_darwin = -xplatform macx-clang-linux @@ -119,6 +121,7 @@ define $(package)_extract_cmds tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef + define $(package)_preprocess_cmds sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \ @@ -130,9 +133,10 @@ define $(package)_preprocess_cmds cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ - patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ patch -p1 < $($(package)_patch_dir)/mingw-uuidof.patch && \ patch -p1 < $($(package)_patch_dir)/pidlist_absolute.patch && \ + patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ + patch -p1 < $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch index ae469ea94..c7dbebedc 100644 --- a/depends/patches/qt/fix-xcb-include-order.patch +++ b/depends/patches/qt/fix-xcb-include-order.patch @@ -1,15 +1,15 @@ --- old/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:06:42.705930685 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:08:41.281926351 +0000 -@@ -94,8 +94,6 @@ - +@@ -74,8 +74,6 @@ + DEFINES += $$QMAKE_DEFINES_XCB LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB -QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB - + CONFIG += qpa/genericunixfontdatabase - -@@ -104,7 +102,8 @@ + +@@ -87,7 +85,8 @@ contains(QT_CONFIG, xcb-qt) { DEFINES += XCB_USE_RENDER XCB_DIR = ../../../3rdparty/xcb @@ -18,28 +18,32 @@ + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms -lxcb-xinerama --- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000 -@@ -8,7 +8,8 @@ - +@@ -9,7 +9,8 @@ + XCB_DIR = ../../../../3rdparty/xcb - + -INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude +QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude +QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude - + QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB --- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:02:59.530038830 -0400 +++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:01:22.106037459 -0400 -@@ -11,3 +11,9 @@ +@@ -6,6 +6,13 @@ qxcbmain.cpp OTHER_FILES += xcb.json README - + +contains(QT_CONFIG, xcb-qt) { + DEFINES += XCB_USE_RENDER + XCB_DIR = ../../../3rdparty/xcb + QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB +} ++ + PLUGIN_TYPE = platforms + PLUGIN_CLASS_NAME = QXcbIntegrationPlugin + !equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch new file mode 100644 index 000000000..3772db4f8 --- /dev/null +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -0,0 +1,11 @@ +--- old/qtbase/mkspecs/features/qt_module.prf 2016-03-17 02:06:42.705930685 +0000 ++++ new/qtbase/mkspecs/features/qt_module.prf 2016-03-17 02:06:42.705930685 +0000 +@@ -244,7 +244,7 @@ + load(qt_targets) + + # this builds on top of qt_common +-!internal_module:!lib_bundle:if(unix|mingw) { ++unix|mingw { + CONFIG += create_pc + QMAKE_PKGCONFIG_DESTDIR = pkgconfig + host_build: \ From 9e3ec74fac76f93bedaca882cc7053cc46199a61 Mon Sep 17 00:00:00 2001 From: Nathaniel Mahieu Date: Tue, 14 Jun 2016 17:49:09 -0500 Subject: [PATCH 0805/1223] Clarify documentation for running a tor node Previous wording suggested that no additional setup was required for a tor hidden service to be created. --- doc/tor.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 43e922718..79f156302 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -95,12 +95,22 @@ Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically. Bitcoin Core has been updated to make use of this. -This means that if Tor is running (and proper authorization is available), -Bitcoin Core automatically creates a hidden service to listen on, without -manual configuration. This will positively affect the number of available -.onion nodes. +This means that if Tor is running (and proper authentication has been configured), +Bitcoin Core automatically creates a hidden service to listen on. This will positively +affect the number of available .onion nodes. This new feature is enabled by default if Bitcoin Core is listening, and a connection to Tor can be made. It can be configured with the `-listenonion`, `-torcontrol` and `-torpassword` settings. To show verbose debugging information, pass `-debug=tor`. + +Connecting to Tor's control socket API requires one of two authentication methods to be +configured. For cookie authentication the user running bitcoind must have write access +to the `CookieAuthFile` specified in Tor configuration. In some cases this is +preconfigured and the creation of a hidden service is automatic. If permission problems +are seen with `-debug=tor` they can be resolved by adding both the user running tor and +the user running bitcoind to the same group and setting permissions appropriately. On +Debian-based systems the user running bitcoind can be added to the debian-tor group, +which has the appropriate permissions. An alternative authentication method is the use +of the `-torpassword` flag and a `hash-password` which can be enabled and specified in +Tor configuration. \ No newline at end of file From 59d063d07660d6e8d53ed8aa1eb8b0747ea6767c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 18 Jun 2016 13:51:45 +0200 Subject: [PATCH 0806/1223] Use runtime linking of QT libdbus, use custom/temp. SDK URL --- .travis.yml | 2 +- contrib/devtools/symbol-check.py | 1 - depends/packages/qt.mk | 3 ++- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a6c51753b..af9c476dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ env: - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoincore.org/depends-sources/sdks + - SDK_URL=https://bitcoin.jonasschnelli.ch/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all matrix: diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 037b34212..e26c0fbb9 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -68,7 +68,6 @@ b'libX11.so.6', # part of X11 b'libxcb.so.1', # part of X11 b'libfontconfig.so.1', # font support b'libfreetype.so.6', # font parsing -b'libdbus-1.so.3', # inter process communication (notification system) b'libdl.so.2' # programming interface to dynamic linker } diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index c452823a9..d41d0b9ea 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -5,7 +5,7 @@ $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=0ac67cf8d66d52b995f96c31c4b48117a1afb3db99eaa93e20ccd8f7f55f7fde $(package)_dependencies=openssl -$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext +$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib $(package)_patches=mac-qmake.conf mingw-uuidof.patch pidlist_absolute.patch fix-xcb-include-order.patch fix_qt_pkgconfig.patch @@ -26,6 +26,7 @@ $(package)_config_opts_debug = -debug $(package)_config_opts += -bindir $(build_prefix)/bin $(package)_config_opts += -c++11 $(package)_config_opts += -confirm-license +$(package)_config_opts += -dbus-runtime $(package)_config_opts += -hostprefix $(build_prefix) $(package)_config_opts += -no-alsa $(package)_config_opts += -no-audio-backend From ad0752e41f7804fd1d0e639c51e927ed4f430e09 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 18 Jun 2016 18:16:36 +0200 Subject: [PATCH 0807/1223] Stop trimming when mapTx is empty --- src/txmempool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 205ffd637..18c54b08b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1075,7 +1075,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); - while (DynamicMemoryUsage() > sizelimit) { + while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) { indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the From 3775ff9ea7e92cc1e6a0cdbb15999913d93c87e7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 18 Jun 2016 19:15:03 +0200 Subject: [PATCH 0808/1223] Enable mempool consistency checks in unit tests --- src/test/test_bitcoin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index c68320ba8..3dc59ddd0 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -55,6 +55,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); + mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); From 1e9aab0dbfcb844458b5f221a9af0141bba6280f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Sat, 18 Jun 2016 20:53:17 -0400 Subject: [PATCH 0809/1223] Remove sipa's old revoked key from verify-commits Now that the trusted root is past all commits signed by that key we don't need it in the trusted-keys list, nor do we need to whitelist those commits in allow-revsig-commits --- contrib/verify-commits/allow-revsig-commits | 2 -- contrib/verify-commits/trusted-keys | 1 - 2 files changed, 3 deletions(-) diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits index 31aeb8f3d..e69de29bb 100644 --- a/contrib/verify-commits/allow-revsig-commits +++ b/contrib/verify-commits/allow-revsig-commits @@ -1,2 +0,0 @@ -586a29253dabec3ca0f1ccba9091daabd16b8411 -eddaba7b5692288087a926da5733e86b47274e4e diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index 9c36d58cd..75242c2a9 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -1,5 +1,4 @@ 71A3B16735405025D447E8F274810B012346C9A6 -1F4410F6A89268CE3197A84C57896D2FF8F0B657 3F1888C6DCA92A6499C4911FDBA1A67379A1A931 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC FE09B823E6D83A3BC7983EAA2D7F2372E50FE137 From 96806c39f4ef395975c0cd7d654dcb71c4790be2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 18 Jun 2016 18:16:36 +0200 Subject: [PATCH 0810/1223] Stop trimming when mapTx is empty --- src/txmempool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 205ffd637..18c54b08b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1075,7 +1075,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); - while (DynamicMemoryUsage() > sizelimit) { + while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) { indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the From 7c29ec94490a2fb0b5f9aec56c89d0a9a58eec79 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 10 Apr 2016 18:52:32 -0700 Subject: [PATCH 0811/1223] If AcceptBlockHeader returns true, pindex will be set. Assert this instead of checking (and then dref'ing later anyway) to make sure no one thinks they can change that postcondition of AcceptBlockHeader.. --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bdb3457f8..378d2c702 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5218,10 +5218,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } - if (pindexLast) - UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); + assert(pindexLast); + UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); - if (nCount == MAX_HEADERS_RESULTS && pindexLast && hasNewHeaders) { + if (nCount == MAX_HEADERS_RESULTS && hasNewHeaders) { // Headers message had its maximum size; the peer may have more headers. // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. From cbda71cf04ef6f2abe6eaa56c3140a6f5cff4feb Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 8 Jun 2016 16:12:52 -0700 Subject: [PATCH 0812/1223] Move context-required checks from CheckBlockHeader to Contextual... --- src/main.cpp | 28 ++++++++++++++-------------- src/main.h | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 378d2c702..7d267bef7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2241,7 +2241,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTimeStart = GetTimeMicros(); // Check it again in case a previous version let a bad block in - if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), !fJustCheck, !fJustCheck)) + if (!CheckBlock(block, state, chainparams.GetConsensus(), !fJustCheck, !fJustCheck)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block @@ -3258,20 +3258,16 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne return true; } -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW) +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW) { // Check proof of work matches claimed amount if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); - // Check timestamp - if (block.GetBlockTime() > nAdjustedTime + 2 * 60 * 60) - return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); - return true; } -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW, bool fCheckMerkleRoot) +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot) { // These are checks that are independent of context. @@ -3280,7 +3276,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. - if (!CheckBlockHeader(block, state, consensusParams, nAdjustedTime, fCheckPOW)) + if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW)) return false; // Check the merkle root. @@ -3346,7 +3342,7 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati return true; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex * const pindexPrev) +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex * const pindexPrev, int64_t nAdjustedTime) { // Check proof of work if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) @@ -3356,6 +3352,10 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early"); + // Check timestamp + if (block.GetBlockTime() > nAdjustedTime + 2 * 60 * 60) + return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); + // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) @@ -3420,7 +3420,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return true; } - if (!CheckBlockHeader(block, state, chainparams.GetConsensus(), GetAdjustedTime())) + if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index @@ -3436,7 +3436,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) + if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } if (pindex == NULL) @@ -3569,9 +3569,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, indexDummy.nHeight = pindexPrev->nHeight + 1; // NOTE: CheckBlockHeader is called by CheckBlock - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev)) + if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); - if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime(), fCheckPOW, fCheckMerkleRoot)) + if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); if (!ContextualCheckBlock(block, state, pindexPrev)) return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); @@ -3916,7 +3916,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime())) + if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus())) return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity diff --git a/src/main.h b/src/main.h index e2bfdfdf6..56e81ec29 100644 --- a/src/main.h +++ b/src/main.h @@ -425,13 +425,13 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus /** Functions for validating blocks and updating the block tree */ /** Context-independent validity checks */ -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW = true); -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, int64_t nAdjustedTime, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true); +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** Context-dependent validity checks. * By "context", we mean only the previous block headers, but not the UTXO * set; UTXO-related validity checks are done in ConnectBlock(). */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex* pindexPrev); +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex* pindexPrev, int64_t nAdjustedTime); bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); /** Apply the effects of this block (with given index) on the UTXO set represented by coins. From 5249daca5a8c4ebdc6c9a3090af0e1bdddcfba1b Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 18 May 2016 13:11:42 -0700 Subject: [PATCH 0813/1223] Add COMPACTSIZE wrapper similar to VARINT for serialization --- src/serialize.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/serialize.h b/src/serialize.h index 5c2db9d33..378ed3907 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -373,6 +373,7 @@ I ReadVarInt(Stream& is) #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) #define VARINT(obj) REF(WrapVarInt(REF(obj))) +#define COMPACTSIZE(obj) REF(CCompactSize(REF(obj))) #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj))) /** @@ -443,6 +444,28 @@ public: } }; +class CCompactSize +{ +protected: + uint64_t &n; +public: + CCompactSize(uint64_t& nIn) : n(nIn) { } + + unsigned int GetSerializeSize(int, int) const { + return GetSizeOfCompactSize(n); + } + + template + void Serialize(Stream &s, int, int) const { + WriteCompactSize(s, n); + } + + template + void Unserialize(Stream& s, int, int) { + n = ReadCompactSize(s); + } +}; + template class LimitedString { From 85ad31ede7bc338079c8ae643542fde7ad83ce55 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 15 Apr 2016 12:23:57 -0700 Subject: [PATCH 0814/1223] Add partial-block block encodings API --- src/Makefile.am | 2 + src/blockencodings.cpp | 158 +++++++++++++++++++++++++++++++ src/blockencodings.h | 205 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 365 insertions(+) create mode 100644 src/blockencodings.cpp create mode 100644 src/blockencodings.h diff --git a/src/Makefile.am b/src/Makefile.am index 3df8e267b..e3eaacdb4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,6 +74,7 @@ BITCOIN_CORE_H = \ addrman.h \ base58.h \ bloom.h \ + blockencodings.h \ chain.h \ chainparams.h \ chainparamsbase.h \ @@ -163,6 +164,7 @@ libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ bloom.cpp \ + blockencodings.cpp \ chain.cpp \ checkpoints.cpp \ httprpc.cpp \ diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp new file mode 100644 index 000000000..c6b79f420 --- /dev/null +++ b/src/blockencodings.cpp @@ -0,0 +1,158 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "blockencodings.h" +#include "consensus/consensus.h" +#include "consensus/validation.h" +#include "chainparams.h" +#include "hash.h" +#include "random.h" +#include "streams.h" +#include "txmempool.h" +#include "main.h" + +#include + +#define MIN_TRANSACTION_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION)) + +CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : + nonce(GetRand(std::numeric_limits::max())), + shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) { + FillShortTxIDSelector(); + //TODO: Use our mempool prior to block acceptance to predictively fill more than just the coinbase + prefilledtxn[0] = {0, block.vtx[0]}; + for (size_t i = 1; i < block.vtx.size(); i++) { + const CTransaction& tx = block.vtx[i]; + shorttxids[i - 1] = GetShortID(tx.GetHash()); + } +} + +void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const { + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << header << nonce; + CSHA256 hasher; + hasher.Write((unsigned char*)&(*stream.begin()), stream.end() - stream.begin()); + uint256 shorttxidhash; + hasher.Finalize(shorttxidhash.begin()); + shorttxidk0 = shorttxidhash.GetUint64(0); + shorttxidk1 = shorttxidhash.GetUint64(1); +} + +uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const { + static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids"); + return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL; +} + + + +ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock) { + if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty())) + return READ_STATUS_INVALID; + if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_SIZE / MIN_TRANSACTION_SIZE) + return READ_STATUS_INVALID; + + assert(header.IsNull() && txn_available.empty()); + header = cmpctblock.header; + txn_available.resize(cmpctblock.BlockTxCount()); + + int32_t lastprefilledindex = -1; + for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) { + if (cmpctblock.prefilledtxn[i].tx.IsNull()) + return READ_STATUS_INVALID; + + lastprefilledindex += cmpctblock.prefilledtxn[i].index + 1; //index is a uint16_t, so cant overflow here + if (lastprefilledindex > std::numeric_limits::max()) + return READ_STATUS_INVALID; + if ((uint32_t)lastprefilledindex > cmpctblock.shorttxids.size() + i) { + // If we are inserting a tx at an index greater than our full list of shorttxids + // plus the number of prefilled txn we've inserted, then we have txn for which we + // have neither a prefilled txn or a shorttxid! + return READ_STATUS_INVALID; + } + txn_available[lastprefilledindex] = std::make_shared(cmpctblock.prefilledtxn[i].tx); + } + + // Calculate map of txids -> positions and check mempool to see what we have (or dont) + // Because well-formed cmpctblock messages will have a (relatively) uniform distribution + // of short IDs, any highly-uneven distribution of elements can be safely treated as a + // READ_STATUS_FAILED. + std::unordered_map shorttxids(cmpctblock.shorttxids.size()); + uint16_t index_offset = 0; + for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) { + while (txn_available[i + index_offset]) + index_offset++; + shorttxids[cmpctblock.shorttxids[i]] = i + index_offset; + // Bucket selection is a simple Binomial distribution. If we assume blocks of + // 10,000 transactions, allowing up to 12 elements per bucket should only fail + // once every ~1.3 million blocks and once every 74,000 blocks in a worst-case + // 16,000-transaction block. + if (shorttxids.bucket_size(shorttxids.bucket(cmpctblock.shorttxids[i])) > 12) + return READ_STATUS_FAILED; + } + // TODO: in the shortid-collision case, we should instead request both transactions + // which collided. Falling back to full-block-request here is overkill. + if (shorttxids.size() != cmpctblock.shorttxids.size()) + return READ_STATUS_FAILED; // Short ID collision + + std::vector have_txn(txn_available.size()); + LOCK(pool->cs); + for (CTxMemPool::txiter it = pool->mapTx.begin(); it != pool->mapTx.end(); it++) { + std::unordered_map::iterator idit = shorttxids.find(cmpctblock.GetShortID(it->GetTx().GetHash())); + if (idit != shorttxids.end()) { + if (!have_txn[idit->second]) { + txn_available[idit->second] = it->GetSharedTx(); + have_txn[idit->second] = true; + } else { + // If we find two mempool txn that match the short id, just request it. + // This should be rare enough that the extra bandwidth doesn't matter, + // but eating a round-trip due to FillBlock failure would be annoying + txn_available[idit->second].reset(); + } + } + // Though ideally we'd continue scanning for the two-txn-match-shortid case, + // the performance win of an early exit here is too good to pass up and worth + // the extra risk. + if (mempool_count == shorttxids.size()) + break; + } + + return READ_STATUS_OK; +} + +bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const { + assert(!header.IsNull()); + assert(index < txn_available.size()); + return txn_available[index] ? true : false; +} + +ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector& vtx_missing) const { + assert(!header.IsNull()); + block = header; + block.vtx.resize(txn_available.size()); + + size_t tx_missing_offset = 0; + for (size_t i = 0; i < txn_available.size(); i++) { + if (!txn_available[i]) { + if (vtx_missing.size() <= tx_missing_offset) + return READ_STATUS_INVALID; + block.vtx[i] = vtx_missing[tx_missing_offset++]; + } else + block.vtx[i] = *txn_available[i]; + } + if (vtx_missing.size() != tx_missing_offset) + return READ_STATUS_INVALID; + + CValidationState state; + if (!CheckBlock(block, state, Params().GetConsensus())) { + // TODO: We really want to just check merkle tree manually here, + // but that is expensive, and CheckBlock caches a block's + // "checked-status" (in the CBlock?). CBlock should be able to + // check its own merkle root and cache that check. + if (state.CorruptionPossible()) + return READ_STATUS_FAILED; // Possible Short ID collision + return READ_STATUS_INVALID; + } + + return READ_STATUS_OK; +} diff --git a/src/blockencodings.h b/src/blockencodings.h new file mode 100644 index 000000000..adc60c85d --- /dev/null +++ b/src/blockencodings.h @@ -0,0 +1,205 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_BLOCK_ENCODINGS_H +#define BITCOIN_BLOCK_ENCODINGS_H + +#include "primitives/block.h" + +#include + +class CTxMemPool; + +// Dumb helper to handle CTransaction compression at serialize-time +struct TransactionCompressor { +private: + CTransaction& tx; +public: + TransactionCompressor(CTransaction& txIn) : tx(txIn) {} + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(tx); //TODO: Compress tx encoding + } +}; + +class BlockTransactionsRequest { +public: + // A BlockTransactionsRequest message + uint256 blockhash; + std::vector indexes; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(blockhash); + uint64_t indexes_size = (uint64_t)indexes.size(); + READWRITE(COMPACTSIZE(indexes_size)); + if (ser_action.ForRead()) { + size_t i = 0; + while (indexes.size() < indexes_size) { + indexes.resize(std::min((uint64_t)(1000 + indexes.size()), indexes_size)); + for (; i < indexes.size(); i++) { + uint64_t index = 0; + READWRITE(COMPACTSIZE(index)); + if (index > std::numeric_limits::max()) + throw std::ios_base::failure("index overflowed 16 bits"); + indexes[i] = index; + } + } + + uint16_t offset = 0; + for (size_t i = 0; i < indexes.size(); i++) { + if (uint64_t(indexes[i]) + uint64_t(offset) > std::numeric_limits::max()) + throw std::ios_base::failure("indexes overflowed 16 bits"); + indexes[i] = indexes[i] + offset; + offset = indexes[i] + 1; + } + } else { + for (size_t i = 0; i < indexes.size(); i++) { + uint64_t index = indexes[i] - (i == 0 ? 0 : (indexes[i - 1] + 1)); + READWRITE(COMPACTSIZE(index)); + } + } + } +}; + +class BlockTransactions { +public: + // A BlockTransactions message + uint256 blockhash; + std::vector txn; + + BlockTransactions() {} + BlockTransactions(const BlockTransactionsRequest& req) : + blockhash(req.blockhash), txn(req.indexes.size()) {} + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(blockhash); + uint64_t txn_size = (uint64_t)txn.size(); + READWRITE(COMPACTSIZE(txn_size)); + if (ser_action.ForRead()) { + size_t i = 0; + while (txn.size() < txn_size) { + txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size)); + for (; i < txn.size(); i++) + READWRITE(REF(TransactionCompressor(txn[i]))); + } + } else { + for (size_t i = 0; i < txn.size(); i++) + READWRITE(REF(TransactionCompressor(txn[i]))); + } + } +}; + +// Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and PartiallyDownlaodedBlock +struct PrefilledTransaction { + // Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs, + // as a proper transaction-in-block-index in PartiallyDownloadedBlock + uint16_t index; + CTransaction tx; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + uint64_t idx = index; + READWRITE(COMPACTSIZE(idx)); + if (idx > std::numeric_limits::max()) + throw std::ios_base::failure("index overflowed 16-bits"); + index = idx; + READWRITE(REF(TransactionCompressor(tx))); + } +}; + +typedef enum ReadStatus_t +{ + READ_STATUS_OK, + READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap + READ_STATUS_FAILED, // Failed to process object +} ReadStatus; + +class CBlockHeaderAndShortTxIDs { +private: + mutable uint64_t shorttxidk0, shorttxidk1; + uint64_t nonce; + + void FillShortTxIDSelector() const; + + friend class PartiallyDownloadedBlock; + + static const int SHORTTXIDS_LENGTH = 6; +protected: + std::vector shorttxids; + std::vector prefilledtxn; + +public: + CBlockHeader header; + + // Dummy for deserialization + CBlockHeaderAndShortTxIDs() {} + + CBlockHeaderAndShortTxIDs(const CBlock& block); + + uint64_t GetShortID(const uint256& txhash) const; + + size_t BlockTxCount() const { return shorttxids.size() + prefilledtxn.size(); } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(header); + READWRITE(nonce); + + uint64_t shorttxids_size = (uint64_t)shorttxids.size(); + READWRITE(COMPACTSIZE(shorttxids_size)); + if (ser_action.ForRead()) { + size_t i = 0; + while (shorttxids.size() < shorttxids_size) { + shorttxids.resize(std::min((uint64_t)(1000 + shorttxids.size()), shorttxids_size)); + for (; i < shorttxids.size(); i++) { + uint32_t lsb = 0; uint16_t msb = 0; + READWRITE(lsb); + READWRITE(msb); + shorttxids[i] = (uint64_t(msb) << 32) | uint64_t(lsb); + static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids serialization assumes 6-byte shorttxids"); + } + } + } else { + for (size_t i = 0; i < shorttxids.size(); i++) { + uint32_t lsb = shorttxids[i] & 0xffffffff; + uint16_t msb = (shorttxids[i] >> 32) & 0xffff; + READWRITE(lsb); + READWRITE(msb); + } + } + + READWRITE(prefilledtxn); + + if (ser_action.ForRead()) + FillShortTxIDSelector(); + } +}; + +class PartiallyDownloadedBlock { +protected: + std::vector > txn_available; + CTxMemPool* pool; +public: + CBlockHeader header; + PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} + + ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock); + bool IsTxAvailable(size_t index) const; + ReadStatus FillBlock(CBlock& block, const std::vector& vtx_missing) const; +}; + +#endif From f4f8f14adc79f71eb3cfd3a8d6dbfe9878d1e3f6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 25 Apr 2016 17:04:13 -0700 Subject: [PATCH 0815/1223] Add TestMemPoolEntryHelper::FromTx version for CTransaction --- src/test/test_bitcoin.cpp | 6 +++++- src/test/test_bitcoin.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index c68320ba8..199670918 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -126,7 +126,11 @@ TestChain100Setup::~TestChain100Setup() CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) { CTransaction txn(tx); - bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies; + return FromTx(txn, pool); +} + +CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CTransaction &txn, CTxMemPool *pool) { + bool hasNoDependencies = pool ? pool->HasNoInputsOf(txn) : hadNoDependencies; // Hack to assume either its completely dependent on other mempool txs or not at all CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 57f66f6c6..78b87e710 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -78,6 +78,7 @@ struct TestMemPoolEntryHelper hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { } CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL); + CTxMemPoolEntry FromTx(CTransaction &tx, CTxMemPool *pool = NULL); // Change the default value TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; } From e3b2222144a0def7fa61822bdd11fb7e6bdc70ec Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 25 Apr 2016 15:51:08 -0700 Subject: [PATCH 0816/1223] Add some blockencodings tests --- src/Makefile.test.include | 1 + src/test/blockencodings_tests.cpp | 315 ++++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+) create mode 100644 src/test/blockencodings_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 41d811fb5..c8918eb53 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -45,6 +45,7 @@ BITCOIN_TESTS =\ test/base58_tests.cpp \ test/base64_tests.cpp \ test/bip32_tests.cpp \ + test/blockencodings_tests.cpp \ test/bloom_tests.cpp \ test/Checkpoints_tests.cpp \ test/coins_tests.cpp \ diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp new file mode 100644 index 000000000..3884bf3fe --- /dev/null +++ b/src/test/blockencodings_tests.cpp @@ -0,0 +1,315 @@ +// Copyright (c) 2011-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "blockencodings.h" +#include "consensus/merkle.h" +#include "chainparams.h" +#include "random.h" + +#include "test/test_bitcoin.h" + +#include + +struct RegtestingSetup : public TestingSetup { + RegtestingSetup() : TestingSetup(CBaseChainParams::REGTEST) {} +}; + +BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegtestingSetup) + +static CBlock BuildBlockTestCase() { + CBlock block; + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].scriptSig.resize(10); + tx.vout.resize(1); + tx.vout[0].nValue = 42; + + block.vtx.resize(3); + block.vtx[0] = tx; + block.nVersion = 42; + block.hashPrevBlock = GetRandHash(); + block.nBits = 0x207fffff; + + tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].prevout.n = 0; + block.vtx[1] = tx; + + tx.vin.resize(10); + for (size_t i = 0; i < tx.vin.size(); i++) { + tx.vin[i].prevout.hash = GetRandHash(); + tx.vin[i].prevout.n = 0; + } + block.vtx[2] = tx; + + bool mutated; + block.hashMerkleRoot = BlockMerkleRoot(block, &mutated); + assert(!mutated); + while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce; + return block; +} + +// Number of shared use_counts we expect for a tx we havent touched +// == 2 (mempool + our copy from the GetSharedTx call) +#define SHARED_TX_OFFSET 2 + +BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) +{ + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + CBlock block(BuildBlockTestCase()); + + pool.addUnchecked(block.vtx[2].GetHash(), entry.FromTx(block.vtx[2])); + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); + + // Do a simple ShortTxIDs RT + { + CBlockHeaderAndShortTxIDs shortIDs(block); + + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << shortIDs; + + CBlockHeaderAndShortTxIDs shortIDs2; + stream >> shortIDs2; + + PartiallyDownloadedBlock partialBlock(&pool); + BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK( partialBlock.IsTxAvailable(0)); + BOOST_CHECK(!partialBlock.IsTxAvailable(1)); + BOOST_CHECK( partialBlock.IsTxAvailable(2)); + + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + + std::list removed; + pool.removeRecursive(block.vtx[2], removed); + BOOST_CHECK_EQUAL(removed.size(), 1); + + CBlock block2; + std::vector vtx_missing; + BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions + + vtx_missing.push_back(block.vtx[2]); // Wrong transaction + partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that + bool mutated; + BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); + + vtx_missing[0] = block.vtx[1]; + CBlock block3; + BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); + BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); + BOOST_CHECK(!mutated); + } +} + +class TestHeaderAndShortIDs { + // Utility to encode custom CBlockHeaderAndShortTxIDs +public: + CBlockHeader header; + uint64_t nonce; + std::vector shorttxids; + std::vector prefilledtxn; + + TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) { + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << orig; + stream >> *this; + } + TestHeaderAndShortIDs(const CBlock& block) : + TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block)) {} + + uint64_t GetShortID(const uint256& txhash) const { + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << *this; + CBlockHeaderAndShortTxIDs base; + stream >> base; + return base.GetShortID(txhash); + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(header); + READWRITE(nonce); + size_t shorttxids_size = shorttxids.size(); + READWRITE(VARINT(shorttxids_size)); + shorttxids.resize(shorttxids_size); + for (size_t i = 0; i < shorttxids.size(); i++) { + uint32_t lsb = shorttxids[i] & 0xffffffff; + uint16_t msb = (shorttxids[i] >> 32) & 0xffff; + READWRITE(lsb); + READWRITE(msb); + shorttxids[i] = (uint64_t(msb) << 32) | uint64_t(lsb); + } + READWRITE(prefilledtxn); + } +}; + +BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) +{ + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + CBlock block(BuildBlockTestCase()); + + pool.addUnchecked(block.vtx[2].GetHash(), entry.FromTx(block.vtx[2])); + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); + + // Test with pre-forwarding tx 1, but not coinbase + { + TestHeaderAndShortIDs shortIDs(block); + shortIDs.prefilledtxn.resize(1); + shortIDs.prefilledtxn[0] = {1, block.vtx[1]}; + shortIDs.shorttxids.resize(2); + shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0].GetHash()); + shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2].GetHash()); + + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << shortIDs; + + CBlockHeaderAndShortTxIDs shortIDs2; + stream >> shortIDs2; + + PartiallyDownloadedBlock partialBlock(&pool); + BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(!partialBlock.IsTxAvailable(0)); + BOOST_CHECK( partialBlock.IsTxAvailable(1)); + BOOST_CHECK( partialBlock.IsTxAvailable(2)); + + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + + CBlock block2; + std::vector vtx_missing; + BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions + + vtx_missing.push_back(block.vtx[1]); // Wrong transaction + partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that + bool mutated; + BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); + + vtx_missing[0] = block.vtx[0]; + CBlock block3; + BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); + BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); + BOOST_CHECK(!mutated); + + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + } + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); +} + +BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) +{ + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + CBlock block(BuildBlockTestCase()); + + pool.addUnchecked(block.vtx[1].GetHash(), entry.FromTx(block.vtx[1])); + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); + + // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool + { + TestHeaderAndShortIDs shortIDs(block); + shortIDs.prefilledtxn.resize(2); + shortIDs.prefilledtxn[0] = {0, block.vtx[0]}; + shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1 + shortIDs.shorttxids.resize(1); + shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1].GetHash()); + + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << shortIDs; + + CBlockHeaderAndShortTxIDs shortIDs2; + stream >> shortIDs2; + + PartiallyDownloadedBlock partialBlock(&pool); + BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK( partialBlock.IsTxAvailable(0)); + BOOST_CHECK( partialBlock.IsTxAvailable(1)); + BOOST_CHECK( partialBlock.IsTxAvailable(2)); + + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + + CBlock block2; + std::vector vtx_missing; + BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); + bool mutated; + BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); + BOOST_CHECK(!mutated); + + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + } + BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); +} + +BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) +{ + CTxMemPool pool(CFeeRate(0)); + CMutableTransaction coinbase; + coinbase.vin.resize(1); + coinbase.vin[0].scriptSig.resize(10); + coinbase.vout.resize(1); + coinbase.vout[0].nValue = 42; + + CBlock block; + block.vtx.resize(1); + block.vtx[0] = coinbase; + block.nVersion = 42; + block.hashPrevBlock = GetRandHash(); + block.nBits = 0x207fffff; + + bool mutated; + block.hashMerkleRoot = BlockMerkleRoot(block, &mutated); + assert(!mutated); + while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce; + + // Test simple header round-trip with only coinbase + { + CBlockHeaderAndShortTxIDs shortIDs(block); + + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << shortIDs; + + CBlockHeaderAndShortTxIDs shortIDs2; + stream >> shortIDs2; + + PartiallyDownloadedBlock partialBlock(&pool); + BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.IsTxAvailable(0)); + + CBlock block2; + std::vector vtx_missing; + BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); + bool mutated; + BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); + BOOST_CHECK(!mutated); + } +} + +BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) { + BlockTransactionsRequest req1; + req1.blockhash = GetRandHash(); + req1.indexes.resize(4); + req1.indexes[0] = 0; + req1.indexes[1] = 1; + req1.indexes[2] = 3; + req1.indexes[3] = 4; + + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << req1; + + BlockTransactionsRequest req2; + stream >> req2; + + BOOST_CHECK_EQUAL(req1.blockhash.ToString(), req2.blockhash.ToString()); + BOOST_CHECK_EQUAL(req1.indexes.size(), req2.indexes.size()); + BOOST_CHECK_EQUAL(req1.indexes[0], req2.indexes[0]); + BOOST_CHECK_EQUAL(req1.indexes[1], req2.indexes[1]); + BOOST_CHECK_EQUAL(req1.indexes[2], req2.indexes[2]); + BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]); +} + +BOOST_AUTO_TEST_SUITE_END() From 00c40784fe737ca67122fdec6538c450d2a516f3 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 6 Jun 2016 01:26:52 -0700 Subject: [PATCH 0817/1223] Add protocol messages for short-ids blocks --- src/protocol.cpp | 13 +++++++++++-- src/protocol.h | 31 +++++++++++++++++++++++++++++-- src/version.h | 5 ++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 422ef6f63..2f90fb764 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -35,6 +35,10 @@ const char *FILTERCLEAR="filterclear"; const char *REJECT="reject"; const char *SENDHEADERS="sendheaders"; const char *FEEFILTER="feefilter"; +const char *SENDCMPCT="sendcmpct"; +const char *CMPCTBLOCK="cmpctblock"; +const char *GETBLOCKTXN="getblocktxn"; +const char *BLOCKTXN="blocktxn"; }; static const char* ppszTypeName[] = @@ -42,7 +46,8 @@ static const char* ppszTypeName[] = "ERROR", // Should never occur NetMsgType::TX, NetMsgType::BLOCK, - "filtered block" // Should never occur + "filtered block", // Should never occur + "compact block" // Should never occur }; /** All known message types. Keep this in the same order as the list of @@ -70,7 +75,11 @@ const static std::string allNetMessageTypes[] = { NetMsgType::FILTERCLEAR, NetMsgType::REJECT, NetMsgType::SENDHEADERS, - NetMsgType::FEEFILTER + NetMsgType::FEEFILTER, + NetMsgType::SENDCMPCT, + NetMsgType::CMPCTBLOCK, + NetMsgType::GETBLOCKTXN, + NetMsgType::BLOCKTXN, }; const static std::vector allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); diff --git a/src/protocol.h b/src/protocol.h index ab0a58178..a72813e95 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -217,6 +217,32 @@ extern const char *SENDHEADERS; * @since protocol version 70013 as described by BIP133 */ extern const char *FEEFILTER; +/** + * Contains a 1-byte bool and 8-byte LE version number. + * Indicates that a node is willing to provide blocks via "cmpctblock" messages. + * May indicate that a node prefers to receive new block announcements via a + * "cmpctblock" message rather than an "inv", depending on message contents. + * @since protocol version 70014 as described by BIP 152 + */ +extern const char *SENDCMPCT; +/** + * Contains a CBlockHeaderAndShortTxIDs object - providing a header and + * list of "short txids". + * @since protocol version 70014 as described by BIP 152 + */ +extern const char *CMPCTBLOCK; +/** + * Contains a BlockTransactionsRequest + * Peer should respond with "blocktxn" message. + * @since protocol version 70014 as described by BIP 152 + */ +extern const char *GETBLOCKTXN; +/** + * Contains a BlockTransactions. + * Sent in response to a "getblocktxn" message. + * @since protocol version 70014 as described by BIP 152 + */ +extern const char *BLOCKTXN; }; /* Get a vector of all valid message types (see above) */ @@ -315,9 +341,10 @@ public: enum { MSG_TX = 1, MSG_BLOCK, - // Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however, - // MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata. + // Nodes may always request a MSG_FILTERED_BLOCK/MSG_CMPCT_BLOCK in a getdata, however, + // MSG_FILTERED_BLOCK/MSG_CMPCT_BLOCK should not appear in any invs except as a part of getdata. MSG_FILTERED_BLOCK, + MSG_CMPCT_BLOCK, }; #endif // BITCOIN_PROTOCOL_H diff --git a/src/version.h b/src/version.h index 0e1d8a63c..68ccd6d37 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70013; +static const int PROTOCOL_VERSION = 70014; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -39,4 +39,7 @@ static const int SENDHEADERS_VERSION = 70012; //! "feefilter" tells peers to filter invs to you by fee starts with this version static const int FEEFILTER_VERSION = 70013; +//! shord-id-based block download starts with this version +static const int SHORT_IDS_BLOCKS_VERSION = 70014; + #endif // BITCOIN_VERSION_H From 9c837d5468063917009aef8569ce6ce9ddd340d2 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 11 Apr 2016 01:00:17 -0700 Subject: [PATCH 0818/1223] Add sender-side protocol implementation for CMPCTBLOCK stuff --- src/main.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7d267bef7..911c0a648 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -274,6 +274,10 @@ struct CNodeState { bool fPreferredDownload; //! Whether this peer wants invs or headers (when possible) for block announcements. bool fPreferHeaders; + //! Whether this peer wants invs or cmpctblocks (when possible) for block announcements. + bool fPreferHeaderAndIDs; + //! Whether this peer will send us cmpctblocks if we request them + bool fProvidesHeaderAndIDs; CNodeState() { fCurrentlyConnected = false; @@ -290,6 +294,8 @@ struct CNodeState { nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; fPreferHeaders = false; + fPreferHeaderAndIDs = false; + fProvidesHeaderAndIDs = false; } }; @@ -4454,7 +4460,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam boost::this_thread::interruption_point(); it++; - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) + if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) { bool send = false; BlockMap::iterator mi = mapBlockIndex.find(inv.hash); @@ -4496,7 +4502,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) pfrom->PushMessage(NetMsgType::BLOCK, block); - else // MSG_FILTERED_BLOCK) + else if (inv.type == MSG_FILTERED_BLOCK) { LOCK(pfrom->cs_filter); if (pfrom->pfilter) @@ -4516,6 +4522,18 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // else // no response } + else if (inv.type == MSG_CMPCT_BLOCK) + { + // If a peer is asking for old blocks, we're almost guaranteed + // they wont have a useful mempool to match against a compact block, + // and we dont feel like constructing the object for them, so + // instead we respond with the full, non-compact block. + if (mi->second->nHeight >= chainActive.Height() - 10) { + CBlockHeaderAndShortTxIDs cmpctblock(block); + pfrom->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock); + } else + pfrom->PushMessage(NetMsgType::BLOCK, block); + } // Trigger the peer node to send a getblocks request for the next batch of inventory if (inv.hash == pfrom->hashContinue) @@ -4839,6 +4857,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, State(pfrom->GetId())->fPreferHeaders = true; } + else if (strCommand == NetMsgType::SENDCMPCT) + { + bool fAnnounceUsingCMPCTBLOCK = false; + uint64_t nCMPCTBLOCKVersion = 1; + vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion; + if (nCMPCTBLOCKVersion == 1) { + LOCK(cs_main); + State(pfrom->GetId())->fProvidesHeaderAndIDs = true; + State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; + } + } + else if (strCommand == NetMsgType::INV) { @@ -4982,6 +5012,39 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + else if (strCommand == NetMsgType::GETBLOCKTXN) + { + BlockTransactionsRequest req; + vRecv >> req; + + BlockMap::iterator it = mapBlockIndex.find(req.blockhash); + if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) { + Misbehaving(pfrom->GetId(), 100); + LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id); + return true; + } + + if (it->second->nHeight < chainActive.Height() - 10) { + LogPrint("net", "Peer %d sent us a getblocktxn for a block > 10 deep", pfrom->id); + return true; + } + + CBlock block; + assert(ReadBlockFromDisk(block, it->second, chainparams.GetConsensus())); + + BlockTransactions resp(req); + for (size_t i = 0; i < req.indexes.size(); i++) { + if (req.indexes[i] >= block.vtx.size()) { + Misbehaving(pfrom->GetId(), 100); + LogPrintf("Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->id); + return true; + } + resp.txn[i] = block.vtx[req.indexes[i]]; + } + pfrom->PushMessage(NetMsgType::BLOCKTXN, resp); + } + + else if (strCommand == NetMsgType::GETHEADERS) { CBlockLocator locator; @@ -5824,7 +5887,9 @@ bool SendMessages(CNode* pto) // add all to the inv queue. LOCK(pto->cs_inventory); vector vHeaders; - bool fRevertToInv = (!state.fPreferHeaders || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); + bool fRevertToInv = ((!state.fPreferHeaders && + (!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) || + pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); CBlockIndex *pBestIndex = NULL; // last header queued for delivery ProcessBlockAvailability(pto->id); // ensure pindexBestKnownBlock is up-to-date @@ -5876,6 +5941,33 @@ bool SendMessages(CNode* pto) } } } + if (!fRevertToInv && !vHeaders.empty()) { + if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) { + // We only send up to 1 block as header-and-ids, as otherwise + // probably means we're doing an initial-ish-sync or they're slow + LogPrint("net", "%s sending header-and-ids %s to peer %d\n", __func__, + vHeaders.front().GetHash().ToString(), pto->id); + //TODO: Shouldn't need to reload block from disk, but requires refactor + CBlock block; + assert(ReadBlockFromDisk(block, pBestIndex, consensusParams)); + CBlockHeaderAndShortTxIDs cmpctblock(block); + pto->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock); + state.pindexBestHeaderSent = pBestIndex; + } else if (state.fPreferHeaders) { + if (vHeaders.size() > 1) { + LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__, + vHeaders.size(), + vHeaders.front().GetHash().ToString(), + vHeaders.back().GetHash().ToString(), pto->id); + } else { + LogPrint("net", "%s: sending header %s to peer=%d\n", __func__, + vHeaders.front().GetHash().ToString(), pto->id); + } + pto->PushMessage(NetMsgType::HEADERS, vHeaders); + state.pindexBestHeaderSent = pBestIndex; + } else + fRevertToInv = true; + } if (fRevertToInv) { // If falling back to using an inv, just try to inv the tip. // The last entry in vBlockHashesToAnnounce was our tip at some point @@ -5901,18 +5993,6 @@ bool SendMessages(CNode* pto) pto->id, hashToAnnounce.ToString()); } } - } else if (!vHeaders.empty()) { - if (vHeaders.size() > 1) { - LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__, - vHeaders.size(), - vHeaders.front().GetHash().ToString(), - vHeaders.back().GetHash().ToString(), pto->id); - } else { - LogPrint("net", "%s: sending header %s to peer=%d\n", __func__, - vHeaders.front().GetHash().ToString(), pto->id); - } - pto->PushMessage(NetMsgType::HEADERS, vHeaders); - state.pindexBestHeaderSent = pBestIndex; } pto->vBlockHashesToAnnounce.clear(); } From 7734479a012be173b788e48ef1b99852437fe23c Mon Sep 17 00:00:00 2001 From: Will Binns Date: Sun, 19 Jun 2016 14:15:58 -0600 Subject: [PATCH 0819/1223] readme: Omit phrasing; 'new' This commit removes the word "new" in reference to describing Bitcoin, as it has been around for over seven years, now. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e816e7a4..3c41649c1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ https://bitcoincore.org What is Bitcoin? ---------------- -Bitcoin is an experimental new digital currency that enables instant payments to +Bitcoin is an experimental digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source From d25cd3ec4e8961c5f36c29a65395f52d0db294c5 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 14 Apr 2016 17:45:49 -0700 Subject: [PATCH 0820/1223] Add receiver-side protocol implementation for CMPCTBLOCK stuff --- src/main.cpp | 215 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 207 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 911c0a648..26b215f94 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "addrman.h" #include "arith_uint256.h" +#include "blockencodings.h" #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" @@ -197,8 +198,9 @@ namespace { /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ struct QueuedBlock { uint256 hash; - CBlockIndex* pindex; //!< Optional. - bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. + CBlockIndex* pindex; //!< Optional. + bool fValidatedHeaders; //!< Whether this block has validated headers at the time of request. + std::unique_ptr partialBlock; //!< Optional, used for CMPCTBLOCK downloads }; map::iterator> > mapBlocksInFlight; @@ -364,6 +366,7 @@ void FinalizeNode(NodeId nodeid) { // Requires cs_main. // Returns a bool indicating whether we requested this block. +// Also used if a block was /not/ received and timed out or started with another peer bool MarkBlockAsReceived(const uint256& hash) { map::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); if (itInFlight != mapBlocksInFlight.end()) { @@ -387,17 +390,26 @@ bool MarkBlockAsReceived(const uint256& hash) { } // Requires cs_main. -void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) { +// returns false, still setting pit, if the block was already in flight from the same peer +// pit will only be valid as long as the same cs_main lock is being held +bool MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL, list::iterator **pit = NULL) { CNodeState *state = State(nodeid); assert(state != NULL); + // Short-circuit most stuff in case its from the same node + map::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash); + if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) { + *pit = &itInFlight->second.second; + return false; + } + // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, pindex, pindex != NULL}; - list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); + list::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), + {hash, pindex, pindex != NULL, std::unique_ptr(pit ? new PartiallyDownloadedBlock(&mempool) : NULL)}); state->nBlocksInFlight++; - state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders; + state->nBlocksInFlightValidHeaders += it->fValidatedHeaders; if (state->nBlocksInFlight == 1) { // We're starting a block download (batch) from this peer. state->nDownloadingSince = GetTimeMicros(); @@ -405,7 +417,10 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Pa if (state->nBlocksInFlightValidHeaders == 1 && pindex != NULL) { nPeersWithValidatedDownloads++; } - mapBlocksInFlight[hash] = std::make_pair(nodeid, it); + itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first; + if (pit) + *pit = &itInFlight->second.second; + return true; } /** Check whether the last unknown block a peer advertised is not yet known. */ @@ -4783,6 +4798,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // nodes) pfrom->PushMessage(NetMsgType::SENDHEADERS); } + if (pfrom->nVersion >= SHORT_IDS_BLOCKS_VERSION) { + // Tell our peer we are willing to provide version-1 cmpctblocks + // However, we do not request new block announcements using + // cmpctblock messages. + // We send this to non-NODE NETWORK peers as well, because + // they may wish to request compact blocks from us + bool fAnnounceUsingCMPCTBLOCK = false; + uint64_t nCMPCTBLOCKVersion = 1; + pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + } } @@ -4915,7 +4940,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CNodeState *nodestate = State(pfrom->GetId()); if (CanDirectFetch(chainparams.GetConsensus()) && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { - vToFetch.push_back(inv); + if (nodestate->fProvidesHeaderAndIDs) + vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); + else + vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out // later (within the same cs_main lock, though). MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus()); @@ -5232,6 +5260,174 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + else if (strCommand == NetMsgType::CMPCTBLOCK && !fImporting && !fReindex) // Ignore blocks received while importing + { + CBlockHeaderAndShortTxIDs cmpctblock; + vRecv >> cmpctblock; + + LOCK(cs_main); + + if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) { + // Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers + if (!IsInitialBlockDownload()) + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()); + return true; + } + + CBlockIndex *pindex = NULL; + CValidationState state; + if (!AcceptBlockHeader(cmpctblock.header, state, chainparams, &pindex)) { + int nDoS; + if (state.IsInvalid(nDoS)) { + if (nDoS > 0) + Misbehaving(pfrom->GetId(), nDoS); + LogPrintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->id); + return true; + } + } + + // If AcceptBlockHeader returned true, it set pindex + assert(pindex); + UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash()); + + std::map::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash()); + bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end(); + + if (pindex->nStatus & BLOCK_HAVE_DATA) // Nothing to do here + return true; + + if (pindex->nChainWork <= chainActive.Tip()->nChainWork || // We know something better + pindex->nTx != 0) { // We had this block at some point, but pruned it + if (fAlreadyInFlight) { + // We requested this block for some reason, but our mempool will probably be useless + // so we just grab the block via normal getdata + std::vector vInv(1); + vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + pfrom->PushMessage(NetMsgType::GETDATA, vInv); + return true; + } + } + + // If we're not close to tip yet, give up and let parallel block fetch work its magic + if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus())) + return true; + + CNodeState *nodestate = State(pfrom->GetId()); + + // We want to be a bit conservative just to be extra careful about DoS + // possibilities in compact block processing... + if (pindex->nHeight <= chainActive.Height() + 2) { + if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) || + (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->GetId())) { + list::iterator *queuedBlockIt = NULL; + if (!MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex, &queuedBlockIt)) { + if (!(*queuedBlockIt)->partialBlock) + (*queuedBlockIt)->partialBlock.reset(new PartiallyDownloadedBlock(&mempool)); + else { + // The block was already in flight using compact blocks from the same peer + LogPrint("net", "Peer sent us compact block we were already syncing!\n"); + return true; + } + } + + PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock; + ReadStatus status = partialBlock.InitData(cmpctblock); + if (status == READ_STATUS_INVALID) { + MarkBlockAsReceived(pindex->GetBlockHash()); // Reset in-flight state in case of whitelist + Misbehaving(pfrom->GetId(), 100); + LogPrintf("Peer %d sent us invalid compact block\n", pfrom->id); + return true; + } else if (status == READ_STATUS_FAILED) { + // Duplicate txindexes, the block is now in-flight, so just request it + std::vector vInv(1); + vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + pfrom->PushMessage(NetMsgType::GETDATA, vInv); + return true; + } + + BlockTransactionsRequest req; + for (size_t i = 0; i < cmpctblock.BlockTxCount(); i++) { + if (!partialBlock.IsTxAvailable(i)) + req.indexes.push_back(i); + } + if (req.indexes.empty()) { + // Dirty hack to jump to BLOCKTXN code (TODO: move message handling into their own functions) + BlockTransactions txn; + txn.blockhash = cmpctblock.header.GetHash(); + CDataStream blockTxnMsg(SER_NETWORK, PROTOCOL_VERSION); + blockTxnMsg << txn; + return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams); + } else { + req.blockhash = pindex->GetBlockHash(); + pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req); + } + } + } else { + if (fAlreadyInFlight) { + // We requested this block, but its far into the future, so our + // mempool will probably be useless - request the block normally + std::vector vInv(1); + vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + pfrom->PushMessage(NetMsgType::GETDATA, vInv); + return true; + } else { + // If this was an announce-cmpctblock, we want the same treatment as a header message + // Dirty hack to process as if it were just a headers message (TODO: move message handling into their own functions) + std::vector headers; + headers.push_back(cmpctblock.header); + CDataStream vHeadersMsg(SER_NETWORK, PROTOCOL_VERSION); + vHeadersMsg << headers; + return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams); + } + } + + CheckBlockIndex(chainparams.GetConsensus()); + } + + else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing + { + BlockTransactions resp; + vRecv >> resp; + + LOCK(cs_main); + + map::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash); + if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock || + it->second.first != pfrom->GetId()) { + LogPrint("net", "Peer %d sent us block transactions for block we weren't expecting\n", pfrom->id); + return true; + } + + PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock; + CBlock block; + ReadStatus status = partialBlock.FillBlock(block, resp.txn); + if (status == READ_STATUS_INVALID) { + MarkBlockAsReceived(resp.blockhash); // Reset in-flight state in case of whitelist + Misbehaving(pfrom->GetId(), 100); + LogPrintf("Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->id); + return true; + } else if (status == READ_STATUS_FAILED) { + // Might have collided, fall back to getdata now :( + std::vector invs; + invs.push_back(CInv(MSG_BLOCK, resp.blockhash)); + pfrom->PushMessage(NetMsgType::GETDATA, invs); + } else { + CValidationState state; + ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL); + int nDoS; + if (state.IsInvalid(nDoS)) { + assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash()); + if (nDoS > 0) { + LOCK(cs_main); + Misbehaving(pfrom->GetId(), nDoS); + } + } + } + } + + else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing { std::vector headers; @@ -5334,6 +5530,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { + if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) { + vGetData[0] = CInv(MSG_CMPCT_BLOCK, vGetData[0].hash); + } pfrom->PushMessage(NetMsgType::GETDATA, vGetData); } } From 927f8eede0c9e0ab9cc2b5e43e39cfe3e1340dd6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 6 May 2016 11:50:24 -0700 Subject: [PATCH 0821/1223] Add ability to fetch CNode by NodeId --- src/net.cpp | 10 ++++++++++ src/net.h | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 4eca3d75c..336163a89 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -368,6 +368,16 @@ CNode* FindNode(const CService& addr) return NULL; } +//TODO: This is used in only one place in main, and should be removed +CNode* FindNode(const NodeId nodeid) +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->GetId() == nodeid) + return (pnode); + return NULL; +} + CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == NULL) { diff --git a/src/net.h b/src/net.h index 67b95fe0e..aa9b2c11a 100644 --- a/src/net.h +++ b/src/net.h @@ -80,12 +80,15 @@ static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Defaul unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); +typedef int NodeId; + void AddOneShot(const std::string& strDest); void AddressCurrentlyConnected(const CService& addr); CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); +CNode* FindNode(const NodeId id); //TODO: Remove this bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); @@ -94,8 +97,6 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler); bool StopNode(); void SocketSendData(CNode *pnode); -typedef int NodeId; - struct CombinerAll { typedef bool result_type; From 2f34a2e476ae9d0585c67e275d238e44119c56cf Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 6 May 2016 18:33:46 -0400 Subject: [PATCH 0822/1223] Get our "best three" peers to announce blocks using cmpctblocks --- src/main.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 26b215f94..60a33f9c2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -204,6 +204,9 @@ namespace { }; map::iterator> > mapBlocksInFlight; + /** Stack of nodes which we have set to announce using compact blocks */ + list lNodesAnnouncingHeaderAndIDs; + /** Number of preferable block download peers. */ int nPreferredDownload = 0; @@ -456,6 +459,28 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } } +void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom) { + if (nodestate->fProvidesHeaderAndIDs) { + BOOST_FOREACH(const NodeId nodeid, lNodesAnnouncingHeaderAndIDs) + if (nodeid == pfrom->GetId()) + return; + bool fAnnounceUsingCMPCTBLOCK = false; + uint64_t nCMPCTBLOCKVersion = 1; + if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { + // As per BIP152, we only get 3 of our peers to announce + // blocks using compact encodings. + CNode* pnodeStop = FindNode(lNodesAnnouncingHeaderAndIDs.front()); + if (pnodeStop) { + pnodeStop->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + lNodesAnnouncingHeaderAndIDs.pop_front(); + } + } + fAnnounceUsingCMPCTBLOCK = true; + pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId()); + } +} + // Requires cs_main bool CanDirectFetch(const Consensus::Params &consensusParams) { @@ -5531,6 +5556,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (vGetData.size() > 0) { if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) { + // We seem to be rather well-synced, so it appears pfrom was the first to provide us + // with this block! Let's get them to announce using compact blocks in the future. + MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); + // In any case, we want to download using a compact block, not a regular one vGetData[0] = CInv(MSG_CMPCT_BLOCK, vGetData[0].hash); } pfrom->PushMessage(NetMsgType::GETDATA, vGetData); From 56ba5167272bc5afa8629ad93f16ed5135490bf5 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 8 Jun 2016 15:43:50 -0700 Subject: [PATCH 0823/1223] Add reconstruction debug logging --- src/blockencodings.cpp | 16 +++++++++++++++- src/blockencodings.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index c6b79f420..204de45c2 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -11,6 +11,7 @@ #include "streams.h" #include "txmempool.h" #include "main.h" +#include "util.h" #include @@ -72,6 +73,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c } txn_available[lastprefilledindex] = std::make_shared(cmpctblock.prefilledtxn[i].tx); } + prefilled_count = cmpctblock.prefilledtxn.size(); // Calculate map of txids -> positions and check mempool to see what we have (or dont) // Because well-formed cmpctblock messages will have a (relatively) uniform distribution @@ -103,11 +105,15 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c if (!have_txn[idit->second]) { txn_available[idit->second] = it->GetSharedTx(); have_txn[idit->second] = true; + mempool_count++; } else { // If we find two mempool txn that match the short id, just request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying - txn_available[idit->second].reset(); + if (txn_available[idit->second]) { + txn_available[idit->second].reset(); + mempool_count--; + } } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, @@ -117,6 +123,8 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c break; } + LogPrint("cmpctblock", "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), cmpctblock.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION)); + return READ_STATUS_OK; } @@ -154,5 +162,11 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< return READ_STATUS_INVALID; } + LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size()); + if (vtx_missing.size() < 5) { + for(const CTransaction& tx : vtx_missing) + LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx.GetHash().ToString()); + } + return READ_STATUS_OK; } diff --git a/src/blockencodings.h b/src/blockencodings.h index adc60c85d..b980e9e28 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -192,6 +192,7 @@ public: class PartiallyDownloadedBlock { protected: std::vector > txn_available; + size_t prefilled_count = 0, mempool_count = 0; CTxMemPool* pool; public: CBlockHeader header; From 678ee9793f6279c07b57c22c3cce983ab1e069d0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 6 Jun 2016 01:15:21 -0700 Subject: [PATCH 0824/1223] Add BIP 152 to implemented BIPs list --- doc/bips.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/bips.md b/doc/bips.md index 1ec03d2fb..62bde20d9 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -26,3 +26,4 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). +* [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)). From 811902649d6aaddd886cb39b83aa69adf7b441bd Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 14 Jun 2016 23:59:03 -0700 Subject: [PATCH 0825/1223] Provide a flat list of txid/terators to txn in CTxMemPool --- src/txmempool.cpp | 14 +++++++++++++- src/txmempool.h | 5 +++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 18c54b08b..ead28546d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -438,6 +438,9 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, totalTxSize += entry.GetTxSize(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); + vTxHashes.emplace_back(hash, newit); + newit->vTxHashesIdx = vTxHashes.size() - 1; + return true; } @@ -447,6 +450,15 @@ void CTxMemPool::removeUnchecked(txiter it) BOOST_FOREACH(const CTxIn& txin, it->GetTx().vin) mapNextTx.erase(txin.prevout); + if (vTxHashes.size() > 1) { + vTxHashes[it->vTxHashesIdx] = std::move(vTxHashes.back()); + vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx; + vTxHashes.pop_back(); + if (vTxHashes.size() * 2 < vTxHashes.capacity()) + vTxHashes.shrink_to_fit(); + } else + vTxHashes.clear(); + totalTxSize -= it->GetTxSize(); cachedInnerUsage -= it->DynamicMemoryUsage(); cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children); @@ -965,7 +977,7 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. - return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage; } void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants) { diff --git a/src/txmempool.h b/src/txmempool.h index f0e9b2e2c..d6d0d72ff 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -150,6 +150,8 @@ public: uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } unsigned int GetSigOpCountWithAncestors() const { return nSigOpCountWithAncestors; } + + mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes }; // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. @@ -457,7 +459,10 @@ public: mutable CCriticalSection cs; indexed_transaction_set mapTx; + typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; + std::vector > vTxHashes; //!< All tx hashes/entries in mapTx, in random order + struct CompareIteratorByHash { bool operator()(const txiter &a, const txiter &b) const { return a->GetTx().GetHash() < b->GetTx().GetHash(); From 0d4cb48ef1b916679d9fad9f247a297c85c7fedf Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 19 Jun 2016 01:31:52 -0700 Subject: [PATCH 0826/1223] Use vTxHashes to optimize InitData significantly --- src/blockencodings.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 204de45c2..9a0805e40 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -99,11 +99,13 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c std::vector have_txn(txn_available.size()); LOCK(pool->cs); - for (CTxMemPool::txiter it = pool->mapTx.begin(); it != pool->mapTx.end(); it++) { - std::unordered_map::iterator idit = shorttxids.find(cmpctblock.GetShortID(it->GetTx().GetHash())); + const std::vector >& vTxHashes = pool->vTxHashes; + for (size_t i = 0; i < vTxHashes.size(); i++) { + uint64_t shortid = cmpctblock.GetShortID(vTxHashes[i].first); + std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { if (!have_txn[idit->second]) { - txn_available[idit->second] = it->GetSharedTx(); + txn_available[idit->second] = vTxHashes[i].second->GetSharedTx(); have_txn[idit->second] = true; mempool_count++; } else { From ccd06b94f69c3e7758c35ac4bcd36d0e9450e158 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 18 Jun 2016 01:36:23 +0200 Subject: [PATCH 0827/1223] Elaborate bucket size math --- src/blockencodings.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 9a0805e40..7fd6a9cf5 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -85,10 +85,16 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c while (txn_available[i + index_offset]) index_offset++; shorttxids[cmpctblock.shorttxids[i]] = i + index_offset; - // Bucket selection is a simple Binomial distribution. If we assume blocks of - // 10,000 transactions, allowing up to 12 elements per bucket should only fail - // once every ~1.3 million blocks and once every 74,000 blocks in a worst-case - // 16,000-transaction block. + // To determine the chance that the number of entries in a bucket exceeds N, + // we use the fact that the number of elements in a single bucket is + // binomially distributed (with n = the number of shorttxids S, and p = + // 1 / the number of buckets), that in the worst case the number of buckets is + // equal to S (due to std::unordered_map having a default load factor of 1.0), + // and that the chance for any bucket to exceed N elements is at most + // buckets * (the chance that any given bucket is above N elements). + // Thus: P(max_elements_per_bucket > N) <= S * (1 - cdf(binomial(n=S,p=1/S), N)). + // If we assume blocks of up to 16000, allowing 12 elements per bucket should + // only fail once per ~1 million block transfers (per peer and connection). if (shorttxids.bucket_size(shorttxids.bucket(cmpctblock.shorttxids[i])) > 12) return READ_STATUS_FAILED; } From 2759597bc8617039a7ffa6210f4d49a985a20093 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 20 Jun 2016 10:17:01 +0200 Subject: [PATCH 0828/1223] Only pass -lQt5PlatformSupport if >=Qt5.6 --- build-aux/m4/bitcoin_qt.m4 | 4 +++- src/qt/bitcoin.cpp | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 210df3c02..74d910267 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -343,7 +343,9 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi else - QT_LIBS="-lQt5PlatformSupport $QT_LIBS" + if ${PKG_CONFIG} --exists "Qt5Core >= 5.6" 2>/dev/null; then + QT_LIBS="-lQt5PlatformSupport $QT_LIBS" + fi fi ]) else diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6218ab6ab..64b5c83d7 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -533,6 +533,9 @@ int main(int argc, char *argv[]) // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif +#if QT_VERSION >= 0x050600 + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif From fa58f94ff7f097260ebee791008dab368c7ac318 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 20 Jun 2016 11:21:00 +0200 Subject: [PATCH 0829/1223] [qa] pull-tester: Start longest test first --- qa/pull-tester/rpc-tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 988230850..6c0ed4510 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -101,6 +101,8 @@ if ENABLE_ZMQ: #Tests testScripts = [ + # longest test should go first, to favor running tests in parallel + 'p2p-fullblocktest.py', 'walletbackup.py', 'bip68-112-113-p2p.py', 'wallet.py', @@ -125,7 +127,6 @@ testScripts = [ 'nodehandling.py', 'reindex.py', 'decodescript.py', - 'p2p-fullblocktest.py', 'blockchain.py', 'disablewallet.py', 'sendheaders.py', From e5a680dc6a69cc5c35f2debeba15d4886fa4f789 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 12 Jun 2016 12:59:02 +0800 Subject: [PATCH 0830/1223] [Doc] Update OS X build notes for 10.11 SDK --- doc/{README_osx.txt => README_osx.md} | 28 +++++++++++++-------------- doc/build-osx.md | 8 +++++--- doc/release-process.md | 16 +++++---------- 3 files changed, 24 insertions(+), 28 deletions(-) rename doc/{README_osx.txt => README_osx.md} (81%) diff --git a/doc/README_osx.txt b/doc/README_osx.md similarity index 81% rename from doc/README_osx.txt rename to doc/README_osx.md index c13efaa14..aed3cd97e 100644 --- a/doc/README_osx.txt +++ b/doc/README_osx.md @@ -1,21 +1,19 @@ Deterministic OS X Dmg Notes. Working OS X DMGs are created in Linux by combining a recent clang, -the Apple's binutils (ld, ar, etc), and DMG authoring tools. +the Apple binutils (ld, ar, etc) and DMG authoring tools. Apple uses clang extensively for development and has upstreamed the necessary functionality so that a vanilla clang can take advantage. It supports the use of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary -when building for OS X. A pre-compiled version of 3.2 is used because it was not -available in the Precise repositories at the time this work was started. In the -future, it can be switched to use system packages instead. +when building for OS X. Apple's version of binutils (called cctools) contains lots of functionality missing in the FSF's binutils. In addition to extra linker options for frameworks and sysroots, several other tools are needed as well such as install_name_tool, lipo, and nmedit. These do not build under linux, so they have been patched to do so. The work here was used as a starting point: -https://github.com/mingwandroid/toolchain4 +[mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4). In order to build a working toolchain, the following source packages are needed from Apple: cctools, dyld, and ld64. @@ -29,16 +27,19 @@ originally done in toolchain4. To complicate things further, all builds must target an Apple SDK. These SDKs are free to download, but not redistributable. -To obtain it, register for a developer account, then download the Xcode 6.1.1 dmg: -https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg +To obtain it, register for a developer account, then download the [Xcode 7.3.1 dmg](https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_7.3.1/Xcode_7.3.1.dmg). This file is several gigabytes in size, but only a single directory inside is -needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk +needed: +``` +Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk +``` Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file. To create a tarball suitable for Gitian input, mount the dmg in OS X, then create it with: - $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk - +``` + $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz MacOSX10.11.sdk +``` The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries which are created using these tools. The build process has been designed to @@ -48,15 +49,14 @@ fully deterministic and may be freely redistributed. genisoimage is used to create the initial DMG. It is not deterministic as-is, so it has been patched. A system genisoimage will work fine, but it will not be deterministic because the file-order will change between invocations. -The patch can be seen here: -https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff +The patch can be seen here: [theuni/osx-cross-depends](https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff). No effort was made to fix this cleanly, so it likely leaks memory badly. But it's only used for a single invocation, so that's no real concern. genisoimage cannot compress DMGs, so afterwards, the 'dmg' tool from the libdmg-hfsplus project is used to compress it. There are several bugs in this tool and its maintainer has seemingly abandoned the project. It has been forked -and is available (with fixes) here: https://github.com/theuni/libdmg-hfsplus . +and is available (with fixes) here: [theuni/libdmg-hfsplus](https://github.com/theuni/libdmg-hfsplus). The 'dmg' tool has the ability to create DMGs from scratch as well, but this functionality is broken. Only the compression feature is currently used. @@ -77,6 +77,6 @@ build process to remain somewhat deterministic. Here's how it works: that have been previously (deterministically) built in order to create a final dmg. - The Apple keyholder uses this unsigned app to create a detached signature, - using the script that is also included there. + using the script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). - Builders feed the unsigned app + detached signature back into Gitian. It uses the pre-built tools to recombine the pieces into a deterministic dmg. diff --git a/doc/build-osx.md b/doc/build-osx.md index 89d7816c9..c9eb4225a 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -5,11 +5,13 @@ The built-in one is located in `/Applications/Utilities/Terminal.app`. Preparation ----------- -Download and install [Xcode](https://developer.apple.com/xcode/download). +Install the OS X command line tools: -Once installed, run `xcode-select --install` to install the OS X command line tools. +`xcode-select --install` -Install [Homebrew](http://brew.sh). +When the popup appears, click `Install`. + +Then install [Homebrew](http://brew.sh). Dependencies ---------------------- diff --git a/doc/release-process.md b/doc/release-process.md index 3bfcc3817..f5d0d836d 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -3,7 +3,7 @@ Release Process Before every release candidate: -* Update translations (ping wumpus on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex) +* Update translations (ping wumpus on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#synchronising-translations). Before every minor and major release: @@ -13,7 +13,7 @@ Before every minor and major release: Before every major release: -* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example. +* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example. ### First time / New builders @@ -75,7 +75,7 @@ Ensure your gitian.sigs are up-to-date if you wish to gverify your builds agains git pull popd -Ensure gitian-builder is up-to-date to take advantage of new caching features (`e9741525c` or later is recommended). +Ensure gitian-builder is up-to-date: pushd ./gitian-builder git pull @@ -89,13 +89,7 @@ Ensure gitian-builder is up-to-date to take advantage of new caching features (` wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz popd -Register and download the Apple SDK: see [OS X readme](README_osx.txt) for details. - -https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg - -Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: - - tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk +Create the OS X SDK tarball, see the [OS X readme](README_osx.md) for details, and copy it into the inputs directory. ### Optional: Seed the Gitian sources cache and offline git repositories @@ -239,7 +233,7 @@ transmission-show -m Insert the magnet URI into the announcement sent to mailing lists. This permits people without access to `bitcoin.org` to download the binary distribution. Also put it into the `optional_magnetlink:` slot in the YAML file for -bitcoin.org (see below for bitcoin.org update instructions). +bitcoin.org (see below for bitcoin.org update instructions). - Update bitcoin.org version From fa6ad56948d1163ec7e3a7cd49d7e9d99787e27a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 20 Jun 2016 14:57:39 +0200 Subject: [PATCH 0831/1223] [travis] Update SDK_URL --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index af9c476dc..a6c51753b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ env: - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoin.jonasschnelli.ch/sdks + - SDK_URL=https://bitcoincore.org/depends-sources/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all matrix: From bf9c70b1008e1eada462955a6420e79a7d2a8352 Mon Sep 17 00:00:00 2001 From: TheLazieR Yip Date: Tue, 21 Jun 2016 00:46:59 +0700 Subject: [PATCH 0832/1223] Fix LogPrint to LogPrintf Printing Log without category defined should use LogPrintf Github-Pull: #8230 Meta: PR should have been based on master in the first place --- src/qt/winshutdownmonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index 1bc4f7795..a11da5058 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -27,7 +27,7 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM // Warn only once as this is performance-critical static bool warned = false; if (!warned) { - LogPrint("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__); + LogPrintf("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__); warned = true; } } From b3e1348c46573630e5899b53f77236fd51f78d13 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 21 Jun 2016 10:54:57 +0200 Subject: [PATCH 0833/1223] [Qt] fix a bug where the SplashScreen will not be hidden during startup --- src/qt/splashscreen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index b46321fa8..e36d86fdd 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -141,6 +141,11 @@ SplashScreen::~SplashScreen() void SplashScreen::slotFinish(QWidget *mainWin) { Q_UNUSED(mainWin); + + /* If the window is minimized, hide() will be ignored. */ + /* Make sure we de-minimize the splashscreen window before hiding */ + if (isMinimized()) + showNormal(); hide(); } From b7bf037121f0a46ee9f7a31e3c0b78f118dadba2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Jun 2016 14:10:53 +0200 Subject: [PATCH 0834/1223] doc: Mention ARM executables in release process Mention ARM executables in the release process documentation (these were introduced in #8188). As well as that Linux tarballs have changed name to contain an architecture tuple, instead of `linux32`/`linux64`. Also mention that `-debug` files should not be uploaded (these were introduced in #8167). --- doc/release-process.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 3bfcc3817..0263bdf69 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -210,8 +210,10 @@ sha256sum * > SHA256SUMS The list of files should be: ``` -bitcoin-${VERSION}-linux32.tar.gz -bitcoin-${VERSION}-linux64.tar.gz +bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz +bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz +bitcoin-${VERSION}-i686-pc-linux-gnu.tar.gz +bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz bitcoin-${VERSION}-osx64.tar.gz bitcoin-${VERSION}-osx.dmg bitcoin-${VERSION}.tar.gz @@ -220,6 +222,11 @@ bitcoin-${VERSION}-win32.zip bitcoin-${VERSION}-win64-setup.exe bitcoin-${VERSION}-win64.zip ``` +The `*-debug*` files generated by the gitian build contain debug symbols +for troubleshooting by developers. It is assumed that anyone that is interested +in debugging can run gitian to generate the files for themselves. To avoid +end-user confusion about which file to pick, as well as save storage +space *do not upload these to the bitcoin.org server, nor put them in the torrent*. - GPG-sign it, delete the unsigned file: ``` From 05f64c9940478f3d40104a5083a1b850f0358879 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Jun 2016 14:33:13 +0200 Subject: [PATCH 0835/1223] doc: Mention Linux ARM builds in release notes --- doc/release-notes.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6cc05989d..df3c265dc 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -61,6 +61,26 @@ When cross-compiling for a target that doesn't have C++11 libraries, configure w For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now required. +Linux ARM builds +------------------ + +Due to popular request, Linux ARM builds have been added to the uploaded +executables. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries for the most + common 32-bit ARM architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries for the most + common 64-bit ARM architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + 0.13.0 Change log ================= From 4cbe05bf205ceeb23d1d47360693c8235b497ed5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Jun 2016 13:23:39 +0000 Subject: [PATCH 0836/1223] qt: Periodic transifex update Pulls in the following new languages: - `af` Afrikaans - `es_419` Spanish (Latin America) - `es_AR` Spanish (Argentina) - `es_CO` Spanish (Colombia) - `fil` Filipino - `it_IT` Italian (Italy) - `ro` Romanian - `sr@latin` Serbian (Latin) - `ta` Tamil - `uz@Latn` Uzbek (Latin) - `zh_HK` Chinese (Hong Kong) --- src/Makefile.qt.include | 11 + src/qt/bitcoin_locale.qrc | 11 + src/qt/bitcoinstrings.cpp | 10 + src/qt/locale/bitcoin_af.ts | 509 ++++++++ src/qt/locale/bitcoin_af_ZA.ts | 26 +- src/qt/locale/bitcoin_ar.ts | 152 ++- src/qt/locale/bitcoin_bg.ts | 10 +- src/qt/locale/bitcoin_ca.ts | 80 +- src/qt/locale/bitcoin_ca@valencia.ts | 8 - src/qt/locale/bitcoin_ca_ES.ts | 76 +- src/qt/locale/bitcoin_cs.ts | 376 +++++- src/qt/locale/bitcoin_cs_CZ.ts | 24 + src/qt/locale/bitcoin_da.ts | 74 +- src/qt/locale/bitcoin_de.ts | 106 +- src/qt/locale/bitcoin_el_GR.ts | 13 +- src/qt/locale/bitcoin_en.ts | 1652 +------------------------- src/qt/locale/bitcoin_en_GB.ts | 66 +- src/qt/locale/bitcoin_eo.ts | 42 +- src/qt/locale/bitcoin_es.ts | 242 +++- src/qt/locale/bitcoin_es_419.ts | 173 +++ src/qt/locale/bitcoin_es_AR.ts | 373 ++++++ src/qt/locale/bitcoin_es_CL.ts | 120 +- src/qt/locale/bitcoin_es_CO.ts | 542 +++++++++ src/qt/locale/bitcoin_es_DO.ts | 4 - src/qt/locale/bitcoin_es_MX.ts | 100 +- src/qt/locale/bitcoin_et.ts | 4 - src/qt/locale/bitcoin_fa.ts | 4 - src/qt/locale/bitcoin_fi.ts | 92 +- src/qt/locale/bitcoin_fil.ts | 157 +++ src/qt/locale/bitcoin_fr.ts | 60 +- src/qt/locale/bitcoin_fr_FR.ts | 1640 ++++++++++++++++++++++++- src/qt/locale/bitcoin_gl.ts | 4 - src/qt/locale/bitcoin_he.ts | 16 +- src/qt/locale/bitcoin_hr.ts | 4 - src/qt/locale/bitcoin_hu.ts | 8 +- src/qt/locale/bitcoin_id_ID.ts | 302 +++-- src/qt/locale/bitcoin_it.ts | 18 +- src/qt/locale/bitcoin_it_IT.ts | 325 +++++ src/qt/locale/bitcoin_ja.ts | 64 +- src/qt/locale/bitcoin_ka.ts | 4 - src/qt/locale/bitcoin_ko_KR.ts | 1324 +++++++++++++++++++-- src/qt/locale/bitcoin_la.ts | 4 - src/qt/locale/bitcoin_lt.ts | 24 +- src/qt/locale/bitcoin_lv_LV.ts | 4 - src/qt/locale/bitcoin_nb.ts | 12 - src/qt/locale/bitcoin_nl.ts | 68 +- src/qt/locale/bitcoin_pam.ts | 4 - src/qt/locale/bitcoin_pl.ts | 221 +++- src/qt/locale/bitcoin_pt_BR.ts | 174 ++- src/qt/locale/bitcoin_pt_PT.ts | 894 ++++++++++++-- src/qt/locale/bitcoin_ro.ts | 169 +++ src/qt/locale/bitcoin_ro_RO.ts | 138 ++- src/qt/locale/bitcoin_ru.ts | 36 +- src/qt/locale/bitcoin_ru_RU.ts | 52 + src/qt/locale/bitcoin_sk.ts | 287 ++++- src/qt/locale/bitcoin_sl_SI.ts | 20 +- src/qt/locale/bitcoin_sq.ts | 8 + src/qt/locale/bitcoin_sr@latin.ts | 653 ++++++++++ src/qt/locale/bitcoin_sv.ts | 64 +- src/qt/locale/bitcoin_ta.ts | 1029 ++++++++++++++++ src/qt/locale/bitcoin_th_TH.ts | 182 ++- src/qt/locale/bitcoin_tr.ts | 72 +- src/qt/locale/bitcoin_tr_TR.ts | 8 + src/qt/locale/bitcoin_uk.ts | 16 +- src/qt/locale/bitcoin_uz@Cyrl.ts | 4 - src/qt/locale/bitcoin_uz@Latn.ts | 169 +++ src/qt/locale/bitcoin_zh_CN.ts | 80 +- src/qt/locale/bitcoin_zh_HK.ts | 521 ++++++++ src/qt/locale/bitcoin_zh_TW.ts | 178 +-- 69 files changed, 11482 insertions(+), 2435 deletions(-) create mode 100644 src/qt/locale/bitcoin_af.ts create mode 100644 src/qt/locale/bitcoin_es_419.ts create mode 100644 src/qt/locale/bitcoin_es_AR.ts create mode 100644 src/qt/locale/bitcoin_es_CO.ts create mode 100644 src/qt/locale/bitcoin_fil.ts create mode 100644 src/qt/locale/bitcoin_it_IT.ts create mode 100644 src/qt/locale/bitcoin_ro.ts create mode 100644 src/qt/locale/bitcoin_sr@latin.ts create mode 100644 src/qt/locale/bitcoin_ta.ts create mode 100644 src/qt/locale/bitcoin_uz@Latn.ts create mode 100644 src/qt/locale/bitcoin_zh_HK.ts diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 9381cca9f..dc775a356 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -3,6 +3,7 @@ EXTRA_LIBRARIES += qt/libbitcoinqt.a # bitcoin qt core # QT_TS = \ + qt/locale/bitcoin_af.ts \ qt/locale/bitcoin_af_ZA.ts \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ @@ -22,7 +23,10 @@ QT_TS = \ qt/locale/bitcoin_en_GB.ts \ qt/locale/bitcoin_en.ts \ qt/locale/bitcoin_eo.ts \ + qt/locale/bitcoin_es_419.ts \ + qt/locale/bitcoin_es_AR.ts \ qt/locale/bitcoin_es_CL.ts \ + qt/locale/bitcoin_es_CO.ts \ qt/locale/bitcoin_es_DO.ts \ qt/locale/bitcoin_es_ES.ts \ qt/locale/bitcoin_es_MX.ts \ @@ -33,6 +37,7 @@ QT_TS = \ qt/locale/bitcoin_eu_ES.ts \ qt/locale/bitcoin_fa_IR.ts \ qt/locale/bitcoin_fa.ts \ + qt/locale/bitcoin_fil.ts \ qt/locale/bitcoin_fi.ts \ qt/locale/bitcoin_fr_CA.ts \ qt/locale/bitcoin_fr_FR.ts \ @@ -43,6 +48,7 @@ QT_TS = \ qt/locale/bitcoin_hr.ts \ qt/locale/bitcoin_hu.ts \ qt/locale/bitcoin_id_ID.ts \ + qt/locale/bitcoin_it_IT.ts \ qt/locale/bitcoin_it.ts \ qt/locale/bitcoin_ja.ts \ qt/locale/bitcoin_ka.ts \ @@ -62,22 +68,27 @@ QT_TS = \ qt/locale/bitcoin_pt_BR.ts \ qt/locale/bitcoin_pt_PT.ts \ qt/locale/bitcoin_ro_RO.ts \ + qt/locale/bitcoin_ro.ts \ qt/locale/bitcoin_ru_RU.ts \ qt/locale/bitcoin_ru.ts \ qt/locale/bitcoin_sk.ts \ qt/locale/bitcoin_sl_SI.ts \ qt/locale/bitcoin_sq.ts \ + qt/locale/bitcoin_sr@latin.ts \ qt/locale/bitcoin_sr.ts \ qt/locale/bitcoin_sv.ts \ + qt/locale/bitcoin_ta.ts \ qt/locale/bitcoin_th_TH.ts \ qt/locale/bitcoin_tr_TR.ts \ qt/locale/bitcoin_tr.ts \ qt/locale/bitcoin_uk.ts \ qt/locale/bitcoin_ur_PK.ts \ qt/locale/bitcoin_uz@Cyrl.ts \ + qt/locale/bitcoin_uz@Latn.ts \ qt/locale/bitcoin_vi.ts \ qt/locale/bitcoin_vi_VN.ts \ qt/locale/bitcoin_zh_CN.ts \ + qt/locale/bitcoin_zh_HK.ts \ qt/locale/bitcoin_zh.ts \ qt/locale/bitcoin_zh_TW.ts diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index a8a0253b0..1acda7f28 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -1,5 +1,6 @@ + locale/bitcoin_af.qm locale/bitcoin_af_ZA.qm locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm @@ -19,7 +20,10 @@ locale/bitcoin_en_GB.qm locale/bitcoin_en.qm locale/bitcoin_eo.qm + locale/bitcoin_es_419.qm + locale/bitcoin_es_AR.qm locale/bitcoin_es_CL.qm + locale/bitcoin_es_CO.qm locale/bitcoin_es_DO.qm locale/bitcoin_es_ES.qm locale/bitcoin_es_MX.qm @@ -30,6 +34,7 @@ locale/bitcoin_eu_ES.qm locale/bitcoin_fa_IR.qm locale/bitcoin_fa.qm + locale/bitcoin_fil.qm locale/bitcoin_fi.qm locale/bitcoin_fr_CA.qm locale/bitcoin_fr_FR.qm @@ -40,6 +45,7 @@ locale/bitcoin_hr.qm locale/bitcoin_hu.qm locale/bitcoin_id_ID.qm + locale/bitcoin_it_IT.qm locale/bitcoin_it.qm locale/bitcoin_ja.qm locale/bitcoin_ka.qm @@ -59,22 +65,27 @@ locale/bitcoin_pt_BR.qm locale/bitcoin_pt_PT.qm locale/bitcoin_ro_RO.qm + locale/bitcoin_ro.qm locale/bitcoin_ru_RU.qm locale/bitcoin_ru.qm locale/bitcoin_sk.qm locale/bitcoin_sl_SI.qm locale/bitcoin_sq.qm + locale/bitcoin_sr@latin.qm locale/bitcoin_sr.qm locale/bitcoin_sv.qm + locale/bitcoin_ta.qm locale/bitcoin_th_TH.qm locale/bitcoin_tr_TR.qm locale/bitcoin_tr.qm locale/bitcoin_uk.qm locale/bitcoin_ur_PK.qm locale/bitcoin_uz@Cyrl.qm + locale/bitcoin_uz@Latn.qm locale/bitcoin_vi.qm locale/bitcoin_vi_VN.qm locale/bitcoin_zh_CN.qm + locale/bitcoin_zh_HK.qm locale/bitcoin_zh.qm locale/bitcoin_zh_TW.qm diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 9e53f1959..ce8753fc7 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -60,6 +60,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Do not keep transactions in the mempool longer than hours (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error loading %s: You can't enable HD on a already existing non-HD wallet"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Error reading %s! All keys read correctly, but transaction data or address " "book entries might be missing or incorrect."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -114,6 +116,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Please check that your computer's date and time are correct! If your clock " "is wrong, %s will not work properly."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Please contribute if you find %s useful. Visit %s for further information " +"about the software."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Prune configured below the minimum of %d MiB. Please use a higher number."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Prune: last wallet synchronisation goes beyond pruned data. You need to -" @@ -168,6 +173,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Use UPnP to map the listening port (default: 1 when listening and no -proxy)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Use hierarchical deterministic key generation (HD) after bip32. Only has " +"effect during wallet creation/first start"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -243,6 +251,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environmen QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet corrupted"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet requires newer version of %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: You can't disable HD on a already existing HD wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."), @@ -317,6 +326,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "The source code is available from %s."), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts new file mode 100644 index 000000000..492c7bccd --- /dev/null +++ b/src/qt/locale/bitcoin_af.ts @@ -0,0 +1,509 @@ + + + AddressBookPage + + Right-click to edit address or label + Regs-kliek om die adres of etiket te verander + + + Create a new address + Skep 'n nuwe adres + + + &New + &Nuut + + + Copy the currently selected address to the system clipboard + Dupliseer die geselekteerde adres na die sisteem se geheuebord + + + &Copy + &Dupliseer + + + &Copy Address + &Dupliseer Adres + + + Delete the currently selected address from the list + Verwyder die adres wat u gekies het van die lys + + + Export the data in the current tab to a file + Voer die inligting op hierdie bladsy uit na 'n leer + + + &Export + &Voer uit + + + &Delete + &Vee uit + + + Choose the address to send coins to + Kies die adres waarheen u munte wil stuur + + + Choose the address to receive coins with + Kies die adres wat die munte moet ontvang + + + Sending addresses + Stuurders adresse + + + Receiving addresses + Ontvanger adresse + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Hierdie is die adresse vanwaar u Bitcoin betalings stuur. U moet altyd die bedrag en die adres van die ontvanger nagaan voordat u enige munte stuur. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Hierdie is die adresse waar u Bitcoins sal ontvang. Ons beveel aan dat u 'n nuwe adres kies vir elke transaksie + + + &Edit + &Verander + + + Export Address List + Voer adreslys uit + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Uitvoer was onsuksesvol + + + There was an error trying to save the address list to %1. Please try again. + Die adreslys kon nie in %1 gestoor word nie. Probeer asseblief weer. + + + + AddressTableModel + + Address + Adres + + + (no label) + (geen etiket) + + + + AskPassphraseDialog + + Passphrase Dialog + Wagwoord Dialoog + + + Enter passphrase + Tik u wagwoord in + + + New passphrase + Nuwe wagwoord + + + Repeat new passphrase + Herhaal nuwe wagwoord + + + Encrypt wallet + Kodifiseer beursie + + + This operation needs your wallet passphrase to unlock the wallet. + U het u beursie se wagwoord nodig om toegang tot u beursie te verkry. + + + Unlock wallet + Sluit beursie oop + + + This operation needs your wallet passphrase to decrypt the wallet. + U het u beursie se wagwoord nodig om u beursie se kode te ontsyfer. + + + Decrypt wallet + Ontsleutel beursie + + + Change passphrase + Verander wagwoord + + + Confirm wallet encryption + Bevestig dat die beursie gekodifiseer is + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Waarskuwing: Indien u die beursie kodifiseer en u vergeet u wagwoord <b>VERLOOR U AL U BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Is u seker dat u die beursie wil kodifiseer? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Kern gaan nou toemaak om die kodifikasie af te handel. Onthou dat die kodifikasie van u beursie nie altyd u munte kan beskerm teen diefstal deur kwaadwillige sagteware op u rekenaar nie. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + BELANGRIK: Alle vorige kopieë en rugsteun-weergawes wat u tevore van die gemaak het, moet vervang word met die jongste weergawe van u nuutste gekodifiseerde beursie. Alle vorige weergawes en rugsteun-kopieë van u beursie sal nutteloos raak die oomblik wat u die nuut-gekodifiseerde beursie begin gebruik. + + + Warning: The Caps Lock key is on! + WAARSKUWING: Outomatiese Kapitalisering is aktief op u sleutelbord! + + + Wallet encrypted + Beursie gekodifiseer + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Tik die nuwe wagwoord vir u beursie.<br/>Gerbuik asseblief 'n wagwoord met <b>tien of meer lukrake karakters</b>, of <b>agt of meer woorde</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Tik die ou en die nuwe wagwoorde vir die beursie. + + + Wallet encryption failed + Kodifikasie was onsuksesvol + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Weens 'n interne fout het kodifikasie het nie geslaag nie. U beursie is nie gekodifiseer nie + + + The supplied passphrases do not match. + Die wagwoorde stem nie ooreen nie. + + + Wallet unlock failed + Die beursie is nie oopgesluit nie + + + The passphrase entered for the wallet decryption was incorrect. + U het die verkeerde wagwoord ingetik. + + + + BanTableModel + + Banned Until + Verban tot + + + + BitcoinGUI + + Synchronizing with network... + Netwerk-sinkronisasie... + + + &Overview + &Oorsig + + + Node + Node + + + Show general overview of wallet + Vertoon 'n algemene oorsig van die beursie + + + &Transactions + &Transaksies + + + Quit application + Stop en verlaat die applikasie + + + &Options... + &Opsies + + + &Encrypt Wallet... + &Kodifiseer Beursie + + + &Backup Wallet... + &Rugsteun-kopie van Beursie + + + &Change Passphrase... + &Verander Wagwoord + + + &Sending addresses... + &Versending adresse... + + + &Receiving addresses... + &Ontvanger adresse + + + Open &URI... + Oop & URI... + + + Bitcoin Core client + Bitcoin Kern klient + + + Importing blocks from disk... + Besig om blokke vanaf die hardeskyf in te voer... + + + Reindexing blocks on disk... + Besig met herindeksering van blokke op hardeskyf... + + + Send coins to a Bitcoin address + Stuur munte na 'n Bitcoin adres + + + Backup wallet to another location + Maak 'n rugsteun-kopié van beursie na 'n ander stoorplek + + + Change the passphrase used for wallet encryption + Verander die wagwoord wat ek vir kodifikasie van my beursie gebruik + + + Bitcoin + Bitcoin + + + Wallet + Beursie + + + &Send + &Stuur + + + &Receive + &Ontvang + + + Show information about Bitcoin Core + Vertoon inligting oor Bitcoin Kern + + + Show or hide the main Window + Wys of versteek die hoofbladsy + + + Encrypt the private keys that belong to your wallet + Kodifiseer die private sleutes wat aan jou beursie gekoppel is. + + + Sign messages with your Bitcoin addresses to prove you own them + Onderteken boodskappe met u Bitcoin adresse om u eienaarskap te bewys + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verifieër boodskappe om seker te maak dat dit met die gespesifiseerde Bitcoin adresse + + + &Help + &Help + + + Bitcoin Core + Bitcoin Kern + + + Request payments (generates QR codes and bitcoin: URIs) + Versoek betalings (genereer QR-kodes en bitcoin: URI's) + + + &About Bitcoin Core + &Omtrent Bitcoin Kern + + + Modify configuration options for Bitcoin Core + Verander konfigurasie-opsies vir Bitcoin Kern + + + Show the list of used sending addresses and labels + Vertoon die lys van gebruikte versendingsadresse en etikette + + + Show the list of used receiving addresses and labels + Vertoon die lys van gebruikte ontvangers-adresse en etikette + + + Open a bitcoin: URI or payment request + Skep 'n bitcoin: URI of betalingsversoek + + + + ClientModel + + + CoinControlDialog + + (no label) + (geen etiket) + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Kern + + + Reset all settings changes made over the GUI + Herstel al my veranderinge aan die stellings terug na die verstek-opsies + + + + Intro + + Bitcoin Core + Bitcoin Kern + + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Adres + + + + RecentRequestsTableModel + + (no label) + (geen etiket) + + + + SendCoinsDialog + + (no label) + (geen etiket) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Bitcoin Kern + + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + + TransactionView + + Exporting Failed + Uitvoer was onsuksesvol + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Address + Adres + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Voer uit + + + Export the data in the current tab to a file + Voer die inligting op hierdie bladsy uit na 'n leer + + + + bitcoin-core + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + WAARSKUWING: toets die status van u netwerk, %d blokke ontvang in die laaste %d ure (%d verwag) + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Moenie transaksies vir langer as <n> ure in die geheuepoel hou nie (verstek: %u) + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index d77aa77f8..12ac21eb8 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -31,17 +31,21 @@ AskPassphraseDialog + + Passphrase Dialog + Wagfrase Dialoog + Enter passphrase - Tik Wagwoord in + Tik wagfrase in New passphrase - Nuwe wagwoord + Nuwe wagfrase Repeat new passphrase - Herhaal nuwe wagwoord + Herhaal nuwe wagfrase Encrypt wallet @@ -65,7 +69,7 @@ Change passphrase - Verander wagwoord + Verander wagfrase Confirm wallet encryption @@ -75,6 +79,10 @@ Wallet encrypted Die beursie is nou bewaak + + Enter the old passphrase and new passphrase to the wallet. + Tik in die ou wagfrase en die nuwe wagfrase vir die beursie. + Wallet encryption failed Die beursie kon nie bewaak word nie @@ -85,7 +93,7 @@ The supplied passphrases do not match. - Die wagwoord stem nie ooreen nie + Die wagfrase stem nie ooreen nie Wallet unlock failed @@ -93,13 +101,17 @@ The passphrase entered for the wallet decryption was incorrect. - Die wagwoord wat ingetik was om die beursie oop te sluit, was verkeerd. + Die wagfrase wat ingetik was om die beursie oop te sluit, was verkeerd. Wallet decryption failed Beursie dekripsie het misluk - + + Wallet passphrase was successfully changed. + Die beursie se wagfrase verandering was suksesvol. + + BanTableModel diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 88ce05bbd..1e74564ed 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + عنوان البروتوكول/قناع + + + Banned Until + محظور حتى + + BitcoinGUI @@ -325,6 +333,10 @@ &Debug window &نافذة المعالجة + + Open debugging and diagnostic console + إفتح وحدة التصحيح و التشخيص + &Verify message... &التحقق من الرسالة... @@ -361,6 +373,14 @@ Encrypt the private keys that belong to your wallet تشفير المفتاح الخاص بمحفظتك + + Sign messages with your Bitcoin addresses to prove you own them + وقَع الرسائل بواسطة ال: Bitcoin الخاص بك لإثبات امتلاكك لهم + + + Verify messages to ensure they were signed with specified Bitcoin addresses + تحقق من الرسائل للتأكد من أنَها وُقعت برسائل Bitcoin محدَدة + &File &ملف @@ -381,14 +401,58 @@ Bitcoin Core جوهر البيت كوين + + Request payments (generates QR codes and bitcoin: URIs) + أطلب دفعات (يولد كودات الرمز المربع وبيت كوين: العناوين المعطاة) + &About Bitcoin Core حول bitcoin core + + Modify configuration options for Bitcoin Core + تغيير خيارات الإعداد لأساس Bitcoin + + + Show the list of used sending addresses and labels + عرض قائمة عناوين الإرسال المستخدمة والملصقات + + + Show the list of used receiving addresses and labels + عرض قائمة عناوين الإستقبال المستخدمة والملصقات + + + Open a bitcoin: URI or payment request + فتح URI : Bitcoin أو طلب دفع + + + &Command-line options + &خيارات سطر الأوامر + + + No block source available... + لا يوجد أي مصدر الكتلة + + + Processed %n block(s) of transaction history. + لم يتم معالجة أي كتلة سجل المعاملاتتم معالجة كتلة واحدة سجل المعاملاتتم معالجة كتلتين سجل المعاملاتتم معالجة %n كتل سجل المعاملاتتم معالجة %n كتلة سجل المعاملاتتم معالجة %n كتلة سجل المعاملات + + + %n hour(s) + 0 ساعة%n ساعة%n ساعتين%n ساعات%n ساعة%n ساعات + %1 and %2 %1 و %2 + + Last received block was generated %1 ago. + تم توليد الكتلة المستقبلة الأخيرة منذ %1. + + + Transactions after this will not yet be visible. + المعاملات بعد ذلك لن تكون مريئة بعد. + Error خطأ @@ -463,6 +527,14 @@ Amount المبلغ + + Received with label + مستقبل مع ملصق + + + Received with address + مستقبل مع عنوان + Date التاريخ @@ -531,6 +603,14 @@ medium-high متوسط-مرتفع + + medium + متوسط + + + low-medium + متوسط-منخفض + low منخفض @@ -547,6 +627,10 @@ none لا شيء + + This label turns red if the transaction size is greater than 1000 bytes. + هذا الملصق يصبح أخمرا إذا كان حجم المعاملة أكبر من 1000 بايت. + yes نعم @@ -555,6 +639,18 @@ no لا + + This means a fee of at least %1 per kB is required. + هذا يعني أن من المطلوب أن يكون الرسم ألى الأقل %1 لكل كيلوبايت. + + + Can vary +/- 1 byte per input. + يمكن أن يتفاوت بـ 1 بايت لكل مساهمة. + + + Transactions with higher priority are more likely to get included into a block. + المعاملات التي لديها أولوية أعلى على الأرجح سيتم إنضمامها في الكتلة. + (no label) (لا وصف) @@ -598,6 +694,10 @@ The entered address "%1" is already in the address book. هدا العنوان "%1" موجود مسبقا في دفتر العناوين + + The entered address "%1" is not a valid Bitcoin address. + العنوان المدخل "%1" ليس عنوان بيت كوين صحيح. + Could not unlock wallet. يمكن فتح المحفظة. @@ -617,6 +717,14 @@ name الاسم + + Directory already exists. Add %1 if you intend to create a new directory here. + الدليل موجوج بالفعل. أضف %1 لو نويت إنشاء دليل جديد هنا. + + + Path already exists, and is not a directory. + المسار موجود بالفعل، وهو ليس دليلاً. + Cannot create data directory here. لا يمكن انشاء دليل بيانات هنا . @@ -636,11 +744,39 @@ About Bitcoin Core عن جوهر البيت كوين + + Command-line options + خيارات سطر الأوامر + Usage: المستخدم - + + command-line options + خيارات سطر الأوامر + + + UI Options: + خيارات واجهة المستخدم + + + Choose data directory on startup (default: %u) + اختر دليل البيانات عند بدء التشغير (افتراضي: %u) + + + Set SSL root certificates for payment request (default: -system-) + أضع شهادة بروتوكول الشبقة الأمنية لطلب المدفوع (افتراضي: -نظام-) + + + Show splash screen on startup (default: %u) + أظهر شاشة البداية عند بدء التشغيل (افتراضي: %u) + + + Reset all settings changes made over the GUI + إعادة تعيين كل الإعدادات تم تغييرها من خلال الواجهة الرسومية + + Intro @@ -1793,14 +1929,26 @@ Invalid -proxy address: '%s' عنوان البروكسي غير صحيح : '%s' + + Make the wallet broadcast transactions + إنتاج معاملات بث المحفظة + Insufficient funds اموال غير كافية + + Loading block index... + تحميل مؤشر الكتلة + Loading wallet... تحميل المحفظه + + Cannot downgrade wallet + لا يمكن تخفيض قيمة المحفظة + Cannot write default address لايمكن كتابة العنوان الافتراضي diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index ecd10e546..54bf8136a 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -214,7 +214,11 @@ BanTableModel - + + Banned Until + Със забранен достъп до + + BitcoinGUI @@ -1229,10 +1233,6 @@ General Основни - - Using OpenSSL version - Използване на OpenSSL версия - Using BerkeleyDB version Използване на база данни BerkeleyDB diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 38e770f18..8bc9281f1 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -1115,6 +1115,22 @@ Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Conectar a la red de Bitcoin a través de un proxy SOCKS5 per als serveis ocults de Tor + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: @@ -1457,10 +1473,6 @@ General General - - Using OpenSSL version - Utilitzant OpenSSL versió - Using BerkeleyDB version Utilitzant BerkeleyDB versió @@ -1489,6 +1501,18 @@ Current number of blocks Nombre de blocs actuals + + Memory Pool + Reserva de memòria + + + Current number of transactions + Nombre actual de transaccions + + + Memory usage + Us de memoria + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans. @@ -2748,6 +2772,10 @@ Copy transaction ID Copiar ID de transacció + + Copy raw transaction + Copia la transacció crua + Edit label Editar etiqueta @@ -2895,22 +2923,62 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si no es proporciona <category> o si <category> = 1, treu a la sortida tota la informació de depuració. + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Comproveu que la data i hora de l'ordinador són correctes! Si el vostre rellotge no té l'hora correcta, el Bitcoin Core no funcionarà adequadament. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Poda configurada per sota el mínim de %d MiB. Utilitzeu un nombre superior. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Poda: la darrera sincronització del moneder va més enllà de les dades podades. Cal que activeu -reindex (baixeu tota la cadena de blocs de nou en cas de node podat) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduïu els requisits d'emmagatzematge podant (suprimint) els blocs antics. Aquest mode és incompatible amb -txindex i -rescan. Avís: la reversió d'aquest paràmetre implica haver de tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar en els fitxers de blocs) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Els rescanejos no són possible en el mode de poda. Caldrà que utilitzeu -reindex, que tornarà a baixar la cadena de blocs sencera. + + + Error: A fatal internal error occurred, see debug.log for details + Error: s'ha produït un error intern fatal. Vegeu debug.log per a més detalls + Fee (in %s/kB) to add to transactions you send (default: %s) Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + + Pruning blockstore... + S'està podant la cadena de blocs... + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres + + Unable to start HTTP server. See debug log for details. + No s'ha pogut iniciar el servidor HTTP. Vegeu debug.log per a més detalls. + Accept connections from outside (default: 1 if no -proxy or -connect) Accepta connexions de fora (per defecte: 1 si no -proxy o -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee és molt elevat. Aquesta és la comissió de transacció que podeu pagar quan les estimacions de comissions no estan disponibles. + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6 @@ -3079,10 +3147,6 @@ Wallet options: Opcions de moneder: - - Warning: This version is obsolete; upgrade required! - Avís: aquesta versió és obsoleta; cal actualitzar-la! - You need to rebuild the database using -reindex to change -txindex Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index 2c41ec78d..e5744fcbb 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1413,10 +1413,6 @@ General General - - Using OpenSSL version - Utilitzant OpenSSL versió - Using BerkeleyDB version Utilitzant BerkeleyDB versió @@ -2959,10 +2955,6 @@ Wallet options: Opcions de moneder: - - Warning: This version is obsolete; upgrade required! - Avís: esta versió és obsoleta; cal actualitzar-la! - You need to rebuild the database using -reindex to change -txindex Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index e6a932ebe..2c238bb44 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -1115,6 +1115,22 @@ Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Conectar a la red de Bitcoin a través de un proxy SOCKS5 per als serveis ocults de Tor + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: @@ -1457,10 +1473,6 @@ General General - - Using OpenSSL version - Utilitzant OpenSSL versió - Using BerkeleyDB version Utilitzant BerkeleyDB versió @@ -1489,6 +1501,18 @@ Current number of blocks Nombre de blocs actuals + + Memory Pool + Reserva de memòria + + + Current number of transactions + Nombre actual de transaccions + + + Memory usage + Us de memoria + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans. @@ -2748,6 +2772,10 @@ Copy transaction ID Copiar ID de transacció + + Copy raw transaction + Copia la transacció crua + Edit label Editar etiqueta @@ -2895,18 +2923,54 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si no es proporciona <category> o si <category> = 1, treu a la sortida tota la informació de depuració. + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Comproveu que la data i hora de l'ordinador són correctes! Si el vostre rellotge no té l'hora correcta, el Bitcoin Core no funcionarà adequadament. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Poda configurada per sota el mínim de %d MiB. Utilitzeu un nombre superior. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Poda: la darrera sincronització del moneder va més enllà de les dades podades. Cal que activeu -reindex (baixeu tota la cadena de blocs de nou en cas de node podat) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduïu els requisits d'emmagatzematge podant (suprimint) els blocs antics. Aquest mode és incompatible amb -txindex i -rescan. Avís: la reversió d'aquest paràmetre implica haver de tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar en els fitxers de blocs) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Els rescanejos no són possible en el mode de poda. Caldrà que utilitzeu -reindex, que tornarà a baixar la cadena de blocs sencera. + + + Error: A fatal internal error occurred, see debug.log for details + Error: s'ha produït un error intern fatal. Vegeu debug.log per a més detalls + Fee (in %s/kB) to add to transactions you send (default: %s) Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + + Pruning blockstore... + S'està podant la cadena de blocs... + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres + + Unable to start HTTP server. See debug log for details. + No s'ha pogut iniciar el servidor HTTP. Vegeu debug.log per a més detalls. + Accept connections from outside (default: 1 if no -proxy or -connect) Accepta connexions de fora (per defecte: 1 si no -proxy o -connect) @@ -3079,10 +3143,6 @@ Wallet options: Opcions de moneder: - - Warning: This version is obsolete; upgrade required! - Avís: aquesta versió és obsoleta; cal actualitzar-la! - You need to rebuild the database using -reindex to change -txindex Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index ef1903edd..d3ff5c1f5 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Pravým tlačítkem myši začneš upravovat označení adresy + Pravým tlačítkem myši můžeš upravit označení adresy Create a new address @@ -71,7 +71,7 @@ These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Je doporučené používat pokaždé novou adresu pro každou transakci. + Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Nezapomeň si pro každou transakci vždy vygenerovat novou adresu. Copy &Label @@ -83,11 +83,11 @@ Export Address List - Exportuj seznam adres + Export seznamu adres Comma separated file (*.csv) - CSV formát (*.csv) + Formát CSV (*.csv) Exporting Failed @@ -343,7 +343,7 @@ &Send - &Pošli + P&ošli &Receive @@ -383,7 +383,7 @@ &Help - Ná&pověda + Nápověd&a Tabs toolbar @@ -419,7 +419,7 @@ &Command-line options - Ar&gumenty z příkazové řádky + Ar&gumenty příkazové řádky Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options @@ -467,7 +467,7 @@ Transactions after this will not yet be visible. - Následné transakce ještě nebudou vidět. + Novější transakce zatím nejsou vidět. Error @@ -806,11 +806,11 @@ The entered address "%1" is already in the address book. - Zadaná adresa "%1" už v adresáři je. + Zadaná adresa „%1“ už v adresáři je. The entered address "%1" is not a valid Bitcoin address. - Zadaná adresa "%1" není platná Bitcoinová adresa. + Zadaná adresa „%1“ není platná Bitcoinová adresa. Could not unlock wallet. @@ -864,7 +864,7 @@ Command-line options - Argumenty z příkazové řádky + Argumenty příkazové řádky Usage: @@ -874,7 +874,35 @@ command-line options možnosti příkazové řádky - + + UI Options: + Možnosti UI: + + + Choose data directory on startup (default: %u) + Zvolit při startu adresář pro data (výchozí: %u) + + + Set language, for example "de_DE" (default: system locale) + Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení) + + + Start minimized + Nastartovat minimalizovaně + + + Set SSL root certificates for payment request (default: -system-) + Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-) + + + Show splash screen on startup (default: %u) + Zobrazit startovací obrazovku (výchozí: %u) + + + Reset all settings changes made over the GUI + Resetovat všechna nastavení provedené v GUI + + Intro @@ -989,7 +1017,7 @@ 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 |. - URL třetích stran (např. block exploreru), které se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |. + URL třetích stran (např. block exploreru), která se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |. Third party transaction URLs @@ -997,7 +1025,7 @@ Active command-line options that override above options: - Aktivní argumenty z příkazové řádky, které přetloukly tato nastavení: + Aktivní argumenty z příkazové řádky, které mají přednost před nastavením výše: Reset all client options to default. @@ -1029,7 +1057,7 @@ Expert - Odborník + Pokročilá nastavení Enable coin &control features @@ -1071,6 +1099,30 @@ Port of the proxy (e.g. 9050) Port proxy (např. 9050) + + Used for reaching peers via: + Použije se k připojování k protějškům přes: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Ukazuje, jestli se zadaná výchozí SOCKS5 proxy používá k připojování k peerům v rámci tohoto typu sítě. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Připojí se do Bitcoinové sítě přes SOCKS5 proxy vyhrazenou pro skryté služby v Tor síti. + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru: @@ -1101,7 +1153,7 @@ &Unit to show amounts in: - J&ednotka pro částky: + Je&dnotka pro částky: Choose the default subdivision unit to show in the interface and when sending coins. @@ -1113,7 +1165,7 @@ &OK - &Budiž + &Použít &Cancel @@ -1141,7 +1193,7 @@ This change would require a client restart. - Tahle změna bude chtít restartovat klienta. + Tato změna vyžaduje restart aplikace. The supplied proxy address is invalid. @@ -1188,7 +1240,7 @@ Balances - Stavy účtů + Stav účtů Total: @@ -1413,10 +1465,6 @@ General Obecné - - Using OpenSSL version - Používaná verze OpenSSL - Using BerkeleyDB version Používaná verze BerkeleyDB @@ -1445,6 +1493,10 @@ Current number of blocks Aktuální počet bloků + + Memory usage + Využití paměti + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Otevři soubor s ladicími záznamy Bitcoin Core z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat. @@ -1549,6 +1601,34 @@ Clear console Vyčistit konzoli + + &Disconnect Node + &Odpojit uzel + + + Ban Node for + Uvalit na uzel klatbu na + + + 1 &hour + 1 &hodinu + + + 1 &day + 1 &den + + + 1 &week + 1 &týden + + + 1 &year + 1 &rok + + + &Unban Node + &Zbavit uzel klatby + Welcome to the Bitcoin Core RPC console. Vítej v RPC konzoli Bitcoin Core. @@ -1577,6 +1657,10 @@ %1 GB %1 GB + + (node id: %1) + (id uzlu: %1) + via %1 via %1 @@ -1630,7 +1714,7 @@ 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. - Volitelná zpráva, která se připojí k platebnímu požadavku a která se zobrazí, když se požadavek otevře. Poznámka: Tahle zpráva se neposílá s platbou po Bitcoinové síti. + Volitelná zpráva, která se připojí k platebnímu požadavku a která se zobrazí, když se požadavek otevře. Poznámka: tahle zpráva se neposílá s platbou po Bitcoinové síti. An optional label to associate with the new receiving address. @@ -1638,7 +1722,7 @@ Use this form to request payments. All fields are <b>optional</b>. - Tímto formulář můžeš požadovat platby. Všechna pole jsou <b>volitelná</b>. + Tímto formulářem můžeš požadovat platby. Všechna pole jsou <b>volitelná</b>. An optional amount to request. Leave this empty or zero to not request a specific amount. @@ -1931,7 +2015,7 @@ S&end - P&ošli + Pošl&i Confirm send coins @@ -1969,6 +2053,10 @@ Copy change Kopíruj drobné + + Total Amount %1 + Celková částka %1 + or nebo @@ -2001,6 +2089,10 @@ Payment request expired. Platební požadavek vypršel. + + Pay only the required fee of %1 + Zaplatit pouze vyžadovaný poplatek %1 + Estimated to begin confirmation within %n block(s). Potvrzování by podle odhadu mělo začít během %n bloku.Potvrzování by podle odhadu mělo začít během %n bloků.Potvrzování by podle odhadu mělo začít během %n bloků. @@ -2090,7 +2182,7 @@ S&ubtract fee from amount - &Odečíst poplatek od částky + Od&ečíst poplatek od částky Message: @@ -2176,7 +2268,7 @@ Copy the current signature to the system clipboard - Zkopíruj aktuálně vybraný podpis do systémové schránky + Zkopíruj tento podpis do schránky Sign the message to prove you own this Bitcoin address @@ -2220,7 +2312,7 @@ Click "Sign Message" to generate signature - Kliknutím na "Podepiš zprávu" vygeneruješ podpis + Kliknutím na „Podepiš zprávu“ vygeneruješ podpis The entered address is invalid. @@ -2248,7 +2340,7 @@ Message signed. - Zpráv podepsána. + Zpráva podepsána. The signature could not be decoded. @@ -2405,7 +2497,7 @@ 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. - Vygenerované mince musí čekat %1 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na "neakceptovaný" a nepůjde utratit. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. + Vygenerované mince musí čekat %1 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na „neakceptovaný“ a nepůjde utratit. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. Debug information @@ -2467,7 +2559,7 @@ Immature (%1 confirmations, will be available after %2) - Nedozráno (%1 potvrzení, bude k dispozici za %2) + Nedozráno (%1 potvrzení, dozraje při %2 potvrzeních) Open for %n more block(s) @@ -2636,6 +2728,10 @@ Copy transaction ID Kopíruj ID transakce + + Copy raw transaction + Kopíruj surovou transakci + Edit label Uprav označení @@ -2670,7 +2766,7 @@ Comma separated file (*.csv) - CSV formát (*.csv) + Formát CSV (*.csv) Confirmed @@ -2783,14 +2879,66 @@ Accept command line and JSON-RPC commands Akceptovat příkazy z příkazové řádky a přes JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Pokud není <category> zadána nebo je <category> = 1, bude tisknout veškeré ladicí informace. + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Prosím zkontrolujte nastavení času na svém počítači. Pokud čas a datum není nastaven správně, Bitcoin Core nebude fungovat! + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Prořezávání je nastaveno pod minimum %d MiB. Použij, prosím, nějaké vyšší číslo. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prořezávání: poslední synchronizace peněženky proběhla před už prořezanými daty. Je třeba provést -reindex (tedy v případě prořezávacího režimu stáhnout znovu celý řetězec bloků) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. Tento režim není slučitelný s -txindex ani -rescan. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, >%u = cílová velikost souborů s bloky, v MiB) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + V prořezávacím režimu není možné přeskenovávat řetězec bloků. Musíš provést -reindex, což znovu stáhne celý řetězec bloků. + + + Error: A fatal internal error occurred, see debug.log for details + Chyba: Přihodila se závažná vnitřní chyba, podrobnosti viz v debug.log + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Poplatek (v %s/kB), který se přidá ke každé odeslané transakci (výchozí: %s) + + + Pruning blockstore... + Prořezávám úložiště bloků... + Run in the background as a daemon and accept commands - Běžet na pozadí jako démon a akceptovat příkazy + Běžet na pozadí jako démon a přijímat příkazy + + + Unable to start HTTP server. See debug log for details. + Nemohu spustit HTTP server. Detaily viz v debug.log. Accept connections from outside (default: 1 if no -proxy or -connect) Přijímat spojení zvenčí (výchozí: 1, pokud není zadáno -proxy nebo -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee je nastaveno velmi vysoko! Toto je transakční poplatek, který bys platil, pokud nebude k dispozici odhad poplatků. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Sazba poplatku (v %s/kB), která se použije, pokud nebude k dispozici dostatek dat pro automatický odhad poplatku (výchozí: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Přijímat přeposílané transakce obdržené od vždy vítaných protějšků, i když transakce nepřeposíláme (výchozí: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port @@ -2807,10 +2955,18 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Vynutit přeposílání transakcí od vždy vítaných protějšků (tj. těch na bílé listině), i když porušují místní zásady pro přeposílání (výchozí: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d) + + 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 + Databáze bloků obsahuje blok, který vypadá jako z budoucnosti, což může být kvůli špatně nastavenému datu a času na tvém počítači. Nech databázi bloků přestavět pouze v případě, že si jsi jistý, že máš na počítači správný datum a čas + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Tohle je testovací verze – používej ji jen na vlastní riziko, ale rozhodně ji nepoužívej k těžbě nebo pro obchodní aplikace @@ -2819,6 +2975,14 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Nepodporovaný argument -whitelistalwaysrelay se ignoruje, použij -whitelistrelay a/nebo -whitelistforcerelay. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá a nepoužívá -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d) @@ -2837,16 +3001,24 @@ Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud je stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu. + Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud jsou stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu. Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. - Umístit na bílou listinu protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. + Vždy vítat protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. + + + -maxmempool must be at least %d MB + -maxmempool musí být alespoň %d MB <category> can be: <category> může být: + + Append comment to the user agent string + Připojit komentář k typu klienta + Block creation options: Možnosti vytváření bloku: @@ -2911,6 +3083,22 @@ Invalid -onion address: '%s' Neplatná -onion adresa: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Neplatná částka pro -fallbackfee=<částka>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Udržovat zasobník transakcí menší než <n> megabajtů (výchozí: %u) + + + Location of the auth cookie (default: data dir) + Místo pro autentizační cookie (výchozí: adresář pro data) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Minimální počet bajtů na každý sigop v transakcích, které přeposíláme a těžíme (výchozí: %u) + Not enough file descriptors available. Je nedostatek deskriptorů souborů. @@ -2919,6 +3107,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion) + + Print version and exit + Vypsat verzi a skončit + Prune cannot be configured with a negative value. Prořezávání nemůže být zkonfigurováno s negativní hodnotou. @@ -2939,10 +3131,26 @@ Specify wallet file (within data directory) Udej název souboru s peněženkou (v rámci datového adresáře) + + Unsupported argument -benchmark ignored, use -debug=bench. + Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Nepodporovaný argument -debugnet se ignoruje, použij -debug=net. + + + Unsupported argument -tor found, use -onion. + Argument -tor již není podporovaný, použij -onion. + Use UPnP to map the listening port (default: %u) Použít UPnP k namapování naslouchacího portu (výchozí: %u) + + User Agent comment (%s) contains unsafe characters. + Komentář u typu klienta (%s) obsahuje riskantní znaky. + Verifying blocks... Ověřuji bloky... @@ -2959,10 +3167,6 @@ Wallet options: Možnosti peněženky: - - Warning: This version is obsolete; upgrade required! - Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat! - You need to rebuild the database using -reindex to change -txindex Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex @@ -2973,7 +3177,7 @@ Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 - Obsadit zadanou adresu a protějšky, které se na ní připojí, umístit na bílou listinu. Pro zápis IPv6 adresy použij notaci [adresa]:port + Obsadit zadanou adresu a vždy vítat protějšky, které se na ni připojí. Pro zápis IPv6 adresy použij notaci [adresa]:port Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) @@ -2999,6 +3203,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Spustit příkaz, když přijde relevantní upozornění nebo když dojde k opravdu dlouhému rozštěpení řetezce bloků (%s se v příkazu nahradí zprávou) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Poplatky (v %s/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání, těžení a vytváření transakcí (výchozí: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u) @@ -3037,7 +3245,7 @@ Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway - Na protějšky na bílé listině se nevztahuje DoS klatba a jejich transakce jsou vždy přeposílány, i když už třeba jsou v mempoolu, což je užitečné např. pro bránu + Na vždy vítané protějšky se nevztahuje DoS klatba a jejich transakce jsou vždy přeposílány, i když už třeba jsou v transakčním zásobníku, což je užitečné např. pro bránu You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain @@ -3055,6 +3263,14 @@ Activating best chain... Aktivuji nejlepší řetězec... + + Attempt to recover private keys from a corrupt wallet.dat on startup + Pokusit se při startu zachránit soukromé klíče z poškozeného souboru wallet.dat + + + Automatically create Tor hidden service (default: %d) + Automaticky v Toru vytvářet skryté služby (výchozí: %d) + Cannot resolve -whitebind address: '%s' Nemohu přeložit -whitebind adresu: '%s' @@ -3075,6 +3291,10 @@ Error reading from database, shutting down. Chyba při čtení z databáze, ukončuji se. + + Imports blocks from external blk000??.dat file on startup + Importovat při startu bloky z externího souboru blk000??.dat + Information Informace @@ -3127,6 +3347,14 @@ Receive and display P2P network alerts (default: %u) Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Omezuji -maxconnections z %d na %d kvůli systémovým omezením. + + + Rescan the block chain for missing wallet transactions on startup + Přeskenovat při startu řetězec bloků na chybějící transakce tvé pěněženky + Send trace/debug info to console instead of debug.log file Posílat stopovací/ladicí informace do konzole místo do souboru debug.log @@ -3155,6 +3383,14 @@ This is experimental software. Tohle je experimentální program. + + Tor control port password (default: empty) + Heslo ovládacího portu Toru (výchozí: prázdné) + + + Tor control port to use if onion listening enabled (default: %s) + Ovládací port Toru, je-li zapnuté onion naslouchání (výchozí: %s) + Transaction amount too small Částka v transakci je příliš malá @@ -3175,6 +3411,10 @@ Unable to bind to %s on this computer (bind returned error %s) Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s) + + Upgrade wallet to latest format on startup + Převést při startu peněženku na nejnovější formát + Username for JSON-RPC connections Uživatelské jméno pro JSON-RPC spojení @@ -3187,10 +3427,18 @@ Warning Upozornění + + Whether to operate in a blocks only mode (default: %u) + Zda fungovat v čistě blokovém režimu (výchozí: %u) + Zapping all transactions from wallet... Vymazat všechny transakce z peněženky... + + ZeroMQ notification options: + Možnosti ZeroMQ oznámení: + wallet.dat corrupt, salvage failed Soubor wallet.dat je poškozen, jeho záchrana se nezdařila @@ -3223,6 +3471,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee je nastaveno velmi vysoko! Takto vysoký poplatek může být zaplacen v jednotlivé transakci. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Nedržet transakce v zásobníku déle než <n> hodin (výchozí: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Nastala chyba při čtení souboru wallet.dat! Všechny klíče se přečetly správně, ale data o transakcích nebo záznamy v adresáři mohou chybět či být nesprávné. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Poplatky (v %s/kB) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u) @@ -3239,10 +3507,30 @@ Output debugging information (default: %u, supplying <category> is optional) Tisknout ladicí informace (výchozí: %u, zadání <category> je volitelné) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Umožnit filtrování bloků a transakcí pomocí Bloomova filtru (výchozí: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Celková délka síťového identifikačního řetězce (%i) překročila svůj horní limit (%i). Omez počet nebo velikost voleb uacomment. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Pokusit se udržet odchozí provoz pod stanovenou hodnotou (v MiB za 24 hodin), 0 = bez omezení (výchozí: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Byl použit nepodporovaný argument -socks. Nastavení verze SOCKS už není možné, podporovány jsou pouze SOCKS5 proxy. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru (výchozí: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Uživatelské jméno a zahašované heslo pro JSON-RPC spojení. Pole <userpw> má formát: <UŽIVATELSKÉ_JMÉNO>:<SŮL>$<HAŠ>. Pomocný pythonní skript je přiložen v share/rpcuser. Tuto volbu lze použít i vícekrát + (default: %s) (výchozí: %s) @@ -3327,10 +3615,6 @@ Specify connection timeout in milliseconds (minimum: 1, default: %d) Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d) - - Specify pid file (default: %s) - PID soubor (výchozí: %s) - Spend unconfirmed change when sending transactions (default: %u) Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u) diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts index cc0c79115..34d7b4b4a 100644 --- a/src/qt/locale/bitcoin_cs_CZ.ts +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + Pravým klikem editujte adresu nebo popisek + Create a new address Vytvořit novou adresu @@ -9,6 +13,18 @@ Copy the currently selected address to the system clipboard Kopírovat aktuálně vybrané adresy do schránky + + Delete the currently selected address from the list + Odstraní aktuálně vybrané adresy ze seznamu + + + Export the data in the current tab to a file + Exportovat aktuální pohled do souboru + + + &Export + &Exportovat + &Delete &Odstranit @@ -622,6 +638,14 @@ WalletView + + &Export + &Exportovat + + + Export the data in the current tab to a file + Exportovat aktuální pohled do souboru + bitcoin-core diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index aa2724a1e..7d11825a6 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1017,7 +1017,7 @@ 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. - Minimér i stedet for at lukke applikationen, når vinduet lukkes. Når denne indstilling er slået til, vil applikationen først blive lukket, når Afslut vælges i menuen. + Minimér i stedet for at lukke applikationen, når vinduet lukkes. Når denne indstilling er aktiveret, vil applikationen først blive lukket, når Afslut vælges i menuen. The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. @@ -1069,7 +1069,7 @@ Enable coin &control features - Slå egenskaber for &coin-styring til + Aktivér egenskaber for &coin-styring 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. @@ -1473,10 +1473,6 @@ General Generelt - - Using OpenSSL version - Anvender OpenSSL-version - Using BerkeleyDB version Bruger BerkeleyDB version @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Acceptér forbindelser udefra (standard: 1 hvis hverken -proxy eller -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee er sat meget højt! Dette er transaktionsgebyret, du eventuelt betaler, hvis gebyrestimater ikke er tilgængelige. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + En gebyrsats (i %s/kB), som vil blive brugt, hvis gebyrestimering har utilstrækkelig data (standard: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Acceptér videresendte transaktioner, der modtages fra hvidlistede knuder, selv når transaktioner ikke videresendes (standard: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6 @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argument -whitelistalwaysrelay understøttes ikke og ignoreres; brug -whitelistrelay og/eller -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Brug UPnP for at konfigurere den lyttende port (standard: 1 under lytning og ingen -proxy) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Advarsel: Netværket ser ikke ud til at være fuldt ud enige! Enkelte minere ser ud til at opleve problemer. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advarsel: Ukendte blokversioner bliver minet! Det er muligt, at ukendte regler er i brug + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Advarsel: Vi ser ikke ud til at være fuldt ud enige med andre knuder! Du kan være nødt til at opgradere, eller andre knuder kan være nødt til at opgradere. @@ -3047,6 +3067,10 @@ <category> can be: <kategori> kan være: + + Append comment to the user agent string + Føj kommentar til brugeragentstrengen + Block creation options: Blokoprettelsestilvalg: @@ -3091,6 +3115,10 @@ Enable publish raw transaction in <address> Aktivér offentliggørelse af rå transaktion i <address> + + Enable transaction replacement in the memory pool (default: %u) + Aktivér transaktionserstatning i hukommelsespuljen (standard: %u) + Error initializing block database Klargøring af blokdatabase mislykkedes @@ -3127,10 +3155,22 @@ Invalid -onion address: '%s' Ugyldig -onion adresse: "%s" + + Invalid amount for -fallbackfee=<amount>: '%s' + Ugyldigt beløb for -fallbackfee=<beløb>: "%s" + Keep the transaction memory pool below <n> megabytes (default: %u) Hold hukommelsespuljen med transaktioner under <n> megabyte (standard: %u) + + Location of the auth cookie (default: data dir) + Placering for autentificerings-cookie (standard: datamappe) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Minimum bytes pr. sigop i transaktioner, vi videresender og miner (standard: %u) + Not enough file descriptors available. For få tilgængelige fildeskriptorer. @@ -3139,6 +3179,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Tilslut kun til knuder i netværk <net> (IPv4, IPv6 eller Onion) + + Print version and exit + Udskriv version og afslut + Prune cannot be configured with a negative value. Beskæring kan ikke opsættes med en negativ værdi. @@ -3195,10 +3239,6 @@ Wallet options: Tilvalg for tegnebog: - - Warning: This version is obsolete; upgrade required! - Advarsel: Denne version er forældet; opgradering påkrævet! - You need to rebuild the database using -reindex to change -txindex Du er nødt til at genopbygge databasen ved hjælp af -reindex for at ændre -txindex @@ -3257,7 +3297,7 @@ Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) - Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette tillader strømisolation med Tor (standard: %u) + Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette aktiverer strømisolation med Tor (standard: %u) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) @@ -3277,7 +3317,7 @@ Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway - Andre knuder på hvidliste kan ikke DoS-bandlyses, og deres transaktioner videresendes altid, selv hvis de allerede er i mempool'en. Brugbart til fx et adgangspunkt + Andre knuder på hvidliste kan ikke DoS-bandlyses, og deres transaktioner videresendes altid, selv hvis de allerede er i hukommelsespuljen. Brugbart til fx et adgangspunkt You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain @@ -3295,10 +3335,6 @@ Activating best chain... Aktiverer bedste kæde… - - Always relay transactions received from whitelisted peers (default: %d) - Videresend altid transaktioner, der modtages fra hvidlistede knuder (standard: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Forsøg at genskabe private nøgler fra en ødelagt wallet.dat under opstart @@ -3425,7 +3461,7 @@ Tor control port to use if onion listening enabled (default: %s) - Tor kontrolport, der skal bruges, hvis onion-lytning er slået til (standard: %s) + Tor kontrolport, der skal bruges, hvis onion-lytning er aktiveret (standard: %s) Transaction amount too small @@ -3463,6 +3499,10 @@ Warning Advarsel + + Warning: unknown new rules activated (versionbit %i) + Advarsel: Ukendte nye regler aktiveret (versionsbit %i) + Whether to operate in a blocks only mode (default: %u) Hvorvidt der skal arbejdes i kun-blokke-tilstand (standard: %u) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 84de80aff..947a471ac 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -892,7 +892,7 @@ Set language, for example "de_DE" (default: system locale) - Sprache einstellen, zum Beispiel "de_DE" (default: system locale) + Sprache einstellen, zum Beispiel "de_DE" (Standard: Systemgebietsschema) Start minimized @@ -1473,10 +1473,6 @@ General Allgemein - - Using OpenSSL version - Verwendete OpenSSL-Version - Using BerkeleyDB version Verwendete BerkeleyDB-Version @@ -2927,6 +2923,10 @@ Accept command line and JSON-RPC commands Kommandozeilen- und JSON-RPC-Befehle annehmen + + If <category> is not supplied or if <category> = 1, output all debugging information. + Wenn <category> nicht angegeben wird oder <category>=1, jegliche Debugginginformationen ausgeben. + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) @@ -2935,10 +2935,22 @@ Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird. + + Prune configured below the minimum of %d MiB. Please use a higher number. + Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert. + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus ist nicht mit -txindex und -rescan kompatibel. Warnung: Die Umkehr dieser Einstellung erfordert das erneute Herunterladen der gesamten Blockkette. (Standard: 0 = deaktiviert das Kürzen von Blöcken, >%u = Zielgröße in MiB, die für Blockdateien verwendet werden darf) + Error: A fatal internal error occurred, see debug.log for details Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details. + + Fee (in %s/kB) to add to transactions you send (default: %s) + Gebühr (in %s/kB), die von Ihnen gesendeten Transaktionen hinzugefügt wird (Standard: %s) + Pruning blockstore... Kürze Blockspeicher... @@ -2955,6 +2967,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee ist sehr hoch eingestellt! Das ist die Transaktionsgebühr, welche du zahlen müsstest, wenn die Gebührenschätzungen nicht verfügbar sind. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Eine Transaktionsgebühr (in %s/kB) wird genutzt, wenn für die Gebührenschützung zu wenig Daten vorliegen (Standardwert: %s) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden @@ -2971,10 +2991,18 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Maximale Anzahl an Skript-Verifizierungs-Threads festlegen (%u bis %d, 0 = automatisch, <0 = so viele Kerne frei lassen, Standard: %d) + + 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 + Die Block-Datenbank enthält einen Block, der in der Zukunft auftaucht. Dies kann daran liegen, dass die Systemzeit Ihres Computers falsch eingestellt ist. Stellen Sie die Block-Datenbank nur wieder her, wenn Sie sich sicher sind, dass Ihre Systemzeit korrekt eingestellt ist. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen! @@ -2983,6 +3011,14 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Das Argument -whitelistalwaysrelay wird nicht unterstützt und deswegen ignoriert. Benutze -whitelistrelay und/oder -whitelistforcerelay. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet). @@ -2995,6 +3031,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Warnung: Unbekannte Blockversion wird durch Mining erzeugt! Es ist möglich, dass unbekannte Regeln in Kraft sind. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Warnung: Wir scheinen nicht vollständig mit unseren Gegenstellen übereinzustimmen! Sie oder die anderen Knoten müssen unter Umständen Ihre Client-Software aktualisieren. @@ -3015,6 +3055,10 @@ <category> can be: <category> kann sein: + + Append comment to the user agent string + Hänge ein Kommentar zur User Agent-Zeichenkette an + Block creation options: Blockerzeugungsoptionen: @@ -3055,6 +3099,10 @@ Enable publish raw block in <address> Aktiviere das Veröffentlichen des Raw-Blocks in <address> + + Enable publish raw transaction in <address> + Aktiviere das Veröffentlichen der Roh-Transaktion in <address> + Error initializing block database Fehler beim Initialisieren der Blockdatenbank @@ -3091,6 +3139,18 @@ Invalid -onion address: '%s' Ungültige "-onion"-Adresse: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Ungültiger Betrag für -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Halten Sie den Transaktionsspeicherpool unter <n> Megabytes (Voreinstellung: %u) + + + Location of the auth cookie (default: data dir) + Dateiort für das Auth-Cookie (Standard: Datenverzeichnis) + Not enough file descriptors available. Nicht genügend Datei-Deskriptoren verfügbar. @@ -3099,6 +3159,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Nur zu Knoten des Netzwerktyps <net> verbinden (ipv4, ipv6 oder onion) + + Print version and exit + Gibt die Versionsnummer aus und beendet das Programm + Prune cannot be configured with a negative value. Kürzungsmodus kann nicht mit einem negativen Wert konfiguriert werden. @@ -3135,6 +3199,10 @@ Use UPnP to map the listening port (default: %u) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u) + + User Agent comment (%s) contains unsafe characters. + Der User Agent Kommentar (%s) enthält unsichere Zeichen. + Verifying blocks... Verifiziere Blöcke... @@ -3151,10 +3219,6 @@ Wallet options: Wallet-Optionen: - - Warning: This version is obsolete; upgrade required! - Warnung: Diese Version is veraltet, Aktualisierung erforderlich! - You need to rebuild the database using -reindex to change -txindex Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um -txindex zu verändern @@ -3191,6 +3255,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Befehl ausführen wenn ein relevanter Alarm empfangen wird oder wir einen wirklich langen Fork entdecken (%s im Befehl wird durch die Nachricht ersetzt) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Niedrigere Gebühren (in %s/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u) @@ -3331,6 +3399,10 @@ Receive and display P2P network alerts (default: %u) P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduziere -maxconnections von %d zu %d, aufgrund von Systemlimitierungen. + Rescan the block chain for missing wallet transactions on startup Blockkette beim Starten erneut nach fehlenden Wallet-Transaktionen durchsuchen @@ -3407,6 +3479,10 @@ Warning Warnung + + Warning: unknown new rules activated (versionbit %i) + Warnung: Unbekannte neue Regeln aktiviert (Versionsbit %i) + Whether to operate in a blocks only mode (default: %u) Legt fest ob nur Blöcke Modus aktiv sein soll (Standard: %u) @@ -3467,6 +3543,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Niedrigere Gebühren (in %s/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u) @@ -3483,6 +3563,10 @@ Output debugging information (default: %u, supplying <category> is optional) Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional) + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Gesamtlänge des Netzwerkversionstrings (%i) erreicht die maximale Länge (%i). Reduzieren Sie die Nummer oder die Größe von uacomments. + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) Versucht ausgehenden Datenverkehr unter dem gegebenen Wert zu halten (in MiB pro 24h), 0 = kein Limit (default: %d) @@ -3495,6 +3579,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Benutzername und gehashtes Passwort für JSON-RPC Verbindungen. Das Feld <userpw> kommt im Format: <USERNAME>:<SALT>$<HASH>. Ein kanonisches Pythonskript ist in share/rpcuser inbegriffen. Diese Option kann mehrere Male spezifiziert werden + (default: %s) (Standard: %s) diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 90c27c439..b5fb22f97 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -168,6 +168,11 @@ Are you sure you wish to encrypt your wallet? Είστε σίγουροι ότι θέλετε να κρυπτογραφήσετε το πορτοφόλι σας; + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Το Bitcoin Core θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογράφησης. Θυμήσου ότι κρυπτογραφώντας το πορτοφόλι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση που μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικό. + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. ΣΗΜΑΝΤΙΚΟ: Τα προηγούμενα αντίγραφα ασφαλείας που έχετε κάνει από το αρχείο του πορτοφόλιου σας θα πρέπει να αντικατασταθουν με το νέο που δημιουργείται, κρυπτογραφημένο αρχείο πορτοφόλιου. Για λόγους ασφαλείας, τα προηγούμενα αντίγραφα ασφαλείας του μη κρυπτογραφημένου αρχείου πορτοφόλιου θα καταστουν άχρηστα μόλις αρχίσετε να χρησιμοποιείτε το νέο κρυπτογραφημένο πορτοφόλι. @@ -184,6 +189,10 @@ Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι <br/> Παρακαλώ χρησιμοποιείστε ένα κωδικό με <b> 10 ή περισσότερους τυχαίους χαρακτήρες</b> ή <b> οχτώ ή παραπάνω λέξεις</b>. + + Enter the old passphrase and new passphrase to the wallet. + Πληκτρολόγησε τον παλιό και τον νέο κωδικό στο πορτοφολι. + Wallet encryption failed Η κρυπτογραφηση του πορτοφολιού απέτυχε @@ -1324,10 +1333,6 @@ General Γενικά - - Using OpenSSL version - Χρησιμοποιηση της OpenSSL εκδοσης - Using BerkeleyDB version Χρήση BerkeleyDB έκδοσης diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index b90221f2c..f122273a3 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -34,12 +34,7 @@ - - &Copy Address - &Copy Address - - - + Delete the currently selected address from the list Delete the currently selected address from the list @@ -58,89 +53,6 @@ &Delete &Delete - - - Choose the address to send coins to - - - - - Choose the address to receive coins with - - - - - C&hoose - - - - - Sending addresses - - - - - Receiving addresses - - - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - - - - - Copy &Label - Copy &Label - - - - &Edit - &Edit - - - - Export Address List - - - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - - Exporting Failed - - - - - There was an error trying to save the address list to %1. Please try again. - - - - - AddressTableModel - - - Label - Label - - - - Address - Address - - - - (no label) - (no label) - AskPassphraseDialog @@ -164,124 +76,6 @@ Repeat new passphrase Repeat new passphrase - - - Encrypt wallet - Encrypt wallet - - - - This operation needs your wallet passphrase to unlock the wallet. - This operation needs your wallet passphrase to unlock the wallet. - - - - Unlock wallet - Unlock wallet - - - - This operation needs your wallet passphrase to decrypt the wallet. - This operation needs your wallet passphrase to decrypt the wallet. - - - - Decrypt wallet - Decrypt wallet - - - - Change passphrase - Change passphrase - - - - Confirm wallet encryption - Confirm wallet encryption - - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - - - - Are you sure you wish to encrypt your wallet? - Are you sure you wish to encrypt your wallet? - - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - - - - - Warning: The Caps Lock key is on! - Warning: The Caps Lock key is on! - - - - - Wallet encrypted - Wallet encrypted - - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - - - - - Enter the old passphrase and new passphrase to the wallet. - - - - - %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - - - - - - - - Wallet encryption failed - Wallet encryption failed - - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - - - - - The supplied passphrases do not match. - The supplied passphrases do not match. - - - - Wallet unlock failed - Wallet unlock failed - - - - - - The passphrase entered for the wallet decryption was incorrect. - The passphrase entered for the wallet decryption was incorrect. - - - - Wallet decryption failed - Wallet decryption failed - - - - Wallet passphrase was successfully changed. - Wallet passphrase was successfully changed. - BanTableModel @@ -795,189 +589,6 @@ Priority - - - Copy address - Copy address - - - - Copy label - Copy label - - - - - Copy amount - Copy amount - - - - Copy transaction ID - Copy transaction ID - - - - Lock unspent - - - - - Unlock unspent - - - - - Copy quantity - - - - - Copy fee - - - - - Copy after fee - - - - - Copy bytes - - - - - Copy priority - - - - - Copy dust - - - - - Copy change - - - - - highest - - - - - higher - - - - - high - - - - - medium-high - - - - - medium - - - - - low-medium - - - - - low - - - - - lower - - - - - lowest - - - - - (%1 locked) - - - - - none - - - - - This label turns red if the transaction size is greater than 1000 bytes. - - - - - This label turns red if the priority is smaller than "medium". - - - - - Can vary +/- %1 satoshi(s) per input. - - - - - yes - - - - - no - - - - - - This means a fee of at least %1 per kB is required. - - - - - Can vary +/- 1 byte per input. - - - - - Transactions with higher priority are more likely to get included into a block. - - - - - This label turns red if any recipient receives an amount smaller than the current dust threshold. - - - - - - (no label) - (no label) - - - - change from %1 (%2) - - - - - (change) - - EditAddressDialog @@ -1006,46 +617,6 @@ &Address &Address - - - New receiving address - New receiving address - - - - New sending address - New sending address - - - - Edit receiving address - Edit receiving address - - - - Edit sending address - Edit sending address - - - - The entered address "%1" is already in the address book. - The entered address "%1" is already in the address book. - - - - The entered address "%1" is not a valid Bitcoin address. - The entered address "%1" is not a valid Bitcoin address. - - - - Could not unlock wallet. - Could not unlock wallet. - - - - New key generation failed. - New key generation failed. - FreespaceChecker @@ -1225,11 +796,6 @@ Select payment request file - - - Select payment request file to open - - OptionsDialog @@ -1626,132 +1192,6 @@ - - PaymentServer - - - - - URI handling - URI handling - - - - Invalid payment address %1 - - - - - - - - - - Payment request rejected - - - - - Payment request network doesn't match client network. - - - - - Payment request is not initialized. - - - - - Requested payment amount of %1 is too small (considered dust). - - - - - - - - - - Payment request error - - - - - Cannot start bitcoin: click-to-pay handler - - - - - Payment request fetch URL is invalid: %1 - - - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - - - - - Payment request file handling - - - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - - - - - Payment request expired. - - - - - Unverified payment requests to custom payment scripts are unsupported. - - - - - - Invalid payment request. - - - - - Refund from %1 - - - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - - - - - Error communicating with %1: %2 - - - - - Payment request cannot be parsed! - - - - - Bad response from server %1 - - - - - Payment acknowledged - - - - - Network request error - - - PeerTableModel @@ -1819,29 +1259,6 @@ - - QRImageWidget - - - &Save Image... - - - - - &Copy Image - - - - - Save QR Code - Save QR Code - - - - PNG Image (*.png) - - - RPCConsole @@ -2338,21 +1755,6 @@ Remove - - - Copy label - Copy label - - - - Copy message - - - - - Copy amount - Copy amount - ReceiveRequestDialog @@ -2376,95 +1778,11 @@ &Save Image... - - - Request payment to %1 - - - - - Payment information - - - - - URI - - - - - Address - Address - - - - Amount - Amount - - - - Label - Label - - - - Message - Message - - - - Resulting URI too long, try to reduce the text for label / message. - Resulting URI too long, try to reduce the text for label / message. - - - - Error encoding URI into QR Code. - Error encoding URI into QR Code. - - - - RecentRequestsTableModel - - - Date - Date - - - - Label - Label - - - - Message - Message - - - - (no amount requested) - - - - - Requested - - - - - (no label) - (no label) - - - - (no message) - - SendCoinsDialog - Send Coins Send Coins @@ -2650,152 +1968,6 @@ S&end S&end - - - Confirm send coins - Confirm send coins - - - - - - - %1 to %2 - - - - - Copy quantity - - - - - Copy amount - Copy amount - - - - Copy fee - - - - - Copy after fee - - - - - Copy bytes - - - - - Copy priority - - - - - Copy change - - - - - Total Amount %1 - - - - - or - - - - - The amount to pay must be larger than 0. - The amount to pay must be larger than 0. - - - - The amount exceeds your balance. - The amount exceeds your balance. - - - - The total exceeds your balance when the %1 transaction fee is included. - The total exceeds your balance when the %1 transaction fee is included. - - - - Transaction creation failed! - - - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - - - - - A fee higher than %1 is considered an absurdly high fee. - - - - - Payment request expired. - - - - - Pay only the required fee of %1 - - - - - Estimated to begin confirmation within %n block(s). - - Estimated to begin confirmation within %n block. - Estimated to begin confirmation within %n blocks. - - - - - The recipient address is not valid. Please recheck. - - - - - Duplicate address found: addresses should only be used once each. - - - - - Warning: Invalid Bitcoin address - - - - - (no label) - (no label) - - - - Warning: Unknown change address - - - - - Copy dust - - - - - Are you sure you want to send? - - - - - added as transaction fee - - SendCoinsEntry @@ -2812,12 +1984,7 @@ Pay &To: - - Enter a label for this address to add it to your address book - Enter a label for this address to add it to your address book - - - + &Label: &Label: @@ -2906,15 +2073,6 @@ - - SendConfirmationDialog - - - - Yes - - - ShutdownWindow @@ -3038,77 +2196,6 @@ Reset all verify message fields Reset all verify message fields - - - Click "Sign Message" to generate signature - Click "Sign Message" to generate signature - - - - - The entered address is invalid. - The entered address is invalid. - - - - - - - Please check the address and try again. - Please check the address and try again. - - - - - The entered address does not refer to a key. - The entered address does not refer to a key. - - - - Wallet unlock was cancelled. - Wallet unlock was cancelled. - - - - Private key for the entered address is not available. - Private key for the entered address is not available. - - - - Message signing failed. - Message signing failed. - - - - Message signed. - Message signed. - - - - The signature could not be decoded. - The signature could not be decoded. - - - - - Please check the signature and try again. - Please check the signature and try again. - - - - The signature did not match the message digest. - The signature did not match the message digest. - - - - Message verification failed. - Message verification failed. - - - - Message verified. - Message verified. - SplashScreen @@ -3126,242 +2213,6 @@ - - TransactionDesc - - - Open until %1 - Open until %1 - - - - %1/offline - %1/offline - - - - 0/unconfirmed, %1 - - - - - in memory pool - - - - - not in memory pool - - - - - abandoned - - - - - %1/unconfirmed - %1/unconfirmed - - - - %1 confirmations - %1 confirmations - - - - Status - Status - - - - , broadcast through %n node(s) - - , broadcast through %n node - , broadcast through %n nodes - - - - - Date - Date - - - - Source - Source - - - - Generated - Generated - - - - - - From - From - - - - - - To - To - - - - own address - own address - - - - - watch-only - - - - - label - label - - - - - - - - Credit - Credit - - - - matures in %n more block(s) - - matures in %n more block - matures in %n more blocks - - - - - not accepted - not accepted - - - - - - Debit - Debit - - - - Total debit - - - - - Total credit - - - - - Transaction fee - Transaction fee - - - - Net amount - Net amount - - - - - Message - Message - - - - Comment - Comment - - - - Transaction ID - Transaction ID - - - - Output index - - - - - Merchant - - - - - 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. - - - - - Debug information - Debug information - - - - Transaction - Transaction - - - - Inputs - Inputs - - - - Amount - Amount - - - - - true - true - - - - - false - false - - - - , has not been successfully broadcast yet - , has not been successfully broadcast yet - - - - Open for %n more block(s) - - Open for %n more block - Open for %n more blocks - - - - - conflicted with a transaction with %1 confirmations - - - - - unknown - unknown - - TransactionDescDialog @@ -3369,351 +2220,6 @@ This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction - - - Details for %1 - - - - - TransactionTableModel - - - Date - Date - - - - Type - Type - - - - Immature (%1 confirmations, will be available after %2) - - - - - Open for %n more block(s) - - Open for %n more block - Open for %n more blocks - - - - - Open until %1 - Open until %1 - - - - Confirmed (%1 confirmations) - Confirmed (%1 confirmations) - - - - This block was not received by any other nodes and will probably not be accepted! - This block was not received by any other nodes and will probably not be accepted! - - - - Generated but not accepted - Generated but not accepted - - - - Offline - - - - - Label - Label - - - - Unconfirmed - - - - - Abandoned - - - - - Confirming (%1 of %2 recommended confirmations) - - - - - Conflicted - - - - - Received with - Received with - - - - Received from - Received from - - - - Sent to - Sent to - - - - Payment to yourself - Payment to yourself - - - - Mined - Mined - - - - watch-only - - - - - (n/a) - (n/a) - - - - (no label) - (no label) - - - - Transaction status. Hover over this field to show number of confirmations. - Transaction status. Hover over this field to show number of confirmations. - - - - Date and time that the transaction was received. - Date and time that the transaction was received. - - - - Type of transaction. - Type of transaction. - - - - Whether or not a watch-only address is involved in this transaction. - - - - - User-defined intent/purpose of the transaction. - - - - - Amount removed from or added to balance. - Amount removed from or added to balance. - - - - TransactionView - - - - All - All - - - - Today - Today - - - - This week - This week - - - - This month - This month - - - - Last month - Last month - - - - This year - This year - - - - Range... - Range... - - - - Received with - Received with - - - - Sent to - Sent to - - - - To yourself - To yourself - - - - Mined - Mined - - - - Other - Other - - - - Enter address or label to search - Enter address or label to search - - - - Min amount - Min amount - - - - Abandon transaction - - - - - Copy address - Copy address - - - - Copy label - Copy label - - - - Copy amount - Copy amount - - - - Copy transaction ID - Copy transaction ID - - - - Copy raw transaction - - - - - Copy full transaction details - - - - - Edit label - Edit label - - - - Show transaction details - Show transaction details - - - - Export Transaction History - - - - - Watch-only - - - - - Exporting Failed - - - - - There was an error trying to save the transaction history to %1. - - - - - Exporting Successful - - - - - The transaction history was successfully saved to %1. - - - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - - Confirmed - Confirmed - - - - Date - Date - - - - Type - Type - - - - Label - Label - - - - Address - Address - - - - ID - ID - - - - Range: - Range: - - - - to - to - UnitDisplayStatusBarControl @@ -3723,69 +2229,10 @@ - - WalletFrame - - - No wallet has been loaded. - - - - - WalletModel - - - Send Coins - Send Coins - - - - WalletView - - - &Export - &Export - - - - Export the data in the current tab to a file - Export the data in the current tab to a file - - - - Backup Wallet - Backup Wallet - - - - Wallet Data (*.dat) - Wallet Data (*.dat) - - - - Backup Failed - Backup Failed - - - - There was an error trying to save the wallet data to %1. - - - - - The wallet data was successfully saved to %1. - - - - - Backup Successful - Backup Successful - - bitcoin-core - + Options: Options: @@ -3795,27 +2242,27 @@ Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. - + Prune configured below the minimum of %d MiB. Please use a higher number. @@ -3835,7 +2282,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -3855,17 +2302,17 @@ Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -3911,6 +2358,11 @@ + Error loading %s: You can't enable HD on a already existing non-HD wallet + + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. @@ -3939,6 +2391,11 @@ Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -3960,7 +2417,12 @@ - + + Use hierarchical deterministic key generation (HD) after bip32. Only has effect during wallet creation/first start + + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) @@ -4114,6 +2576,11 @@ Error loading %s: Wallet requires newer version of %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + + Error loading block database @@ -4240,7 +2707,12 @@ Specify wallet file (within data directory) - + + The source code is available from %s. + + + + Unable to bind to %s on this computer. %s is probably already running. @@ -4300,7 +2772,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -4325,7 +2797,7 @@ - + Error: Listening for incoming connections failed (listen returned error %s) @@ -4355,7 +2827,7 @@ - + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) @@ -4380,7 +2852,7 @@ - + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -4410,7 +2882,7 @@ - + Error reading from database, shutting down. @@ -4490,7 +2962,7 @@ Signing transaction failed - + The transaction amount is too small to pay the fee @@ -4570,27 +3042,27 @@ - + Password for JSON-RPC connections Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect - + Loading addresses... Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -4610,7 +3082,7 @@ - + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) @@ -4635,7 +3107,7 @@ - + Support filtering of blocks and transaction with bloom filters (default: %u) @@ -4660,7 +3132,7 @@ - + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) @@ -4690,7 +3162,7 @@ - + How many blocks to check at startup (default: %u, 0 = all) @@ -4785,7 +3257,7 @@ - + Threshold for disconnecting misbehaving peers (default: %u) @@ -4795,7 +3267,7 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds @@ -4805,17 +3277,17 @@ Loading block index... - + Add a node to connect to and attempt to keep the connection open Add a node to connect to and attempt to keep the connection open - + Loading wallet... Loading wallet... - + Cannot downgrade wallet Cannot downgrade wallet @@ -4825,17 +3297,17 @@ Cannot write default address - + Rescanning... Rescanning... - + Done loading Done loading - + Error Error diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index bf912d295..b9c0c8281 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -908,7 +908,7 @@ Reset all settings changes made over the GUI - Reset all settings changes made over the GUI + Reset all setting changes made via the GUI @@ -1473,10 +1473,6 @@ General General - - Using OpenSSL version - Using OpenSSL version - Using BerkeleyDB version Using BerkeleyDB version @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind to given address and always listen on it. Use [host]:port notation for IPv6 @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Unable to bind to %s on this computer. Bitcoin Core is probably already running. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. @@ -3047,6 +3067,10 @@ <category> can be: <category> can be: + + Append comment to the user agent string + Append comment to the user agent string + Block creation options: Block creation options: @@ -3091,6 +3115,10 @@ Enable publish raw transaction in <address> Enable publish raw transaction in <address> + + Enable transaction replacement in the memory pool (default: %u) + Enable transaction replacement in the memory pool (default: %u) + Error initializing block database Error initialising block database @@ -3127,10 +3155,22 @@ Invalid -onion address: '%s' Invalid -onion address: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Keep the transaction memory pool below <n> megabytes (default: %u) + + Location of the auth cookie (default: data dir) + Location of the auth cookie (default: data dir) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Not enough file descriptors available. Not enough file descriptors available. @@ -3139,6 +3179,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Only connect to nodes in network <net> (ipv4, ipv6 or onion) + + Print version and exit + Print version and exit + Prune cannot be configured with a negative value. Prune cannot be configured with a negative value. @@ -3195,10 +3239,6 @@ Wallet options: Wallet options: - - Warning: This version is obsolete; upgrade required! - Warning: This version is obsolete; upgrade required! - You need to rebuild the database using -reindex to change -txindex You need to rebuild the database using -reindex to change -txindex @@ -3295,10 +3335,6 @@ Activating best chain... Activating best chain... - - Always relay transactions received from whitelisted peers (default: %d) - Always relay transactions received from whitelisted peers (default: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Attempt to recover private keys from a corrupt wallet.dat on startup @@ -3463,6 +3499,10 @@ Warning Warning + + Warning: unknown new rules activated (versionbit %i) + Warning: unknown new rules activated (versionbit %i) + Whether to operate in a blocks only mode (default: %u) Whether to operate in a blocks only mode (default: %u) diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index ab8dd65f8..2095db34b 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -179,6 +179,10 @@ Wallet encrypted La monujo estas ĉifrita + + Enter the old passphrase and new passphrase to the wallet. + Tajpu la malnovan pasvorton kaj la novan pasvorton por la monujo. + Wallet encryption failed Ĉifrado de la monujo fiaskis @@ -409,6 +413,10 @@ No block source available... Neniu fonto de blokoj trovebla... + + %n hour(s) + %n horo%n horoj + %n day(s) %n tago%n tagoj @@ -479,6 +487,12 @@ Label: %1 Etikedo: %1 + + + + Address: %1 + + Adreso: %1 @@ -812,6 +826,10 @@ command-line options komandliniaj agordaĵoj + + UI Options: + Uzantinterfaco ebloj: + Intro @@ -847,6 +865,10 @@ Error Eraro + + %n GB of free space available + %n gigabajto de libera loko disponeble%n gigabajtoj de libera loko disponebla. + OpenURIDialog @@ -1098,6 +1120,10 @@ PeerTableModel + + User Agent + Uzanto Agento + QObject @@ -1167,10 +1193,6 @@ General Ĝenerala - - Using OpenSSL version - uzas OpenSSL-version - Startup time Horo de lanĉo @@ -1203,10 +1225,22 @@ Sent Sendita + + &Peers + &Samuloj + + + Banned peers + Malpermesita samuloj. + Version Versio + + User Agent + Uzanto Agento + Services Servoj diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 936074210..5322634c5 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -882,6 +882,10 @@ command-line options opciones de la consola de comandos + + UI Options: + Opciones de interfaz de usuario: + Choose data directory on startup (default: %u) Elegir directorio de datos al iniciar (predeterminado: %u) @@ -898,7 +902,11 @@ Set SSL root certificates for payment request (default: -system-) Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) - + + Reset all settings changes made over the GUI + Resetear los cambios de configuracion hechos por el GUI + + Intro @@ -1095,6 +1103,14 @@ Port of the proxy (e.g. 9050) Puerto del servidor proxy (ej. 9050) + + Used for reaching peers via: + Usado para alcanzar compañeros via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Muestra si el proxy SOCKS5 predeterminado es utilizado para llegar a los pares a traves de este tipo de red. + IPv4 IPv4 @@ -1107,6 +1123,10 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Conectar a la red Bitcoin mediante un proxy SOCKS5 por separado para los servicios ocultos de Tor. + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima: @@ -1449,10 +1469,6 @@ General General - - Using OpenSSL version - Utilizando la versión de OpenSSL - Using BerkeleyDB version Utilizando la versión de BerkeleyDB @@ -1481,6 +1497,18 @@ Current number of blocks Número actual de bloques + + Memory Pool + Piscina de Memoria + + + Current number of transactions + Número actual de transacciones + + + Memory usage + Uso de memoria + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Abre el archivo de registro de depuración de Bitcoin desde el directorio de datos actual. Esto puede tardar unos segundos para ficheros de registro de gran tamaño. @@ -1505,6 +1533,10 @@ Select a peer to view detailed information. Seleccionar un par para ver su información detallada. + + Whitelisted + En la lista blanca + Direction Dirección @@ -1553,6 +1585,14 @@ Ping Time Ping + + The duration of a currently outstanding ping. + La duración de un ping actualmente en proceso. + + + Ping Wait + Espera de Ping + Time Offset Desplazamiento de tiempo @@ -1605,6 +1645,10 @@ &Disconnect Node Nodo &Desconectado + + Ban Node for + Prohibir Nodo para + 1 &hour 1 &hora @@ -1621,6 +1665,10 @@ 1 &year 1 &año + + &Unban Node + &Desbanear Nodo + Welcome to the Bitcoin Core RPC console. Bienvenido a la consola RPC de Bitcoin Core. @@ -2720,6 +2768,10 @@ Copy transaction ID Copiar identificador de transacción + + Copy raw transaction + Copiar traducción en crudo + Edit label Editar etiqueta @@ -2869,6 +2921,34 @@ Aceptar comandos consola y JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si <category> no es proporcionado o si <category> =1, muestra toda la información de depuración. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Máximas comisiones totales (en %s) para utilizar en una sola transacción de la cartera; establecer esto demasiado bajo puede abortar grandes transacciones (predeterminado: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Por favor, mira si la fecha y la hora en tu computador son correctas! Si tu hara es errónea Bitcoin Core no funcionará correctamente. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + La Poda se ha configurado por debajo del minimo de %d MiB. Por favor utiliza un valor mas alto. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Poda: la ultima sincronizacion de la cartera sobrepasa los datos podados. Necesitas reindexar con -reindex (o descargar la cadena de bloques de nuevo en el caso de un nodo podado) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduce los requisitos de almacenaje podando (eliminando) los bloques viejos. Este modo es incompatible con -txindex y -rescan. Advertencia: Revertir este ajuste requiere volver a descargar la cadena de bloques al completo. (predeterminado: 0 = deshabilitar la poda de bloques, >%u = objetivo de tamaño en MiB para usar para los archivos de bloques) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Nos es posible re-escanear en modo podado.Necesitas utilizar -reindex el cual descargara la cadena de bloques al completo de nuevo. + Error: A fatal internal error occurred, see debug.log for details Un error interno fatal ocurrió, ver debug.log para detalles @@ -2894,6 +2974,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee tiene un ajuste muy alto! Esta es la comisión de transacción que pagarás cuando las estimaciones de comisiones no estén disponibles. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Una comision (en %s/kB) que sera usada cuando las estimacion de comision no disponga de suficientes datos (predeterminado: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Aceptar transacciones retransmitidas recibidas desde nodos en la lista blanca incluso cuando no estés retransmitiendo transacciones (predeterminado: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6 @@ -2910,10 +3002,18 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, <0 = dejar libres ese número de núcleos; predeterminado: %d) + + 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 + La base de datos de bloques contiene un bloque que parece ser del futuro. Esto puede ser porque la fecha y hora de tu ordenador están mal ajustados. Reconstruye la base de datos de bloques solo si estas seguro de que la fecha y hora de tu ordenador estan ajustados correctamente. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería. @@ -2922,6 +3022,14 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + El argumento no soportado -whitelistalwaysrelay ha sido ignorado, utiliza -whitelistrelay y/o -whitelistforcerelay. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera) @@ -2934,6 +3042,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advertencia: Se están minando versiones de bloques desconocidas! Es posible que normas desconocidas estén activas + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla. @@ -2954,6 +3066,10 @@ <category> can be: <category> puede ser: + + Append comment to the user agent string + Adjunta un comentario a la linea de agente de usuario + Block creation options: Opciones de creación de bloques: @@ -2982,6 +3098,26 @@ Do you want to rebuild the block database now? ¿Quieres reconstruir la base de datos de bloques ahora? + + Enable publish hash block in <address> + Activar publicar bloque .hash en <.Address> + + + Enable publish hash transaction in <address> + Activar publicar transacción .hash en <.Address> + + + Enable publish raw block in <address> + Habilita la publicacion de bloques en bruto en <direccion> + + + Enable publish raw transaction in <address> + Habilitar publicar transacción en rama en <dirección> + + + Enable transaction replacement in the memory pool (default: %u) + Habilita el reemplazamiento de transacciones en la piscina de memoria (predeterminado: %u) + Error initializing block database Error al inicializar la base de datos de bloques @@ -3018,6 +3154,22 @@ Invalid -onion address: '%s' Dirección -onion inválida: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Cantidad inválida para -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Mantener la memoria de transacciones por debajo de <n> megabytes (predeterminado: %u) + + + Location of the auth cookie (default: data dir) + Ubicación de la cookie de autenticación (default: data dir) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Mínimo de bytes por sigop en transacciones que retransmitimos y minamos (predeterminado: %u) + Not enough file descriptors available. No hay suficientes descriptores de archivo disponibles. @@ -3026,6 +3178,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion) + + Print version and exit + Imprimir versión y salir + Prune cannot be configured with a negative value. Pode no se puede configurar con un valor negativo. @@ -3046,10 +3202,26 @@ Specify wallet file (within data directory) Especificar archivo de monedero (dentro del directorio de datos) + + Unsupported argument -benchmark ignored, use -debug=bench. + El argumento -benchmark no es soportado y ha sido ignorado, utiliza -debug=bench + + + Unsupported argument -debugnet ignored, use -debug=net. + Parámetros no compatibles -debugnet ignorados , use -debug = red. + + + Unsupported argument -tor found, use -onion. + Parámetros no compatibles -tor encontrados, use -onion . + Use UPnP to map the listening port (default: %u) Usar UPnP para asignar el puerto de escucha (predeterminado:: %u) + + User Agent comment (%s) contains unsafe characters. + El comentario del Agente de Usuario (%s) contiene caracteres inseguros. + Verifying blocks... Verificando bloques... @@ -3066,10 +3238,6 @@ Wallet options: Opciones de monedero: - - Warning: This version is obsolete; upgrade required! - Peligro: Esta versión es obsoleta; actualización requerida! - You need to rebuild the database using -reindex to change -txindex Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex @@ -3106,6 +3274,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Las comisiones (en %s/kB) mas pequeñas que esto se consideran como cero comisión para la retransmisión, minería y creación de la transacción (predeterminado: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u) @@ -3246,6 +3418,10 @@ Receive and display P2P network alerts (default: %u) Recibir y mostrar alertas de red P2P (default: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduciendo -maxconnections de %d a %d, debido a limitaciones del sistema. + Rescan the block chain for missing wallet transactions on startup Rescanea la cadena de bloques para transacciones perdidas de la cartera @@ -3278,6 +3454,14 @@ This is experimental software. Este software es experimental. + + Tor control port password (default: empty) + Contraseña del puerto de control de Tor (predeterminado: vacio) + + + Tor control port to use if onion listening enabled (default: %s) + Puerto de control de Tor a utilizar si la escucha de onion esta activada (predeterminado: %s) + Transaction amount too small Cantidad de la transacción demasiado pequeña @@ -3315,10 +3499,22 @@ Warning Aviso + + Warning: unknown new rules activated (versionbit %i) + Advertencia: nuevas reglas desconocidas activadas (versionbit %i) + + + Whether to operate in a blocks only mode (default: %u) + Si se debe o no operar en un modo de solo bloques (predeterminado: %u) + Zapping all transactions from wallet... Eliminando todas las transacciones del monedero... + + ZeroMQ notification options: + Opciones de notificación ZeroQM: + wallet.dat corrupt, salvage failed wallet.dat corrupto. Ha fallado la recuperación. @@ -3353,6 +3549,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee tiene un ajuste muy elevado! Las comisiones así de grandes podrían ser pagadas en una única transaccion. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee tiene un ajuste muy elevado! Esta es la comisión de transacción que pagaras si envías una transaccion. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + No mantener transacciones en la memoria mas de <n> horas (predeterminado: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error al leer wallet.dat! Todas las llaves se leyeron correctamente, pero los datos de transacciones o la libreta de direcciones pueden faltar o ser incorrectos. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Las comisiones (en %s/kB) menores que esto son consideradas de cero comision para la creacion de transacciones (predeterminado: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u) @@ -3369,10 +3585,18 @@ Output debugging information (default: %u, supplying <category> is optional) Mostrar depuración (por defecto: %u, proporcionar <category> es opcional) + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nombre de usuario y hash de la contraseña para las conexiones JSON-RPC. El campo <userpw> tiene el formato: <USERNAME>:<SALT>$<HASH>. Se incluye un script python convencional en share/rpcuser. Esta opción puede ser especificada multiples veces + (default: %s) (predeterminado: %s) diff --git a/src/qt/locale/bitcoin_es_419.ts b/src/qt/locale/bitcoin_es_419.ts new file mode 100644 index 000000000..b76915662 --- /dev/null +++ b/src/qt/locale/bitcoin_es_419.ts @@ -0,0 +1,173 @@ + + + AddressBookPage + + Right-click to edit address or label + Haga clic para editar la dirección o etiqueta + + + Create a new address + Crear una nueva dirección + + + &New + &New + + + Copy the currently selected address to the system clipboard + Copia la dirección seleccionada al portapapeles del sistema + + + Choose the address to send coins to + Seleccione la Direccion a la que enviara dinero + + + Choose the address to receive coins with + Seleccione la direccion de la que recibira dinero + + + Export Address List + Exportar Lista de Direcciones + + + + AddressTableModel + + Address + Direccion + + + + AskPassphraseDialog + + Decrypt wallet + Desencriptar Monedero + + + Confirm wallet encryption + Confirmar Encriptacion de Monedero + + + Warning: The Caps Lock key is on! + Advertencia: La Tecla Caps Lock esta habilitada! + + + Wallet encrypted + Monedero ha sido encriptado + + + Wallet encryption failed + La encriptacion del monedero ha fallado + + + + BanTableModel + + + BitcoinGUI + + + ClientModel + + + CoinControlDialog + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Direccion + + + + RecentRequestsTableModel + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + + TransactionView + + Address + Direccion + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_AR.ts b/src/qt/locale/bitcoin_es_AR.ts new file mode 100644 index 000000000..fb9ac895b --- /dev/null +++ b/src/qt/locale/bitcoin_es_AR.ts @@ -0,0 +1,373 @@ + + + AddressBookPage + + Right-click to edit address or label + Hacé click para editar la dirección o etiqueta + + + Create a new address + Crear una nueva dirección + + + &New + &Nuevo + + + Copy the currently selected address to the system clipboard + Copiá la dirección que seleccionaste al portapapeles + + + &Copy + &Copiar + + + C&lose + C&lose + + + &Copy Address + &Copiar Dirección + + + Delete the currently selected address from the list + Borrar de la lista la dirección seleccionada + + + Export the data in the current tab to a file + Exportar los datos de la pestaña actual a un archivo + + + &Export + &Exportar + + + &Delete + &Borrar + + + Choose the address to send coins to + Elegir la dirección a donde enviar las monedas (coins) + + + Choose the address to receive coins with + Elegí la dirección donde recibir las monedas + + + C&hoose + E&legir + + + Sending addresses + Direcciones de envío + + + Receiving addresses + Direcciones de recepción + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son tus direcciones Bitcoin para enviar pagos. Siempre chequeá el monto y la dirección de recepción antes de mandar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son tus direcciones para recibir pagos. Te recomendamos que uses una dirección de recibir para cada transacción. + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado por coma (*.csv) + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the address list to %1. Please try again. + Hubo un error al tratar de guardar la lista de direcciones a %1. Por favor tratá de nuevo. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + + + + AskPassphraseDialog + + Passphrase Dialog + Diálogo de Frase de Contraseña + + + Enter passphrase + Ingresar la Frase de Contraseña + + + New passphrase + Nueva Frase de Contraseña + + + Repeat new passphrase + Repetí la nueva Frase de Contraseña + + + Encrypt wallet + Encriptar la billetera + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita tu frase de contraseña para desbloquear tu billetera. + + + Unlock wallet + Desbloquear la billetera + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita tu Frase de Contraseña de billetera para desencriptar la billetera. + + + Decrypt wallet + Desencriptar la billetera + + + Change passphrase + Cambiar la Frase de Contraseña + + + Confirm wallet encryption + Confirmá la encriptación de la billetera + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Atención: Si encriptás tu billetera y perdés tu frase de contraseña, vas a <b>PERDER TODOS TUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + ¿Estás seguro que querés encriptar tu billetera? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core ahora se va a cerrar para terminar el proceso de encriptación. Acordate que encriptar tu billetera no te protege completamente de que algún malware que pueda infectar tu computadora te robe tus bitcoins. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Todos los backups que hayas hecho de tu billetera tendrían que ser reemplazados por el archivo encriptado de billetera que generaste. Por razones de seguridad, los backups anteriores del archivo de billetera no encriptado se inutilizan en el momento en que empezás a usar la nueva billetera encriptada + + + Warning: The Caps Lock key is on! + Atención: Tenés puestas las mayúsculas! + + + Wallet encrypted + Billetera encriptada + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Ingresá una nueva frase de contraseña para la billetera.<br/>Por favor, fijate de usar una frase de contraseña de <b>diez o más caracteres aleatorios</b>, o de <b>ocho o más palabras</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Ingresá la frase de contraseña vieja y la nueva para la billetera. + + + Wallet encryption failed + Falló la encriptación de la billetera + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falló la encriptación de la billetera por un error interno. Tu billetera no está encriptada. + + + The supplied passphrases do not match. + Las frases de contraseña no son iguales. + + + Wallet unlock failed + Falló el desbloqueo de la billetera + + + The passphrase entered for the wallet decryption was incorrect. + La frase de contraseña que ingresaste para desencriptar la billetera es incorrecta. + + + Wallet decryption failed + Falló la desencriptación de la billetera + + + + BanTableModel + + + BitcoinGUI + + + ClientModel + + + CoinControlDialog + + (no label) + (sin etiqueta) + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Dirección + + + Label + Etiqueta + + + + RecentRequestsTableModel + + Label + Etiqueta + + + (no label) + (sin etiqueta) + + + + SendCoinsDialog + + (no label) + (sin etiqueta) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Etiqueta + + + + TransactionView + + Exporting Failed + Falló la exportación + + + Comma separated file (*.csv) + Archivo separado por coma (*.csv) + + + Label + Etiqueta + + + Address + Dirección + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar los datos de la pestaña actual a un archivo + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index e6d48a29f..742dee29d 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -7,7 +7,7 @@ Create a new address - Crea una nueva direCrea una nueva direccióncción + Crea una nueva dirección &New @@ -45,6 +45,22 @@ &Delete &Borrar + + Choose the address to send coins to + Selecciona la direccion para enviar coins + + + Choose the address to receive coins with + Selecciona la dirección para recibir coins + + + Sending addresses + Dirección de envio + + + Receiving addresses + Dirección para recibir + Copy &Label Copia &etiqueta @@ -53,10 +69,18 @@ &Edit &Editar + + Export Address List + Exportar lista de direcciones + Comma separated file (*.csv) Archivos separados por coma (*.csv) + + Exporting Failed + Exportado fallo + AddressTableModel @@ -225,6 +249,14 @@ &Change Passphrase... &Cambiar la contraseña... + + &Sending addresses... + Mandando direcciones + + + &Receiving addresses... + Recibiendo direcciones + Open &URI... Abrir y url... @@ -257,6 +289,10 @@ Open debugging and diagnostic console Abre consola de depuración y diagnóstico + + &Verify message... + Verificar mensaje.... + Bitcoin Bitcoin @@ -273,6 +309,10 @@ &Receive y recibir + + Show information about Bitcoin Core + Mostrar informacion sobre Bitcoin Core + &Show / Hide &Mostrar/Ocultar @@ -301,6 +341,18 @@ Bitcoin Core bitcoin core + + Request payments (generates QR codes and bitcoin: URIs) + Pide pagos (genera codigos QR and bitcoin: URls) + + + &About Bitcoin Core + &Sobre Bitcoin Core + + + Modify configuration options for Bitcoin Core + Modifica las opciones para BitCoin Core + %1 and %2 %1 y %2 @@ -359,6 +411,11 @@ Priority: prioridad: + + Fee: + comisión: + + Amount Cantidad @@ -367,6 +424,10 @@ Date Fecha + + Confirmations + Confirmaciones + Confirmed Confirmado @@ -387,10 +448,26 @@ Copy amount Copiar Cantidad + + Copy quantity + copiar cantidad + + + Copy fee + copiar comision + + + Copy bytes + copiar bytes + medium medio + + low + bajo + yes si @@ -468,6 +545,10 @@ version versión + + Command-line options + opciones de linea de comando + Usage: Uso: @@ -793,10 +874,23 @@ Priority: prioridad: + + Fee: + comisión: + + Transaction Fee: Comisión transacción: + + normal + normal + + + fast + rapido + Send to multiple recipients at once Enviar a múltiples destinatarios @@ -825,10 +919,22 @@ Confirm send coins Confirmar el envio de monedas + + Copy quantity + copiar cantidad + Copy amount Copiar Cantidad + + Copy fee + copiar comision + + + Copy bytes + copiar bytes + The amount to pay must be larger than 0. La cantidad por pagar tiene que ser mayor 0. @@ -1113,10 +1219,18 @@ Generated but not accepted Generado pero no acceptado + + Offline + fuera de linea + Label Etiqueta + + Unconfirmed + no confirmado + Received with Recibido con @@ -1236,6 +1350,10 @@ Show transaction details Mostrar detalles de la transacción + + Exporting Failed + Exportado fallo + Comma separated file (*.csv) Archivos separados por coma (*.csv) diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts new file mode 100644 index 000000000..ea0664636 --- /dev/null +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -0,0 +1,542 @@ + + + AddressBookPage + + Right-click to edit address or label + Click derecho para editar la dirección o etiqueta + + + Create a new address + Crear una nueva dirección + + + &New + &Nuevo + + + Copy the currently selected address to the system clipboard + Copiar la dirección actualmente seleccionada al sistema de portapapeles + + + &Copy + &Copiar + + + C&lose + C&errar + + + &Copy Address + &Copiar dirección + + + Delete the currently selected address from the list + Borrar la dirección actualmente seleccionada de la lista + + + &Export + &Exportar + + + &Delete + &Borrar + + + Choose the address to send coins to + Escoje la dirección para enviar monedas a + + + Choose the address to receive coins with + Escoje la dirección para recibir monedas con + + + C&hoose + E&scojer + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + +Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la cantidad y la dirección de recepción antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son las direcciones de Bitcoin para recibir los pagos . Se recomienda el uso de una nueva dirección de recepción para cada transacción. + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Coma(,) archivo separado (*.csv) + + + Exporting Failed + Exportación Fallida + + + There was an error trying to save the address list to %1. Please try again. + Hubo un error intentando guardar la lista de direcciones a %1 Inténtelo otravez + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (ninguna dirección) + + + + AskPassphraseDialog + + Passphrase Dialog + Diálogo de contraseña + + + Enter passphrase + Poner contraseña + + + New passphrase + Nueva contraseña + + + Repeat new passphrase + Repetir nueva contraseña + + + Encrypt wallet + Billetera Encriptada + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita tu contraseña de la billetera para desbloquear la billetera + + + Unlock wallet + Billetera Desbloqueada + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita tu contraseña de la billetera para desencriptar la billetera. + + + Decrypt wallet + Billetera Desencriptada + + + Change passphrase + Cambiar contraseña + + + Confirm wallet encryption + Confirmar encriptación de la billetera + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Precaución: Si tú has encriptado tu billetera y has perdido tu contraseña, usted <b>PERDERÁ TODOS TUS BITCOINS</b> + + + Are you sure you wish to encrypt your wallet? + Estas seguro de que deseas encriptar tu billetera? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core se cerrará ahora para finalizar el proceso de encriptación. Recuerda que encriptando tu billetera no protegera por completo tus bitcoins desde robos por malware que infectan tu computadora. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE : Cualquier copias de seguridad anteriores que han hecho de su archivo cartera debe ser reemplazado por el archivo de la carpeta recién generado , encriptado . Por razones de seguridad , las copias de seguridad anteriores del archivo cartera sin cifrar se vuelven inútiles , tan pronto como empiece a utilizar el nuevo , carpeta cifrada . + + + Warning: The Caps Lock key is on! + Ojo: El bloqueo de MAYUSCULAS esta activado! + + + Wallet encrypted + Billetera encriptada + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Poner la nueva contraseña a la billetera.<br/>Por favor usa una contraseña de <b>diez o más palabras aleatorias</b>, o <b>nueve o más letras</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Poner la antigua contraseña y nueva contraseña a la billetera. + + + Wallet encryption failed + Encriptación de la billetera fallida + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Encriptación de la billetera fallida por un error interno. Tu billetera no ha sido encriptada. + + + Wallet unlock failed + Falló el desbloqueo de la billetera + + + The passphrase entered for the wallet decryption was incorrect. + La contraseña tecleada de la desencriptación de la billetera ha sido incorrecta. + + + Wallet decryption failed + Encriptación de la billetera fallida + + + Wallet passphrase was successfully changed. + La contraseña de la billetera a sido cambiada exitosamente. + + + + BanTableModel + + + BitcoinGUI + + Synchronizing with network... + Sincronizando con la red... + + + Node + Nodo + + + Show general overview of wallet + Mostrar vista general de la billetera + + + &Transactions + &Transacciones + + + E&xit + S&alir + + + Quit application + Salir de la aplicación + + + About &Qt + Acerca de &Qt + + + Show information about Qt + Mostrar información sobre Qt + + + &Options... + &Opciones + + + &Encrypt Wallet... + &Billetera Encriptada + + + &Backup Wallet... + &Billetera Copia de seguridad... + + + &Change Passphrase... + &Cambiar contraseña... + + + &Sending addresses... + &Enviando Direcciones... + + + &Receiving addresses... + &Recibiendo Direcciones... + + + Open &URI... + Abrir &URL... + + + Bitcoin Core client + Bitcoin Core cliente + + + Importing blocks from disk... + Importando bloques desde el disco... + + + Send coins to a Bitcoin address + Enviando monedas a una dirección de Bitcoin + + + Change the passphrase used for wallet encryption + Cambiar la contraseña usando la encriptación de la billetera + + + &Debug window + &Ventana desarrollador + + + Open debugging and diagnostic console + Abrir consola de diagnóstico y desarrollo + + + &Verify message... + &Verificar Mensaje... + + + Bitcoin + Bitcoin + + + Wallet + Billetera + + + &Send + &Enviar + + + &Receive + &Recibir + + + Show information about Bitcoin Core + Mostrar información sobre Bitcoin Core + + + &Show / Hide + &Mostrar / Ocultar + + + Show or hide the main Window + Mostrar u ocultar la Ventana Principal + + + &File + &Archivo + + + &Settings + &Configuraciones + + + &Help + &Ayuda + + + Bitcoin Core + Bitcoin Core + + + Error + Error + + + + ClientModel + + + CoinControlDialog + + (no label) + (ninguna dirección) + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + + Intro + + Bitcoin Core + Bitcoin Core + + + Error + Error + + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Dirección + + + Label + Etiqueta + + + + RecentRequestsTableModel + + Label + Etiqueta + + + (no label) + (ninguna dirección) + + + + SendCoinsDialog + + (no label) + (ninguna dirección) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Etiqueta + + + + TransactionView + + Exporting Failed + Exportación Fallida + + + Comma separated file (*.csv) + Coma(,) archivo separado (*.csv) + + + Label + Etiqueta + + + Address + Dirección + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Exportar + + + + bitcoin-core + + Insufficient funds + Fondos Insuficientes + + + Loading wallet... + Cargando billetera... + + + Cannot write default address + No se puede escribir la dirección por defecto + + + Rescanning... + Reescaneando + + + Done loading + Listo Cargando + + + Error + Error + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 0463c0f6e..b4841ca9b 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -1075,10 +1075,6 @@ General General - - Using OpenSSL version - Utilizando la versión OpenSSL - Startup time Hora de inicio diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index fa2b3c062..b0dfa4ab7 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + Click derecho para editar tu dirección o etiqueta + Create a new address Crear una dirección nueva @@ -345,6 +349,10 @@ &About Bitcoin Core Acerca de Bitcoin Core + + Modify configuration options for Bitcoin Core + Modificar las opciones de configuración de Bitcoin Core + &Command-line options opciones de la &Linea de comandos @@ -353,6 +361,18 @@ Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options Mostrar mensaje de ayuda del nucleo de Bitcoin para optener una lista con los posibles comandos de Bitcoin + + Error + Error + + + Warning + Aviso + + + Information + Información + Up to date Actualizado al dia @@ -383,6 +403,10 @@ CoinControlDialog + + Quantity: + Cantidad + Bytes: Bytes: @@ -399,6 +423,14 @@ Fee: Cuota: + + After Fee: + Después de los cargos por comisión. + + + Change: + Cambio + Amount Monto @@ -427,6 +459,10 @@ Copy amount Copiar monto + + Copy transaction ID + Copiar identificación de la transacción. + Copy quantity Copiar cantidad @@ -451,11 +487,31 @@ Copy change Copiar cambio + + low + Bajo + + + none + Ninguno + + + yes + si + + + no + no + (no label) (sin etiqueta) - + + (change) + cambio + + EditAddressDialog @@ -501,6 +557,10 @@ FreespaceChecker + + name + nombre + HelpMessageDialog @@ -539,6 +599,10 @@ Bitcoin Core nucleo Bitcoin + + Error + Error + OpenURIDialog @@ -557,6 +621,10 @@ W&allet Cartera + + none + Ninguno + OverviewPage @@ -675,6 +743,10 @@ Send Coins Enviar monedas + + Quantity: + Cantidad + Bytes: Bytes: @@ -691,6 +763,14 @@ Fee: Cuota: + + After Fee: + Después de los cargos por comisión. + + + Change: + Cambio + fast rápido @@ -1062,6 +1142,10 @@ Copy amount copiar monto + + Copy transaction ID + Copiar identificación de la transacción. + Edit label Editar capa @@ -1177,6 +1261,14 @@ Wallet options: Opciones de cartera: + + Information + Información + + + Warning + Aviso + Loading addresses... Cargando direcciones... @@ -1193,5 +1285,9 @@ Done loading Carga completa - + + Error + Error + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 945e4cfa5..089f01035 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -829,10 +829,6 @@ General Üldine - - Using OpenSSL version - Kasutan OpenSSL versiooni - Startup time Käivitamise hetk diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 7ab3b77da..02c216765 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -999,10 +999,6 @@ Debug window پنجرهٔ اشکالزدایی - - Using OpenSSL version - نسخهٔ OpenSSL استفاده شده - Startup time زمان آغاز به کار diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 57987b26e..0fb6aebb9 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1473,10 +1473,6 @@ General Yleinen - - Using OpenSSL version - Käytössä oleva OpenSSL-versio - Using BerkeleyDB version Käyttää BerkeleyDB-versiota @@ -2001,6 +1997,10 @@ Custom: Muokattu: + + (Smart fee not initialized yet. This usually takes a few blocks...) + (Älykästä rahansiirtokulua ei ole vielä alustettu. Tähän kuluu yleensä aikaa muutaman lohkon verran...) + Confirmation time: Vahvistusaika: @@ -2907,10 +2907,38 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Jos <category> on toimittamatta tai jos <category> = 1, tulosta kaikki debug-tieto. + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Tarkistathan että tietokoneesi päivämäärä ja kellonaika ovat oikeassa! Jos kellosi on väärässä, Bitcoin Core ei toimi oikein. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Karsinta konfiguroitu alle minimin %d MiB. Käytä surempaa numeroa. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Karsinta: viime lompakon synkronisointi menee karsitun datan taakse. Sinun tarvitsee ajaa -reindex (lataa koko lohkoketju uudelleen tapauksessa jossa karsiva noodi) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Vähennä levytilan tarvetta karsimalla (poistamalla) vanhoja lohkoja. Tämä tila ei ole yhteensopiva -txindex ja -rescan -parametrien kanssa. Varoitus: Tämän asetuksen peruutus vaatii koko lohkoketjun uudelleenlataamisen. (oletus: 0 = poista karsinta käytöstä, >%u = kohdekoko muodossa MiB jota käytetään lohkotiedostoille) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Uudelleenskannaukset eivät ole mahdollisia karsivassa tilassa. Sinun täytyy käyttää -reindex joka lataa koko lohkoketjun uudelleen. + Error: A fatal internal error occurred, see debug.log for details Virhe: Kriittinen sisäinen virhe kohdattiin, katso debug.log lisätietoja varten + + Fee (in %s/kB) to add to transactions you send (default: %s) + Kulu (muodossa %s/kB) joka lisätään rahansiirtoihin joita lähetät (oletus: %s) + + + Pruning blockstore... + Karsitaan lohkovarastoa... + Run in the background as a daemon and accept commands Aja taustalla daemonina ja hyväksy komennot @@ -2923,6 +2951,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Hyväksy yhteyksiä ulkopuolelta (vakioasetus: 1 jos -proxy tai -connect ei määritelty) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee on asetettu erittäin suureksi! Tämä on rahansiirtokulu jonka voit maksaa kun arvioitu rahansirtokulu ei ole saatavilla. + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle. @@ -2967,6 +2999,10 @@ Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta. + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Salli vertaisten yhdistää annetusta verkkomaskista tai IP-osoitteesta. Voidaan määrittää useampia kertoja. + -maxmempool must be at least %d MB -maxmempool on oltava vähintään %d MB @@ -3087,18 +3123,22 @@ Wallet options: Lompakon valinnat: - - Warning: This version is obsolete; upgrade required! - Varoitus: Tämä versio on vanhentunut; päivittämistä vaaditaan! - You need to rebuild the database using -reindex to change -txindex Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex + + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + Salli JSON-RPC-yhteydet määritetystä lähteestä. Kelvolliset arvot <ip> ovat yksittäinen IP (esim. 1.2.3.4), verkko/verkkomaski (esim. 1.2.3.4/255.255.255.0) tai verkko/luokaton reititys (esim. 1.2.3.4/24). Tätä valintatapaa voidaan käyttää useita kertoja + Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Ei voida lukita data-hakemistoa %s. Bitcoin Core on luultavasti jo käynnissä. + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Paljasta omat IP-osoitteet (oletus: 1 kun kuunnellaan ja -externalip tai -proxy ei ole käytössä) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Aja komento kun olennainen hälytys vastaanotetaan tai nähdään todella pitkä haara (%s komennossa korvataan viestillä) @@ -3163,6 +3203,10 @@ Invalid amount for -mintxfee=<amount>: '%s' Virheellinen määrä -mintxfee=<amount>: '%s' + + Keep at most <n> unconnectable transactions in memory (default: %u) + Pidä enimmillään <n> yhdistämiskelvotonta rahansiirtoa muistissa (oletus: %u) + Node relay options: Välityssolmukohdan asetukset: @@ -3283,10 +3327,22 @@ Error loading wallet.dat: Wallet corrupted Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee on asetettu erittäin suureksi! Tämänkokoisia kuluja saatetaan maksaa yhdessä rahansiirrossa. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee on asetettu erittäin suureksi! Tämä on rahansiirtokulu, jonka maksat, mikäli lähetät rahansiirron. + Do not keep transactions in the mempool longer than <n> hours (default: %u) Älä pidä rahansiirtoja muistivarannoissa kauemmin kuin <n> tuntia (oletus: %u) + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Virhe lukiessa wallet.dat-tiedostoa! Kaikki avaimet luettiin onnistuneesti, mutta rahansiirtotiedot tai osoitekirjan sisältö saattavat olla muuttuneita tai vääriä. + How thorough the block verification of -checkblocks is (0-4, default: %u) Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) @@ -3299,6 +3355,10 @@ (default: %s) (oletus: %s) + + Always query for peer addresses via DNS lookup (default: %u) + Pyydä vertaisten osoitteita aina DNS-kyselyjen avulla (oletus: %u) + Error loading wallet.dat Virhe ladattaessa wallet.dat-tiedostoa @@ -3327,6 +3387,10 @@ Listen for connections on <port> (default: %u or testnet: %u) Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u) + + Maintain at most <n> connections to peers (default: %u) + Ylläpidä enimmillään <n> yhteyttä vertaisiin (oletus: %u) + Make the wallet broadcast transactions Aseta lompakko kuuluttamaan rahansiirtoja @@ -3339,6 +3403,10 @@ Maximum per-connection send buffer, <n>*1000 bytes (default: %u) Maksimi yhteyttä kohden käytettävä lähetyspuskurin koko, <n>*1000 tavua (oletus: %u) + + Prepend debug output with timestamp (default: %u) + Lisää debug-tietojen alkuun aikaleimat (oletus: %u) + Relay and mine data carrier transactions (default: %u) Välitä ja louhi dataa kantavia rahansiirtoja (oletus: %u) @@ -3363,6 +3431,10 @@ Specify configuration file (default: %s) Määritä asetustiedosto (oletus: %s) + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Määritä yhteyden aikakatkaisu millisekunneissa (minimi: 1, oletus: %d) + Specify pid file (default: %s) Määritä pid-tiedosto (oletus: %s) @@ -3371,6 +3443,10 @@ Spend unconfirmed change when sending transactions (default: %u) Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u) + + Threshold for disconnecting misbehaving peers (default: %u) + Aikaväli sopimattomien vertaisten yhteyksien katkaisuun (oletus: %u) + Unknown network specified in -onlynet: '%s' Tuntematon verkko -onlynet parametrina: '%s' diff --git a/src/qt/locale/bitcoin_fil.ts b/src/qt/locale/bitcoin_fil.ts new file mode 100644 index 000000000..fba823837 --- /dev/null +++ b/src/qt/locale/bitcoin_fil.ts @@ -0,0 +1,157 @@ + + + AddressBookPage + + Create a new address + Gumawa ng bagong address + + + Copy the currently selected address to the system clipboard + Kopyahin ang napiling tahanan sa clipboard + + + &Copy + Kumopya + + + C&lose + Isarado + + + &Copy Address + Tumulad ng kinatatahanan + + + Delete the currently selected address from the list + Alisin ang napiling address sa pagpipilian + + + Choose the address to send coins to + Pumili ng pagpapadalahang address + + + Choose the address to receive coins with + Piliin ang address ng nagpadala + + + C&hoose + Piliin + + + Sending addresses + Address pagpapadala + + + Receiving addresses + Address bilang pagtanggap + + + + AddressTableModel + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + + ClientModel + + + CoinControlDialog + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + RecentRequestsTableModel + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + + TransactionView + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index a0b9feb9a..65808c774 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1244,7 +1244,7 @@ Mined balance that has not yet matured - Le solde généré n'est pas encore mûr + Le solde miné n'est pas encore mûr Balances @@ -1473,10 +1473,6 @@ General Général - - Using OpenSSL version - Version d'OpenSSL utilisée - Using BerkeleyDB version Version BerkeleyDB utilisée @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepter les connexions entrantes (par défaut : 1 si aucun -proxy ou -connect ) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + La valeur -fallbackfee est très élevée ! Elle représente les frais de transaction que vous pourriez acquitter si aucune estimation de frais n'est proposée. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Un taux de frais (en %s/Ko) qui sera utilisé si l'estimation de frais ne possède pas suffisamment de données (par défaut : %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accepter les transactions relayées reçues de pairs de la liste blanche même si le nœud ne relaie pas les transactions (par défaut : %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6 @@ -3011,6 +3019,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argument non pris charge -whitelistalwaysrelay ignoré, utiliser -whitelistrelay et/ou -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) @@ -3027,6 +3039,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avertissement : le réseau ne semble pas totalement d'accord ! Quelques mineurs semblent éprouver des difficultés. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Avertissement : des versions de blocs inconnues sont minées ! Il est possible que des règles inconnues soient en vigeur + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Avertissement : nous ne semblons pas être en accord complet avec nos pairs ! Vous pourriez avoir besoin d'effectuer une mise à niveau, ou d'autres nœuds du réseau pourraient avoir besoin d'effectuer une mise à niveau. @@ -3047,6 +3063,10 @@ <category> can be: <category> peut être : + + Append comment to the user agent string + Ajouter un commentaire à la chaîne d'agent utilisateur + Block creation options: Options de création de bloc : @@ -3127,10 +3147,22 @@ Invalid -onion address: '%s' Adresse -onion invalide : « %s » + + Invalid amount for -fallbackfee=<amount>: '%s' + Montant invalide pour -fallbackfee=<amount> : « %s » + Keep the transaction memory pool below <n> megabytes (default: %u) Garder la réserve de mémoire transactionnelle sous <n> mégaoctets (par défaut : %u) + + Location of the auth cookie (default: data dir) + Emplacement du fichier témoin auth (par défaut : data dir) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Octets minimaux par sigop dans les transactions que nous relayons et minons (par défaut : %u) + Not enough file descriptors available. Pas assez de descripteurs de fichiers proposés. @@ -3139,6 +3171,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Seulement se connecter aux nœuds du réseau <net> (IPv4, IPv6 ou oignon) + + Print version and exit + Imprimer la version et quitter + Prune cannot be configured with a negative value. L'élagage ne peut pas être configuré avec une valeur négative. @@ -3195,10 +3231,6 @@ Wallet options: Options du portefeuille : - - Warning: This version is obsolete; upgrade required! - Avertissement : cette version est obsolète. Une mise à niveau est exigée ! - You need to rebuild the database using -reindex to change -txindex Vous devez reconstruire la base de données en utilisant -reindex afin de modifier -txindex @@ -3295,10 +3327,6 @@ Activating best chain... Activation de la meilleure chaîne... - - Always relay transactions received from whitelisted peers (default: %d) - Toujours relayer les transactions reçues des pairs de la liste blanche (par défaut : %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Tenter de récupérer les clefs privées d'un wallet.dat corrompu lors du démarrage @@ -3381,7 +3409,7 @@ Receive and display P2P network alerts (default: %u) - Recevoir et afficher les alertes du réseau poste à poste (%u par défaut) + Recevoir et afficher les alertes du réseau poste à poste (par défaut : %u) Reducing -maxconnections from %d to %d, because of system limitations. @@ -3463,6 +3491,10 @@ Warning Avertissement + + Warning: unknown new rules activated (versionbit %i) + Avertissement : nouvelles règles inconnues activées (bit de version %i) + Whether to operate in a blocks only mode (default: %u) Faut-il fonctionner en mode blocs seulement (par défaut : %u) diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index df6324335..9a2ac551c 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -1,27 +1,104 @@ AddressBookPage + + Right-click to edit address or label + Double cliquez afin de modifier l'adresse ou l'étiquette + Create a new address Créer une nouvelle adresse + + &New + &Nouveau + Copy the currently selected address to the system clipboard Copier l'adresse surlignée dans votre presse-papiers + + &Copy + &Copie + + + C&lose + F&ermer + + + &Copy Address + &Adresse de copie + + + Delete the currently selected address from the list + Supprimer l'adresse sélectionnée de la liste + Export the data in the current tab to a file Exporter les données de l'onglet courant vers un fichier + + &Export + &Exporter... + &Delete &Supprimer + + Choose the address to send coins to + Choisissez une adresse où envoyer les bitcoins + + + Choose the address to receive coins with + Choisissez une adresse où recevoir les bitcoins + + + C&hoose + C&oisir + + + Sending addresses + Adresses d'envoi + + + Receiving addresses + Adresses de réception + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Voici vos adresses Bitcoin qui vous permettent d'envoyer des paiements. Vérifiez toujours le montant et l'adresse de réception avant d'envoyer des pièces. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Voici vos adresses Bitcoin qui vous permettent de recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction + + + Copy &Label + Copier &Étiquette + + + &Edit + &Éditer + + + Export Address List + Exporter la liste d'adresses + Comma separated file (*.csv) Valeurs séparées par des virgules (*.csv) - + + Exporting Failed + Échec de l'export + + + There was an error trying to save the address list to %1. Please try again. + Il y a eu une erreur durant la tentative de sauvegarde de la liste d’adresse vers %1. +Réessayez. + + AddressTableModel @@ -39,6 +116,10 @@ AskPassphraseDialog + + Passphrase Dialog + Dialogue mot de passe + Enter passphrase Entrez la phrase de passe @@ -79,10 +160,30 @@ Confirm wallet encryption Confirmer le chiffrement du porte-monnaie + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Attention: Si vous cryptez votre portefeuille et que vous perdez votre mot de passe vous <b> PERDREZ TOUS VOS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Êtes-vous sûr de de vouloir crypter votre portefeuille ? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core fermera maintenant pour finir le processus de chiffrement. Rappelez-vous que crypter votre portefeuille ne protége pas totalement vos bitcoins d'être volé par un malware ayant infecté votre ordinateur. + + + Warning: The Caps Lock key is on! + Attention : La touche majuscule est enfoncé. + Wallet encrypted Porte-monnaie chiffré + + Enter the old passphrase and new passphrase to the wallet. + Entrez l'ancien mot de passe et le nouveau mot de passe pour le portefeuille + Wallet encryption failed Le chiffrement du porte-monnaie a échoué @@ -107,12 +208,28 @@ Wallet decryption failed Le décryptage du porte-monnaie a échoué - + + Wallet passphrase was successfully changed. + Le changement du mot de passe du portefeuille à été effectué avec succès. + + BanTableModel - + + IP/Netmask + IP/Masque de sous réseau + + + Banned Until + Banni jusque + + BitcoinGUI + + Sign &message... + Signer &message... + Synchronizing with network... Synchronisation avec le réseau... @@ -121,6 +238,10 @@ &Overview &Vue d'ensemble + + Node + Nœud + Show general overview of wallet Affiche une vue d'ensemble du porte-monnaie @@ -153,6 +274,46 @@ &Options... &Options... + + &Encrypt Wallet... + &Chiffrer le portefeuille + + + &Backup Wallet... + &Sauvegarder le portefeuille + + + &Change Passphrase... + &Modifier le mot de passe + + + &Sending addresses... + &Adresses d'envoi + + + &Receiving addresses... + &Adresses de réception + + + Open &URI... + Ouvrir &URI + + + Bitcoin Core client + Client Bitcoin Core + + + Importing blocks from disk... + Importer les blocs depuis le disque... + + + Reindexing blocks on disk... + Réindexer les blocs sur le disque... + + + Send coins to a Bitcoin address + Envoyer des pièces à une adresse Bitcoin + Backup wallet to another location Sauvegarder le porte-monnaie à un autre emplacement @@ -161,14 +322,54 @@ Change the passphrase used for wallet encryption Modifier la phrase de passe utilisée pour le cryptage du porte-monnaie + + &Debug window + &Fenêtre de débogage + + + Open debugging and diagnostic console + Ouvrir la console de débogage et de diagnostic + + + &Verify message... + &Vérification du message + Bitcoin Bitcoin + + Wallet + Portefeuille + &Send &Envoyer + + &Receive + &Réception + + + Show information about Bitcoin Core + Montrer les informations à propos de Bitcoin Core + + + &Show / Hide + &Montrer / Cacher + + + Show or hide the main Window + Montrer ou cacher la fenêtre principale + + + Encrypt the private keys that belong to your wallet + Crypter les clé privées qui appartiennent votre portefeuille + + + Sign messages with your Bitcoin addresses to prove you own them + Signer vos messages avec vos adresses Bitcoin pour prouver que vous les détenez + &File &Fichier @@ -185,6 +386,86 @@ Tabs toolbar Barre d'outils des onglets + + Bitcoin Core + Bitcoin Core + + + Request payments (generates QR codes and bitcoin: URIs) + Demander des paiements (générer QR codes et bitcoin: URIs) + + + &About Bitcoin Core + &À propos de Bitcoin + + + Modify configuration options for Bitcoin Core + Modifier les options de configuration de Bitcoin Core + + + Show the list of used sending addresses and labels + Montrer la liste des adresses d'envois utilisées et les étiquettes + + + Open a bitcoin: URI or payment request + Ouvrir un bitcoin: URI ou demande de paiement + + + &Command-line options + &Options de ligne de commande + + + %n active connection(s) to Bitcoin network + %n connexion active au réseau Bitcoin%n connexions actives au réseau Bitcoin + + + No block source available... + Aucun bloc source disponible + + + %n hour(s) + %n heure%n heures + + + %n day(s) + %n jour%n jours + + + %n week(s) + %n semaine%n semaines + + + %1 and %2 + %1 et %2 + + + %n year(s) + %n an%n années + + + %1 behind + en retard de %1 + + + Last received block was generated %1 ago. + Le dernier bloc reçu a été généré %1. + + + Transactions after this will not yet be visible. + Les transactions ne seront plus visible après ceci. + + + Error + Erreur + + + Warning + Attention + + + Information + Information + Up to date À jour @@ -193,6 +474,36 @@ Catching up... Rattrapage... + + Date: %1 + + Date: %1 + + + + Amount: %1 + + Montant:%1 + + + + Type: %1 + + Type: %1 + + + + Label: %1 + + Étiquette: %1 + + + + Address: %1 + + Adresse: %1 + + Sent transaction Transaction envoyée @@ -212,25 +523,89 @@ ClientModel - + + Network Alert + Alerte réseau + + CoinControlDialog + + Coin Selection + Sélection de pièce + + + Quantity: + Quantité: + + + Bytes: + Octets: + Amount: Montant : + + Priority: + Priorité: + + + Fee: + Frais: + + + Dust: + Poussière: + + + After Fee: + Après frais: + + + Change: + Change: + + + (un)select all + (dé)sélectionné tout: + + + Tree mode + Mode arbre + + + List mode + Mode list + Amount Montant + + Received with label + Reçu avec : + + + Received with address + Reçue avec l'adresse + Date Date + + Confirmations + Confirmations + Confirmed Confirmée + + Priority + Priorité + Copy address Copier l'adresse @@ -243,11 +618,131 @@ Copy amount Copier le montant + + Copy transaction ID + Copie ID transaction + + + Lock unspent + Verrouiller les non dépensés + + + Unlock unspent + Déverrouiller les non dépensés + + + Copy quantity + Copier la quantité + + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy dust + Copier la poussière + + + Copy change + Copier changement + + + highest + le plus élevé + + + higher + plus haute + + + high + haut + + + medium-high + moyen-élevé + + + medium + moyen + + + low-medium + bas-moyen + + + low + bas + + + lower + inférieur + + + lowest + le plus bas + + + (%1 locked) + (%1 verrouillé) + + + none + aucun + + + This label turns red if the transaction size is greater than 1000 bytes. + Cette étiquette devient rouge si la taille de la transaction est plus grande que 1000 octets + + + This label turns red if the priority is smaller than "medium". + Cette étiquette devient rouge si la priorité est plus petite que "moyen" + + + Can vary +/- %1 satoshi(s) per input. + Peut varier de +/- %1 satoshi(s) par entrée. + + + yes + oui + + + no + non + + + This means a fee of at least %1 per kB is required. + Cela signifie que des frais d'au moins %1 par kO sont requis. + + + Can vary +/- 1 byte per input. + Peut varier de +/- 1 octet par entrée. + (no label) (aucune étiquette) - + + change from %1 (%2) + changement de %1 (%2) + + + (change) + (changement) + + EditAddressDialog @@ -282,6 +777,10 @@ The entered address "%1" is already in the address book. L'adresse fournie « %1 » est déjà présente dans le carnet d'adresses. + + The entered address "%1" is not a valid Bitcoin address. + L'adresse entrée "%1" n'est pas une adresse Bitcoin valide. + Could not unlock wallet. Impossible de déverrouiller le porte-monnaie. @@ -293,26 +792,174 @@ FreespaceChecker - + + A new data directory will be created. + Un nouveau répertoire de données sera créé. + + + name + nom + + + Path already exists, and is not a directory. + Le chemin existe déjà et ce n'est pas un répertoire. + + + Cannot create data directory here. + Impossible de créer un répertoire ici. + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + version + version + + + (%1-bit) + (%1-bit) + + + About Bitcoin Core + À propos de Bitcoin Core + + + Command-line options + Options de ligne de commande + Usage: Utilisation : + + command-line options + Options de ligne de commande + + + UI Options: + Options interface graphique: + + + Start minimized + Démarrer sous forme minimisée + Intro - + + Welcome + Bienvenue + + + Welcome to Bitcoin Core. + Bienvenue sur Bitcoin Core. + + + Use the default data directory + Utiliser le répertoire par défaut + + + Use a custom data directory: + Utiliser votre propre répertoire + + + Bitcoin Core + Bitcoin Core + + + Error: Specified data directory "%1" cannot be created. + Erreur: Le répertoire de données "%1" n'a pas pu être créé. + + + Error + Erreur + + + %n GB of free space available + %n GO d'espace libre disponible%n GO d'espace libre disponible + + + (of %n GB needed) + (%n GB nécessaire)(%n GB nécessaire) + + OpenURIDialog - + + Open URI + Ouvrir URI + + + Open payment request from URI or file + Ouvrir une demande de paiement depuis une URI ou un fichier + + + URI: + URI: + + + Select payment request file + Sélectionner un fichier de demande de paiement + + + Select payment request file to open + Sélectionnez le fichier de demande de paiement à ouvrir + + OptionsDialog Options Options + + &Main + &Principal + + + Size of &database cache + Taille du cache de la base de données. + + + MB + MO + + + Accept connections from outside + Accepter les connexions venant de l'extérieur + + + Allow incoming connections + Autoriser les connexions entrantes + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Adresse IP du proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + + + Reset all client options to default. + Réinitialiser toutes les options du client par défaut. + + + &Reset Options + &Options de réinitialisation + + + &Network + &Réseau + + + Automatically start Bitcoin Core after logging in to the system. + Démarrer automatiquement Bitcoin Core après s'être connecté au système. + + + Expert + Expert + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Ouvrir le port du client Bitcoin automatiquement sur le routeur. Cela ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée. @@ -321,6 +968,38 @@ Map port using &UPnP Ouvrir le port avec l'&UPnP + + Proxy &IP: + Proxy &IP: + + + &Port: + &Port: + + + Port of the proxy (e.g. 9050) + Port du proxy (e.g. 9050) + + + Used for reaching peers via: + Utilisé pour contacter des pairs via: + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + &Window + &Fenêtre + &Minimize to the tray instead of the taskbar &Minimiser dans la barre système au lieu de la barre des tâches @@ -329,37 +1008,429 @@ M&inimize on close Mi&nimiser lors de la fermeture - + + &Display + &Afficher + + + User Interface &language: + Interface utilisateur &langage: + + + &OK + &OK + + + &Cancel + &Annuler + + + default + defaut + + + none + aucun + + + Confirm options reset + Confirmer les options de réinitialisation + + + Client restart required to activate changes. + Redémarrage du client nécessaire pour activer les changements. + + + This change would require a client restart. + Ce changement nécessiterait un redémarrage du client. + + + The supplied proxy address is invalid. + L'adresse du proxy est invalide. + + OverviewPage Form Formulaire + + Watch-only: + Regarder seulement: + + + Available: + Disponible: + + + Pending: + En attente: + + + Immature: + Immature: + + + Balances + Balances + + + Total: + Total: + + + Your current total balance + Votre balance totale courante + + + Spendable: + Dépensable: + + + Recent transactions + Transactions récentes + PaymentServer - + + Invalid payment address %1 + Adresse de paiement invalide %1 + + + Payment request rejected + Requête de paiement rejetée + + + Payment request is not initialized. + La demande de paiement n'a pas été initialisée. + + + Payment request error + Erreur lors de la requête de paiement + + + Payment request expired. + Demande de paiement expirée. + + + Invalid payment request. + Demande de paiement invalide. + + + Refund from %1 + Remboursement de %1 + + + Bad response from server %1 + Mauvaise réponse du serveur %1 + + + Network request error + Erreur de demande de réseau + + PeerTableModel - + + User Agent + Agent Utilisateur + + + Node/Service + Nœud/Service + + + Ping Time + Temps du ping + + QObject Amount Montant - + + Enter a Bitcoin address (e.g. %1) + Entrer une adresse Bitcoin (e.g. %1) + + + %1 d + %1 j + + + %1 h + %1 h + + + %1 m + %1 m + + + %1 s + %1 s + + + None + Aucun + + + N/A + N/A + + + %1 ms + %1 ms + + QRImageWidget - + + &Save Image... + &Sauvegarder image + + + &Copy Image + &Copier image + + + Save QR Code + Sauvegarder QR code + + + PNG Image (*.png) + Image PNG (*.png) + + RPCConsole + + Client name + Nom du client + + + N/A + N/A + + + Client version + Version du client + + + &Information + &Information + + + Debug window + Fenêtre de débogage + + + General + Général + + + Using BerkeleyDB version + Version BerkeleyDButilisée + + + Startup time + Le temps de démarrage + + + Network + Réseau + Name Nom - + + Number of connections + Nombre de connexions + + + Block chain + Chaîne de bloc + + + Current number of blocks + Nombre courant de blocs + + + Memory Pool + Mémoire du pool + + + Current number of transactions + Nombre courant de transactions + + + Memory usage + Usage de la mémoire + + + Received + Reçu + + + Sent + Envoyé + + + &Peers + &Pairs + + + Banned peers + Pairs bannis + + + Whitelisted + Autorisé par la liste + + + Direction + Direction + + + Version + Version + + + Starting Block + Bloc de départ + + + Synced Blocks + Blocs Synchronisés + + + User Agent + Agent Utilisateur + + + Services + Services + + + Ban Score + Score de ban + + + Connection Time + Temps de connexion + + + Last Send + Dernier envoyé + + + Last Receive + Dernier reçu + + + Ping Time + Temps du ping + + + Ping Wait + Attente du ping + + + &Open + &Ouvert + + + &Console + &Console + + + &Network Traffic + &Trafic réseau + + + &Clear + &Nettoyer + + + Totals + Totaux + + + In: + Entrée: + + + Out: + Sortie: + + + Build date + Date de création + + + Debug log file + Fichier du journal de débogage + + + Clear console + Nettoyer la console + + + 1 &hour + 1 &heure + + + 1 &day + 1 &jour + + + 1 &week + 1 &semaine + + + 1 &year + 1 &an + + + %1 B + %1 O + + + %1 KB + %1 KO + + + %1 MB + %1 MO + + + %1 GB + %1 GO + + + via %1 + via %1 + + + never + jamais + + + Yes + Oui + + + No + Non + + + Unknown + Inconnu + + ReceiveCoinsDialog @@ -374,10 +1445,38 @@ &Message: Message : + + Clear all fields of the form. + Nettoyer tous les champs du formulaire. + + + Clear + Nettoyer + + + Requested payments history + Historique des demandes de paiements. + + + &Request payment + &Demande de paiement + + + Show + Montrer + + + Remove + Retirer + Copy label Copier l'étiquette + + Copy message + Copier message + Copy amount Copier le montant @@ -389,6 +1488,30 @@ QR Code QR Code + + Copy &URI + Copier &URI + + + Copy &Address + Copier &Adresse + + + &Save Image... + &Sauvegarder image + + + Request payment to %1 + Demande de paiement à %1 + + + Payment information + Informations de paiement + + + URI + URI + Address Adresse @@ -428,25 +1551,113 @@ (no label) (aucune étiquette) - + + (no message) + (pas de message) + + + (no amount) + (pas de montant) + + SendCoinsDialog Send Coins Envoyer des pièces + + Inputs... + Sorties... + + + automatically selected + Automatiquement sélectionné + Insufficient funds! Fonds insuffisants + + Quantity: + Quantité: + + + Bytes: + Octets: + Amount: Montant : + + Priority: + Priorité: + + + Fee: + Frais: + + + After Fee: + Après frais: + + + Change: + Change: + + + Transaction Fee: + Frais de transaction + + + Choose... + Choisir... + + + per kilobyte + par kilo octet + + + Hide + Cacher + + + total at least + Au total au moins + + + Recommended: + Recommandé: + + + Confirmation time: + Temps de confirmation: + + + normal + normal + + + fast + rapide + Send to multiple recipients at once Envoyer des pièces à plusieurs destinataires à la fois + + Clear all fields of the form. + Nettoyer tous les champs du formulaire. + + + Dust: + Poussière: + + + Clear &All + Nettoyer &Tout + Balance: Solde : @@ -459,19 +1670,87 @@ Confirm send coins Confirmer l'envoi des pièces + + %1 to %2 + %1 à %2 + + + Copy quantity + Copier la quantité + Copy amount Copier le montant + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy change + Copier changement + + + Total Amount %1 + Montant Total %1 + + + or + ou + The amount to pay must be larger than 0. Le montant à payer doit être supérieur à 0. + + The amount exceeds your balance. + Le montant excède votre balance. + + + Transaction creation failed! + Échec de la création de la transaction + + + Payment request expired. + Demande de paiement expirée. + + + Pay only the required fee of %1 + Payer seulement les frais obligatoire de %1 + + + Warning: Invalid Bitcoin address + Attention: Adresse Bitcoin Invalide + (no label) (aucune étiquette) - + + Copy dust + Copier la poussière + + + Are you sure you want to send? + Êtes-vous sûr de vouloir envoyer ? + + + added as transaction fee + Ajoute en tant que frais de transaction + + SendCoinsEntry @@ -490,6 +1769,14 @@ &Label: &Étiquette : + + Choose previously used address + Choisir une adresse précédemment utilisée + + + This is a normal payment. + C'est un paiement normal. + Alt+A Alt+A @@ -502,6 +1789,10 @@ Alt+P Alt+P + + Remove this entry + Retirer cette entrée + Message: Message : @@ -510,7 +1801,11 @@ Pay To: Payer à : - + + Memo: + Memo: + + ShutdownWindow @@ -520,6 +1815,10 @@ &Sign Message &Signer le message + + Choose previously used address + Choisir une adresse précédemment utilisée + Alt+A Alt+A @@ -536,13 +1835,65 @@ Enter the message you want to sign here Entrez ici le message que vous désirez signer + + Signature + Signature + + + Copy the current signature to the system clipboard + Copier l'adresse courante dans le presse papier + Sign &Message &Signer le message - + + Clear &All + Nettoyer &Tout + + + &Verify Message + &Vérifier message + + + Verify &Message + Vérifier &Message + + + The entered address is invalid. + L'adresse entrée est invalide. + + + Please check the address and try again. + Vérifiez l'adresse et réessayer. + + + Message signed. + Message signé. + + + Please check the signature and try again. + Vérifiez la signature et réessayer. + + + Message verification failed. + Vérification du message échouée. + + + Message verified. + Message vérifié. + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + The Bitcoin Core developers + Les développeurs de Bitcoin Core + [testnet] [testnet] @@ -550,7 +1901,11 @@ TrafficGraphWidget - + + KB/s + KO/s + + TransactionDesc @@ -573,30 +1928,110 @@ Date Date + + Source + Source + Generated Généré + + From + De + + + To + Á + + + own address + Votre adresse + + + watch-only + Lecture uniquement + + + label + Étiquette + Credit Crédit + + not accepted + Pas accepté + Debit Débit + + Total debit + Débit total + + + Total credit + Crédit total + + + Transaction fee + Frais de transaction + + + Net amount + Montant net + Message Message + + Comment + Commentaire + + + Transaction ID + ID de transaction + + + Merchant + Marchant + + + Debug information + Information de débogage + + + Transaction + Transaction + + + Inputs + Entrées + Amount Montant + + true + vrai + + + false + faux + , has not been successfully broadcast yet , n'a pas encore été diffusée avec succès + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + unknown inconnue @@ -623,6 +2058,10 @@ Type Type + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + Open until %1 Ouvert jusqu'à %1 @@ -639,10 +2078,18 @@ Generated but not accepted Généré mais pas accepté + + Offline + Hors ligne + Label Étiquette + + Unconfirmed + Non Confirmé + Received with Reçues avec @@ -663,6 +2110,10 @@ Mined Extraction + + watch-only + Lecture uniquement + (n/a) (indisponible) @@ -754,10 +2205,30 @@ Copy amount Copier le montant + + Copy transaction ID + Copie ID transaction + Edit label Éditer l'étiquette + + Show transaction details + Afficher les détails de la transaction + + + Export Transaction History + Exporter l'historique des transactions + + + Exporting Failed + Échec de l'export + + + Exporting Successful + Export réalisé avec sucés + Comma separated file (*.csv) Valeurs séparées par des virgules (*.csv) @@ -800,7 +2271,11 @@ WalletFrame - + + No wallet has been loaded. + Aucun portefeuille a été chargé. + + WalletModel @@ -810,6 +2285,10 @@ WalletView + + &Export + &Exporter... + Export the data in the current tab to a file Exporter les données de l'onglet courant vers un fichier @@ -826,7 +2305,11 @@ Backup Failed La sauvegarde a échoué - + + Backup Successful + Sauvegarde réussie + + bitcoin-core @@ -837,6 +2320,10 @@ Specify data directory Spécifier le répertoire de données + + Specify your own public address + Spécifier votre adresse publique + Accept command line and JSON-RPC commands Accepter les commandes de JSON-RPC et de la ligne de commande @@ -845,14 +2332,95 @@ Run in the background as a daemon and accept commands Fonctionner en arrière-plan en tant que démon et accepter les commandes + + <category> can be: + <category> peut être: + + + Block creation options: + Options de création de bloc: + + + Connection options: + Options de connexion: + + + Debugging/Testing options: + Options de débogage/test + + + Importing... + +Importation ... + + + Verifying blocks... + Vérifications des blocs... + + + Verifying wallet... + Vérification du portefeuille... + + + Wallet options: + Options du portefeuille: + + + (default: %u) + (défaut: %u) + + + Connect through SOCKS5 proxy + Connecté au travers du proxy SOCKS5 + + + Information + Information + + + Node relay options: + Options du relais de nœud: + + + RPC server options: + Options de serveur RPC: + Send trace/debug info to console instead of debug.log file Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log + + Signing transaction failed + Transaction signée échouée + + + This is experimental software. + C'est un logiciel expérimental. + + + Transaction amount too small + Montant de la transaction trop bas + + + Transaction amounts must be positive + Les montants de la transaction doivent être positif + + + Transaction too large for fee policy + Montant de la transaction trop élevé pour la politique de frais + + + Transaction too large + Transaction trop grande + Username for JSON-RPC connections Nom d'utilisateur pour les connexions JSON-RPC + + Warning + Attention + Password for JSON-RPC connections Mot de passe pour les connexions JSON-RPC @@ -869,10 +2437,26 @@ Error loading wallet.dat: Wallet corrupted Erreur lors du chargement de wallet.dat : porte-monnaie corrompu + + (default: %s) + (défaut: %s) + Error loading wallet.dat Erreur lors du chargement de wallet.dat + + Generate coins (default: %u) + Générer des pièces (défaut: %u) + + + Invalid -proxy address: '%s' + Adresse -proxy invalide: '%s' + + + Specify pid file (default: %s) + Spécifier le pid du fichier (défaut: %s) + Insufficient funds Fonds insuffisants @@ -885,6 +2469,14 @@ Loading wallet... Chargement du porte-monnaie... + + Cannot downgrade wallet + Vous ne pouvez pas rétrograder votre portefeuille + + + Cannot write default address + Impossible d'écrire l'adresse par défaut + Rescanning... Nouvelle analyse... @@ -893,5 +2485,9 @@ Done loading Chargement terminé - + + Error + Erreur + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 96d4adeba..50b081d20 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -983,10 +983,6 @@ Debug window Ventana de Depuración - - Using OpenSSL version - Usar versión OpenSSL - Startup time Tempo de arranque diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 926d20620..d937e211b 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + לחץ משק ימני כדי לערוך כתובת או חברה + Create a new address יצירת כתובת חדשה @@ -163,6 +167,10 @@ Are you sure you wish to encrypt your wallet? האם אכן להצפין את הארנק? + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + ליבת ביטקוין תיסגר עכשיו כדי לסיים את תליך ההצפנה. זכור כי הצפנה אינה יכולה להגן עלייך באופן מלא מגניבה שמקורה בתוכנות זדוניות המצויות במחשב שלך. + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. לתשומת לבך: כל גיבוי קודם שביצעת לארנק שלך יש להחליף בקובץ הארנק המוצפן שזה עתה נוצר. מטעמי אבטחה, גיבויים קודמים של קובץ הארנק הבלתי-מוצפן יהפכו לחסרי תועלת עם התחלת השימוש בארנק החדש המוצפן. @@ -179,6 +187,10 @@ Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. נא להזין את מילת הצופן החדשה לארנק.<br/>כדאי להשתמש במילת צופן המורכבת מ<b>עשרה תווים אקראיים ומעלה</b>, או <b>שמונה מילים ומעלה</b>. + + Enter the old passphrase and new passphrase to the wallet. + הכנס את מילת הצופן הישנה ומילת צופן חדשה לארנק שלך. + Wallet encryption failed הצפנת הארנק נכשלה @@ -1259,10 +1271,6 @@ General כללי - - Using OpenSSL version - שימוש ב־OpenSSL גרסה - Using BerkeleyDB version שימוש ב־BerkeleyDB גרסה diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index 413dc2185..f9d744aa3 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -1017,10 +1017,6 @@ Debug window Konzola za dijagnostiku - - Using OpenSSL version - OpenSSL verzija u upotrebi - Network Mreža diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index ab4517ccf..839ee883b 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -963,6 +963,10 @@ The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. Itt beállíthatod a kezelőfelület nyelvét. A beállítás a Bitcoin újraindítása után lép érvénybe. + + Third party transaction URLs + Harmadik fél tranzakció URL-ek + Reset all client options to default. Minden kliensbeállítás alapértelmezettre állítása. @@ -1257,10 +1261,6 @@ General Általános - - Using OpenSSL version - Használt OpenSSL verzió - Using BerkeleyDB version Használt BerkeleyDB verzió diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 1b626fbf2..e1ec7ae7f 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -59,19 +59,19 @@ Sending addresses - Alamat-alamat mengirim + Alamat pengirim Receiving addresses - Alamat-alamat menerima + Alamat penerima These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Alamat-alamat Anda supaya mengirim pembayaran. Periksalah jumlah dan alamat penerima setiap kali Anda mengirim Bitcoin. + Alamat-alamat Anda untuk mengirim pembayaran. Periksalah jumlah dan alamat penerima setiap kali Anda mengirim Bitcoin. These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Alamat-alamat Anda supaya menerima pembayaran. Dianjurkan agar Anda menggunakan alamat menerima yang baru untuk setiap transaksi. + Alamat-alamat Anda untuk menerima pembayaran. Dianjurkan agar Anda menggunakan alamat yang baru untuk setiap transaksi. Copy &Label @@ -93,7 +93,11 @@ Exporting Failed Proses Ekspor Gagal - + + There was an error trying to save the address list to %1. Please try again. + Terjadi kesalahan saat menyimpan daftar alamat ke %1. Silakan coba lagi. + + AddressTableModel @@ -133,7 +137,7 @@ This operation needs your wallet passphrase to unlock the wallet. - Operasi ini memerlukan kata kunci dompet Anda untuk membuka dompet ini. + Operasi ini memerlukan kata kunci dompet Anda untuk membuka dompet. Unlock wallet @@ -141,7 +145,7 @@ This operation needs your wallet passphrase to decrypt the wallet. - Operasi ini memerlukan kata kunci dompet Anda untuk mendekripsi dompet ini. + Operasi ini memerlukan kata kunci dompet Anda untuk mendekripsi dompet. Decrypt wallet @@ -157,11 +161,19 @@ Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Perhatian: Jika anda mengenkripsi dompet anda dan lupa kata kuncinya, anda pasti <b>KEHILANGAN SELURUH BITCOIN ANDA</B>! + Perhatian: Jika anda mengenkripsi dompet anda dan lupa kata kuncinya, anda akan <b>KEHILANGAN SELURUH BITCOIN ANDA</b>! Are you sure you wish to encrypt your wallet? - Apakah kamu yakin ingin mengenkripsi dompet anda? + Apakah Anda yakin ingin mengenkripsi dompet Anda? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core akan ditutup untuk menyelesaikan proses enkripsi. Mohon diingat bahwa mengenkripsi dompet Anda tidak akan sepenuhnya melindungi bitcoin Anda dari virus atau malware yang menginfeksi komputer Anda. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + PENTING: Setiap back up yang sudah Anda buat sebaiknya diganti dengan data dompet Anda yang baru dan terenkripsi. Untuk alasan keamanan, data back up tidak terenkripsi yang sudah Anda buat sebelumnya tidak akan dapat digunakan setelah Anda mulai menggunakan dompet yang baru dan terenkripsi. Warning: The Caps Lock key is on! @@ -171,6 +183,14 @@ Wallet encrypted Dompet terenkripsi + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Masukkan kata kunci untuk dompet Anda.<br/>Mohon gunakan kata kunci <b>yang terdiri dari 10 karakter acak</b>, atau <b>delapan atau beberapa kata lagi</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Masukkan kata kunci lama dan kata kunci baru dompet Anda. + Wallet encryption failed Enkripsi dompet gagal @@ -197,12 +217,20 @@ Wallet passphrase was successfully changed. - Kata kunci untuk dompet berubah berhasil. + Kata kunci dompet Anda berhasil diubah. BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Di banned sampai + + BitcoinGUI @@ -223,7 +251,7 @@ Show general overview of wallet - Tampilkan kilasan umum dari dompet + Tampilkan gambaran umum dompet Anda &Transactions @@ -231,7 +259,7 @@ Browse transaction history - Jelajah sejarah transaksi + Lihat riwayat transaksi E&xit @@ -267,11 +295,11 @@ &Sending addresses... - Alamat-alamat &Mengirim + &Alamat-alamat untuk mengirim... &Receiving addresses... - Alamat-alamat &Menerima + &Alamat-alamat untuk menerima... Open &URI... @@ -279,15 +307,15 @@ Bitcoin Core client - Client Bitcoin Inti + Klien Bitcoin Core Importing blocks from disk... - Blok-blok sedang di-impor dari disk + Mengimpor blok dari disk... Reindexing blocks on disk... - Mengindex ulang block di harddisk... + Mengindex ulang blok di dalam disk... Send coins to a Bitcoin address @@ -331,11 +359,11 @@ Show information about Bitcoin Core - Tampilkan informasi tentang Bitcoin Inti + Tampilkan informasi tentang Bitcoin Core &Show / Hide - &Sunjukkan / Menyembungi + &Tampilkan / Sembunyikan Show or hide the main Window @@ -343,15 +371,15 @@ Encrypt the private keys that belong to your wallet - Mengenkripsi kunci-kunci pribadi yang dipunyai dompetmu + Enkripsi private key yang dimiliki dompet Anda Sign messages with your Bitcoin addresses to prove you own them - Tandalah pesanan dengan alamat-alamat Bitcoin Anda supaya membuktikan pesanan itu dikirim oleh Anda + Tanda tangani sebuah pesan menggunakan alamat Bitcoin Anda untuk membuktikan bahwa Anda adalah pemilik alamat tersebut Verify messages to ensure they were signed with specified Bitcoin addresses - Periksakan pesan-pesan supaya menjaminkan ditandatangani oleh alamat Bitcoin yang terperinci + Verifikasi pesan untuk memastikan bahwa pesan tersebut ditanda tangani oleh suatu alamat Bitcoin tertentu &File @@ -375,12 +403,16 @@ Request payments (generates QR codes and bitcoin: URIs) - Permintaan pembayaran (membangkitkan kode QR dan bitcoin: URIs) + Permintaan pembayaran (membuat kode QR dan bitcoin: URIs) &About Bitcoin Core &Mengenai Bitcoin Core + + Modify configuration options for Bitcoin Core + Modifikasi pengaturan konfigurasi untuk Bitcoin Core + Show the list of used sending addresses and labels Tampilkan daftar alamat dan label yang terkirim @@ -395,20 +427,24 @@ &Command-line options - &pilihan Perintah-baris + &pilihan Command-line Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Tampilkan pesan bantuan Bitcoin Core untuk memberikan daftar pilihan perintah-baris yang memungkinkan dalam aplikasi Bitcoin + Tampilkan pesan bantuan Bitcoin Core untuk mendapatkan daftar pilihan Command-line %n active connection(s) to Bitcoin network - %n hubungan aktif ke jaringan Bitcoin + %n koneksi aktif ke jaringan Bitcoin No block source available... Sumber blok tidak tersedia... + + Processed %n block(s) of transaction history. + %n blok dari riwayat transaksi diproses. + %n hour(s) %n jam @@ -435,15 +471,15 @@ Last received block was generated %1 ago. - Blok terakhir dibuat %1 lalu. + Blok terakhir yang diterima %1 lalu. Transactions after this will not yet be visible. - Transaksi setelah ini tidak akan ditampilkan + Transaksi setelah ini belum akan terlihat. Error - Gagal + Terjadi sebuah kesalahan Warning @@ -531,7 +567,7 @@ Amount: - Nilai: + Jumlah: Priority: @@ -541,13 +577,17 @@ Fee: Biaya: + + Dust: + Dust: + After Fee: Dengan Biaya: Change: - Uang Kembali: + Kembalian: (un)select all @@ -555,7 +595,7 @@ Tree mode - mode pohon + Tree mode List mode @@ -563,7 +603,15 @@ Amount - Nilai + Jumlah + + + Received with label + Diterima dengan label + + + Received with address + Diterima dengan alamat Date @@ -571,7 +619,7 @@ Confirmations - Konfirmasi-konfirmasi + Konfirmasi Confirmed @@ -591,19 +639,19 @@ Copy amount - Salin nilai + Salin jumlah Copy transaction ID - Menyalinkan ID transaksi + Salin ID transaksi Lock unspent - Kunci terpakai. + Kunci unspent. Unlock unspent - Membuka kunci terpakai + Buka unspent Copy quantity @@ -625,9 +673,13 @@ Copy priority Salin prioritas + + Copy dust + Salin dust + Copy change - Salin uang kembali + Salin kembalian highest @@ -673,6 +725,22 @@ none tidak satupun + + This label turns red if the transaction size is greater than 1000 bytes. + Label ini akan menjadi merah apabila ukuran transaksi melebihi 1000 bytes. + + + This label turns red if the priority is smaller than "medium". + Label ini akan menjadi merah apabila prioritasnya lebih kecil dari "sedang" + + + This label turns red if any recipient receives an amount smaller than %1. + Label ini akan menjadi merah apabila penerima menerima jumlah yang lebih kecil dari %1. + + + Can vary +/- %1 satoshi(s) per input. + Dapat beragam +/- %1 satoshi per input. + yes ya @@ -683,15 +751,15 @@ This means a fee of at least %1 per kB is required. - Berarti perlu biaya lebih dari %1 untuk setiap kB. + Perlu biaya lebih dari %1 untuk setiap kB. Can vary +/- 1 byte per input. - Boleh berbeda +/- 1 byte setiap masukan. + Dapat beragam +/- 1 byte per input. Transactions with higher priority are more likely to get included into a block. - Makin penting transaksinya, makin kemungkinan akan termasuk dalam blok. + Transaksi dengan prioritas lebih tinggi akan lebih cepat dimasukkan kedalam blok. (no label) @@ -699,11 +767,11 @@ change from %1 (%2) - uang kembali dari %1 (%2) + kembalian dari %1 (%2) (change) - (uang kembali) + (kembalian) @@ -718,11 +786,11 @@ The label associated with this address list entry - Label yang terkait dengan daftar alamat yang dimasukkan ini + Label yang terkait dengan daftar alamat The address associated with this address list entry. This can only be modified for sending addresses. - Alamat yang terkait dengan entri buku alamat ini. Hanya dapat diubah untuk alamat pengirim. + Alamat yang terkait dengan daftar alamat. Hanya dapat diubah untuk alamat pengirim. &Address @@ -773,15 +841,15 @@ Directory already exists. Add %1 if you intend to create a new directory here. - Direktori masih ada. Tambahlah %1 kalau ingin membuat direktori baru disini. + Direktori masih ada. Tambahlah %1 apabila Anda ingin membuat direktori baru disini. Path already exists, and is not a directory. - Masih ada Path, dan path itu bukan direktori. + Sudah ada path, dan itu bukan direktori. Cannot create data directory here. - Tidak busa membuat direktori untuk data disini. + Tidak bisa membuat direktori data disini. @@ -794,13 +862,17 @@ version versi + + (%1-bit) + (%1-bit) + About Bitcoin Core Mengenai Bitcoin Core Command-line options - pilihan Perintah-baris + Pilihan Command-line Usage: @@ -808,9 +880,37 @@ command-line options - pilihan perintah-baris + pilihan command-line - + + UI Options: + Pilihan UI: + + + Choose data directory on startup (default: %u) + Pilih direktori data saat memulai (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Pilih bahasa, contoh "id_ID" (default: system locale) + + + Start minimized + Start minimized + + + Set SSL root certificates for payment request (default: -system-) + Pilih sertifikat root SSL untuk permintaan pembayaran {default: -system-) + + + Show splash screen on startup (default: %u) + Tampilkan layar kilat saat memulai (default: %u) + + + Reset all settings changes made over the GUI + Reset semua pengaturan yang dibuat dari GUI + + Intro @@ -821,27 +921,43 @@ Welcome to Bitcoin Core. Selamat Datang ke Bitcoin Core + + As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + Ini adalah pertama kali program ini dijalankan, Anda dapat memilih dimana Bitcoin Core menyimpan data. + + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Bitcoin Core akan mengunduh dan menyimpan salinan dari block chain Bitcoin. Setidaknya %1GB data akan disimpan di direktori ini, dan akan terus bertambah. Dompet Anda juga akan disimpan di direktori ini. + Use the default data directory - Menggunakan direktori untuk data yang biasa. + Gunakan direktori data default. Use a custom data directory: - Menggunakan direktori data yang dipilih Anda: + Gunakan direktori pilihan Anda: Bitcoin Core Bitcoin Core + + Error: Specified data directory "%1" cannot be created. + Kesalahan: Direktori data "%1" tidak dapat dibuat. + Error - Gagal + Kesalahan %n GB of free space available - %n GB dari ruang yang tersedia + %n GB ruang kosong tersedia. - + + (of %n GB needed) + (dari %n GB yang dibutuhkan) + + OpenURIDialog @@ -850,7 +966,7 @@ Open payment request from URI or file - Buka permintaan pembayaran dari URI atau arsip + Buka permintaan pembayaran dari URI atau data URI: @@ -858,11 +974,11 @@ Select payment request file - Pilihlah arsip permintaan pembayaran + Pilih data permintaan pembayaran Select payment request file to open - Pilihlah arsip permintaan pembayaran yang Anda ingin membuka + Pilih data permintaan pembayaran yang akan dibuka @@ -875,25 +991,53 @@ &Main &Utama + + Size of &database cache + Ukuran cache &database + MB MB + + Number of script &verification threads + Jumlah script &verification threads + + + Accept connections from outside + Terima koneksi dari luar + + + Allow incoming connections + Perbolehkan koneksi masuk + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) Alamat IP proxy (cth. IPv4: 127.0.0.1 / IPv6: ::1) + + 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. + Minimalisasi aplikasi ketika jendela ditutup. Ketika pilihan ini dipilih, aplikasi akan menutup seluruhnya jika anda memilih Keluar di menu yang tersedia. + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + Bahasa interface pengguna bisa diubah disini. Pengaturan ini akan memberikan efek setelah Bitcoin Core di-restart. + + + 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 |. + URL pihak ketika (misalnya sebuah block explorer) yang mumcul dalam tab transaksi sebagai konteks menu. %s dalam URL diganti dengan kode transaksi. URL dipisahkan dengan tanda vertikal |. + Third party transaction URLs - Transaksi URLs pihak ketiga + URL transaksi pihak ketiga Active command-line options that override above options: - pilihan perintah-baris aktif menimpa atas pilihan-pilihan: + Pilihan command-line yang aktif menimpa diatas opsi: Reset all client options to default. - Reset setiap pilihan untuk pilihan biasa + Kembalikan semua pengaturan ke awal. &Reset Options @@ -903,6 +1047,18 @@ &Network &Jaringan + + Automatically start Bitcoin Core after logging in to the system. + Buka Bitcoin Core secara otomatis setelah Anda log-in ke sistem Anda. + + + &Start Bitcoin Core on system login + &Mulai Bitcoin Core saat log-in sistem + + + (0 = auto, <0 = leave that many cores free) + (0 = auto, <0 = leave that many cores free) + W&allet D&ompet @@ -913,7 +1069,7 @@ Enable coin &control features - Nyalain cara &pengaturan koin + Perbolehkan fitur &pengaturan koin 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. @@ -931,6 +1087,10 @@ Map port using &UPnP Petakan port dengan &UPnP + + Connect to the Bitcoin network through a SOCKS5 proxy. + Hubungkan ke jaringan Bitcoin melalui SOCKS5 proxy. + Proxy &IP: IP Proxy: @@ -1197,10 +1357,6 @@ General Umum - - Using OpenSSL version - Menggunakan versi OpenSSL - Startup time Waktu nyala @@ -1595,6 +1751,10 @@ Clear all fields of the form. Hapus informasi dari form. + + Dust: + Dust: + Clear &All Hapus &Semua @@ -1691,6 +1851,10 @@ (no label) (tidak ada label) + + Copy dust + Salin dust + Are you sure you want to send? Apakah Anda yakin ingin kirim? diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index d510b1063..2f14c4201 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -949,6 +949,10 @@ Error Errore + + %n GB of free space available + GB di spazio libero disponibile%n GB di spazio disponibile + (of %n GB needed) (di %nGB richiesti)(%n GB richiesti) @@ -1470,10 +1474,6 @@ Per specificare più URL separarli con una barra verticale "|". General Generale - - Using OpenSSL version - Versione OpenSSL in uso - Using BerkeleyDB version Versione BerkeleyDB in uso @@ -2850,7 +2850,7 @@ Per specificare più URL separarli con una barra verticale "|". UnitDisplayStatusBarControl Unit to show amounts in. Click to select another unit. - Unità con cui visualizzare gli importi. Clicca per selezionare un altra unità. + Unità con cui visualizzare gli importi. Clicca per selezionare un'altra unità. @@ -3192,10 +3192,6 @@ Per specificare più URL separarli con una barra verticale "|". Wallet options: Opzioni portamonete: - - Warning: This version is obsolete; upgrade required! - Attenzione: questa versione è obsoleta. Aggiornamento necessario! - You need to rebuild the database using -reindex to change -txindex È necessario ricostruire il database usando -reindex per cambiare -txindex @@ -3292,10 +3288,6 @@ Per specificare più URL separarli con una barra verticale "|". Activating best chain... Attivazione della blockchain migliore... - - Always relay transactions received from whitelisted peers (default: %d) - Trasmetti sempre le transazioni ricevute da peers whitelisted (default: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Prova a recuperare le chiavi private da un wallet corrotto all'avvio diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts new file mode 100644 index 000000000..46ad0e933 --- /dev/null +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -0,0 +1,325 @@ + + + AddressBookPage + + Right-click to edit address or label + Click destro per modificare indirizzo o etichetta + + + Create a new address + Crea un nuovo indirizzo + + + &New + nuovo + + + Copy the currently selected address to the system clipboard + copia l'indirizzo selezionato correntemente nella clipboard di sistema + + + &Copy + copia + + + C&lose + chiudi + + + &Copy Address + copia indirizzo + + + Delete the currently selected address from the list + Cancella l'indirizzo attualmente selezionato dalla lista. + + + Export the data in the current tab to a file + Esportare i dati nella scheda corrente in un file + + + &Export + Esporta + + + &Delete + Cancella + + + Choose the address to send coins to + Scegli l'indirizzo a cui inviare denaro + + + Choose the address to receive coins with + Scegli l'indirizzo con cui ricevere i coin + + + C&hoose + Scegli + + + Sending addresses + Indirizzi mittenti + + + Receiving addresses + Indirizzi destinatari + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Questi sono gli indirizzi Bitcoin per l'invio di pagamenti. Controlla sempre la quantità e l'indirizzo di ricezione prima di inviare monete. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Questi sono i tuoi indirizzi Bitcoin per ricevere pagamenti. Si raccomanda di generare un nuovo indirizzo per ogni transazione + + + Copy &Label + copia etichetta + + + &Edit + Modifica + + + Export Address List + Esporta lista degli indirizzi + + + Comma separated file (*.csv) + Contenuto del file separato da virgole (*.csv) + + + Exporting Failed + Esportazione fallita + + + + AddressTableModel + + Label + Etichetta + + + Address + Indirizzo + + + (no label) + (nessuna etichetta) + + + + + AskPassphraseDialog + + Enter passphrase + Invia passphrase + + + New passphrase + Nuova passphrase + + + Repeat new passphrase + Ripeti nuova passphrase + + + Encrypt wallet + Cifra portagoflio + + + This operation needs your wallet passphrase to unlock the wallet. + Questa operazione richiede la passphrase del tuo portafoglio per sbloccare il portafoglio. + + + Unlock wallet + Sblocca portafoglio + + + Decrypt wallet + decifra portafoglio + + + Change passphrase + cambia passphrase + + + Confirm wallet encryption + conferma cifrazione del portagoglio + + + Wallet encrypted + portafoglio cifrato + + + Wallet unlock failed + sblocco portafoglio fallito + + + + BanTableModel + + Banned Until + bannato fino + + + + BitcoinGUI + + &Transactions + Transazioni + + + + ClientModel + + + CoinControlDialog + + (no label) + (nessuna etichetta) + + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Indirizzo + + + Label + Etichetta + + + + RecentRequestsTableModel + + Label + Etichetta + + + (no label) + (nessuna etichetta) + + + + + SendCoinsDialog + + (no label) + (nessuna etichetta) + + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Etichetta + + + + TransactionView + + Exporting Failed + Esportazione fallita + + + Comma separated file (*.csv) + Contenuto del file separato da virgole (*.csv) + + + Label + Etichetta + + + Address + Indirizzo + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + Esporta + + + Export the data in the current tab to a file + Esportare i dati nella scheda corrente in un file + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 4344fd043..06fd27fa1 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1473,10 +1473,6 @@ General 一般 - - Using OpenSSL version - 使用中の OpenSSL のバージョン - Using BerkeleyDB version 使用中のBerkleyDBバージョン @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 外部からの接続を許可 (初期値: -proxy または -connect を使用していない場合は1) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee が高すぎます!これは手数料の推定機能が利用できない場合に支払うトランザクション手数料です。 + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + 十分なデータが蓄積されていない場合に手数料推定機能が利用する手数料レート (%s/kB) (デフォルト: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + トランザクションの中継を行っていない場合でも、ホワイトリストのピアから受け取った中継トランザクションは受け取るようにする (デフォルト: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 指定のアドレスへバインドし、その上で常にリスンします。IPv6 は [ホスト名]:ポート番号 と表記します @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) スクリプト検証スレッドを設定 (%uから%dの間, 0 = 自動, <0 = たくさんのコアを自由にしておく, 初期値: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + サポートされていない引数 -whitelistalwaysrelay は無視されました。-whitelistrelay または -whitelistforcerelay を利用してください + Use UPnP to map the listening port (default: 1 when listening and no -proxy) リスン ポートの割当に UPnP を使用 (初期値: リスン中および-proxyが指定されていない場合は1) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告: ネットワークは完全に同意しないみたいです。マイナーは何かの問題を経験してるみたいなんです。 + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 未知のバージョンのブロックが採掘されました。未知のルールが導入された可能性があります + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 警告: ピアーと完全に同意しないみたいです!アップグレードは必要かもしれません、それとも他のノードはアップグレードは必要かもしれません。 @@ -3047,6 +3067,10 @@ <category> can be: <category>は以下の値を指定できます: + + Append comment to the user agent string + ユーザエージェント文字列にコメントを + Block creation options: ブロック作成オプション: @@ -3092,6 +3116,10 @@ Enable publish raw transaction in <address> <address> に対し、生トランザクションの公開を有効にする + + Enable transaction replacement in the memory pool (default: %u) + メモリプール内のトランザクションの置換を有効化する (デフォルト: %u) + Error initializing block database ブロック データベースの初期化中にエラー @@ -3128,10 +3156,22 @@ Invalid -onion address: '%s' 無効な -onion アドレス:'%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + 不正な額 -fallbackfee=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) トランザクションのメモリ・プールの総量を <n> メガバイト以下に維持する (初期値: %u) + + Location of the auth cookie (default: data dir) + 認証クッキーの場所 (デフォルト: ) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + 中継や採掘を行ってもよい、sigopあたりの最小バイト数 (デフォルト: %u) + Not enough file descriptors available. 使用可能なファイルディスクリプタが不足しています。 @@ -3140,6 +3180,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) <net> (ipv4, ipv6 または onion) ネットワーク内のノードだけに接続する + + Print version and exit + バージョンを表示し終了 + Prune cannot be configured with a negative value. 剪定値は負の値に設定できません。 @@ -3196,10 +3240,6 @@ Wallet options: ウォレットオプション: - - Warning: This version is obsolete; upgrade required! - 警告: このバージョンはサポートされません。アップグレードが必要です! - You need to rebuild the database using -reindex to change -txindex -txindex を変更するには -reindex を使用してデータベースを再構築する必要があります @@ -3296,10 +3336,6 @@ Activating best chain... 最優良のチェインを有効化しています... - - Always relay transactions received from whitelisted peers (default: %d) - ホワイトリストにあるピアから受け取ったトランザクションを常にリレーする (初期値: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup 起動時に壊れた wallet.dat から秘密鍵を復旧することを試す @@ -3464,6 +3500,10 @@ Warning 警告 + + Warning: unknown new rules activated (versionbit %i) + 警告: 未知の新しいルールが有効化されました (バージョンビット %i) + Whether to operate in a blocks only mode (default: %u) ブロック限定モードにおいて動作を行うかどうか (初期値: %u) diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 11c73ec76..1a072d1df 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -1111,10 +1111,6 @@ General საერთო - - Using OpenSSL version - OpenSSL-ის ვერსია - Startup time სტარტის დრო diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index ce48ce249..34aeafcd5 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -11,7 +11,7 @@ &New - 새 항목(N) + 새 항목(&N) Copy the currently selected address to the system clipboard @@ -19,11 +19,11 @@ &Copy - 복사 + 복사(&C) C&lose - 닫기 (L) + 닫기(&L) &Copy Address @@ -39,11 +39,11 @@ &Export - &내보내기 + 내보내기(&E) &Delete - &삭제 + 삭제(&D) Choose the address to send coins to @@ -55,7 +55,7 @@ C&hoose - 선택하기 (H) + 선택하기(&H) Sending addresses @@ -67,7 +67,7 @@ These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 비트코인을 받는 계좌 주소입니다. 코인을 보내기 전에 잔고와 받는 주소를 항상 확인하세요. + 비트코인을 보내는 계좌 주소입니다. 코인을 보내기 전에 잔고와 받는 주소를 항상 확인하세요. These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. @@ -75,11 +75,11 @@ Copy &Label - 라벨 복사 + 라벨 복사(&L) &Edit - 편집& + 편집(&E) Export Address List @@ -167,6 +167,10 @@ Are you sure you wish to encrypt your wallet? 지갑 암호화를 허용하시겠습니까? + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + 비트코인 코어는 암호화 과정을 마무리 하기 위해 종료됩니다. 당신의 지갑을 암호화하는 것이 여러분의 컴퓨터에 해를 끼치는 프로그램으로부터 여러분의 비트코인을 완전히 보호해주지는 못한다는 사실을 기억하십시오. + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. 중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암호화 된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암호화 된 지갑을 사용하시기 바랍니다. @@ -179,6 +183,10 @@ Wallet encrypted 지갑 암호화 완료 + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 지갑에 새로운 비밀문구를 입력하세요.<br/>비밀문구를 <b>열 개 이상의 무작위 글자</b> 혹은 <b>여덟개 이상의 단어로<b> 정하세요. + Enter the old passphrase and new passphrase to the wallet. 지갑의 기존 암호와 새로운 암호를 입력해주세요. @@ -189,7 +197,7 @@ Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 지갑 암호화는 내부 에러로 인해 실패했습니다. 당신의 지갑은 암호화 되지 않았습니다. + 지갑 암호화는 내부 오류로 인해 실패했습니다. 당신의 지갑은 암호화 되지 않았습니다. The supplied passphrases do not match. @@ -214,12 +222,20 @@ BanTableModel - + + IP/Netmask + IP주소/넷마스크 + + + Banned Until + 다음과 같은 상황이 될 때까지 계정 정지됩니다. + + BitcoinGUI Sign &message... - 메시지 서명&... + 메시지 서명(&M)... Synchronizing with network... @@ -227,7 +243,7 @@ &Overview - &개요 + 개요(&O) Node @@ -239,7 +255,7 @@ &Transactions - &거래 + 거래(&T) Browse transaction history @@ -251,11 +267,11 @@ Quit application - 적용 중단 + 어플리케이션 종료 About &Qt - Qt 정보(&Q) + &Qt 정보 Show information about Qt @@ -263,31 +279,31 @@ &Options... - &옵션 + 옵션(&O) &Encrypt Wallet... - 지갑 암호화&... + 지갑 암호화(&E)... &Backup Wallet... - 지갑 백업&... + 지갑 백업(&B)... &Change Passphrase... - 암호문 변경&... + 암호문 변경(&C)... &Sending addresses... - &주소 보내는 중 + 보내는 주소(&S) &Receiving addresses... - & 주소 받는 중 + 받는 주소(&R) Open &URI... - URI&열기... + &URI 열기... Bitcoin Core client @@ -315,7 +331,7 @@ &Debug window - 디버그 창& + 디버그 창(&D) Open debugging and diagnostic console @@ -323,7 +339,7 @@ &Verify message... - 메시지 확인&... + 메시지 확인(&V)... Bitcoin @@ -367,15 +383,15 @@ &File - &파일 + 파일(&F) &Settings - &설정 + 설정(&S) &Help - &도움말 + 도움말(&H) Tabs toolbar @@ -391,7 +407,11 @@ &About Bitcoin Core - &비트코인 코어 소개 + 비트코인 코어 소개(&A) + + + Modify configuration options for Bitcoin Core + 비트코인 코어에 대한 설정을 수정합니다. Show the list of used sending addresses and labels @@ -407,16 +427,24 @@ &Command-line options - 명령어-라인 옵션 + 명령줄 옵션(&C) Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 사용할 수 있는 비트코인 명령어 옵션 목록을 가져오기 위해 Bitcoin-Qt 도움말 메시지를 표시합니다. + 사용할 수 있는 비트코인 명령줄 옵션 목록을 가져오기 위해 Bitcoin-Qt 도움말 메시지를 표시합니다. + + + %n active connection(s) to Bitcoin network + 비트코인 네트워크에 %n개의 연결이 활성화되어 있습니다. No block source available... 사용 가능한 블록이 없습니다... + + Processed %n block(s) of transaction history. + %n 블럭 만큼의 거래 기록이 처리됨. + %n hour(s) %n시간 @@ -575,7 +603,15 @@ Amount - 거래량 + 거래액 + + + Received with label + 입금과 함께 수신된 라벨 + + + Received with address + 입금과 함께 수신된 주소 Date @@ -599,11 +635,11 @@ Copy label - 표 복사하기 + 라벨 복사하기 Copy amount - 거래량 복사 + 거래액 복사 Copy transaction ID @@ -637,6 +673,14 @@ Copy priority 우선도 복사 + + Copy dust + 더스트 복사 + + + Copy change + 잔돈 복사 + highest 아주 높음 @@ -681,6 +725,22 @@ none 없음 + + This label turns red if the transaction size is greater than 1000 bytes. + 이 라벨은 1000바이트 이상의 거래가 이루어지면 붉게 변합니다. + + + This label turns red if the priority is smaller than "medium". + 이 라벨은 우선순위가 "보통" 이하인 경우 붉게 변합니다. + + + This label turns red if any recipient receives an amount smaller than %1. + 이 라벨은 수령인이 받은 액수가 잔고의 %1보다 작으면 붉게 변합니다. + + + Can vary +/- %1 satoshi(s) per input. + 입력마다 +/- %1 사토시가 변할 수 있습니다. + yes @@ -691,7 +751,11 @@ This means a fee of at least %1 per kB is required. - 이 의미는 수수료가 최소한 %1 per 키로바이트 필요합니다 + 이 뜻은 최소한 1kB 당 %1의 수수료가 필요하다는 의미입니다. + + + Can vary +/- 1 byte per input. + 입력마다 +/- 1 바이트가 변할 수 있습니다. Transactions with higher priority are more likely to get included into a block. @@ -699,13 +763,17 @@ (no label) - (표 없음) + (라벨 없음) change from %1 (%2) ~로부터 변경 %1 (%2) - + + (change) + (잔돈) + + EditAddressDialog @@ -714,15 +782,19 @@ &Label - &표 + 라벨(&L) The label associated with this address list entry 현재 선택된 주소 필드의 제목입니다. + + The address associated with this address list entry. This can only be modified for sending addresses. + 본 주소록 입력은 주소와 연계되었습니다. 이것은 보내는 주소들에서만 변경될수 있습니다. + &Address - &주소 + 주소(&A) New receiving address @@ -754,7 +826,7 @@ New key generation failed. - 새로운 키 생성이 실패하였습니다 + 새로운 키 생성이 실패하였습니다. @@ -810,7 +882,35 @@ command-line options 명령줄 옵션 - + + UI Options: + UI 옵션: + + + Choose data directory on startup (default: %u) + 실행시 데이터 폴더 선택하기 (기본값: %u) + + + Set language, for example "de_DE" (default: system locale) + "ko_KR"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘) + + + Start minimized + 최소화된 상태에서 시작 + + + Set SSL root certificates for payment request (default: -system-) + 지불 요청을 위한 SSL 루트 인증서 설정 (기본값: -system-) + + + Show splash screen on startup (default: %u) + 실행시 시작화면 보기 (기본값: %u) + + + Reset all settings changes made over the GUI + GUI를 통해 수정된 모든 설정을 초기화 + + Intro @@ -819,7 +919,7 @@ Welcome to Bitcoin Core. - 비트코인 코어에 오신것을 환영합니. + 비트코인 코어에 오신것을 환영합니다. As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. @@ -841,11 +941,23 @@ Bitcoin Core 비트코인 코어 + + Error: Specified data directory "%1" cannot be created. + 오류: "%1" 지정한 데이터 디렉토리를 생성할 수 없습니다. + Error 오류 - + + %n GB of free space available + %n GB 사용가능 + + + (of %n GB needed) + (%n GB가 필요) + + OpenURIDialog @@ -873,7 +985,7 @@ OptionsDialog Options - 선택들 + 환경설정 &Main @@ -881,7 +993,7 @@ Size of &database cache - 데이터베이스 캐시 크기 + 데이터베이스 캐시 크기(&D) MB @@ -889,7 +1001,7 @@ Number of script &verification threads - 스크립트 인증 쓰레드의 개수 + 스크립트 인증 쓰레드의 개수(&V) Accept connections from outside @@ -901,7 +1013,19 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) - 프록시 아이피 주소(예. IPv4:127.0.0.1 / IPv6: ::1) + 프록시 아이피 주소 (예. IPv4:127.0.0.1 / IPv6: ::1) + + + 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. + 창을 닫으면 종료 대신 트레이로 보내기. 이 옵션을 활성화하면 메뉴에서 종료를 선택한 후에만 어플리케이션이 종료됩니다. + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + 사용자 인터페이스 언어를 여기서 설정할 수 있습니다. 이 설정은 Bitcoin Core를 다시 시작할 때 적용됩니다. + + + 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 |. + 서드-파티 URLs (예. 블록 탐색기)는 거래 탭의 컨텍스트 메뉴에 나타납니다. URL의 %s는 트랜잭션 해시값으로 대체됩니다. 여러 URLs는 수직 바 | 에서 나누어 집니다. Third party transaction URLs @@ -909,7 +1033,7 @@ Active command-line options that override above options: - 명령어 라인 옵션을 활성화해서 옵션을 우회하시오 + 명령줄 옵션 활성화는 위의 옵션들을 대체합니다: Reset all client options to default. @@ -923,9 +1047,21 @@ &Network 네트워크(&N) + + Automatically start Bitcoin Core after logging in to the system. + 시스템 로그인 후 자동으로 Bitcoin Core를 실행합니다. + + + &Start Bitcoin Core on system login + 시스템 로그인 후 Bitcoin Core 시작(&S) + + + (0 = auto, <0 = leave that many cores free) + (0 = 자동, <0 = 지정된 코어 개수만큼 사용 안함) + W&allet - 지갑 + 지갑(&A) Expert @@ -933,19 +1069,23 @@ Enable coin &control features - 코인 상세 제어기능을 활성화합니다 - &C + 코인 상세 제어기능을 활성화합니다 (&C) + + + 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. + 검증되지 않은 잔돈 쓰기를 비활성화하면 트랜잭션이 적어도 1회 이상 검증되기 전까지 그 트랜잭션의 거스름돈은 사용할 수 없습니다. 이는 잔액 계산 방법에도 영향을 미칩니다. &Spend unconfirmed change - &확인되지 않은 돈을 쓰다 + 검증되지 않은 잔돈 쓰기 (&S) Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - 라우터의 비트코인 클라이언트 포트를 자동으로 엽니다. 라우터에서 UPnP를 지원하고 활성화 했을 경우에만 동작합니다. + 라우터에서 Bitcoin 클라이언트 포트를 자동적으로 엽니다. 라우터에서 UPnP를 지원하고 활성화 했을 경우에만 동작합니다. Map port using &UPnP - 사용중인 UPnP 포트 매핑(&U) + 사용중인 &UPnP 포트 매핑 Connect to the Bitcoin network through a SOCKS5 proxy. @@ -953,11 +1093,11 @@ &Connect through SOCKS5 proxy (default proxy): - SOCKS5 프록시를 거쳐 연결합니다 (기본값 프록시): + SOCKS5 프록시를 거쳐 연결합니다(&C) (기본 프록시): Proxy &IP: - 프록시 IP(&I): + 프록시 &IP: &Port: @@ -967,6 +1107,14 @@ Port of the proxy (e.g. 9050) 프록시의 포트번호입니다(예: 9050) + + Used for reaching peers via: + 피어에 연결하기 위해 사용된 방법: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + 이 SOCK5 프록시를 통과해 피어와 접속한 네트워크 유형이 표시됩니다. + IPv4 IPv4 @@ -979,6 +1127,14 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Tor 서비스를 경유하여 비트코인 네트워크에 연결하기 위해 분리된 SOCKS5 프록시를 사용. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Tor 서비스를 이용하여 피어에게 연결하기 위해 분리된 SOCKS5 프록시 사용 + &Window 창(&W) @@ -1039,6 +1195,10 @@ Client restart required to activate changes. 변경 사항을 적용하기 위해서는 프로그램이 종료 후 재시작되어야 합니다. + + Client will be shut down. Do you want to proceed? + 클라이언트가 종료됩니다, 계속 진행하시겠습니까? + This change would require a client restart. 이 변경 사항 적용을 위해 프로그램 재시작이 필요합니다. @@ -1056,7 +1216,7 @@ 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. - 표시한 정보가 오래된 것 같습니다. 비트코인 네트워크에 연결하고 난 다음에 지갑을 자동으로 동기화 하지만, 아직 과정이 끝나지는 않았습니다. + 표시된 정보가 오래된 것 같습니다. 비트코인 네트워크에 연결하고 난 다음에 지갑을 자동으로 동기화 하지만, 아직 과정이 끝나지는 않았습니다. Watch-only: @@ -1102,11 +1262,27 @@ Your current balance in watch-only addresses 모니터링 지갑의 현재 잔액 + + Spendable: + 사용가능: + Recent transactions 최근 거래 - + + Unconfirmed transactions to watch-only addresses + 모니터링 지갑의 검증되지 않은 트랜잭션 + + + Mined balance in watch-only addresses that has not yet matured + 모니터링 지갑의 채굴된 잔액 중 숙성되지 않은 것 + + + Current total balance in watch-only addresses + 모니터링 지갑의 현재 잔액 + + PaymentServer @@ -1117,13 +1293,25 @@ Invalid payment address %1 잘못된 지불 주소입니다 %1 + + Payment request rejected + 지불 요청이 거부됨 + + + Payment request network doesn't match client network. + 지급 요청 네트워크가 클라이언트 네트워크와 일치되지 않습니다. + + + Payment request is not initialized. + 지불 요청이 초기화 되지 않았습니다. + Requested payment amount of %1 is too small (considered dust). 요청한 금액 %1의 양이 너무 적습니다. (스팸성 거래로 간주) Payment request error - 지불 요청 애러 + 지불 요청 오류 Cannot start bitcoin: click-to-pay handler @@ -1133,21 +1321,45 @@ Payment request fetch URL is invalid: %1 대금 청구서의 URL이 올바르지 않습니다: %1 + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI의 파싱에 문제가 발생했습니다. 잘못된 비트코인 주소나 URI 파라미터 구성에 오류가 존재할 수 있습니다. + Payment request file handling 지불이 파일 처리를 요청합니다 + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 지불 요청 파일을 읽을 수 없습니다. 이것은 잘못된 지불 요청 파일에 의해 발생하는 오류일 수 있습니다. + + + Payment request expired. + 지불 요청이 만료됨. + Unverified payment requests to custom payment scripts are unsupported. 임의로 변경한 결제 스크립트 기반의 대금 청구서 양식은 검증되기 전까지는 지원되지 않습니다. + + Invalid payment request. + 잘못된 지불 요청. + Refund from %1 %1 으로부터의 환불 + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + 지불 요청 %1은 너무 큽니다 (%2 바이트, %3 바이트까지 허용됩니다). + Error communicating with %1: %2 - %1과 소통하는데 애러: %2 + %1과 소통하는데 오류: %2 + + + Payment request cannot be parsed! + 지불요청을 처리할 수 없습니다. Bad response from server %1 @@ -1159,22 +1371,38 @@ Network request error - 네트워크 요청 애러 + 네트워크 요청 오류 PeerTableModel - + + User Agent + 유저 에이전트 + + + Node/Service + 노드/서비스 + + + Ping Time + Ping 시간 + + QObject Amount - 거래량 + 거래액 Enter a Bitcoin address (e.g. %1) 비트코인 주소를 입력하기 (예. %1) + + %1 d + %1 일 + %1 h %1 시간 @@ -1187,6 +1415,10 @@ %1 s %1 초 + + None + 없음 + N/A 없음 @@ -1212,7 +1444,7 @@ PNG Image (*.png) - PNG 이미지(*.png) + PNG 이미지 (*.png) @@ -1231,7 +1463,7 @@ &Information - 정보 + 정보(&I) Debug window @@ -1241,13 +1473,9 @@ General 일반 - - Using OpenSSL version - 사용중인 OpenSSL 버전 - Using BerkeleyDB version - 사용중인 BerkeleyDB 버전 + 사용 중인 BerkeleyDB 버전 Startup time @@ -1273,6 +1501,22 @@ Current number of blocks 현재 블럭 수 + + Memory Pool + 메모리 풀 + + + Current number of transactions + 현재 트랜잭션 수 + + + Memory usage + 메모리 사용량 + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + 현재의 데이터폴더에서 비트코인 디버그 파일을 엽니다. 용량이 큰 로그 파일은 몇 초가 걸릴 수 있습니다. + Received 받음 @@ -1283,12 +1527,80 @@ &Peers - &피어 + 피어(&P) + + + Banned peers + 차단된 피어 + + + Select a peer to view detailed information. + 자세한 정보를 보려면 피어를 선택하세요. + + + Whitelisted + 화이트리스트에 포함 + + + Direction + 방향 Version 버전 + + Starting Block + 시작된 블록 + + + Synced Headers + 동기화된 헤더 + + + Synced Blocks + 동기화된 블록 + + + User Agent + 유저 에이전트 + + + Services + 서비스 + + + Ban Score + 밴 스코어 + + + Connection Time + 접속 시간 + + + Last Send + 마지막으로 보낸 시간 + + + Last Receive + 마지막으로 받은 시간 + + + Ping Time + Ping 시간 + + + The duration of a currently outstanding ping. + 현재 진행중인 PING에 걸린 시간. + + + Ping Wait + Ping 대기 + + + Time Offset + 시간 오프셋 + Last block time 최종 블럭 시각 @@ -1303,11 +1615,11 @@ &Network Traffic - &네트워크 트래픽 + 네트워크 트래픽(&N) &Clear - &지우기 + 지우기(&C) Totals @@ -1333,6 +1645,38 @@ Clear console 콘솔 초기화 + + &Disconnect Node + 끊긴 노드(&D) + + + Ban Node for + 추방된 노드: + + + 1 &hour + 1시간(&H) + + + 1 &day + 1일(&D) + + + 1 &week + 1주(&W) + + + 1 &year + 1년(&Y) + + + &Unban Node + 노드 추방 취소(&U) + + + Welcome to the Bitcoin Core RPC console. + 비트코인 RPC 콘솔에 오신걸 환영합니다 + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 <b>Ctrl-L</b>키를 사용하십시오. @@ -1357,20 +1701,52 @@ %1 GB %1 기가바이트 - + + (node id: %1) + (노드 ID: %1) + + + via %1 + %1 경유 + + + never + 없음 + + + Inbound + 인바운드 + + + Outbound + 아웃바운드 + + + Yes + + + + No + 아니오 + + + Unknown + 알수없음 + + ReceiveCoinsDialog &Amount: - &거래량: + 거래액(&A): &Label: - 라벨: + 라벨(&L): &Message: - &메시지: + 메시지(&M): Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. @@ -1378,7 +1754,11 @@ R&euse an existing receiving address (not recommended) - 현재의 수취용 주소를 재사용합니다만 권장하지는 않습니다. (R&) + 현재의 수취용 주소를 재사용하기(&E) (권장하지 않습니다) + + + 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. + 지불 요청에 첨부되는 선택가능한 메시지 입니다. 이 메세지는 요청이 열릴 때 표시될 것 입니다. 메모: 이 메시지는 비트코인 네트워크로 전송되지 않습니다. An optional label to associate with the new receiving address. @@ -1408,6 +1788,10 @@ &Request payment 지불 요청(&R) + + Show the selected request (does the same as double clicking an entry) + 선택된 요청을 표시하기 (더블 클릭으로 항목을 표시할 수 있습니다) + Show 보기 @@ -1422,7 +1806,7 @@ Copy label - 표 복사하기 + 라벨 복사하기 Copy message @@ -1430,7 +1814,7 @@ Copy amount - 거래량 복사 + 거래액 복사 @@ -1469,11 +1853,11 @@ Amount - 거래량 + 거래액 Label - + 라벨 Message @@ -1481,7 +1865,7 @@ Resulting URI too long, try to reduce the text for label / message. - URI 결과가 너무 길음, 표/메세지의 글을 줄이도록 하세요. + URI 결과가 너무 길음, 라벨/메세지의 글을 줄이도록 하세요. Error encoding URI into QR Code. @@ -1496,7 +1880,7 @@ Label - + 라벨 Message @@ -1504,7 +1888,7 @@ Amount - 거래량 + 거래액 (no label) @@ -1516,7 +1900,7 @@ (no amount) - (거래량 없음) + (거래액 없음) @@ -1551,7 +1935,7 @@ Amount: - 거래량: + 거래액: Priority: @@ -1569,6 +1953,10 @@ Change: 체인지: + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + 이 기능이 활성화되면 거스름돈 주소가 공란이거나 무효인 경우, 거스름돈은 새롭게 생성된 주소로 송금됩니다. + Custom change address 주소변경 @@ -1577,17 +1965,77 @@ Transaction Fee: 거래 수수료: + + Choose... + 선택 하기... + + + collapse fee-settings + 수수료 설정 접기 + + + per kilobyte + 킬로바이트 당 + + + If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. + 사용자 정의 수수료가 1000사토시로 지정된 경우 트랜잭션의 크기가 250바이트 일 경우 1킬로바이트당 250사토시만 지불되지만 "최소 수수료"에선 1000사토시가 지불됩니다. 1킬로바이트가 넘는 트랜잭션인 경우 어떠한 경우에든 1킬로바이트 기준으로 지불됩니다. + + + Hide + 숨기기 + + + total at least + 최소 수수료 + + + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + 블록의 용량보다 트랜잭션의 용량이 작은 경우에는 최소한의 수수료만으로도 충분합니다. 그러나 비트코인 네트워크의 처리량보다 더 많은 트랜잭션 요구는 영원히 검증이 안 될 수도 있습니다. + + + (read the tooltip) + (툴팁을 읽어보세요) + Recommended: 권장: + + Custom: + 사용자 정의: + + + (Smart fee not initialized yet. This usually takes a few blocks...) + (Smart fee가 아직 초기화되지 않았습니다. 블록 분석이 완료될 때 까지 기다려주십시오...) + + + Confirmation time: + 승인 시간: + + + normal + 일반 + + + fast + 빠름 + + + Send as zero-fee transaction if possible + 가능한 경우 수수료 없이 보내기 + + + (confirmation may take longer) + (거래 검증이 오래 걸릴 수 있습니다) + Send to multiple recipients at once 다수의 수령인들에게 한번에 보내기 Add &Recipient - 수령인 추가하기 + 수령인 추가하기(&R) Clear all fields of the form. @@ -1627,7 +2075,7 @@ Copy amount - 거래량 복사 + 거래액 복사 Copy fee @@ -1645,6 +2093,14 @@ Copy priority 우선도 복사 + + Copy change + 잔돈 복사 + + + Total Amount %1 + 총 액수 %1 + or 또는 @@ -1669,18 +2125,46 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. 거래가 거부되었습니다. 몇몇 코인들이 지갑에서 이미 사용된 경우, 예를 들어 코인을 이미 사용한 wallet.dat를 복사해서 사용한 경우 지금 지갑에 기록이 안되있어 이런 일이 생길 수 있습니다. + + A fee higher than %1 is considered an absurdly high fee. + %1 보다 높은 수수료는 너무 높은 수수료 입니다. + + + Payment request expired. + 지불 요청이 만료됨. + + + Pay only the required fee of %1 + 오직 %1 만의 수수료를 지불하기 + + + Estimated to begin confirmation within %n block(s). + %n 블록 안에 거래검증이 시작 될것으로 예상합니다. + + + The recipient address is not valid. Please recheck. + 수령인 주소가 정확하지 않습니다. 재확인 바랍니다 + + + Duplicate address found: addresses should only be used once each. + 두개 이상의 주소입니다: 한번에 하나의 주소에만 작업할 수 있습니다. + Warning: Invalid Bitcoin address 경고: 잘못된 비트코인주소입니다 (no label) - (표 없음) + (라벨 없음) Warning: Unknown change address 경고: 알려지지 않은 주소변경입니다 + + Copy dust + 더스트 복사 + Are you sure you want to send? 정말로 보내시겠습니까? @@ -1694,19 +2178,19 @@ SendCoinsEntry A&mount: - 금액: + 금액(&M): Pay &To: - 지급&수신: + 송금할 대상(&T) : Enter a label for this address to add it to your address book - 당신의 주소록에 이 주소를 추가하기 위하여 표를 입역하세요 + 주소록에 추가하려면 라벨을 입력하세요 &Label: - 표: + 라벨(&L) Choose previously used address @@ -1714,7 +2198,11 @@ This is a normal payment. - 평균지급입니다 + 이것은 정상적인 지불입니다. + + + The Bitcoin address to send the payment to + 이 비트코인 주소로 송금됩니다 Alt+A @@ -1722,7 +2210,7 @@ Paste address from clipboard - 클립보드로 부터 주소를 붙이세요 + 클립보드로 부터 주소 붙여넣기 Alt+P @@ -1730,15 +2218,31 @@ Remove this entry - 항목을 지우시오 + 항목을 지웁니다 + + + 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. + 수수료가 송금되는 금액에서 공제됩니다. 수령자는 금액 필드에서 입력한 금액보다 적은 금액을 전송받게 됩니다. 받는 사람이 여러 명인 경우 수수료는 균등하게 나누어집니다. + + + S&ubtract fee from amount + 송금액에서 수수료 공제(&U) Message: 메시지: + + This is an unauthenticated payment request. + 인증 되지 않은 지급 요청입니다. + + + This is an authenticated payment request. + 인증 된 지급 요청 입니다. + Enter a label for this address to add it to the list of used addresses - 사용된 주소 목록에 새 주소를 추가하기 위해 제목을 입력합니다. + 사용된 주소 목록에 새 주소를 추가하기 위해 라벨 이름을 입력해 주세요. 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. @@ -1757,7 +2261,7 @@ ShutdownWindow Bitcoin Core is shutting down... - 비트코인코어가 닫아지고 있습니다 + Bitcoin Core이 종료 중입니다... Do not shut down the computer until this window disappears. @@ -1774,6 +2278,14 @@ &Sign Message 메시지 서명(&S) + + 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. + 여러분 자신을 증명하기 위해 주소를 첨가하고 서명할 수 있습니다. 피싱 공격으로 말미암아 여러분의 서명을 통해 속아 넘어가게 할 수 있으므로, 서명하지 않은 모든 모호한 요소를 주의하십시오. 조항들이 완전 무결한지 확인 후 동의하는 경우에만 서명하십시오. + + + The Bitcoin address to sign the message with + 메세지를 서명한 비트코인 주소 + Choose previously used address 이전에 사용한 주소를 선택하십시오 @@ -1784,7 +2296,7 @@ Paste address from clipboard - 클립보드로 부터 주소를 붙이세요 + 클립보드로 부터 주소를 복사하기 Alt+P @@ -1822,6 +2334,14 @@ &Verify Message 메시지 검증(&V) + + 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! + 메시지를 검증하기 위해 아래 칸에 각각 지갑 주소와 메시지, 전자서명을 입력하세요. (메시지 원본의 띄어쓰기, 들여쓰기, 행 나눔 등이 정확하게 입력되어야 하므로 원본을 복사해서 입력하세요) 이 기능은 메시지 검증이 주 목적이며, 네트워크 침입자에 의해 변조되지 않도록 전자서명 해독에 불필요한 시간을 소모하지 마세요. + + + The Bitcoin address the message was signed with + 메세지의 서명에 사용된 비트코인 주소 + Verify the message to ensure it was signed with the specified Bitcoin address 정확한 비트코인주소가 입력됬는지 메시지를 확인하시오 @@ -1935,6 +2455,10 @@ Status 상태 + + , broadcast through %n node(s) + %n 노드를 거쳐 전파합니다. + Date 날짜 @@ -1959,6 +2483,10 @@ own address 자신의 주소 + + watch-only + 모니터링 지갑 + label 라벨 @@ -1967,6 +2495,10 @@ Credit 예금 + + matures in %n more block(s) + %n개 블럭 후에 코인 숙성이 완료됩니다. + not accepted 허용되지 않는다 @@ -1975,13 +2507,21 @@ Debit 차변 + + Total debit + 총 출금액 + + + Total credit + 총 입금액 + Transaction fee 송금 수수료 Net amount - 총액 + 총 거래액 Message @@ -2017,7 +2557,7 @@ Amount - 거래량 + 거래액 true @@ -2031,6 +2571,10 @@ , has not been successfully broadcast yet . 아직 성공적으로 통보하지 않음 + + Open for %n more block(s) + %n 개의 추가 블록을 읽습니다. + unknown 알수없음 @@ -2061,13 +2605,17 @@ Immature (%1 confirmations, will be available after %2) 충분히 숙성되지 않은 상태 (%1 승인, %2 후에 사용 가능합니다) + + Open for %n more block(s) + %n 개의 추가 블록을 읽습니다. + Open until %1 %1 까지 열림 Confirmed (%1 confirmations) - 확인됨(%1 확인됨) + 확인됨 (%1 확인됨) This block was not received by any other nodes and will probably not be accepted! @@ -2083,7 +2631,7 @@ Label - + 라벨 Unconfirmed @@ -2117,13 +2665,17 @@ Mined 채굴 + + watch-only + 모니터링 지갑 + (n/a) (없음) Transaction status. Hover over this field to show number of confirmations. - 거래상황. 마우스를 올리면 승인횟수가 표시됩니다. + 거래상황. 마우스를 올리면 검증횟수가 표시됩니다. Date and time that the transaction was received. @@ -2133,6 +2685,14 @@ Type of transaction. 거래의 종류. + + Whether or not a watch-only address is involved in this transaction. + 이 트랜잭션에 모니터링 지갑를 포함할지의 여부입니다. + + + User-defined intent/purpose of the transaction. + 트랜잭션에 대한 사용자 정의 intent/purpose + Amount removed from or added to balance. 변경된 잔고. @@ -2194,7 +2754,7 @@ Min amount - 최소 거래량 + 최소 거래액 Copy address @@ -2202,19 +2762,23 @@ Copy label - 표 복사하기 + 라벨 복사하기 Copy amount - 거래량 복사 + 거래액 복사 Copy transaction ID 거래 아이디 복사 + + Copy raw transaction + 로우 트랜잭션 복사 + Edit label - 표 수정하기 + 라벨 수정하기 Show transaction details @@ -2234,7 +2798,7 @@ There was an error trying to save the transaction history to %1. - %1으로 거래 기록을 저장하는데 애러가 있었습니다. + %1으로 거래 기록을 저장하는데 오류가 있었습니다. Exporting Successful @@ -2262,7 +2826,7 @@ Label - + 라벨 Address @@ -2283,7 +2847,11 @@ UnitDisplayStatusBarControl - + + Unit to show amounts in. Click to select another unit. + 거래액을 표시하는 단위. 클릭해서 다른 단위를 선택할 수 있습니다. + + WalletFrame @@ -2302,7 +2870,7 @@ WalletView &Export - &내보내기 + 내보내기(&E) Export the data in the current tab to a file @@ -2355,30 +2923,130 @@ Accept command line and JSON-RPC commands 명령줄과 JSON-RPC 명령 수락 + + If <category> is not supplied or if <category> = 1, output all debugging information. + <category>가 제공되지 않거나 <category> = 1 인 경우, 모든 디버깅 정보를 출력 + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + 하나의 지갑 트랜잭션에서의 총 수수료(%s)의 최대치; 너무 낮게 설정하면 큰 트랜잭션이 중지 됩니다 (기본값: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + 컴퓨터의 날짜와 시간이 올바른지 확인하십시오! 시간이 잘못되면 비트코인은 제대로 동작하지 않습니다. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + 블록 축소가 최소치의 %d MiB 밑으로 설정되어 있습니다. 더 높은 값을 사용해 보세요. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + 블록 축소: 마지막 지갑 동기화 지점이 축소된 데이터보다 과거의 것 입니다. -reindex가 필요합니다 (정지된 노드의 경우 모든 블록체인을 재다운로드합니다) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + 오래된 블록을 제거(축소)하여 디스크 용량을 줄입니다. 이 모드는 -txindex 와 -rescan 과 호환되지 않습니다. 경고: 이 모드를 취소하면 모든 블록체인을 다시 다운로드 받아야 합니다. (기본값:0 = 블록 축소 비활성화, >%u = 블록파일에 사용할 용량을 MiB단위로 지정) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + 블록 축소 모드에서는 재검색이 불가능 합니다. -reindex 명령을 사용해서 모든 블록체인을 다시 다운로드 해야 합니다. + + + Error: A fatal internal error occurred, see debug.log for details + 에러: 치명적인 내부 오류가 발생했습니다, 자세한 내용은 debug.log 를 확인해주세요. + + + Fee (in %s/kB) to add to transactions you send (default: %s) + 송금 거래시 추가되는 수수료 (%s/kB) (기본값: %s) + + + Pruning blockstore... + 블록 데이터를 축소 중입니다.. + Run in the background as a daemon and accept commands 데몬으로 백그라운드에서 실행하고 명령을 허용 + + Unable to start HTTP server. See debug log for details. + HTTP 서버를 시작할 수 없습니다. 자세한 사항은 디버그 로그를 확인 하세요. + Accept connections from outside (default: 1 if no -proxy or -connect) 외부 접속을 승인합니다 + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee은 너무 높습니다! 이것은 수수료 예측을 이용할 수 없을 때 지불되는 트랜잭션 수수료입니다. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + 충분한 데이터가 축적되지 않은 상태에서의 수수료 추정 기능이 사용하는 수수료 비율(%s/kB) (기본값: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + 트랜잭션의 중계를 하지 않더라도 화이트 리스트에 포함된 피어에서 받은 트랜잭션은 중계하기 (기본값: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 선택된 주소로 고정하며 항상 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + 시작시 모든 지갑 트랜잭션을 삭제하고 -rescan을 통하여 블록체인만 복구합니다. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + MIT 소프트웨어 라이센스에 따라 배포됩니다. 동봉된 파일 혹은 <http://www.opensource.org/licenses/mit-license.php>를 참조하세요. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + 피어들이 로컬 중계 정책을 위반하더라도 화이트 리스트에 포함된 피어인경우 강제로 중계하기 (기본값: %d) + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + 스크립트 인증 스레드의 갯수 설정 (%u-%d, 0 = 자동, <0 = 지정된 코어 개수만큼 사용 안함, 기본값: %d) + + + 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 + 블록 데이터베이스에 미래의 블록이 포함되어 있습니다. 이것은 사용자의 컴퓨터의 날짜와 시간이 올바르게 설정되어 있지 않을때 나타날 수 있습니다. 만약 사용자의 컴퓨터의 날짜와 시간이 올바르다고 확신할 때에만 블록 데이터 베이스의 재구성을 하십시오 + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다. + + Unable to bind to %s on this computer. Bitcoin Core is probably already running. + 이 컴퓨터의 %s에 바인딩 할 수 없습니다. 아마도 비트코인이 실행중인 것 같습니다. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 지원하지 않는 인수 -whitelistalwaysrelay 는 무시됩니다, -whitelistrelay 나 -whitelistforcerelay 를 사용해 주세요. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: 열려있거나 -proxy 옵션을 사용하지 않을 시 1) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + 경고: 비정상적으로 많은 블록이 생성되고 있습니다. %d 블록은 마지막 %d에 수신되었습니다 (%d 예측됨) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + 경고: 네트워크 연결을 확인해 주세요. %d 블록은 마지막 %d에 수신되었습니다 (%d 예측됨) + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 경고 : 모든 네트워크가 동의해야 하나, 일부 채굴자들에게 문제가 있는 것으로 보입니다. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 경고: 알려지지 않은 버전의 블록이 채굴되었습니다. 알려지지 않은 규칙이 적용되었을 가능성이 있습니다. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 경고: 현재 비트코인 버전이 다른 네트워크 참여자들과 동일하지 않는 것 같습니다. 당신 또는 다른 참여자들이 동일한 비트코인 버전으로 업그레이드 할 필요가 있습니다. @@ -2387,6 +3055,22 @@ Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. 경고 : wallet.dat가 손상되어 데이터가 복구되었습니다. 원래의 wallet.dat 파일은 %s 후에 wallet.{timestamp}.bak 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + 설정된 넷마스크 혹은 IP 주소로 화이트리스트에 포함된 피어에 접속합니다. 이 설정은 복수로 지정 할 수 있습니다. + + + -maxmempool must be at least %d MB + -maxmempool은 최소한 %d MB가 필요합니다 + + + <category> can be: + <category> 지정 가능: + + + Append comment to the user agent string + 사용자 에이전트 문자열에 코멘트 첨부 + Block creation options: 블록 생성 옵션: @@ -2415,6 +3099,26 @@ Do you want to rebuild the block database now? 블락 데이터베이스를 다시 생성하시겠습니까? + + Enable publish hash block in <address> + <address>에 대한 해시 블록 공개 활성화 + + + Enable publish hash transaction in <address> + <address>에 대한 해시 트랙잭션 공개 활성화 + + + Enable publish raw block in <address> + <address>에 대한 로우 블록 공개 활성화 + + + Enable publish raw transaction in <address> + <address>에 대한 로우 트랜잭션 공개 활성화 + + + Enable transaction replacement in the memory pool (default: %u) + 메모리 풀(pool) 내의 트랜잭션 치환(replacement) 활성화 (기본값: %u) + Error initializing block database 블록 데이터베이스를 초기화하는데 오류 @@ -2451,10 +3155,42 @@ Invalid -onion address: '%s' 잘못된 -onion 주소입니다: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + 유효하지 않은 금액 -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + 트랜잭션 메모리 풀의 용량을 <n>메가바이트 아래로 유지하기 (기본값: %u) + + + Location of the auth cookie (default: data dir) + 인증 쿠키의 위치 (기본값: data dir) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + 중계 및 채굴을 할 때 트랜잭션에서의 sigop 당 데이터의 최소 크기 (기본값: %u) + Not enough file descriptors available. 사용 가능한 파일 디스크립터-File Descriptor-가 부족합니다. + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + 오직 <net> 네트워크로 로만 접속 (IPv4, IPv6 혹은 onion) + + + Print version and exit + 버전 출력후 종료 + + + Prune cannot be configured with a negative value. + 블록 축소는 음수로 설정할 수 없습니다. + + + Prune mode is incompatible with -txindex. + 블록 축소 모드는 -txindex와 호환되지 않습니다. + Set database cache size in megabytes (%d to %d, default: %d) 데이터베이스 케시 크기를 메가바이트로 설정(%d 부터 %d, 기본값: %d) @@ -2467,6 +3203,26 @@ Specify wallet file (within data directory) 데이터 폴더 안에 지갑 파일을 선택하세요. + + Unsupported argument -benchmark ignored, use -debug=bench. + 지원하지 않는 인수 -benchmark 은 무시됩니다, -debug=bench 형태로 사용하세요. + + + Unsupported argument -debugnet ignored, use -debug=net. + 지원하지 않는 인수 -debugnet 은 무시됩니다, -debug=net 형태로 사용하세요. + + + Unsupported argument -tor found, use -onion. + 지원하지 않는 인수 -tor를 찾았습니다. -onion를 사용해주세요. + + + Use UPnP to map the listening port (default: %u) + 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: %u) + + + User Agent comment (%s) contains unsafe characters. + 사용자 정의 코멘트 (%s)에 안전하지 못한 글자가 포함되어 있습니다. + Verifying blocks... 블록 검증중... @@ -2487,26 +3243,138 @@ You need to rebuild the database using -reindex to change -txindex -txindex를 바꾸기 위해서는 -reindex를 사용해서 데이터베이스를 재구성해야 합니다. + + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + 특정 소스에서의 JSON-RPC 연결 허가. 유효한 <ip> 같은 하나의 IP주소 (예 1.2.3.4), 네트워크/넷마스크 (예 1.2.3.4/255.255.255.0) 혹은 네트워크/CIDR (예 1.2.3.4/24). 이 옵션은 복수로 설정 할 수 있습니다. + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + 선택된 주소로 고정하여 화이트리스트에 포함된 피어에 접속합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. + + + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + 선택된 주소로 고정하여 JSON-RPC 연결을 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. 이 옵션은 복수로 지정 할수 있습니다. (기본값: 모든 인터페이스에 고정) + Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. 데이터 디렉토리 %s에 락을 걸 수 없었습니다. 비트코인 코어가 이미 실행 중인 것으로 보입니다. + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + umask 077 대신 시스템 기본 퍼미션으로 새 파일을 만듭니다 (지갑 기능이 비활성화 상태에서만 유효합니다) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + 자신의 주소를 탐색 (기본값: 열려있거나 -externalip 나 -proxy 옵션이 없으면 1) + + + Error: Listening for incoming connections failed (listen returned error %s) + 오류: 들어오는 연결을 리슨(Listen)하는데 실패했습니다 (오류 리턴 %s) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) 이 사항과 관련있는 경고가 발생하거나 아주 긴 포크가 발생했을 때 명령어를 실행해 주세요. (cmd 명령어 목록에서 %s는 메시지로 대체됩니다) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + 해당 금액(%s/kB) 보다 적은 수수료는 중계, 채굴, 트랜잭션 생성에서 수수료 면제로 간주됩니다 (기본값: %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + paytxfee가 설정되어 있지 않다면 평균 n 블록안에 승인이 이루어지도록 충분한 수수료가 포함됩니다 (기본값: %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + 유효하지 않은 금액 -maxtxfee=<amount>: '%s' (트랜잭션이 막히는 상황을 방지하게 위해 적어도 %s 의 중계 수수료를 지정해야 합니다) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + 중계 및 채굴을 할 때 데이터 운송 트랜잭션에서 데이터의 최대 크기 (기본값: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + DNS lookup를 통해 피어 주소에 대한 쿼리 보내기 (기본값: 1 -connect 예외) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + 인증정보를 프록시 연결마다 무작위로 합니다. 이는 Tor 스트림을 격리시킬 수 있습니다 (기본값: %u) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + 코인 생성에 대한 스레드 갯수 설정 (-1 = 모든 코어, 기본값: %d) + + + The transaction amount is too small to send after the fee has been deducted + 거래액이 수수료를 지불하기엔 너무 작습니다 + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + 이 프로그램에는 OpenSSL 툴킷<https://www.openssl.org/> 사용 목적으로 개발한 OpenSSL 프로젝트를 포함하고 있으며, 암호화 프로그램은 Eric Young이, UPnP 프로그램은 Thomas Bernard가 작성했습니다. + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + 화이트리스트에 포함된 피어는 이미 메모리풀에 포함되어 있어도 DoS 추방이 되지 않으며 그들의 트랜잭션이 항상 중계됩니다, 이는 예를 들면 게이트웨이에서 유용합니다. + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + 축소 모드를 해제하고 데이터베이스를 재구성 하기 위해 -reindex를 사용해야 합니다. 이 명령은 모든 블록체인을 다시 다운로드 할 것 입니다. + + + (default: %u) + (기본값: %u) + + + Accept public REST requests (default: %u) + 공개 REST 요청을 허가 (기본값: %u) + + + Activating best chain... + 최적 블록 체인을 활성화하는중... + + + Attempt to recover private keys from a corrupt wallet.dat on startup + 시작시 망가진 wallet.dat에서 개인키 복원을 시도 + + + Automatically create Tor hidden service (default: %d) + Tor서비스를 자동적으로 생성 (기본값: %d) + Cannot resolve -whitebind address: '%s' -whitebind 주소를 확인할 수 없습니다: '%s' + + Connect through SOCKS5 proxy + SOCK5 프록시를 통해 연결 + + + Copyright (C) 2009-%i The Bitcoin Core Developers + Copyright (C) 2009-%i The Bitcoin Core Developers + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin Core + wallet.dat 불러오기 오류: 최신 버전의 Bitcoin Core이 필요합니다. + + + Error reading from database, shutting down. + 블록 데이터베이스를 불러오는데 오류가 발생하였습니다, 종료됩니다. + + + Imports blocks from external blk000??.dat file on startup + 외부 blk000??.dat 파일에서 블록을 가져오기 + Information 정보 + + Initialization sanity check failed. Bitcoin Core is shutting down. + 무결성 확인 초기화가 실패했습니다. Bitcoin Core가 종료됩니다. + Invalid amount for -maxtxfee=<amount>: '%s' -maxtxfee=<amount>에 대한 양이 잘못되었습니다: '%s' @@ -2519,14 +3387,54 @@ Invalid amount for -mintxfee=<amount>: '%s' 최저 거래 수수료가 부족합니다. -mintxfee=<amount>: '%s' + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + 유효하지 않은 금액 -paytxfee=<amount>: "%s" (최소 %s 이상이어야 됨) + + + Invalid netmask specified in -whitelist: '%s' + 유효하지 않은 넷마스크가 -whitelist: '%s" 를 통해 지정됨 + + + Keep at most <n> unconnectable transactions in memory (default: %u) + 최대 <n>개의 연결할 수 없는 트랜잭션을 메모리에 저장 (기본값: %u) + + + Need to specify a port with -whitebind: '%s' + -whitebind를 이용하여 포트를 지정해야 합니다: '%s" + + + Node relay options: + Node 중계 옵션: + RPC server options: RPC 서버 설정 + + Rebuild block chain index from current blk000??.dat files on startup + 현재의 blk000??.dat 파일들로부터 블록체인 색인을 재구성합니다. + + + Receive and display P2P network alerts (default: %u) + P2P 네트워크 알림을 수신후 표시합니다 (기본값: %u) + + + Reducing -maxconnections from %d to %d, because of system limitations. + 시스템 한계로 인하여 -maxconnections를 %d 에서 %d로 줄였습니다. + + + Rescan the block chain for missing wallet transactions on startup + 시작시 누락된 지갑 트랜잭션에 대해 블록 체인을 다시 검색 합니다 + Send trace/debug info to console instead of debug.log file 추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기 + + Send transactions as zero-fee transactions if possible (default: %u) + 가능한 경우 수수료 없이 트랜잭션 보내기 (기본값: %u) + Show all debugging options (usage: --help -help-debug) 모든 디버그 설정 보기(설정: --help -help-debug) @@ -2539,30 +3447,70 @@ Signing transaction failed 거래를 서명하는것을 실패하였습니다. + + The transaction amount is too small to pay the fee + 거래액이 수수료를 지불하기엔 너무 작습니다 + + + This is experimental software. + 이 소프트웨어는 시험적입니다. + + + Tor control port password (default: empty) + Tor 관리 포트 암호 (기본값: 공란) + + + Tor control port to use if onion listening enabled (default: %s) + onion 열림이 활성화시 Tor 관리 포트 사용 (기본값: %s) + Transaction amount too small - 거래량이 너무 적습니다 + 거래액이 너무 적습니다 Transaction amounts must be positive - 거래량은 반드시 정수여야합니다. + 거래액은 반드시 정수여야합니다. + + + Transaction too large for fee policy + 수수료 정책에 비해 트랜잭션이 너무 큽니다 Transaction too large 너무 큰 거래 + + Upgrade wallet to latest format on startup + 시작시 지갑 포멧을 최신으로 업그레이드 합니다 + Username for JSON-RPC connections JSON-RPC 연결에 사용할 사용자 이름 + + Wallet needed to be rewritten: restart Bitcoin Core to complete + 지갑을 새로 써야 합니다: 완료하기 위하여 Bitcoin Core을 다시 시작하십시오. + Warning 경고 + + Warning: unknown new rules activated (versionbit %i) + 경고: 알려지지 않은 새로운 규칙이 활성화되었습니다. (버전비트 %i) + + + Whether to operate in a blocks only mode (default: %u) + 블록 전용 모드로 동작할지 여부 (기본값: %u) + Zapping all transactions from wallet... 지갑의 모든거래내역 건너뛰기... + + ZeroMQ notification options: + ZeroMQ 알림 옵션: + wallet.dat corrupt, salvage failed wallet.dat 파일이 손상되었고 복구가 실패하였습니다. @@ -2589,16 +3537,160 @@ Error loading wallet.dat: Wallet corrupted - wallet.dat 불러오기 에러: 지갑 오류 + wallet.dat 불러오기 오류: 지갑 오류 + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = 트랜잭션의 메타 데이터를 유지함 예. 계좌정보 와 지불 요구 정보, 2 = 트랜잭션 메타 데이터 파기) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee값이 너무 큽니다! 하나의 트랜잭션에 너무 큰 수수료가 지불 됩니다. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee값이 너무 큽니다! 이 값은 송금할때 지불할 송금 수수료입니다. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + 메모리 풀에 있는 트랜잭션 기록을 <n>시간 후 부터는 유지하지 않기 (기본값: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + 경고 : wallet.dat 파일을 읽는 중 오류가 발생했습니다. 주소 키는 모두 정확하게 로딩되었으나 거래 데이터와 주소록 필드에서 누락이나 오류가 존재할 수 있습니다. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + 해당 금액(%s/kB) 보다 적은 수수료는 수수료 면제로 간주됩니다.(기본값: %s) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + -checkblocks을 통한 블록 점검 (0-4, 기본값: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + getrawtransaction를 RPC CALL를 통해 완전한 트랜잭션 인덱스 유지 (기본값: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + 이상행동을 하는 네트워크 참여자들을 다시 연결시키는데 걸리는 시간 (기본값: %u) + + + Output debugging information (default: %u, supplying <category> is optional) + 디버그 정보 출력 (기본값: %u, <category> 제공은 선택입니다) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + 블룸필터를 통해 블록과 트랜잭션 필터링 지원 (기본값: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + 네트워크 버전 문자 (%i)의 길이가 최대길이 (%i)를 초과합니다. UA코멘트의 갯수나 길이를 줄이세요. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + 아웃바운드 트래픽을 설정된 목표치 이하로 유지하기 (24시간당 MiB기준), 0 = 무제한 (기본값: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + 지원하지 않는 인수 -socks를 찾았습니다. 설정된 SOCKS의 버전은 더이상 사용할 수 없으며, SOCK5 프록시만을 지원합니다. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Tor 서비스를 이용하여 피어에게 연결하기 위해 분리된 SOCKS5 프록시를 사용 (기본값: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC 연결시 사용자 이름과 해시화된 암호문. <userpw> 필드는 <USERNAME>:<SALT>$<HASH> 포멧으로 구성되어 있습니다. 전형적 파이썬 스크립트에선 share/rpcuser가 포함되어 있습니다. 이 옵션은 여러번 지정할 수 있습니다. + + + Always query for peer addresses via DNS lookup (default: %u) + DNS lookup을 통해 항상 피어주소에 대한 쿼리 보내기 (기본값: %u) Error loading wallet.dat - wallet.dat 불러오기 에러 + wallet.dat 불러오기 오류 + + + Generate coins (default: %u) + 코인 생성 (기본값: %u) + + + How many blocks to check at startup (default: %u, 0 = all) + 시작시 점검할 블록 갯수 (기본값: %u, 0 = 모두) + + + Include IP addresses in debug output (default: %u) + 디버그 출력에 IP주소 포함하기 (기본값: %u) Invalid -proxy address: '%s' 잘못된 -proxy 주소입니다: '%s' + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + JSON-RPC 연결을 <port>포트로 받기 (기본값: %u 혹은 테스트넷: %u) + + + Listen for connections on <port> (default: %u or testnet: %u) + <port>포트로 연결 받기 (기본값: %u 혹은 테스트넷: %u) + + + Maintain at most <n> connections to peers (default: %u) + 피어 연결수를 <n>개로 유지 (기본값: %u) + + + Make the wallet broadcast transactions + 지갑 브로드캐스트 트랜잭션을 만들기 + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + 접속별 최대 수신 버퍼. <n> × 1000바이트 (기본값: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + 접속별 최대 전송 버퍼. <n> × 1000바이트 (기본값: %u) + + + Prepend debug output with timestamp (default: %u) + 디버그 출력에 타임 스탬프 포함하기 (기본값: %u) + + + Relay and mine data carrier transactions (default: %u) + 데이터 운송 트랜잭션을 중계 및 채굴 (기본값: %u) + + + Relay non-P2SH multisig (default: %u) + 비 P2SH 다중서명을 중계 (기본값: %u) + + + Set key pool size to <n> (default: %u) + 키 풀 사이즈를 <n> 로 설정 (기본값: %u) + + + Set the number of threads to service RPC calls (default: %d) + 원격 프로시져 호출 서비스를 위한 쓰레드 개수를 설정 (기본값 : %d) + + + Specify configuration file (default: %s) + 설정파일 지정 (기본값: %s) + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + 밀리초 단위로 연결 제한시간을 설정 (최소값: 1, 기본값: %d) + + + Specify pid file (default: %s) + pid 파일 지정 (기본값: %s) + + + Spend unconfirmed change when sending transactions (default: %u) + 트랜잭션을 보낼 때 검증되지 않은 잔돈 쓰기 (기본값: %u) + + + Threshold for disconnecting misbehaving peers (default: %u) + 이상행동 네트워크 참여자의 연결을 차단시키기 위한 한계치 (기본값: %u) + Unknown network specified in -onlynet: '%s' -onlynet에 지정한 네트워크를 알 수 없습니다: '%s' diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index e3dcd505f..b11027d1e 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -667,10 +667,6 @@ Debug window Fenestra Debug - - Using OpenSSL version - Utens OpenSSL versione - Startup time Tempus initiandi diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index b98976dfe..873a6939b 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -33,6 +33,10 @@ Delete the currently selected address from the list Ištrinti pasirinktą adresą iš sąrašo + + Export the data in the current tab to a file + Eksportuoti informaciją iš dabartinės lentelės į failą + &Export &Eksportuoti @@ -45,6 +49,10 @@ Choose the address to send coins to Pasirinkite adresą kuriam siūsite monetas + + Choose the address to receive coins with + Pasirinkite adresą su kuriuo gauti monetas + C&hoose P&asirinkti @@ -57,6 +65,14 @@ Receiving addresses Gaunami adresai + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Tai yra jūsų Bitcoin adresai mokėjimų siuntimui. Visada patikrinkite siunčiamą sumą ir gavėjo adresą prieš siųsdami monetas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Tai yra jūsų Bitcoin adresai mokėjimų gavimui. Rekomenduojame naudoti naujus gavimo adresus kiekvienai tranzakcijai. + Copy &Label Kopijuoti ž&ymę @@ -907,10 +923,6 @@ Debug window Derinimo langas - - Using OpenSSL version - Naudojama OpenSSL versija - Startup time Paleidimo laikas @@ -1690,6 +1702,10 @@ &Export &Eksportuoti + + Export the data in the current tab to a file + Eksportuoti informaciją iš dabartinės lentelės į failą + Backup Wallet Backup piniginę diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index e01d4c812..5a59184b0 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -1079,10 +1079,6 @@ General Vispārējs - - Using OpenSSL version - Izmantotā OpenSSL versija - Startup time Sākuma laiks diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 9236ac86f..94e02f890 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -1473,10 +1473,6 @@ General Generelt - - Using OpenSSL version - Bruker OpenSSL versjon - Using BerkeleyDB version Bruker BerkeleyDB versjon @@ -3195,10 +3191,6 @@ Wallet options: Valg for lommebok: - - Warning: This version is obsolete; upgrade required! - Advarsel: Denne versjonen er utdatert; oppgradering er påkrevd! - You need to rebuild the database using -reindex to change -txindex Du må gjenoppbygge databasen med å bruke -reindex for å endre -txindex @@ -3295,10 +3287,6 @@ Activating best chain... Aktiverer beste kjede... - - Always relay transactions received from whitelisted peers (default: %d) - Alltid videresend transaksjoner mottatt fra hvitlistede noder (standardverdi: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Forsøk å berge private nøkler fra en korrupt wallet.dat ved oppstart diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 8457a9ab5..fe29959ab 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -7,7 +7,7 @@ Create a new address - Maak een nieuw adres + Maak een nieuw adres aan &New @@ -169,7 +169,7 @@ Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core zal nu afsluiten om het versleutelingsproces te voltooien. Hou er rekening mee dat versleuteling van je portemonnee je niet volledig beschermt tegen diefstal van jouw bitcoins door malware op je computer. + Bitcoin Core zal nu afsluiten om het versleutelingsproces te voltooien. Hou er rekening mee dat versleuteling van uw portemonnee u niet volledig beschermt tegen diefstal van jouw bitcoins door malware op je computer. IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. @@ -1473,10 +1473,6 @@ General Algemeen - - Using OpenSSL version - Gebruikt OpenSSL versie - Using BerkeleyDB version Gebruikt BerkeleyDB versie @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepteer verbindingen van buitenaf (standaard: 1 als geen -proxy of -connect is opgegeven) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee is zeer hoog ingesteld! Dit zijn de transactie kosten die u mogelijk betaald wanneer de schattingen niet beschikbaar zijn. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Een transactietarief (in %s/kB) dat gebruikt wordt als de transactiekosten schatting niet genoeg data heeft. (normaal: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accepteer doorgestuurde transacties ontvangen van goedgekeurde peers, ook wanneer je zelf geen transacties doorstuurt (standaard: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind aan opgegeven adres en luister er altijd op. Gebruik [host]:port notatie voor IPv6 @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuur regels (standaard: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Niet ondersteund argument -whitelistalwaysrelay genegeerd, gebruik -whitelistrelay en/of -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Waarschuwing: Het lijkt erop dat het netwerk geen consensus kan vinden! Sommige delvers lijken problemen te ondervinden. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Waarschuwing: Onbekende blok versies worden gemined! Er zijn mogelijk onbekende regels in werking getreden + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Waarschuwing: Het lijkt erop dat we geen consensus kunnen vinden met onze peers! Mogelijk dient u te upgraden, of andere nodes moeten wellicht upgraden. @@ -3047,6 +3067,10 @@ <category> can be: <categorie> kan zijn: + + Append comment to the user agent string + Voeg commentaar toe aan de user agent string + Block creation options: Blokcreatie-opties: @@ -3091,6 +3115,10 @@ Enable publish raw transaction in <address> Sta toe ruwe transacties te publiceren in <adres> + + Enable transaction replacement in the memory pool (default: %u) + Transactie vervanging inschakelen in het geheugen (standaard: %u) + Error initializing block database Fout bij intialisatie blokkendatabase @@ -3127,10 +3155,22 @@ Invalid -onion address: '%s' Ongeldig -onion adres '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Ongeldig bedrag voor -fallbackfee=<bedrag>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) De transactiegeheugenpool moet onder de <n> megabytes blijven (standaard: %u) + + Location of the auth cookie (default: data dir) + Locatie van de auth cookie (standaard: data dir) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Minimum aantal bytes dat er per sigop in een transactie gerelayed en gemined worden (standaard: %u) + Not enough file descriptors available. Niet genoeg file descriptors beschikbaar. @@ -3139,6 +3179,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion) + + Print version and exit + Laat versie zien en sluit af + Prune cannot be configured with a negative value. Snoeien kan niet worden geconfigureerd met een negatieve waarde. @@ -3195,10 +3239,6 @@ Wallet options: Portemonnee instellingen: - - Warning: This version is obsolete; upgrade required! - Waarschuwing: Deze versie is verouderd; upgraden verplicht! - You need to rebuild the database using -reindex to change -txindex Om -txindex te kunnen veranderen dient u de database herbouwen met gebruik van -reindex. @@ -3295,10 +3335,6 @@ Activating best chain... Beste reeks activeren... - - Always relay transactions received from whitelisted peers (default: %d) - Geef transacties altijd door aan goedgekeurde peers (standaard: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Probeer privésleutels te herstellen van een corrupte wallet.dat bij opstarten @@ -3463,6 +3499,10 @@ Warning Waarschuwing + + Warning: unknown new rules activated (versionbit %i) + Waarschuwing: onbekende nieuwe regels geactiveerd (versionbit %i) + Whether to operate in a blocks only mode (default: %u) Om in alleen een blokmodus te opereren (standaard: %u) diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 233918ff2..c5a0b17e8 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -655,10 +655,6 @@ Debug window I-Debug ing awang - - Using OpenSSL version - Gagamit bersion na ning OpenSSL - Startup time Oras ning umpisa diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 8a8c37748..ffbacfd49 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -87,11 +87,11 @@ Comma separated file (*.csv) - CSV (rozdzielany przecinkami) + Pliki (*.csv) rozdzielone przecinkami Exporting Failed - Błąd przy próbie eksportu + Błąd przy próbie eksportowania There was an error trying to save the address list to %1. Please try again. @@ -137,7 +137,7 @@ This operation needs your wallet passphrase to unlock the wallet. - Ta operacja wymaga hasła do portfela ażeby odblokować portfel. + Operacja wymaga hasła portfela, aby go odblokować. Unlock wallet @@ -145,7 +145,7 @@ This operation needs your wallet passphrase to decrypt the wallet. - Ta operacja wymaga hasła do portfela ażeby odszyfrować portfel. + Operacja wymaga hasła portfela, aby go odszyfrować. Decrypt wallet @@ -161,7 +161,7 @@ Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Uwaga: Jeśli zaszyfrujesz swój portfel i zgubisz hasło to <b>STRACISZ WSZYSTKIE SWOJE BITCOIN'Y</b>! + Uwaga: jeśli zaszyfrujesz swój portfel i zgubisz hasło <b>STRACISZ WSZYSTKIE SWOJE BITCOINY</b>! Are you sure you wish to encrypt your wallet? @@ -169,15 +169,15 @@ Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Program Bitcoin Core zamknie się, aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni Twoich bitcoinów przed kradzieżą przez wirusy lub trojany mogące zainfekować Twój komputer. + Program Bitcoin Core zamknie się, aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni twoich bitcoinów przed kradzieżą przez złośliwe oprogramowanie mogące zainfekować twój komputer. IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - WAŻNE: Wszystkie wykonane wcześniej kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela. + WAŻNE: Wszystkie wcześniejsze kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela. Warning: The Caps Lock key is on! - Uwaga: Klawisz Caps Lock jest włączony! + Uwaga: klawisz Caps Lock jest włączony! Wallet encrypted @@ -185,7 +185,7 @@ Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Wprowadź nowe hasło do portfela.<br/>Proszę używać hasła złożonego z <b>10 lub więcej losowych znaków</b> lub <b>ośmiu lub więcej słów.</b> + Wprowadź nowe hasło do portfela.<br/>Proszę używać hasła złożonego z <b>10 lub więcej losowych znaków</b> albo <b>8 lub więcej słów.</b> Enter the old passphrase and new passphrase to the wallet. @@ -224,7 +224,7 @@ BanTableModel IP/Netmask - IP/Maska Sieci + IP / maska podsieci Banned Until @@ -307,7 +307,7 @@ Bitcoin Core client - Rdzeń klienta Bitcoin + Klient Rdzenia Bitcoina Importing blocks from disk... @@ -319,7 +319,7 @@ Send coins to a Bitcoin address - Wyślij monety na adres Bitcoin + Wyślij monety na adres bitcoinowy Backup wallet to another location @@ -359,7 +359,7 @@ Show information about Bitcoin Core - Pokaż informacje o Rdzeniu Bitcoin + Pokaż informacje o Rdzeniu Bitcoina &Show / Hide @@ -371,7 +371,7 @@ Encrypt the private keys that belong to your wallet - Szyfruj klucze prywatne, które są w Twoim portfelu + Szyfruj klucze prywatne, które są w twoim portfelu Sign messages with your Bitcoin addresses to prove you own them @@ -379,7 +379,7 @@ Verify messages to ensure they were signed with specified Bitcoin addresses - Zweryfikuj wiadomość, aby upewnić się, że została podpisana podanym adresem Bitcoin. + Zweryfikuj wiadomość, aby upewnić się, że została podpisana podanym adresem bitcoinowym. &File @@ -399,11 +399,11 @@ Bitcoin Core - Rdzeń Bitcoin + Rdzeń Bitcoina Request payments (generates QR codes and bitcoin: URIs) - Żądaj płatności (generuje kod QR oraz bitcoin URI) + Żądaj płatności (generuje kod QR oraz bitcoinowe URI) &About Bitcoin Core @@ -449,6 +449,10 @@ %n hour(s) %n godzin%n godzin%n godzin + + %n day(s) + dzień%n dni%n dni + %n week(s) %n tygodni%n tygodni%n tygodni @@ -491,7 +495,7 @@ Catching up... - Synchronizuję się... + Trwa synchronizacja… Date: %1 @@ -810,11 +814,11 @@ The entered address "%1" is already in the address book. - Wprowadzony adres "%1" już istnieje w książce adresowej. + Wprowadzony adres «%1» już istnieje w książce adresowej. The entered address "%1" is not a valid Bitcoin address. - Wprowadzony adres "%1" nie jest poprawnym adresem Bitcoin. + Wprowadzony adres «%1"» nie jest poprawnym adresem bitcoinowym. Could not unlock wallet. @@ -852,7 +856,7 @@ HelpMessageDialog Bitcoin Core - Rdzeń Bitcoin + Rdzeń Bitcoina version @@ -888,7 +892,7 @@ Set language, for example "de_DE" (default: system locale) - Wybierz język, na przykład "de_DE" (domyślnie: język systemowy) + Wybierz język, na przykład «de_DE» (domyślnie: język systemowy) Start minimized @@ -915,7 +919,7 @@ Welcome to Bitcoin Core. - Witam w Bitcoin Core + Witaj w Bitcoin Core As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. @@ -923,7 +927,7 @@ Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Program pobierze i będzie przechowywał kopię łańcucha bloków Bitcoin. W wybranym katalogu musi być przynajmniej %1GB miejsca, a z czasem ilość danych będzie rosła. Portfel będzie przechowywany w tym samym katalogu. + Program pobierze i będzie przechowywał kopię łańcucha bloków bitcoinowych. W wybranym katalogu musi być przynajmniej %1 GB miejsca, a z czasem ilość danych będzie rosła. Portfel będzie przechowywany w tym samym katalogu. Use the default data directory @@ -935,11 +939,11 @@ Bitcoin Core - Rdzeń Bitcoin + Rdzeń Bitcoina Error: Specified data directory "%1" cannot be created. - Błąd: Określony folder danych "%1" nie mógł zostać utworzony. + Błąd: podany folder danych «%1» nie mógł zostać utworzony. Error @@ -1037,7 +1041,7 @@ &Reset Options - Z&resetuj Ustawienia + Z&resetuj ustawienia &Network @@ -1049,7 +1053,7 @@ &Start Bitcoin Core on system login - Uruchamiaj Bitcoin wraz z zalogowaniem do &systemu + Uruchamiaj Bitcoin Core wraz z zalogowaniem do &systemu (0 = auto, <0 = leave that many cores free) @@ -1093,7 +1097,7 @@ Proxy &IP: - Proxy &IP: + &IP proxy: &Port: @@ -1103,6 +1107,10 @@ Port of the proxy (e.g. 9050) Port proxy (np. 9050) + + Used for reaching peers via: + Użyto do połączenia z peerami przy pomocy: + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. Pokazuje, czy wspierane domyślnie proxy SOCKS5 jest używane do łączenia się z peerami w tej sieci @@ -1119,9 +1127,13 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Połącz się z siecią Bitcoin przy pomocy oddzielnego SOCKS5 proxy dla sieci TOR + Use separate SOCKS5 proxy to reach peers via Tor hidden services: - Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor: + Użyj oddzielnego proxy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor: &Window @@ -1133,7 +1145,7 @@ &Minimize to the tray instead of the taskbar - &Minimalizuj do paska przy zegarku zamiast do paska zadań + &Minimalizuj do zasobnika systemowego zamiast do paska zadań M&inimize on close @@ -1145,7 +1157,7 @@ User Interface &language: - Język &Użytkownika: + Język &użytkownika: &Unit to show amounts in: @@ -1240,7 +1252,7 @@ Total: - Wynosi ogółem: + Ogółem: Your current total balance @@ -1385,7 +1397,7 @@ Enter a Bitcoin address (e.g. %1) - Wprowadź adres Bitcoin (np. %1) + Wprowadź adres bitcoinowy (np. %1) %1 d @@ -1428,7 +1440,7 @@ Save QR Code - Zapisz Kod QR + Zapisz kod QR PNG Image (*.png) @@ -1461,10 +1473,6 @@ General Ogólne - - Using OpenSSL version - Używana wersja OpenSSL - Using BerkeleyDB version Używana wersja BerkeleyDB @@ -1493,6 +1501,10 @@ Current number of blocks Aktualna liczba bloków + + Memory Pool + Memory Pool (obszar pamięci) + Current number of transactions Obecna liczba transakcji @@ -1629,10 +1641,30 @@ Clear console Wyczyść konsolę + + &Disconnect Node + Odłącz Nod + Ban Node for Blokuj węzeł na okres + + 1 &hour + 1 &godzina + + + 1 &day + 1 &dzień + + + 1 &week + 1 &tydzień + + + 1 &year + 1 &rok + &Unban Node Odblokuj węzeł @@ -2298,6 +2330,11 @@ &Verify Message &Zweryfikuj wiadomość + + 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! + Wpisz adres, wiadomość oraz sygnaturę (podpis) odbiorcy (upewnij się, że dokładnie skopiujesz wszystkie zakończenia linii, spacje, tabulacje itp.). Uważaj by nie dodać więcej do podpisu niż do samej podpisywanej wiadomości by uniknąć ataku man-in-the-middle. +Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadawca posiada klucz do adresu, natomiast nie potwierdza to, że poprawne wysłanie jakiejkolwiek transakcji! + The Bitcoin address the message was signed with Adres Bitcoin, którym została podpisana wiadomość @@ -2371,7 +2408,7 @@ SplashScreen Bitcoin Core - Rdzeń Bitcoin + Rdzeń Bitcoina The Bitcoin Core developers @@ -2838,11 +2875,11 @@ Backup Wallet - Kopia Zapasowa Portfela + Kopia zapasowa portfela Wallet Data (*.dat) - Dane Portfela (*.dat) + Dane portfela (*.dat) Backup Failed @@ -2858,7 +2895,7 @@ Backup Successful - Wykonano Kopię Zapasową + Wykonano kopię zapasową @@ -2883,6 +2920,18 @@ Accept command line and JSON-RPC commands Akceptuj linię poleceń oraz polecenia JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Jeżeli <category> nie zostanie określona lub <category> = 1, wyświetl wszystkie informacje debugowania. + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Przycinanie skonfigurowano poniżej minimalnych %d MiB. Proszę użyć wyższej liczby. + Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log @@ -2907,6 +2956,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Akceptuj połączenia z zewnątrz (domyślnie: 1 jeśli nie ustawiono -proxy lub -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee ma ustawioną bardzo dużą wartość! Jest to prowizja za transakcje, którą możesz zapłacić gdy oszacowanie opłaty jest niemożliwe. + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6 @@ -2923,6 +2976,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Wymuś przekazywanie transakcji od osób z białej listy, nawet jeśli narusza to lokalną politykę przekazywania (default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Ustaw liczbę wątków skryptu weryfikacyjnego (%u do %d, 0 = auto, <0 = zostaw tyle rdzeni wolnych, domyślnie: %d) @@ -2935,6 +2992,14 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Nie można przywiązać z portem %s na tym komputerze. Bitcoin Core prawdopodobnie już działa. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Niewspierany argument -whitelistalwaysrelay zignorowany, użyj -whitelistrelay i/lub -whitelistforcerelay. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Używaj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje i brak -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) UWAGA: nienaturalnie duża liczba wygenerowanych bloków, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych) @@ -2959,6 +3024,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy. + + -maxmempool must be at least %d MB + -maxmempool musi być przynajmniej %d MB + <category> can be: <category> mogą być: @@ -2991,6 +3060,10 @@ Do you want to rebuild the block database now? Czy chcesz teraz przebudować bazę bloków? + + Enable publish hash block in <address> + Włącz wyświetlanie hasha bloku w <address> + Error initializing block database Błąd inicjowania bazy danych bloków @@ -3027,6 +3100,14 @@ Invalid -onion address: '%s' Nieprawidłowy adres -onion: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Nieprawidłowa kwota dla -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Utrzymuj obszar pamięci dla transakcji poniżej <n> MB (default: %u) + Not enough file descriptors available. Brak wystarczającej liczby deskryptorów plików. @@ -3035,6 +3116,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Łącz z węzłami tylko w sieci <net> (ipv4, piv6 lub onion) + + Print version and exit + Wyświetl wersję i wyjdź + Prune cannot be configured with a negative value. Przycinanie nie może być skonfigurowane z negatywną wartością. @@ -3063,10 +3148,18 @@ Unsupported argument -debugnet ignored, use -debug=net. Niewspierany argument -debugnet zignorowany, użyj -debug=net. + + Unsupported argument -tor found, use -onion. + Znaleziono nieprawidłowy argument -tor, użyj -onion. + Use UPnP to map the listening port (default: %u) Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u) + + User Agent comment (%s) contains unsafe characters. + Komentarz User Agent (%s) zawiera niebezpieczne znaki. + Verifying blocks... Weryfikacja bloków... @@ -3083,10 +3176,6 @@ Wallet options: Opcje portfela: - - Warning: This version is obsolete; upgrade required! - Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja! - You need to rebuild the database using -reindex to change -txindex Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex @@ -3171,10 +3260,6 @@ Activating best chain... Aktywuje najlepszy łańcuch - - Always relay transactions received from whitelisted peers (default: %d) - Zawsze przekazuj informacje o transakcjach otrzymanych od osób z białej listy (domyślnie: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Próbuj podczas uruchamiania programu odzyskać klucze prywatne z uszkodzonego pliku wallet.dat @@ -3259,6 +3344,10 @@ Receive and display P2P network alerts (default: %u) Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Zmniejszanie -maxconnections z %d do %d z powodu ograniczeń systemu. + Rescan the block chain for missing wallet transactions on startup Przeskanuj podczas ładowania programu łańcuch bloków w poszukiwaniu zaginionych transakcji portfela @@ -3335,6 +3424,10 @@ Zapping all transactions from wallet... Usuwam wszystkie transakcje z portfela... + + ZeroMQ notification options: + Opcje powiadomień ZeroMQ: + wallet.dat corrupt, salvage failed wallet.dat uszkodzony, odtworzenie się nie powiodło @@ -3367,14 +3460,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee ma ustawioną bardzo dużą wartość! Jest to prowizja za transakcje, którą płacisz, gdy wysyłasz monety. + Do not keep transactions in the mempool longer than <n> hours (default: %u) - Nie trzymaj w pamięci transakcji starszych niż <n> godzin (domyślnie: %u) + Nie trzymaj w pamięci transakcji starszych niż <n> godz. (domyślnie: %u) Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Opłaty (w %s/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy tworzeniu transakcji (domyślnie: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u) @@ -3391,6 +3496,18 @@ Output debugging information (default: %u, supplying <category> is optional) Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Wspieraj filtrowanie bloków i transakcji używając Filtrów Blooma (domyślnie: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Całkowita długość łańcucha wersji (%i) przekracza maksymalną dopuszczalną długość (%i). Zmniejsz ilość lub rozmiar parametru uacomment. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Próbuje utrzymać ruch wychodzący poniżej zadanego (w MiB na dobę), 0 = bez limitu (domyślnie: %d) + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Znaleziono niewspierany argument -socks. Wybieranie wersji SOCKS nie jest już możliwe, wsparcie programu obejmuje tylko proxy SOCKS5 diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 5cea349fb..1b92395c7 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -387,7 +387,7 @@ &Settings - &definições + &Definições &Help @@ -723,7 +723,7 @@ none - nenhum + Nenhum This label turns red if the transaction size is greater than 1000 bytes. @@ -1033,7 +1033,7 @@ Active command-line options that override above options: - Ativa as opções de linha de comando que sobrescreve as opções acima: + Opções de linha de comando ativas que sobrescreve as opções acima: Reset all client options to default. @@ -1185,7 +1185,7 @@ none - nenhum + Nenhum Confirm options reset @@ -1473,10 +1473,6 @@ General Geral - - Using OpenSSL version - Versão do OpenSSL - Using BerkeleyDB version Versão do BerkeleyDB @@ -1975,7 +1971,7 @@ collapse fee-settings - colapso Taxa de definições + Ocultar painel per kilobyte @@ -2340,7 +2336,7 @@ 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! - Coloque o endereço do destinatário, a mensagem (certifique-se de copiar toda a mensagem, incluindo quebras de linha, espaços, tabulações, etc.) e a assinatura embaixo para verificar a mensagem. Cuidado para não ler mais da assinatura do que está assinado na mensagem, para evitar ser enganado pelo ataque man-in-the-middle. Note que isso somente prova a propriedade de um endereço, e não o remetende de qualquer transação. + Coloque o endereço do autor, a mensagem (certifique-se de copiar toda a mensagem, incluindo quebras de linha, espaços, tabulações, etc.) e a assinatura embaixo para verificar a mensagem. Cuidado para não ler mais da assinatura do que está assinado na mensagem, para evitar ser enganado pelo ataque man-in-the-middle. Note que isso somente prova a propriedade de um endereço, e não o remetende de qualquer transação. The Bitcoin address the message was signed with @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceitar conexões externas (padrão: 1 se opções -proxy ou -connect não estiverem presentes) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee está muito alta! Essa é a taxa de transação que você vai pagar quando a taxa estimada não estiver disponível. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + A variação da taxa (em %s/kB) que será usada quando não houver dados suficientes para se estimar a taxa (default: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Aceita transações retransmitidas advindas de pares em lista branca, mesmo quando não estiver retransmitindo transações (padrão: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6 @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Define o número de threads de verificação de script (%u a %d, 0 = automático, <0 = número de cores deixados livres, padrão: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossível ouvir em %s neste computador. Provavelmente o Bitcoin já está sendo executado. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumento não suportado -whitelistalwaysrelay foi ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atenção: A rede não parecem concordar plenamente! Alguns mineiros parecem estar enfrentando problemas. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Aviso: Versões de bloco desconhecidas sendo mineradas! É possível que regras estranhas estejam ativas + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atenção: Nós não parecemos concordar plenamente com nossos colegas! Você pode precisar atualizar ou outros nós podem precisar atualizar. @@ -3047,6 +3067,10 @@ <category> can be: <category> pode ser: + + Append comment to the user agent string + Adiciona comentário ao user-agent do navegador + Block creation options: Opções de criação de blocos: @@ -3091,6 +3115,10 @@ Enable publish raw transaction in <address> Abilitar a publicação dos dados brutos da transação em <endereço> + + Enable transaction replacement in the memory pool (default: %u) + Habilita substituição de transação em memória (padrão: %u) + Error initializing block database Erro ao inicializar banco de dados de blocos @@ -3127,10 +3155,22 @@ Invalid -onion address: '%s' Endereço -onion inválido: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Valor inválido para -fallbackfee=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Mantenha a mempool de transações abaixo de <n> megabytes (padrão: %u) + + Location of the auth cookie (default: data dir) + Localização do cookie de autenticação (padrão: diretório de dados) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Número mínimo de bytes por sigop em transações que transmitimos e mineramos (default: %u) + Not enough file descriptors available. Decriptadores de arquivos disponíveis insuficientes. @@ -3139,6 +3179,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Somente conectar a clientes na rede <net> (ipv4, ipv6 ou onion) + + Print version and exit + Mostra a versão e sai + Prune cannot be configured with a negative value. O modo Prune não pode ser configurado com um valor negativo. @@ -3195,10 +3239,6 @@ Wallet options: Opções da carteira: - - Warning: This version is obsolete; upgrade required! - Atenção: Essa versão está obsoleta, atualização necessária! - You need to rebuild the database using -reindex to change -txindex Você precisa reconstruir o banco de dados utilizando -reindex @@ -3273,7 +3313,7 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. - Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit<https://www.openssl.org/> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit <https://www.openssl.org> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -3295,10 +3335,6 @@ Activating best chain... Ativando a melhor sequência... - - Always relay transactions received from whitelisted peers (default: %d) - Sempre transmitir transações recebidas de peers confiáveis (padrão: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Tentar recuperar na inicialização chaves privadas de um arquivo wallet.dat corrompido @@ -3383,6 +3419,14 @@ Receive and display P2P network alerts (default: %u) Receba e mostre P2P alerta de rede (padrão: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduzindo -maxconnections de %d para %d, devido a limitações do sistema + + + Rescan the block chain for missing wallet transactions on startup + Re-escanear a block-chain por transações faltantes na carteira durante a inicialização + Send trace/debug info to console instead of debug.log file Mandar informação de trace/debug para o console em vez de para o arquivo debug.log @@ -3411,6 +3455,14 @@ This is experimental software. Este é um software experimental. + + Tor control port password (default: empty) + Senha da porta de controle do Tor (padrão: vazio) + + + Tor control port to use if onion listening enabled (default: %s) + Porta de controle a ser usada se o monitoramento onion estiver habilitado (padrão: %s) + Transaction amount too small Quantidade da transação muito pequena. @@ -3431,6 +3483,10 @@ Unable to bind to %s on this computer (bind returned error %s) Impossível se ligar a %s neste computador (bind retornou erro %s) + + Upgrade wallet to latest format on startup + Atualizar a carteira para o último formato na inicialização + Username for JSON-RPC connections Nome de usuário para conexões JSON-RPC @@ -3443,10 +3499,22 @@ Warning Atenção + + Warning: unknown new rules activated (versionbit %i) + Aviso: Novas regras estranhas foram ativadas (versionbit %i) + + + Whether to operate in a blocks only mode (default: %u) + Quando operar em modo de blocos somente (padrãp: %u) + Zapping all transactions from wallet... Aniquilando todas as transações da carteira... + + ZeroMQ notification options: + Opções de notificação ZeroMQ: + wallet.dat corrupt, salvage failed wallet.dat corrompido, recuperação falhou @@ -3475,14 +3543,70 @@ Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira corrompida + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = manter metadados tx e.g. informação do dono da conta e requisição de pagamente, 2 = descartar metadados tx) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee é muito alto! Essa quantia poderia ser paga em uma única transação. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee é muito alto! Este é o valor da taxa de transação que você irá pagar se enviar a transação. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Não manter transações na mempool por mais que <n> horas (padrão: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Erro ao ler o arquivo wallet.dat! Todas as chaves foram lidas corretamente, mas os dados de transações ou o livro de endereços podem estar faltando ou ser incorretos. + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Comissões (em %s/kB) menores serão consideradas como zero para criação de transação (padrão %s) + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Quão completa a verificação de blocos do -checkblocks é (0-4, padrão: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Mantém um índice completo de transações, usado pela chamada rpc getrawtransaction (padrão: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Número de segundos para impedir que peers mal comportados reconectem (padrão %u) + + + Output debugging information (default: %u, supplying <category> is optional) + Informação de saída de debug (padrão: %u, definir <category> é opcional) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + Suportar filtragem de blocos e transações com filtros bloom (padrão: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + O tamanho total da string de versão da rede (%i) excede o tamanho máximo (%i). Reduza o numero ou tamanho de uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Tenta manter tráfego fora dos limites dentro do alvo especificado (em MiB por 24h), 0 = sem limite (padrão: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Argumento inválido -socks encontrado. Definir a versão do SOCKS não é mais possível, somente proxys SOCK5 são suportados. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor (padrão: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nome de usuário e senha hash para conexões JSON-RPC. O campo <userpw> vem com o formato: <USERNAME>:<SALT>$<HASH>. Um script python canônico é incluído em share/rpcuser. Essa opção pode ser especificada múltiplas vezes. + (default: %s) (padrão: %s) @@ -3531,10 +3655,18 @@ Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) Buffer máximo de recebimento por conexão, <n>*1000 bytes (padrão: %u) + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Buffer máximo de envio por conexão, <n>*1000 bytes (padrão: %u) + Prepend debug output with timestamp (default: %u) Adiciona timestamp como prefixo no debug (padrão: %u) + + Relay and mine data carrier transactions (default: %u) + Transações de dados de operadora (padrão: %u) + Relay non-P2SH multisig (default: %u) Retransmitir P2SH não multisig (padrão: %u) @@ -3567,6 +3699,10 @@ Spend unconfirmed change when sending transactions (default: %u) Gastar troco não confirmado quando enviar transações (padrão: %u) + + Threshold for disconnecting misbehaving peers (default: %u) + Limite para desconectar peers mal comportados (padrão: %u) + Unknown network specified in -onlynet: '%s' Rede desconhecida especificada em -onlynet: '%s' diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index ffed44a61..362769138 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Clique á direita para editar endereço ou rótulo + Clique com o botão direito para editar o endereço ou rótulo Create a new address @@ -31,11 +31,11 @@ Delete the currently selected address from the list - Apagar o endereço selecionado da lista + Eliminar o endereço selecionado da lista Export the data in the current tab to a file - Exportar os dados no separador actual para um ficheiro + Exportar os dados no separador atual para um ficheiro &Export @@ -43,15 +43,15 @@ &Delete - &Eliminar\ + &Eliminar Choose the address to send coins to - Escolha o endereço para o qual pretende enviar moedas + Escolha o endereço para enviar as moedas Choose the address to receive coins with - Escolha o endereço com o qual pretende receber moedas + Escolha o endereço para receber as moedas com C&hoose @@ -63,7 +63,7 @@ Receiving addresses - Endereços de depósito + Endereços de a receber These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. @@ -71,7 +71,7 @@ These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estes são os seus endereços Bitcoin para receber pagamentos. É recomendado que utilize um endereço novo para cada transacção. + Estes são os seus endereços do Bitcoin para receber pagamentos. É recomendado que utilize um novo endereço para cada transação. Copy &Label @@ -91,7 +91,7 @@ Exporting Failed - A Exportação Falhou + Exportação Falhou There was an error trying to save the address list to %1. Please try again. @@ -102,7 +102,7 @@ AddressTableModel Label - Rótulo + Etiqueta Address @@ -110,26 +110,26 @@ (no label) - (sem rótulo) + (sem etiqueta) AskPassphraseDialog Passphrase Dialog - Diálogo de frase de segurança + Janela da frase de palavra-passe Enter passphrase - Insira a frase de segurança + Insira a frase de palavra-passe New passphrase - Nova frase de segurança + Nova frase de palavra-passe Repeat new passphrase - Repita a nova frase de segurança + Repita a nova frase de palavra-passe Encrypt wallet @@ -137,7 +137,7 @@ This operation needs your wallet passphrase to unlock the wallet. - A sua frase de segurança é necessária para desbloquear a carteira. + Esta operação precisa da sua frase de palavra-passe da carteira para desbloquear a mesma. Unlock wallet @@ -145,7 +145,7 @@ This operation needs your wallet passphrase to decrypt the wallet. - A sua frase de segurança é necessária para desencriptar a carteira. + Esta operação precisa da sua frase de palavra-passe da carteira para desencriptar a mesma. Decrypt wallet @@ -153,7 +153,7 @@ Change passphrase - Alterar frase de segurança + Alterar frase de palavra-passe Confirm wallet encryption @@ -161,7 +161,7 @@ Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atenção: Se encriptar a carteira e perder a sua senha irá <b>PERDER TODOS OS SEUS BITCOINS</b>! + Aviso: se encriptar a sua carteira e perder a sua frase de de palavra-passe, irá <b>PERDER TODOS OS SEUS BITCOINS</b>! Are you sure you wish to encrypt your wallet? @@ -177,7 +177,7 @@ Warning: The Caps Lock key is on! - Atenção: A tecla Caps Lock está activa! + Atenção: a tecla Caps Lock está ativada! Wallet encrypted @@ -185,11 +185,11 @@ Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Escreva a nova frase de seguraça da sua carteira. <br/> Por favor, use uma frase de <b>10 ou mais caracteres aleatórios,</b> ou <b>oito ou mais palavras</b>. + Insira a nova frase de palavra-passe da sua carteira. <br/> Por favor, utilize uma frase de palavra-passe com <b>mais de 10 ou mais carateres aleatórios,</b> ou <b>oito ou mais palavras</b>. Enter the old passphrase and new passphrase to the wallet. - Escreva a antiga frase de segurança da carteira, seguida da nova. + Insira a frase de palavra-passe antiga e a nova frase de palavra-passe para carteira. Wallet encryption failed @@ -201,7 +201,7 @@ The supplied passphrases do not match. - As frases de segurança fornecidas não coincidem. + As frases de palavra-passe inseridas não coincidem. Wallet unlock failed @@ -209,7 +209,7 @@ The passphrase entered for the wallet decryption was incorrect. - A frase de segurança introduzida para a desencriptação da carteira estava incorreta. + A frase de palavra-passe inserida para a desencriptação da carteira estava incorreta. Wallet decryption failed @@ -217,12 +217,20 @@ Wallet passphrase was successfully changed. - A frase de segurança da carteira foi alterada com êxito. + A frase de palavra-passe da carteira foi alterada com sucesso. BanTableModel - + + IP/Netmask + IP/Máscara de Rede + + + Banned Until + Banido Até + + BitcoinGUI @@ -235,7 +243,7 @@ &Overview - Visã&o geral + &Sinopse Node @@ -243,7 +251,7 @@ Show general overview of wallet - Mostrar visão geral da carteira + Mostrar sinopse geral da carteira &Transactions @@ -251,7 +259,7 @@ Browse transaction history - Navegar pelo histórico de transações + Explorar histórico das transações E&xit @@ -283,15 +291,15 @@ &Change Passphrase... - Mudar &Palavra-passe... + Alterar &Frase de Palavra-passe... &Sending addresses... - A &enviar endereços... + A &enviar os endereços... &Receiving addresses... - A &receber endereços... + A &receber os endereços... Open &URI... @@ -299,15 +307,15 @@ Bitcoin Core client - Cliente Bitcoin Core + Cliente do Bitcoin Core Importing blocks from disk... - A importar blocos do disco... + A importar os blocos do disco... Reindexing blocks on disk... - A reindexar blocos no disco... + A reindexar os blocos no disco... Send coins to a Bitcoin address @@ -315,11 +323,11 @@ Backup wallet to another location - Faça uma cópia de segurança da carteira para outra localização + Efetue uma cópia de segurança da carteira para outra localização Change the passphrase used for wallet encryption - Mudar a frase de segurança utilizada na encriptação da carteira + Alterar a frase de palavra-passe utilizada na encriptação da carteira &Debug window @@ -351,7 +359,7 @@ Show information about Bitcoin Core - Mostrar informação sobre Bitcoin Core + Mostrar informação sobre o Bitcoin Core &Show / Hide @@ -359,7 +367,7 @@ Show or hide the main Window - Mostrar ou esconder a janela principal + Mostrar ou ocultar a janela principal Encrypt the private keys that belong to your wallet @@ -387,7 +395,7 @@ Tabs toolbar - Barra de separadores + Barra de ferramentas dos separadores Bitcoin Core @@ -395,7 +403,7 @@ Request payments (generates QR codes and bitcoin: URIs) - Solicitar pagamentos (gera códigos QR e URIs bitcoin:) + Solicitar pagamentos (gera códigos QR e bitcoin: URIs) &About Bitcoin Core @@ -403,7 +411,7 @@ Modify configuration options for Bitcoin Core - Modificar opções de configuração de Bitcoin Core + Modificar as opções de configuração do Bitcoin Core Show the list of used sending addresses and labels @@ -419,11 +427,11 @@ &Command-line options - &Opções da linha de &comandos + &Opções da linha de &comando Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostrar a mensagem de ajuda do Bitcoin Core para obter uma lista com possíveis opções de linha de comandos + Mostrar a mensagem de ajuda do Bitcoin Core para obter uma lista com possíveis opções de linha de comando do Bitcoin %n active connection(s) to Bitcoin network @@ -463,11 +471,11 @@ Last received block was generated %1 ago. - O último bloco recebido foi gerado %1 atrás. + O último bloco recebido foi gerado há %1. Transactions after this will not yet be visible. - Transações posteriores não serão visíveis por enquanto. + As transações depois de isto ainda não serão visíveis. Error @@ -498,7 +506,7 @@ Amount: %1 - Quantia: %1 + Valor: %1 @@ -510,7 +518,7 @@ Label: %1 - Rótulo: %1 + Etiqueta: %1 @@ -547,7 +555,7 @@ CoinControlDialog Coin Selection - Seleção de moeda + Seleção de Moeda Quantity: @@ -559,7 +567,7 @@ Amount: - Quantia: + Valor: Priority: @@ -575,7 +583,7 @@ After Fee: - Depois da Taxa: + Depois da taxa: Change: @@ -583,23 +591,23 @@ (un)select all - (des)seleccionar todos + (des)selecionar todos Tree mode - Modo árvore + Modo de árvore List mode - Modo lista + Modo de lista Amount - Quantia + Valor Received with label - Recebido com rótulo + Recebido com etiqueta Received with address @@ -611,7 +619,7 @@ Confirmations - Confirmados + Confirmações Confirmed @@ -627,23 +635,23 @@ Copy label - Copiar rótulo + Copiar etiqueta Copy amount - Copiar quantia + Copiar valor Copy transaction ID - Copiar ID da transação + Copiar id. da transação Lock unspent - Bloquear não gastos + Bloquear não gastas Unlock unspent - Desbloquear não gastos + Desbloquear não gastas Copy quantity @@ -655,7 +663,7 @@ Copy after fee - Copiar valor após taxa + Copiar depois da taxa Copy bytes @@ -687,7 +695,7 @@ medium-high - média-alta + média alta medium @@ -695,7 +703,7 @@ low-medium - média-baixa + média baixa low @@ -707,7 +715,7 @@ lowest - muito alta + muito baixa (%1 locked) @@ -719,15 +727,15 @@ This label turns red if the transaction size is greater than 1000 bytes. - Este rótulo fica vermelho se o tamanho da transacção exceder os 1000 bytes. + Esta etiqueta fica vermelha se o tamanho da transação exceder os 1000 bytes. This label turns red if the priority is smaller than "medium". - Esta legenda fica vermelha se a prioridade for menor que "média". + Esta etiqueta fica vermelha se a prioridade for menor que "média". This label turns red if any recipient receives an amount smaller than %1. - Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1. + Esta etiqueta fica vermelha se qualquer recipiente receber uma quantia menor que %1. Can vary +/- %1 satoshi(s) per input. @@ -755,7 +763,7 @@ (no label) - (sem rótulo) + (sem etiqueta) change from %1 (%2) @@ -774,15 +782,15 @@ &Label - &Rótulo + &Etiqueta The label associated with this address list entry - O rótulo associado com esta entrada no livro de endereços + A etiqueta associada com esta entrada da lista de endereços The address associated with this address list entry. This can only be modified for sending addresses. - O endereço associado com o esta entrada no livro de endereços. Isto só pode ser modificado para endereços de saída. + O endereço associado com o esta entrada da lista de endereços. Isto só pode ser modificado para os endereços de envio. &Address @@ -825,7 +833,7 @@ FreespaceChecker A new data directory will be created. - Uma nova pasta de dados será criada. + Irá ser criada uma nova diretoria de dados. name @@ -841,7 +849,7 @@ Cannot create data directory here. - Não pode ser criada uma pasta de dados aqui. + Não é possível criar aqui uma diretoria de dados. @@ -864,7 +872,7 @@ Command-line options - Opções de linha de comandos + Opções da linha de comando Usage: @@ -872,9 +880,37 @@ command-line options - opções da linha de comandos + opções da linha de comando - + + UI Options: + Opções da IU: + + + Choose data directory on startup (default: %u) + Escolha a diretoria dos dados no arranque (predefinição: %u) + + + Set language, for example "de_DE" (default: system locale) + Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema) + + + Start minimized + Iniciar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Configurar certificados SSL root para pedido de pagamento (default: -system-) + + + Show splash screen on startup (default: %u) + Mostrar o ecrã de abertura no arranque (predefinição: %u) + + + Reset all settings changes made over the GUI + Reiniciar as alterações das configurações efetuadas na GUI + + Intro @@ -887,19 +923,19 @@ As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Sendo esta a primeira vez que o programa é iniciado, poderá escolher onde o Bitcoin Core irá guardar os seus dados. + Como esta é a primeira vez que o programa é iniciado, pode escolher onde guardar os seus dados do Bitcoin Core. Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - O Bitcoin Core vai transferir e armazenar uma cópia do "block chain" (cadeia de blocos). Pelo menos %1GB de dados serão armazenados nesta pasta, e vão crescer ao longo do tempo. A sua carteira também irá ser armazenada nesta pasta. + O Bitcoin Core irá transferir e guardar uma cópia da cadeia de bloco do Bitcoin. Pelo menos %1GB de dados serão guardados nesta diretoria, e estes irão crescer ao longo do tempo. A sua carteira também será guardada nesta diretoria. Use the default data directory - Utilizar a pasta de dados padrão + Utilizar a diretoria de dados predefinida Use a custom data directory: - Utilizar uma pasta de dados personalizada: + Utilizar uma diretoria de dados personalizada: Bitcoin Core @@ -907,7 +943,7 @@ Error: Specified data directory "%1" cannot be created. - Erro: Pasta de dados especificada como "%1, não pode ser criada. + Erro: não pode ser criada a diretoria de dados especificada como "%1. Error @@ -915,7 +951,7 @@ %n GB of free space available - %n GB de espaço livre disponível %n GB de espaço livre disponível + %n GB de espaço livre disponível%n GB de espaço livre disponível (of %n GB needed) @@ -969,11 +1005,11 @@ Accept connections from outside - Aceitar conceções externas + Aceitar ligações externas Allow incoming connections - Permitir conexão + Permitir ligação a receber IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) @@ -985,7 +1021,7 @@ The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin Core. + O idioma da da interface do utilizador pode ser definida aqui. Esta definição será aplicada depois de reiniciar o Bitcoin Core. 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 |. @@ -994,15 +1030,15 @@ Third party transaction URLs - URLs de transação de outrem + URLs de transação de terceiros Active command-line options that override above options: - Opções de linha de comandos ativas que se sobrepõem ás opções anteriores: + Ativar as opções da linha de comando que se sobrepõem às opções acima: Reset all client options to default. - Repor todas as opções do cliente. + Repor todas as opções de cliente para a predefinição. &Reset Options @@ -1014,15 +1050,15 @@ Automatically start Bitcoin Core after logging in to the system. - Começar o Bitcoin Core automaticamente ao iniciar sessão no sistema. + Iniciar automaticamente o Bitcoin Core depois de iniciar a sessão no sistema. &Start Bitcoin Core on system login - &Começar o Bitcoin Core ao iniciar o sistema + &Iniciar o Bitcoin Core ao iniciar a sessão no sistema (0 = auto, <0 = leave that many cores free) - (0 = auto, <0 = Deixar essa quantidade de núcleos livre) + (0 = automático, <0 = deixar essa quantidade de núcleos livre) W&allet @@ -1030,11 +1066,11 @@ Expert - Especialista + Especialistas Enable coin &control features - Ativar funcionalidades de controlo de transação. + Ativar as funcionalidades de controlo de moedas 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. @@ -1050,7 +1086,7 @@ Map port using &UPnP - Mapear porta usando &UPnP + Mapear porta, utilizando &UPnP Connect to the Bitcoin network through a SOCKS5 proxy. @@ -1072,6 +1108,34 @@ Port of the proxy (e.g. 9050) Porto do proxy (p.ex. 9050) + + Used for reaching peers via: + Usado para alcançar nós via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra, caso o proxy SOCKS5 predefinido submetido seja usado para alcançar nós através deste tipo de rede. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Ligar à rede Bitcoin através de um proxy SOCKS5 separado para utilizar os serviços ocultos do Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilizar um proxy SOCKS5 separado para alcançar nós via serviços ocultos do Tor: + &Window &Janela @@ -1102,11 +1166,11 @@ Choose the default subdivision unit to show in the interface and when sending coins. - Escolha a subdivisão unitária a ser mostrada por defeito na aplicação e ao enviar moedas. + Escolha a unidade da subdivisão predefinida para ser mostrada na interface e quando enviar as moedas. Whether to show coin control features or not. - Escolha para mostrar funcionalidades de Coin Control ou não. + Escolha se deve mostrar as funcionalidades de controlo de moedas ou não. &OK @@ -1118,7 +1182,7 @@ default - padrão + predefinição none @@ -1126,7 +1190,7 @@ Confirm options reset - Confirme a reposição de opções + Confirme a reposição das opções Client restart required to activate changes. @@ -1252,7 +1316,7 @@ Cannot start bitcoin: click-to-pay handler - Impossível iniciar o controlador de bitcoin: click-to-pay + Não é possível iniciar o Bitcoin: utilizador clique-para-pagar Payment request fetch URL is invalid: %1 @@ -1410,17 +1474,13 @@ General Geral - - Using OpenSSL version - Usando versão OpenSSL - Using BerkeleyDB version Versão BerkeleyDB em uso Startup time - Hora de inicialização + Hora de Arranque Network @@ -1442,6 +1502,22 @@ Current number of blocks Número actual de blocos + + Memory Pool + Banco de Memória + + + Current number of transactions + Número actual de transacções + + + Memory usage + Utilização de memória + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + Abrir o ficheiro de registo de depuração da pasta de dados actual. Isto pode demorar alguns segundos para ficheiros de registo grandes. + Received Recebido @@ -1452,12 +1528,20 @@ &Peers - &Conexção + &Conexão + + + Banned peers + Nós banidos Select a peer to view detailed information. Selecione uma conexação para ver informação em detalhe. + + Whitelisted + Permitido por si + Direction Direcção @@ -1466,6 +1550,18 @@ Version Versão + + Starting Block + Bloco Inicial + + + Synced Headers + Cabeçalhos Sincronizados + + + Synced Blocks + Blocos Sincronizados + User Agent Agente Usuário @@ -1480,7 +1576,7 @@ Connection Time - Tempo de Conexção + Tempo de Ligação Last Send @@ -1494,6 +1590,18 @@ Ping Time Tempo de Latência + + The duration of a currently outstanding ping. + A duração de um ping atualmente pendente. + + + Ping Wait + Espera do Ping + + + Time Offset + Fuso Horário + Last block time Data do último bloco @@ -1538,6 +1646,34 @@ Clear console Limpar consola + + &Disconnect Node + &Desligar Nó + + + Ban Node for + Banir Nó por + + + 1 &hour + 1 &hora + + + 1 &day + 1 &dia + + + 1 &week + 1 &semana + + + 1 &year + 1 &ano + + + &Unban Node + &Desbloquear Nó + Welcome to the Bitcoin Core RPC console. Bem-vindo à consola RPC do Bitcoin Core. @@ -1566,6 +1702,10 @@ %1 GB %1 GB + + (node id: %1) + (id nó: %1) + via %1 via %1 @@ -1582,6 +1722,14 @@ Outbound Saída + + Yes + Sim + + + No + Não + Unknown Desconhecido @@ -1764,7 +1912,7 @@ Coin Control Features - Funcionalidades de Coin Control: + Funcionalidades do Controlo de Moedas: Inputs... @@ -1820,7 +1968,7 @@ Choose... - Escolha... + Escolher... collapse fee-settings @@ -1950,6 +2098,10 @@ Copy change Copiar alteração + + Total Amount %1 + Quantia Total %1 + or ou @@ -1974,10 +2126,26 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. A transação foi rejeitada! Isto poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas tiverem sido gastas na cópia mas não tiverem sido marcadas como gastas aqui. + + A fee higher than %1 is considered an absurdly high fee. + Uma taxa superior a %1 é considerada muito alta. + Payment request expired. Pedido de pagamento expirou. + + Pay only the required fee of %1 + Pagar somente a taxa mínima de %1 + + + The recipient address is not valid. Please recheck. + O endereço de destino não é válido. Por favor, verifique novamente. + + + Duplicate address found: addresses should only be used once each. + Endereço duplicado encontrado: cada endereço só poderá ser usado uma vez. + Warning: Invalid Bitcoin address Aviso: Endereço Bitcoin inválido @@ -2023,7 +2191,7 @@ Choose previously used address - Escolher endereço usado previamente + Escolha o endereço utilizado anteriormente This is a normal payment. @@ -2049,10 +2217,26 @@ Remove this entry Remover esta entrada + + 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. + A taxa será deduzida ao montante enviado. O destinatário irá receber menos bitcoins do que as que introduziu no campo montante. Caso sejam seleccionados múltiplos destinatários, a taxa será repartida equitativamente. + + + S&ubtract fee from amount + S&ubtrair taxa ao montante + Message: Mensagem: + + This is an unauthenticated payment request. + Pedido de pagamento não autenticado. + + + This is an authenticated payment request. + Pedido de pagamento autenticado. + Enter a label for this address to add it to the list of used addresses Introduza um rótulo para este endereço para o adicionar à sua lista de endereços usados @@ -2091,13 +2275,17 @@ &Sign Message &Assinar Mensagem + + 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. + Pode assinar mensagens com os seus endereços para provar que são seus. Tenha atenção ao assinar mensagens ambíguas, pois ataques de phishing podem tentar enganá-lo de modo a assinar a sua identidade para os atacantes. Apenas assine declarações detalhadas com as quais concorde. + The Bitcoin address to sign the message with O endereço Bitcoin para designar a mensagem Choose previously used address - Escolher endereço usado previamente + Escolha o endereço utilizado anteriormente Alt+A @@ -2143,6 +2331,10 @@ &Verify Message &Verificar Mensagem + + 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! + Introduza o endereço de assinatura, mensagem (assegure-se que copia quebras de linha, espaços, tabulações, etc. exactamente) e assinatura abaixo para verificar a mensagem. Tenha atenção para não ler mais na assinatura do que o que estiver na mensagem assinada, para evitar ser enganado por um atacante que se encontre entre si e quem assinou a mensagem. + The Bitcoin address the message was signed with O endereço Bitcoin com que a mensagem foi designada @@ -2494,6 +2686,10 @@ Whether or not a watch-only address is involved in this transaction. Desde que um endereço de modo-verificação faça parte ou não desta transação + + User-defined intent/purpose of the transaction. + Motivo da transacção definido pelo utilizador. + Amount removed from or added to balance. Quantia retirada ou adicionada ao saldo. @@ -2573,6 +2769,10 @@ Copy transaction ID Copiar ID da Transação + + Copy raw transaction + Copiar dados brutos da transacção + Edit label Editar rótulo @@ -2653,7 +2853,7 @@ WalletFrame No wallet has been loaded. - Nenhuma carteira foi carregada. + Não foi carregada nenhuma carteira. @@ -2720,14 +2920,70 @@ Accept command line and JSON-RPC commands Aceitar comandos de linha de comandos e JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Se <category> não é fornecida ou <category> = 1, imprimir toda a informação de depuração. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Total máximo de taxas (em %s) a utilizar numa única transacção; definir este valor demasiado baixo pode abortar transacções grandes (padrão: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Por favor verifique que a data e hora do seu computador estão correctas! Se o seu relógio não estiver certo o Bitcoin Core não irá funcionar correctamente. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Poda configurada abaixo do mínimo de %d MiB. Por favor, utilize um valor mais elevado. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Suprimir: a última sincronização da carteira vai além dos dados suprimidos. O que precisa para -reindex (transferir novamente toda a cadeia de blocos, no caso de nó suprimido) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduza os requisitos de armazenamento podando (eliminando) blocos antigos. Este modo é incompatível com -txindex e -rescan. Aviso: Reverter esta opção requer um novo descarregamento da cadeia de blocos completa. (padrão: 0 = desactivar poda de blocos, >%u = tamanho desejado em MiB para utilizar em ficheiros de blocos) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Reanálises não são possíveis no modo de suprimir. Para isso terá de utilizar -reindex que irá transferir novamente toda a cadeia de blocos. + + + Error: A fatal internal error occurred, see debug.log for details + Erro: Um erro fatal interno ocorreu, verificar debug.log para mais informação + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Taxa (em %s/kB) a adicionar às transacções que envia (padrão: %s) + + + Pruning blockstore... + A podar a blockstore... + Run in the background as a daemon and accept commands Correr o processo em segundo plano e aceitar comandos + + Unable to start HTTP server. See debug log for details. + Não é possível iniciar o servidor HTTP. Verifique o debug.log para detalhes. + Accept connections from outside (default: 1 if no -proxy or -connect) Aceitar ligações externas (padrão: 1 sem -proxy ou -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee está definida muito elevada! Esta é a taxa de transação pode poderá pagar quando as estimativas de taxas não estão disponíveis. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Uma percentagem da taxa (em %s/kB) que será utilizada quando a estimativa da taxa tiver dados insuficientes (predefinição: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Aceitar as transações retransmitidas recebidas dos pares na lista branca, mesmo quando não retransmitir as transações (predefinição: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Associar a endereço específico e escutar sempre nele. Use a notação [anfitrião]:porta para IPv6 @@ -2744,10 +3000,18 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Forçar retransmissão das transações a partir dos pares da lista branca, mesmo que estes violem a política de retransmissão local (predefinição: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Defina o número de processos de verificação (%u até %d, 0 = automático, <0 = ldisponibiliza esse número de núcleos livres, por defeito: %d) + + 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 + A base de dados de blocos contém um bloco que aparenta ser do futuro. Isto pode ser causado por uma data incorrecta definida no seu computador. Reconstrua apenas a base de dados de blocos caso tenha a certeza de que a data e hora do seu computador estão correctos. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta é uma versão de testes pré-lançamento - use à sua responsabilidade - não usar para minar ou aplicações comerciais @@ -2756,10 +3020,30 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Incapaz de vincular à porta %s neste computador. O Bitcoin Core provavelmente já está a correr. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumento não suportado -whitelistalwaysrelay ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utilizar UPnP para mapear a porta de escuta (predefinição: 1 quando escutar e sem -proxy) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + AVISO: gerado um número anormalmente elevado de blocos, %d blocos recebidos nas últimas %d horas (%d esperados) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + AVISO: verifique a sua conexão à rede, %d blocos recebidos nas últimas %d horas (%d esperados) + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Aviso: A rede não parece estar completamente de acordo! Parece que alguns mineiros estão com dificuldades técnicas. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Atenção: Versões desconhecidas de blocos estão a ser mineradas! É possível que regras desconhecias estão a ser efetuadas + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atenção: Parecemos não estar de acordo com os nossos pares! Poderá ter que atualizar o seu cliente, ou outros nós poderão ter que atualizar os seus clientes. @@ -2772,13 +3056,21 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Ligações na lista branca conectam desde a seguinte netmask ou endereço IP. Posse ser especificado varias vezes. + + -maxmempool must be at least %d MB + - máximo do banco de memória deverá ser pelo menos %d MB + <category> can be: <categoria> pode ser: + + Append comment to the user agent string + Anexar um comentário para a entrada de agente do utilizador + Block creation options: - Opções de criação de bloco: + Opções da criação de bloco: Connect only to the specified node(s) @@ -2786,7 +3078,7 @@ Connection options: - Opcões de conexção: + Opções de ligação: Corrupted block database detected @@ -2794,16 +3086,36 @@ Debugging/Testing options: - Depuração/Opções teste: + Opções de Depuração/Teste: Do not load the wallet and disable wallet RPC calls - Não carregar a carteira e desativar chamadas RPC de carteira. + Não carregar a carteira e desativar as chamadas de RPC da carteira. Do you want to rebuild the block database now? Deseja reconstruir agora a base de dados de blocos. + + Enable publish hash block in <address> + Activar publicação do hash do bloco em <address> + + + Enable publish hash transaction in <address> + Activar publicação do hash da transacção em <address> + + + Enable publish raw block in <address> + Activar publicação de dados brutos do bloco em <address> + + + Enable publish raw transaction in <address> + Activar publicação de dados brutos da transacção em <address> + + + Enable transaction replacement in the memory pool (default: %u) + Ativar substituição da transação no banco de memória (predefinição: %u) + Error initializing block database Erro ao inicializar a cadeia de blocos @@ -2840,6 +3152,22 @@ Invalid -onion address: '%s' Endereço -onion inválido: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Valor inválido para -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Manter o banco de memória da transação abaixo de <n> megabytes (predefinição: %u) + + + Location of the auth cookie (default: data dir) + Localização de cookie de autorização (predefinição: diretoria de dados) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Mínimo de bytes por sigop nas transações que nós transmitimos e mine (predefinição: %u) + Not enough file descriptors available. Os descritores de ficheiros disponíveis são insuficientes. @@ -2848,6 +3176,18 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Somente conectar aos nodes na rede <net> (ipv4, ipv6 ou onion) + + Print version and exit + Imprimir versão e sair + + + Prune cannot be configured with a negative value. + Poda não pode ser configurada com um valor negativo. + + + Prune mode is incompatible with -txindex. + Modo poda é incompatível com -txindex. + Set database cache size in megabytes (%d to %d, default: %d) Definir o tamanho da cache de base de dados em megabytes (%d a %d, padrão: %d) @@ -2860,9 +3200,25 @@ Specify wallet file (within data directory) Especifique ficheiro de carteira (dentro da pasta de dados) + + Unsupported argument -benchmark ignored, use -debug=bench. + Argumento não suportado -benchmark ignorado, use -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argumento não suportado -debugnet ignorado, use -debug=net. + + + Unsupported argument -tor found, use -onion. + Argumento não suportado -tor encontrado, use -onion. + Use UPnP to map the listening port (default: %u) - Use UPnP para mapear a porto de escuta (default: %u) + Utilizar UPnP para mapear a porta de escuta (predefinição: %u) + + + User Agent comment (%s) contains unsafe characters. + Comentário no User Agent (%s) contém caracteres inseguros. Verifying blocks... @@ -2880,10 +3236,6 @@ Wallet options: Opções da carteira: - - Warning: This version is obsolete; upgrade required! - Aviso: Esta versão está desatualizada; atualização necessária! - You need to rebuild the database using -reindex to change -txindex É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex @@ -2904,34 +3256,122 @@ Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin Core já está a ser executado. + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Crie ficheiros novos com as permisões predefinidas do sistema, em vez de umask 077 (apenas eficaz caso a funcionalidade carteira esteja desactivada) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Descobrir o próprio endereço IP (padrão: 1 ao escutar e sem -externalip ou -proxy) + + + Error: Listening for incoming connections failed (listen returned error %s) + Erro: A escuta de ligações de entrada falhou (escuta devolveu erro %s) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Executar comando quando um alerta relevante for recebido ou em caso de uma divisão longa da cadeia de blocos (no comando, %s é substituído pela mensagem) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Taxas (em %s/kB) abaixo deste valor são consideradas nulas para propagação, mineração e criação de transacções (padrão: %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + Caso o paytxfee não seja definido, inclua uma taxa suficiente para que as transacções comecem a ser confirmadas, em média, dentro de n blocos (padrão: %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Montante inválido para -maxtxfee=<amount>: '%s' (deverá ser, no mínimo , a taxa mínima de propagação de %s, de modo a evitar transações bloqueadas) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Tamanho máximo dos dados em transacções que incluem dados que propagamos e mineramos (padrão: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + Encontrar pares usando DNS lookup, caso o número de endereços seja reduzido (padrão: 1 excepto -connect) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Usar credenciais aleatórias por cada ligação proxy. Permite que o Tor use stream isolation (padrão: %u) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Definir o número threads para a geração de moedas, caso activo (-1 = todos os cores, padrão: %d) + + + The transaction amount is too small to send after the fee has been deducted + O montante da transacção é demasiado baixo após a dedução da taxa + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + Este produto inclui software desenvolvido pelo OpenSSL Project para utilização no OpenSSL Toolkit <https://www.openssl.org/> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + Os pares enviados para a lista branca não podem ser DoS banidos e as suas transações são sempre retransmitidas, mesmo que já estejam no banco de memória, útil, por exemplo, para um acesso + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + É necessário reconstruir a base de dados, utilizando -reindex para voltar ao modo de suprimir. Isto irá transferir novamente a cadeia de blocos completa + (default: %u) - (por defeito: %u) + (predefinição: %u) + + + Accept public REST requests (default: %u) + Aceitar pedidos REST públicos (predefinição: %u) + + + Activating best chain... + A activar a melhor cadeia... + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Tentar recuperar chaves privadas de um wallet.dat corrompido ao iniciar + + + Automatically create Tor hidden service (default: %d) + Criar automaticamente o serviço Tor oculto (predefinição: %d) Cannot resolve -whitebind address: '%s' Não foi possível resolver o endereço -whitebind: '%s' + + Connect through SOCKS5 proxy + Ligar através de um proxy SOCKS5 + Copyright (C) 2009-%i The Bitcoin Core Developers Copyright (C) 2009-%i Os Programadores do Bitcoin Core Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin Core + Erro ao carregar wallet.dat: A carteira requer uma versão mais recente do Bitcoin Core + + + Error reading from database, shutting down. + Erro ao ler da base de dados, encerrando. + + + Imports blocks from external blk000??.dat file on startup + Importar blocos de um ficheiro blk000??.dat externo ao iniciar Information Informação + + Initialization sanity check failed. Bitcoin Core is shutting down. + Falha na prova real inicial. Bitcoin Core está a desligar. + Invalid amount for -maxtxfee=<amount>: '%s' Quantia inválida para -maxtxfee=<quantidade>: '%s' @@ -2944,10 +3384,58 @@ Invalid amount for -mintxfee=<amount>: '%s' Quantia inválida para -mintxfee=<quantidade>: '%s' + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Montante inválido para -paytxfee=<amount>: '%s' (deverá ser no mínimo %s) + + + Invalid netmask specified in -whitelist: '%s' + Máscara de rede inválida especificada em -whitelist: '%s' + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Manter no máximo <n> transacções órfãs em memória (padrão: %u) + + + Need to specify a port with -whitebind: '%s' + Necessário especificar uma porta com -whitebind: '%s' + + + Node relay options: + Opções da transmissão de nós: + + + RPC server options: + Opções do servidor RPC: + + + Rebuild block chain index from current blk000??.dat files on startup + Reconstruir a cadeia de blocos a partir dos ficheiros blk000??.dat actuais ao iniciar + + + Receive and display P2P network alerts (default: %u) + Receber e mostrar alertas da rede P2P (padrão: %u) + + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduzindo -maxconnections de %d para %d, devido a limitações no sistema. + + + Rescan the block chain for missing wallet transactions on startup + Procurar transacções em falta na cadeia de blocos ao iniciar + Send trace/debug info to console instead of debug.log file Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log + + Send transactions as zero-fee transactions if possible (default: %u) + Enviar como uma transacção a custo zero se possível (padrão: %u) + + + Show all debugging options (usage: --help -help-debug) + Mostrar todas as opções de depuração (utilização: --help -help-debug) + Shrink debug.log file on client startup (default: 1 when no -debug) Encolher ficheiro debug.log ao iniciar o cliente (por defeito: 1 sem -debug definido) @@ -2956,6 +3444,22 @@ Signing transaction failed Falhou assinatura da transação + + The transaction amount is too small to pay the fee + O montante da transacção é demasiado baixo para pagar a taxa + + + This is experimental software. + Isto é software experimental. + + + Tor control port password (default: empty) + Palavra-passe da porta de controlo Tor (predefinição: vazio) + + + Tor control port to use if onion listening enabled (default: %s) + Porta de controlo Tor a utilizar se a escuta cebola estiver ativada (predefinição: %s) + Transaction amount too small Quantia da transação é muito baixa @@ -2964,10 +3468,22 @@ Transaction amounts must be positive Quantia da transação deverá ser positiva + + Transaction too large for fee policy + Transacção demasiado grande para a política de taxas + Transaction too large Transação grande demais + + Unable to bind to %s on this computer (bind returned error %s) + Incapaz de vincular à porta %s neste computador (vínculo retornou erro %s) + + + Upgrade wallet to latest format on startup + Actualizar carteira para o formato mais recente ao iniciar + Username for JSON-RPC connections Nome de utilizador para ligações JSON-RPC @@ -2980,10 +3496,22 @@ Warning Aviso + + Warning: unknown new rules activated (versionbit %i) + Aviso: ativadas novas regras desconhecidas (versionbit %i) + + + Whether to operate in a blocks only mode (default: %u) + Se operar apenas num modo de blocos (predefinição: %u) + Zapping all transactions from wallet... A limpar todas as transações da carteira... + + ZeroMQ notification options: + Opções de notificação ZeroMQ: + wallet.dat corrupt, salvage failed wallet.dat corrompido, recuperação falhou @@ -3006,27 +3534,107 @@ Loading addresses... - A carregar endereços... + A carregar os endereços... Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira danificada + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = guardar metadados da transacção ex: proprietário da conta e informação do pedido de pagamento, 2 = descartar metadados da transacção) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee está definido com um valor muito alto! Taxas desta magnitude podem ser pagas numa única transacção. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee está definido com um valor muito alto! Esta é a taxa que irá pagar se enviar uma transacção. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Não guardar transações no banco de memória por mais de <n> horas (predefinição: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Erro ao ler wallet.dat! Todas as chaves foram lidas correctamente, mas os dados das transacções ou do livro de endereços podem estar em falta ou incorrectos. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Taxas (em %s/kB) abaixo deste valor são consideradas nulas para a criação de transacções (padrão: %s) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Minuciosidade da verificação de blocos para -checkblocks é (0-4, padrão: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Manter um índice de transacções completo, usado pela chamada RPC getrawtransaction (padrão: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Número de segundos a impedir que pares com comportamento indesejado se liguem de novo (padrão: %u) + + + Output debugging information (default: %u, supplying <category> is optional) + Informação de depuração (padrão: %u, fornecer uma <category> é opcional) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + Suportar filtragem de blocos e transacções com fitros bloom (padrão: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Comprimento total da entrada da versão de rede (%i) excede o comprimento máximo (%i). Reduzir o número ou o tamanho de uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Tenta manter o tráfego externo abaixo do limite especificado (em MiB por 24h), 0 = sem limite (padrão: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Encontrado um argumento não suportado -socks. Definir a versão do SOCKS já não é possível, apenas proxies SOCKS5 são suportados. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use um proxy SOCKS5 separado para alcançar pares via serviços ocultos do Tor (padrão: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Username e hash da password para ligações JSON-RPC. O campo <userpw> está no formato: <USERNAME>:<SALT>$<HASH>. Um script python está incluido em share/rpcuser. Esta opção pode ser especificada múltiplas vezes. + (default: %s) - (por defeito: %s) + (predefinição: %s) + + + Always query for peer addresses via DNS lookup (default: %u) + Utilizar sempre a consulta de DNS para endereços de pares (predefinição: %u) Error loading wallet.dat Erro ao carregar wallet.dat + + Generate coins (default: %u) + Gerar moedas (predefinição: %u) + + + How many blocks to check at startup (default: %u, 0 = all) + Quantos blocos para verificar no arranque (predefinição: %u, 0 = todos) + + + Include IP addresses in debug output (default: %u) + Incluir endereços de IP na informação de depuração (predefinição: %u) + Invalid -proxy address: '%s' Endereço -proxy inválido: '%s' Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) - Escutar por ligações JSON-RPC na porta <port> (por defeito: %u ou rede de testes: %u) + Escutar por ligações JSON-RPC na porta <port> (predefinição: %u ou rede de testes: %u) Listen for connections on <port> (default: %u or testnet: %u) @@ -3036,6 +3644,10 @@ Maintain at most <n> connections to peers (default: %u) Manter no máximo <n> ligações a outros nós da rede (por defeito: %u) + + Make the wallet broadcast transactions + Colocar a carteira a transmitir transacções + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) Maximo armazenamento intermédio de recepção por ligação, <n>*1000 bytes (por defeito: %u) @@ -3048,9 +3660,17 @@ Prepend debug output with timestamp (default: %u) Adicionar data e hora à informação de depuração (por defeito: %u) + + Relay and mine data carrier transactions (default: %u) + Propagar e minerar transacções que incluem dados (padrão: %u) + + + Relay non-P2SH multisig (default: %u) + Propagar não P2SH multisig (predefinição: %u) + Set key pool size to <n> (default: %u) - Definir o tamanho da memória de chaves para <n> (por defeito: %u) + Definir tamanho do banco de memória da chave para <n> (predefinição: %u) Set minimum block size in bytes (default: %u) @@ -3068,6 +3688,18 @@ Specify connection timeout in milliseconds (minimum: 1, default: %d) Especificar tempo de espera da ligação em milissegundos (mínimo 1, por defeito: %d) + + Specify pid file (default: %s) + Especificar ficheiro pid (padrão: %s) + + + Spend unconfirmed change when sending transactions (default: %u) + Gastar troco não confirmado ao enviar transacções (padrão: %u) + + + Threshold for disconnecting misbehaving peers (default: %u) + Tolerância para desligar nós com comportamento indesejável (padrão: %u) + Unknown network specified in -onlynet: '%s' Rede desconhecida especificada em -onlynet: '%s' @@ -3090,7 +3722,7 @@ Loading block index... - A carregar índice de blocos... + A carregar o índice de blocos... Add a node to connect to and attempt to keep the connection open @@ -3098,7 +3730,7 @@ Loading wallet... - A carregar carteira... + A carregar a carteira... Cannot downgrade wallet @@ -3114,7 +3746,7 @@ Done loading - Carregamento completo + Carregamento concluído Error diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts new file mode 100644 index 000000000..11ac69f0f --- /dev/null +++ b/src/qt/locale/bitcoin_ro.ts @@ -0,0 +1,169 @@ + + + AddressBookPage + + Right-click to edit address or label + Click dreapta pentru a modifica adresa o eticheta + + + Create a new address + Crează o nouă adresă + + + &New + &Nou + + + Copy the currently selected address to the system clipboard + Copiază în notițe adresa selectată în prezent + + + &Copy + &Copiază + + + C&lose + Î&nchide + + + &Copy Address + &Copiază Adresa + + + Delete the currently selected address from the list + Șterge adresa curentă selectata din listă + + + Export the data in the current tab to a file + Exportă datele din tabul curent in fisier + + + &Export + &Exportă + + + Choose the address to send coins to + Indică adresa de expediere a monedelor + + + Choose the address to receive coins with + Indică adresa de a primi monedele + + + + AddressTableModel + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + + ClientModel + + + CoinControlDialog + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + RecentRequestsTableModel + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + + TransactionView + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Exportă + + + Export the data in the current tab to a file + Exportă datele din tabul curent in fisier + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 8bccf037a..502052dff 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -27,7 +27,7 @@ &Copy Address - &Copiază adresa + &Copiază Adresa Delete the currently selected address from the list @@ -43,15 +43,15 @@ &Delete - Şterge + &Şterge Choose the address to send coins to - Alegeţi adresa unde vreţi să trimiteţi monezile + Alegeţi adresa unde vreţi să trimiteţi monedele Choose the address to receive coins with - Alegeţi adresa unde vreţi să primiţi monezile + Alegeţi adresa unde vreţi să primiţi monedele C&hoose @@ -67,7 +67,7 @@ These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Acestea sînt adresele dumneavoastră Bitcoin pentru efectuarea plăţilor. Verificaţi întotdeauna cantitatea şi adresa de primire înainte de a trimite monezi. + Acestea sînt adresele dumneavoastră Bitcoin pentru efectuarea plăţilor. Verificaţi întotdeauna cantitatea şi adresa de primire înainte de a trimite monede. These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Banat până la + + BitcoinGUI @@ -547,7 +555,7 @@ CoinControlDialog Coin Selection - Selectarea monezii + Selectarea monedei Quantity: @@ -874,7 +882,35 @@ command-line options Opţiuni linie de comandă - + + UI Options: + Opţiuni UI: + + + Choose data directory on startup (default: %u) + Alege dosarul de date la pornire (implicit: %u) + + + Set language, for example "de_DE" (default: system locale) + Setează limba, de exemplu: "ro_RO" (implicit: sistem local) + + + Start minimized + Porniţi minimizat + + + Set SSL root certificates for payment request (default: -system-) + Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- ) + + + Show splash screen on startup (default: %u) + Afişează ecran splash la pornire (implicit: %u) + + + Reset all settings changes made over the GUI + Resetează toate schimbările făcute în GUI + + Intro @@ -1011,6 +1047,10 @@ &Network Reţea + + Automatically start Bitcoin Core after logging in to the system. + Porneşte automat Bitcoin Core după logarea în sistem. + &Start Bitcoin Core on system login Porneşte Nucleul Bitcoin la pornirea sistemului @@ -1067,6 +1107,18 @@ Port of the proxy (e.g. 9050) Portul proxy (de exemplu: 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &Fereastră @@ -1312,6 +1364,10 @@ User Agent Agent utilizator + + Node/Service + Nod/Serviciu + Ping Time Timp ping @@ -1401,10 +1457,6 @@ General General - - Using OpenSSL version - Foloseşte OpenSSL versiunea - Using BerkeleyDB version Foloseşte BerkeleyDB versiunea @@ -1433,6 +1485,14 @@ Current number of blocks Numărul curent de blocuri + + Current number of transactions + Numărul curent de tranzacţii + + + Memory usage + Memorie folosită + Received Recepţionat @@ -1449,6 +1509,10 @@ Select a peer to view detailed information. Selectaţi un partener pentru a vedea informaţiile detaliate. + + Whitelisted + Whitelisted + Direction Direcţie @@ -1457,6 +1521,18 @@ Version Versiune + + Starting Block + Bloc de început + + + Synced Headers + Headere Sincronizate + + + Synced Blocks + Blocuri Sincronizate + User Agent Agent utilizator @@ -1525,6 +1601,26 @@ Clear console Curăţă consola + + &Disconnect Node + &Deconectare nod + + + 1 &hour + 1 &oră + + + 1 &day + 1 &zi + + + 1 &week + 1 &săptămână + + + 1 &year + 1 &an + Welcome to the Bitcoin Core RPC console. Bun venit la consola Nucleului Bitcoin RPC. @@ -1569,6 +1665,14 @@ Outbound Ieşire + + Yes + Da + + + No + Nu + Unknown Necunoscut @@ -1917,6 +2021,10 @@ Copy change Copiază rest + + Total Amount %1 + Suma totală %1 + or sau @@ -1949,6 +2057,10 @@ The recipient address is not valid. Please recheck. Adresa destinatarului nu este validă, vă rugăm să o verificaţi. + + Duplicate address found: addresses should only be used once each. + Adresă duplicat găsită: fiecare adresă ar trebui folosită o singură dată. + Warning: Invalid Bitcoin address Atenţie: Adresa bitcoin nevalidă! @@ -2317,7 +2429,7 @@ 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. - Monezile generate trebuie să crească %1 blocuri înainte să poată fi cheltuite. Cînd aţi generat acest bloc, a fost transmis reţelei pentru a fi adaugat la lanţul de blocuri. Aceasta se poate întîmpla ocazional dacă alt nod generează un bloc la numai cîteva secunde de al dvs. + Monedele generate trebuie să crească %1 blocuri înainte să poată fi cheltuite. Cînd aţi generat acest bloc, a fost transmis reţelei pentru a fi adaugat la lanţul de blocuri. Aceasta se poate întîmpla ocazional dacă alt nod generează un bloc la numai cîteva secunde de al dvs. Debug information diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 00dfd833a..b4546a215 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -1473,10 +1473,6 @@ General Общие - - Using OpenSSL version - Используется версия OpenSSL - Using BerkeleyDB version Используется версия BerkeleyDB @@ -2995,6 +2991,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Всегда разрешать транзакции, полученные от участников из белого списка (по умолчанию: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d) @@ -3027,6 +3027,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Внимание: похоже, в сети нет полного согласия! Некоторый майнеры, возможно, испытывают проблемы. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Внимание: Получена неизвестная версия блока! Возможно неизвестные правила вступили в силу. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Внимание: мы не полностью согласны с подключенными участниками! Вам или другим участникам, возможно, следует обновиться. @@ -3047,6 +3051,10 @@ <category> can be: <category> может быть: + + Append comment to the user agent string + Добавить комментарий к строке пользовательского агента + Block creation options: Параметры создания блоков: @@ -3131,6 +3139,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Сбрасывать транзакции из памяти на диск каждые <n> мегабайт (по умолчанию: %u) + + Location of the auth cookie (default: data dir) + Расположение куки входы(по умолчанию: data dir) + Not enough file descriptors available. Недостаточно файловых дескрипторов. @@ -3139,6 +3151,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Соединяться только по сети <net> (ipv4, ipv6 или onion) + + Print version and exit + Написать версию и выйти + Prune cannot be configured with a negative value. Удаление блоков не может использовать отрицательное значение. @@ -3195,10 +3211,6 @@ Wallet options: Настройки бумажника: - - Warning: This version is obsolete; upgrade required! - Внимание: эта версия устарела; требуется обновление! - You need to rebuild the database using -reindex to change -txindex Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex @@ -3295,10 +3307,6 @@ Activating best chain... Активируется лучшая цепь... - - Always relay transactions received from whitelisted peers (default: %d) - Всегда транслировать транзакции, полученные из белого списка участников (по умолчанию: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Попытаться восстановить приватные ключи из повреждённого wallet.dat при запуске @@ -3463,6 +3471,10 @@ Warning Внимание + + Warning: unknown new rules activated (versionbit %i) + Внимание: неизвестные правила вступили в силу(versionbit %i) + Whether to operate in a blocks only mode (default: %u) Будет работать в режиме только блоков (по умолчанию: %u) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 53a1c1d8a..41e467e49 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -1,6 +1,50 @@ AddressBookPage + + Create a new address + Создать новый адрес + + + &New + Новый + + + Copy the currently selected address to the system clipboard + Copy the currently selected address to the system clipboardый адрес в буфер + + + &Copy + Копировать + + + C&lose + Закрыть + + + &Copy Address + Копировать адрес + + + Delete the currently selected address from the list + Удалить выбранный адрес из списка + + + Export the data in the current tab to a file + Экспортировать данные текущей вкладки в файл + + + &Export + Экспортировать + + + &Delete + Удалить + + + C&hoose + Выбрать + AddressTableModel @@ -226,6 +270,14 @@ WalletView + + &Export + Экспорт + + + Export the data in the current tab to a file + Экспортировать данные текущей вкладки в файл + bitcoin-core diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 8c779cbe9..9addbdaa8 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -63,7 +63,7 @@ Receiving addresses - Adresa prijatia + Prijímacia adresa These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Maska stiete + + + Banned Until + Blokovaný do + + BitcoinGUI @@ -874,7 +882,35 @@ command-line options voľby príkazového riadku - + + UI Options: + Možnosti používateľského rozhrania: + + + Choose data directory on startup (default: %u) + Vyberte dátový priečinok pri štarte (predvolené: %u) + + + Set language, for example "de_DE" (default: system locale) + Nastavte jazyk, napríklad "de_DE" (predvolené: podľa systému) + + + Start minimized + Spustiť minimalizované + + + Set SSL root certificates for payment request (default: -system-) + Nastaviť SSL root certifikáty pre vyžiadanie platby (predvolené: -system-) + + + Show splash screen on startup (default: %u) + Zobraziť uvítaciu obrazovku pri štarte (predvolené: %u) + + + Reset all settings changes made over the GUI + Reštartovať všetky nastavenia urobené v používateľskom rozhraní. + + Intro @@ -1009,7 +1045,7 @@ &Network - Sieť + &Sieť Automatically start Bitcoin Core after logging in to the system. @@ -1025,7 +1061,7 @@ W&allet - Peňaženka + &Peňaženka Expert @@ -1071,13 +1107,37 @@ Port of the proxy (e.g. 9050) Port proxy (napr. 9050) + + Used for reaching peers via: + Použité pre získavanie peerov cez: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Zobrazuje, či je poskytované predvolené SOCKS5 proxy používané pre získavanie peerov cez tento typ siete. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Pripojiť k Bitcoinovej sieti cez separované SOCKS5 proxy pre skrytú službu Tor. + Use separate SOCKS5 proxy to reach peers via Tor hidden services: Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor: &Window - Okno + &Okno Show only a tray icon after minimizing the window. @@ -1093,7 +1153,7 @@ &Display - &Displej + &Zobrazenie User Interface &language: @@ -1413,10 +1473,6 @@ General Všeobecné - - Using OpenSSL version - Používa OpenSSL verziu - Using BerkeleyDB version Používa BerkeleyDB verziu @@ -1445,6 +1501,18 @@ Current number of blocks Aktuálny počet blokov + + Memory Pool + Pamäť Poolu + + + Current number of transactions + Aktuálny počet tranzakcií + + + Memory usage + Využitie pamäte + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Otvoriť Bitcoin log súbor pre ladenie z aktuálneho dátového adresára. Toto môže trvať niekoľko sekúnd pre veľké súbory. @@ -1461,10 +1529,18 @@ &Peers &Partneri + + Banned peers + Zablokované spojenia + Select a peer to view detailed information. Vyberte počítač pre zobrazenie podrobností. + + Whitelisted + Povolené + Direction Smer @@ -1473,6 +1549,19 @@ Version Verzia + + Starting Block + Počiatočný Blok + + + Synced Headers + Synchronizované hlavičky + + + + Synced Blocks + Synchronizované bloky + User Agent Aplikácia @@ -1501,6 +1590,10 @@ Ping Time Čas odozvy + + Ping Wait + Čakanie na ping + Time Offset Časový posun @@ -1549,6 +1642,34 @@ Clear console Vymazať konzolu + + &Disconnect Node + &Odpojené uzly + + + Ban Node for + Blokovať uzol na + + + 1 &hour + 1 &hodinu + + + 1 &day + 1 &deň + + + 1 &week + 1 &týždeň + + + 1 &year + 1 &rok + + + &Unban Node + &odblokovať uzol + Welcome to the Bitcoin Core RPC console. Vitajte v RPC konzole pre Jadro Bitcoin. @@ -1577,6 +1698,10 @@ %1 GB %1 GB + + (node id: %1) + (ID uzlu: %1) + via %1 cez %1 @@ -1593,6 +1718,14 @@ Outbound Odchádzajúce + + Yes + Áno + + + No + Nie + Unknown neznámy @@ -1961,6 +2094,10 @@ Copy change Kopírovať zmenu + + Total Amount %1 + Celkové množstvo %1 + or alebo @@ -1993,6 +2130,10 @@ Payment request expired. Vypršala platnosť požiadavky na platbu. + + Pay only the required fee of %1 + Zaplatiť len vyžadovaný poplatok z %1 + The recipient address is not valid. Please recheck. Adresa príjemcu je neplatná. Prosím, overte ju. @@ -2072,6 +2213,10 @@ Remove this entry Odstrániť túto položku + + 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. + Poplatok sa odpočíta od čiastky, ktorú odosielate. Príjemca dostane menej bitcoinov ako zadáte. Ak je vybraných viacero príjemcov, poplatok je rozdelený rovným dielom. + S&ubtract fee from amount Odpočítať poplatok od s&umy @@ -2126,6 +2271,10 @@ &Sign Message &Podpísať Správu + + The Bitcoin address to sign the message with + Bitcoin adresa pre podpísanie správy s + Choose previously used address Vybrať predtým použitú adresu @@ -2600,6 +2749,10 @@ Copy transaction ID Kopírovať ID transakcie + + Copy raw transaction + Kopírovať celú tranzakciu + Edit label Editovať popis @@ -2747,10 +2900,30 @@ Accept command line and JSON-RPC commands Prijímať príkazy z príkazového riadku a JSON-RPC + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Skontrolujte správnosť nastavenia dátumu a času na vašom počítači! Ak je čas nesprávny Jadro Bitcoin nebude správne fungovať. + + + Error: A fatal internal error occurred, see debug.log for details + Chyba: Vyskytla sa interná chyba, pre viac informácií zobrazte debug.log + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Poplatok (za %s/kB) pridaný do tranzakcie, ktorú posielate (predvolené: %s) + + + Pruning blockstore... + Redukovanie blockstore... + Run in the background as a daemon and accept commands Bežať na pozadí ako démon a prijímať príkazy + + Unable to start HTTP server. See debug log for details. + Nepodarilo sa spustiť HTTP server. Pre viac detailov zobrazte debug log. + Accept connections from outside (default: 1 if no -proxy or -connect) Prijať spojenia zvonku (predvolené: 1 ak žiadne -proxy alebo -connect) @@ -2783,6 +2956,14 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Nepodarilo sa pripojiť na %s na tomto počítači. Bitcoin Jadro je už pravdepodobne spustené. + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + VAROVANIE: príliš veľa vygenerovaných blokov; %d prijatých blokov v posledných %d hodinách (očakávaných %d) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + VAROVANIE: skontrolujte sieťové pripojenie, %d prijatých blokov za posledných %d hodín (očakávané %d) + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varovanie: Javí sa že sieť sieť úplne nesúhlasí! Niektorí mineri zjavne majú ťažkosti. @@ -2801,6 +2982,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát. + + -maxmempool must be at least %d MB + -maxmempool musí byť najmenej %d MB + <category> can be: <category> môže byť: @@ -2833,6 +3018,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Do you want to rebuild the block database now? Chcete znovu zostaviť databázu blokov? + + Enable publish hash block in <address> + Povoliť zverejneneie hash blokov pre <address> + + + Enable publish hash transaction in <address> + Povoliť zverejnenie hash tranzakcií pre <address> + + + Enable publish raw block in <address> + Povoliť zverejnenie raw bloku pre <address> + Error initializing block database Chyba inicializácie databázy blokov @@ -2869,6 +3066,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Invalid -onion address: '%s' Neplatná -onion adresa: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Neplatná suma pre -fallbackfee=<amount>: '%s' + Not enough file descriptors available. Nedostatok kľúčových slov súboru. @@ -2877,6 +3078,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Only connect to nodes in network <net> (ipv4, ipv6 or onion) Pripojiť iba k uzlom v sieti <net> (ipv4, ipv6, alebo onion) + + Prune cannot be configured with a negative value. + Redukovanie nemôže byť nastavené na zápornú hodnotu. + + + Prune mode is incompatible with -txindex. + Redukovanie je nekompatibilné s -txindex. + Set database cache size in megabytes (%d to %d, default: %d) Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d) @@ -2889,6 +3098,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Specify wallet file (within data directory) Označ súbor peňaženky (v priečinku s dátami) + + Unsupported argument -benchmark ignored, use -debug=bench. + Nepodporovaný parameter -benchmark bol ignorovaný, použite -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Nepodporovaný argument -debugnet bol ignorovaný, použite -debug=net. + + + Unsupported argument -tor found, use -onion. + Nepodporovaný argument -tor, použite -onion. + Use UPnP to map the listening port (default: %u) Použiť UPnP pre mapovanie počúvajúceho portu (predvolené: %u) @@ -2933,6 +3154,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky) + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Zisti vlastnú IP adresu (predvolené: 1 pre listen a -externalip alebo -proxy) + Error: Listening for incoming connections failed (listen returned error %s) Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s) @@ -2965,6 +3190,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d) + + The transaction amount is too small to send after the fee has been deducted + Suma je príliš malá pre odoslanie tranzakcie + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Tento produkt obsahuje softvér vyvinutý projektom OpenSSL pre použitie sady nástrojov OpenSSL <https://www.openssl.org/> a kryptografického softvéru napísaného Eric Young a UPnP softvér napísaný Thomas Bernard. @@ -2981,6 +3210,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Accept public REST requests (default: %u) Akceptovať verejné REST žiadosti (predvolené: %u) + + Activating best chain... + Aktivácia najlepšej reťaze... + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Pokus o obnovenie privátnych kľúčov z poškodenej wallet.dat pri spustení + + + Automatically create Tor hidden service (default: %d) + Automaticky vytvoriť skrytú službu Tor (predvolené: %d) + Cannot resolve -whitebind address: '%s' Nedá sa vyriešiť -whitebind adresa: '%s' @@ -3001,10 +3242,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Error reading from database, shutting down. Chyba pri načítaní z databázy, ukončuje sa. + + Imports blocks from external blk000??.dat file on startup + Importovať bloky z externého súboru blk000??.dat pri štarte + Information Informácia + + Initialization sanity check failed. Bitcoin Core is shutting down. + Inicializačná kontrola zlyhala. Jadro Bitcoin sa ukončuje. + Invalid amount for -maxtxfee=<amount>: '%s' Neplatná suma pre -maxtxfee=<amount>: '%s' @@ -3065,10 +3314,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Signing transaction failed Podpísanie správy zlyhalo + + The transaction amount is too small to pay the fee + Suma tranzakcie je príliš malá na zaplatenie poplatku + This is experimental software. Toto je experimentálny softvér. + + Tor control port password (default: empty) + Heslo na kontrolu portu pre Tor (predvolené: žiadne) + Transaction amount too small Suma transakcie príliš malá @@ -3089,10 +3346,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Unable to bind to %s on this computer (bind returned error %s) Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s) + + Upgrade wallet to latest format on startup + Aktualizovať peňaženku na posledný formát pri štarte + Username for JSON-RPC connections Užívateľské meno pre JSON-RPC spojenia + + Wallet needed to be rewritten: restart Bitcoin Core to complete + Peňaženka musí byť prepísaná: pre dokončenie reštartujte Jadro Bitcoin + Warning Upozornenie diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index c62c8cf27..1b540a731 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -427,7 +427,7 @@ %n active connection(s) to Bitcoin network - %n aktivna povezava v bitcoin omrežje%n aktivni povezavi v bitcoin omrežje%n aktivne povezave v bitcoin omrežje%n aktivnih povezav v bitcoin omrežje + %n aktivna povezava v omrežje Bitcoin%n aktivni povezavi v omrežje Bitcoin%n aktivne povezave v omrežje Bitcoin%n aktivnih povezav v omrežje Bitcoin No block source available... @@ -463,7 +463,7 @@ Last received block was generated %1 ago. - Zadnji prejeti blok je bil ustvarjen %1 nazaj. + Zadnji prejeti blok je star %1. Transactions after this will not yet be visible. @@ -1322,7 +1322,7 @@ Node/Service - Vozlišče/Storitev + Naslov Ping Time @@ -1413,10 +1413,6 @@ General Splošno - - Using OpenSSL version - OpenSSL različica v rabi - Using BerkeleyDB version BerkeleyDB različica v rabi @@ -2437,7 +2433,7 @@ Open for %n more block(s) - Odprto še %n blokOdprto še %n blokaOdprto še %n blokeOdprto še %n blokov + Še %n blok do potrditveŠe %n bloka do potrditveŠe %n bloki do potrditveŠe %n blokov do potrditve unknown @@ -2471,7 +2467,7 @@ Open for %n more block(s) - Odprto še %n blokOdprto še %n blokaOdprto še %n blokeOdprto še %n blokov + Še %n blok do potrditveŠe %n bloka do potrditveŠe %n bloki do potrditveŠe %n blokov do potrditve Open until %1 @@ -2955,10 +2951,6 @@ Wallet options: Izbire denarnice: - - Warning: This version is obsolete; upgrade required! - Opozorilo: Različica vašega odjemalca je zastarela. Potrebna je nadgradnja! - You need to rebuild the database using -reindex to change -txindex Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex @@ -3009,7 +3001,7 @@ Activating best chain... - Preklapljam na najboljšo verigo ... + Prehajam na najboljšo verigo ... Cannot resolve -whitebind address: '%s' diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 994b06599..d87bd9db5 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -29,6 +29,10 @@ Delete the currently selected address from the list Fshi adresen e selektuar nga lista + + Export the data in the current tab to a file + Eksporto të dhënat e skedës korrente në një skedar + &Delete &Fshi @@ -790,6 +794,10 @@ WalletView + + Export the data in the current tab to a file + Eksporto të dhënat e skedës korrente në një skedar + bitcoin-core diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts new file mode 100644 index 000000000..c836c8ddb --- /dev/null +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -0,0 +1,653 @@ + + + AddressBookPage + + Right-click to edit address or label + Klikni desnim tasterom za uređivanje adrese ili oznake + + + Create a new address + Kreiraj novu adresu + + + &New + &Novi + + + Copy the currently selected address to the system clipboard + Kopiraj selektovanu adresu u sistemski klipbord + + + &Copy + &Kopiraj + + + C&lose + Zatvori + + + &Copy Address + Kopiraj adresu + + + Delete the currently selected address from the list + Briše trenutno izabranu adresu sa liste + + + Export the data in the current tab to a file + Izvoz podataka iz trenutne kartice u datoteku + + + &Export + &Izvoz + + + &Delete + &Izbrisati + + + Choose the address to send coins to + Izaberi adresu za slanje bitkoina + + + Choose the address to receive coins with + Izaberi adresu za primanje bitkoina + + + C&hoose + I&zaberi + + + Sending addresses + Adrese za slanje + + + Receiving addresses + Adrese za primanje + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Ovo su vase Bitkoin adrese za slanje bitkoina. Uvek proverite unetu kolicinu bitkoina i adresu za slanje bitkoin pre slanja. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Ovo su vase Bitkoin adrese za primanje bitkoina. Preporuceno je da koristite drugaciju adresu za primanje kod svake transakcije. + + + &Edit + &Izmeni + + + Export Address List + Izvezi listu adresa + + + Comma separated file (*.csv) + Zapetom odvojene ('.csv) datoteke + + + Exporting Failed + Izvoz nije uspeo + + + There was an error trying to save the address list to %1. Please try again. + Dogodila se greska prilikom cuvanja adrese u %1. Molimo pokusajte ponovo. + + + + AddressTableModel + + Label + Etiketa + + + Address + Adresa + + + (no label) + (bez etikete) + + + + AskPassphraseDialog + + Passphrase Dialog + Dialog pristupne fraze + + + Enter passphrase + Unesi pristupnu frazu + + + New passphrase + Nova pristupna fraza + + + Repeat new passphrase + Ponovo unesite pristupnu frazu + + + Encrypt wallet + Enkriptuj/Sifruj novcanik + + + This operation needs your wallet passphrase to unlock the wallet. + Da bi ste otkljucali novcanik potrebno je da unesete pristupnu frazu + + + Unlock wallet + Otkljucaj novcanik + + + This operation needs your wallet passphrase to decrypt the wallet. + Da bi ste dekriptovali/desifrovali novcanik potrebno je da unesete pristupnu frazu + + + Decrypt wallet + Dekriptuj/Desifruj novcanik + + + Change passphrase + Izmeni pristupnu frazu + + + Confirm wallet encryption + Potvrdite enkripciju/sifrovanje novcanika + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Upozorenje: Ako ekriptujete/sifrujete novcanik, a izgubite pristupnu frazu <b>IZGUBICETE SVE VASE BITKOINE</b>! + + + Are you sure you wish to encrypt your wallet? + Da li ste sigurni da zelite da enkriptujete/sifrujete novcanik? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core ce se sada zatvoriti radi zavrsavanje procesa enkripcije/sifrovanja novcanika. Zapamtite da enkriptovanje/sifrovanje novcanika ne moze u potpunosti da zastiti vase bitkoine od kradje od strane virusa koji su zarazili vas racunar. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + VAZNO : Bilo koja prethodne rezervne kopije koje ste nacinili od svoje datoteke novcanika treba da se zamene sa novogenerisanom, sifrovanom datotekom novcanika. Iz bezbednosnih razloga, prethodne rezervne kopije su nezasifrovanih datoteka novcanika ce postati beskorisne cim pocnete da koristite novi, sifrovani novčanik. + + + Warning: The Caps Lock key is on! + Upozorenje: Dugme Caps Lock je upaljeno + + + Wallet encrypted + Novcanik je enkriptovan/sifrovan + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Unesite novu pristupnu frazu u novcanik.<br/>Molimo koristite pristupnu frazu od <br/>deset ili vise nasumicnih karaktera <br/>, ili <b>osm ili vise reci </b>. + + + Enter the old passphrase and new passphrase to the wallet. + Unesite staru pristupnu frazu i novu pristupnu frazu u novcanik. + + + Wallet encryption failed + Ekripcija/Sifrovanje novcanika nije uspelo + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Enkriptovanje/Sifrovanje novcanika nije uspelo zbog greske. Vas novcanik nije enkriptovan/sifrovan. + + + The supplied passphrases do not match. + Uneta pristupne fraze se ne podudaraju + + + Wallet unlock failed + Otkljucavanje novcanika nije uspelo + + + The passphrase entered for the wallet decryption was incorrect. + Pristupna fraza za dekriptovanje/desifrovanje novcanika nije tacna. + + + Wallet decryption failed + Dekriptovanje/desifrovanje novcanika nije uspelo + + + Wallet passphrase was successfully changed. + Pristupna fraza novcanika je uspesno promenjena. + + + + BanTableModel + + IP/Netmask + IP/Netmask + + + Banned Until + Banovani ste do + + + + BitcoinGUI + + Bitcoin Core + Bitcoin Core + + + Error + Greska + + + + ClientModel + + + CoinControlDialog + + Amount + Kolicina + + + Date + Datum + + + (no label) + (bez etikete) + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + + Intro + + Bitcoin Core + Bitcoin Core + + + Error + Greska + + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + Amount + Kolicina + + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Adresa + + + Amount + Kolicina + + + Label + Etiketa + + + Message + Poruka + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Etiketa + + + Message + Poruka + + + Amount + Kolicina + + + (no label) + (bez etikete) + + + + SendCoinsDialog + + (no label) + (bez etikete) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + The Bitcoin Core developers + Razvojni tim Bitcoin Core + + + + TrafficGraphWidget + + + TransactionDesc + + %1/offline + %1/van mreze + + + %1/unconfirmed + %1/nepotvrdjeno + + + %1 confirmations + %1 potvrdjeno/ih + + + Status + Stanje/Status + + + Date + Datum + + + Source + Izvor + + + Generated + Generisano + + + From + Od + + + To + Kome + + + own address + sopstvena adresa + + + watch-only + samo za gledanje + + + label + etiketa + + + Credit + Kredit + + + not accepted + nije prihvaceno + + + Debit + Zaduzenje + + + Total debit + Ukupno zaduzenje + + + Total credit + Totalni kredit + + + Transaction fee + Taksa transakcije + + + Net amount + Neto iznos + + + Message + Poruka + + + Comment + Komentar + + + Transaction ID + ID Transakcije + + + Merchant + Trgovac + + + Debug information + Informacije debugovanja + + + Transaction + Transakcije + + + Inputs + Unosi + + + Amount + Kolicina + + + true + tacno + + + false + netacno + + + , has not been successfully broadcast yet + , nisu uspesno jos emitovano + + + unknown + nepoznato + + + + TransactionDescDialog + + Transaction details + Detalji transakcije + + + + TransactionTableModel + + Date + Datum + + + Type + Tip + + + Label + Etiketa + + + Received with + Primljeno uz + + + Received from + Primljeno od + + + Sent to + Poslat + + + Payment to yourself + Placanje samom sebi + + + Mined + Iskopano + + + watch-only + samo za gledanje + + + + TransactionView + + Received with + Primljeno uz + + + Sent to + Poslat + + + Mined + Iskopano + + + Exporting Failed + Izvoz nije uspeo + + + Comma separated file (*.csv) + Zarezom odvojene ('.csv) datoteke + + + Date + Datum + + + Type + Tip + + + Label + Etiketa + + + Address + Adresa + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Izvoz + + + Export the data in the current tab to a file + Izvoz podataka iz trenutne kartice u datoteku + + + + bitcoin-core + + Insufficient funds + Nedovoljno sredstava + + + Loading block index... + Ucitavanje indeksa bloka... + + + Add a node to connect to and attempt to keep the connection open + Dodajte cvor za povezivanje, da bi pokusali da odrzite vezu otvorenom + + + Loading wallet... + Ucitavanje novcanika... + + + Cannot write default address + Nije moguce ispisivanje podrazumevane adrese + + + Rescanning... + Ponovno skeniranje... + + + Done loading + Zavrseno ucitavanje + + + Error + Greska + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 756114351..acf37bd1d 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1474,10 +1474,6 @@ Var vänlig och försök igen. General Generell - - Using OpenSSL version - Använder OpenSSL version - Using BerkeleyDB version Använder BerkeleyDB versionen @@ -2980,6 +2976,18 @@ Var vänlig och försök igen. Accept connections from outside (default: 1 if no -proxy or -connect) Acceptera anslutningar utifrån (förvalt: 1 om ingen -proxy eller -connect) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee är satt väldigt högt! Detta är avgiften du kan komma att betala om uppskattad avgift inte finns tillgänglig. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + En avgiftskurs (i %s/kB) som används när det inte finns tillräcklig data för att uppskatta avgiften (förvalt: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Acceptera vidarebefodrade transaktioner från vitlistade noder även när transaktioner inte vidarebefodras (förvalt: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6 @@ -2996,6 +3004,10 @@ Var vänlig och försök igen. Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Vidarebefodra alltid transaktioner från vitlistade noder även om de bryter mot lokala reläpolicyn (förvalt: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Ange antalet skriptkontrolltrådar (%u till %d, 0 = auto, <0 = lämna så många kärnor lediga, förval: %d) @@ -3012,6 +3024,10 @@ Var vänlig och försök igen. Unable to bind to %s on this computer. Bitcoin Core is probably already running. Det går inte att binda till %s på den här datorn. Bitcoin Core är förmodligen redan igång. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumentet -whitelistalwaysrelay stöds inte utan ignoreras, använd -whitelistrelay och/eller -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Använd UPnP för att mappa den lyssnande porten (förvalt: 1 när lyssning aktiverat och utan -proxy) @@ -3028,6 +3044,10 @@ Var vänlig och försök igen. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varning: Nätverket verkar inte vara helt överens! Några miners verkar ha problem. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Varning: Okända blockversioner bryts! Det är möjligt att okända regler används + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Varning: Vi verkar inte helt överens med våra peers! Du kan behöva uppgradera, eller andra noder kan behöva uppgradera. @@ -3048,6 +3068,10 @@ Var vänlig och försök igen. <category> can be: <category> Kan vara: + + Append comment to the user agent string + Lägg till kommentar till user-agent-strängen + Block creation options: Block skapande inställningar: @@ -3092,6 +3116,10 @@ Var vänlig och försök igen. Enable publish raw transaction in <address> Aktivera publicering av råa transaktioner i <adress> + + Enable transaction replacement in the memory pool (default: %u) + Aktivera byte av transaktioner i minnespoolen (förvalt: %u) + Error initializing block database Fel vid initiering av blockdatabasen @@ -3128,10 +3156,22 @@ Var vänlig och försök igen. Invalid -onion address: '%s' Ogiltig -onion adress:'%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + Ogiltigt belopp för -fallbackfee=<belopp>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Håll minnespoolen över transaktioner under <n> megabyte (förvalt: %u) + + Location of the auth cookie (default: data dir) + Plats för authcookie (förvalt: datamapp) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Minimum antal byte per sigop i transaktioner som vi reläar och bryter (förvalt: %u) + Not enough file descriptors available. Inte tillräckligt med filbeskrivningar tillgängliga. @@ -3140,6 +3180,10 @@ Var vänlig och försök igen. Only connect to nodes in network <net> (ipv4, ipv6 or onion) Anslut enbart till noder i nätverket <net> (IPv4, IPv6 eller onion) + + Print version and exit + Visa version och avsluta + Prune cannot be configured with a negative value. Beskärning kan inte konfigureras med ett negativt värde. @@ -3196,10 +3240,6 @@ Var vänlig och försök igen. Wallet options: Plånboksinställningar: - - Warning: This version is obsolete; upgrade required! - Varning: Denna version är föråldrad; uppgradering krävs! - You need to rebuild the database using -reindex to change -txindex Du måste återskapa databasen med -reindex för att ändra -txindex @@ -3296,10 +3336,6 @@ Var vänlig och försök igen. Activating best chain... Aktiverar bästa kedjan... - - Always relay transactions received from whitelisted peers (default: %d) - Vidarebefordra alltid transaktioner från vitlistade noder (förval: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Försök att rädda privata nycklar från en korrupt wallet.dat vid uppstart @@ -3464,6 +3500,10 @@ Var vänlig och försök igen. Warning Varning + + Warning: unknown new rules activated (versionbit %i) + Varning: okända nya regler aktiverade (versionsbit %i) + Whether to operate in a blocks only mode (default: %u) Ska allt göras i endast block-läge (förval: %u) diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts new file mode 100644 index 000000000..c93524cda --- /dev/null +++ b/src/qt/locale/bitcoin_ta.ts @@ -0,0 +1,1029 @@ + + + AddressBookPage + + Create a new address + ஒரு புதிய முகவரியை உருவாக்கு + + + &New + &புதிய + + + &Copy + &நகல் + + + C&lose + &மூடு + + + &Copy Address + &முகவரியை நகலெடு + + + &Export + &ஏற்றுமதி + + + &Delete + &அழி + + + C&hoose + &தேர்ந்தெடு + + + Sending addresses + அனுப்பும் முகவரிகள் + + + Receiving addresses + பெறும் முகவரிகள் + + + &Edit + &தொகு + + + + AddressTableModel + + Label + லேபிள் + + + Address + விலாசம் + + + + AskPassphraseDialog + + Encrypt wallet + என்க்ரிப்ட் பணப்பை + + + Decrypt wallet + டிக்ரிப்ட் பணப்பை + + + + BanTableModel + + IP/Netmask + IP/Netmask + + + + BitcoinGUI + + &Overview + &கண்ணோட்டம் + + + &Transactions + &பரிவர்த்தனைகள் + + + E&xit + &வெளியேறு + + + Quit application + விலகு + + + About &Qt + &Qt-ஐ பற்றி + + + &Options... + &விருப்பங்கள்... + + + &Encrypt Wallet... + &என்க்ரிப்ட் பணப்பை... + + + Open &URI... + &URI-ஐ திற + + + &Verify message... + &செய்தியை சரிசெய்... + + + Bitcoin + Bitcoin + + + Wallet + பணப்பை + + + &Send + &அனுப்பு + + + &Receive + &பெறு + + + &Show / Hide + &காட்டு/மறை + + + &File + &கோப்பு + + + &Settings + &அமைப்பு + + + &Help + &உதவி + + + Bitcoin Core + Bitcoin மையம் + + + %n hour(s) + %n மணி%n மணி + + + %1 and %2 + %1 மற்றும் %2 + + + %1 behind + %1 பின்னால் + + + Error + தவறு + + + Warning + எச்சரிக்கை + + + Information + தகவல் + + + Date: %1 + + தேதி: %1 + + + + Amount: %1 + + தொகை: %1 + + + + Type: %1 + + வகை: %1 + + + + Address: %1 + + முகவரி: %1 + + + + Sent transaction + அனுப்பிய பரிவர்த்தனை + + + + ClientModel + + Network Alert + பிணைய எச்சரிக்கை + + + + CoinControlDialog + + Quantity: + அளவு + + + Amount: + விலை: + + + Priority: + முன்னுரிமை + + + Fee: + கட்டணம்: + + + After Fee: + கட்டணத்திறகுப் பின்: + + + Change: + மாற்று: + + + Amount + விலை + + + Date + தேதி + + + Confirmations + உறுதிப்படுத்தல்கள் + + + Confirmed + உறுதியாக + + + Priority + முன்னுரிமை + + + Copy address + பிரதியை முகவரியை + + + Copy amount + நகலை தொகை + + + none + none + + + yes + ஆம் + + + no + இல்லை + + + + EditAddressDialog + + + FreespaceChecker + + name + பெயர் + + + + HelpMessageDialog + + Bitcoin Core + Bitcoin மையம் + + + About Bitcoin Core + Bitcoin மையம் பற்றி + + + + Intro + + Welcome + நல்வரவு + + + Bitcoin Core + Bitcoin மையம் + + + Error + தவறு + + + + OpenURIDialog + + Open URI + URI-ஐ திற + + + URI: + URI: + + + + OptionsDialog + + Options + விருப்பத்தேர்வு + + + &Main + &தலைமை + + + MB + MB + + + &Network + &பிணையம் + + + W&allet + &பணப்பை + + + Expert + வல்லுநர் + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + &Window + &சாளரம் + + + &Display + &காட்டு + + + &OK + &சரி + + + &Cancel + &ரத்து + + + default + இயல்புநிலை + + + none + none + + + + OverviewPage + + Form + படிவம் + + + Available: + கிடைக்ககூடிய: + + + Pending: + நிலுவையில்: + + + Immature: + முதிராத: + + + Balances + மீதி + + + Total: + மொத்தம்: + + + + PaymentServer + + + PeerTableModel + + User Agent + பயனர் முகவர் + + + Ping Time + பிங் நேரம் + + + + QObject + + Amount + விலை + + + %1 d + %1 d + + + %1 h + %1 h + + + %1 s + %1 s + + + N/A + N/A + + + %1 ms + %1 ms + + + + QRImageWidget + + &Save Image... + &படத்தை சேமி... + + + &Copy Image + &படத்தை + + + Save QR Code + QR குறியீடு காப்பாற்ற + + + PNG Image (*.png) + PNG படத்தை (*.png) + + + + RPCConsole + + Client name + வாடிக்கையாளர் பெயர் + + + N/A + N/A + + + Client version + வாடிக்கையாளர் பதிப்பு + + + &Information + &தகவல் + + + Network + பிணையம் + + + Name + பெயர் + + + Memory Pool + நினைவக குளம் + + + Memory usage + நினைவக பயன்பாடு + + + Sent + அனுப்பிய + + + Direction + திசை + + + Version + பதிப்பு + + + User Agent + பயனர் முகவர் + + + Ping Time + பிங் நேரம் + + + &Open + &திற + + + &Console + &பணியகம் + + + &Clear + &வழுநீக்கு + + + Totals + மொத்தம் + + + In: + உள்ளே: + + + Out: + வெளியே: + + + 1 &hour + 1 &மணி + + + 1 &day + 1 &நாள் + + + 1 &week + 1 &வாரம் + + + 1 &year + 1 &ஆண்டு + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + via %1 + via %1 + + + never + ஒருபோதும் + + + Inbound + உள்வரும் + + + Outbound + வெளி செல்லும் + + + Yes + ஆம் + + + No + மறு + + + Unknown + அறியப்படாத + + + + ReceiveCoinsDialog + + &Amount: + &தொகை: + + + &Label: + &சிட்டை: + + + &Message: + &செய்தி: + + + Clear + நீக்கு + + + Show + காண்பி + + + Remove + நீக்கு + + + Copy message + நகலை செய்தி + + + Copy amount + நகலை தொகை + + + + ReceiveRequestDialog + + QR Code + QR குறியீடு + + + Copy &URI + நகலை &URI + + + Copy &Address + நகலை விலாசம் + + + &Save Image... + &படத்தை சேமி... + + + URI + URI + + + Address + விலாசம் + + + Amount + விலை + + + Label + லேபிள் + + + Message + செய்தி + + + + RecentRequestsTableModel + + Date + தேதி + + + Label + லேபிள் + + + Message + செய்தி + + + Amount + விலை + + + + SendCoinsDialog + + Quantity: + அளவு + + + Amount: + விலை + + + Priority: + முன்னுரிமை + + + Fee: + கட்டணம்: + + + After Fee: + கட்டணத்திறகுப் பின்: + + + Change: + மாற்று: + + + Choose... + தேர்ந்தெடு... + + + Hide + மறை + + + normal + இயல்பான + + + fast + வேகமாக + + + Balance: + மீதி: + + + S&end + &அனுப்பு + + + %1 to %2 + %1 to %2 + + + Copy amount + நகலை தொகை + + + or + அல்லது + + + + SendCoinsEntry + + A&mount: + &தொகை: + + + &Label: + &சிட்டை: + + + Alt+A + Alt+A + + + Alt+P + Alt+P + + + Message: + செய்தி: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + Alt+A + Alt+A + + + Alt+P + Alt+P + + + Signature + கையொப்பம் + + + + SplashScreen + + Bitcoin Core + Bitcoin மையம் + + + + TrafficGraphWidget + + KB/s + KB/s + + + + TransactionDesc + + Status + நிலை + + + Date + தேதி + + + Source + மூலம் + + + Credit + கடன் + + + Debit + பற்று + + + Total debit + மொத்த பற்று + + + Total credit + மொத்த கடன் + + + Net amount + நிகர தொகை + + + Message + செய்தி + + + Comment + கருத்து + + + Transaction ID + பரிவர்த்தனை ID + + + Merchant + வணிகர் + + + Debug information + சரிசெய்வதற்கான தகவல் + + + Transaction + பரிவர்த்தனை + + + Inputs + உள்ளீடுகள் + + + Amount + விலை + + + true + உண்மை + + + false + தவறான + + + + TransactionDescDialog + + + TransactionTableModel + + Date + தேதி + + + Offline + ஆஃப்லைன் + + + Label + லேபிள் + + + (n/a) + (n/a) + + + + TransactionView + + All + முழுவதும் + + + Today + இன்று + + + This week + இந்த வாரம் + + + This month + இந்த மாதம் + + + Last month + கடந்த மாதம் + + + This year + இந்த வருடம் + + + Range... + எல்லை... + + + Other + வேறு + + + Copy address + பிரதியை முகவரியை + + + Copy amount + நகலை தொகை + + + Confirmed + உறுதியாக + + + Date + தேதி + + + Label + லேபிள் + + + Address + விலாசம் + + + ID + ID + + + Range: + எல்லை: + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &ஏற்றுமதி + + + + bitcoin-core + + (default: %u) + (default: %u) + + + Information + தகவல் + + + Warning + எச்சரிக்கை + + + (default: %s) + (default: %s) + + + Error + தவறு + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 79a55cdd5..ba3b1e874 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -1,23 +1,99 @@ AddressBookPage + + Right-click to edit address or label + คลิกขวาเพื่อแก้ไขที่อยู่ หรือป้ายชื่อ + Create a new address สร้างที่อยู่ใหม่ + + &New + &สร้างใหม่ + Copy the currently selected address to the system clipboard คัดลอกที่อยู่ที่ถูกเลือกไปยัง คลิปบอร์ดของระบบ + + &Copy + &คัดลอก + + + C&lose + &ปิด + + + &Copy Address + &คัดลอกที่อยู่ + + + Delete the currently selected address from the list + ลบที่อยู่ที่เลือกไว้ในขณะนี้จากรายการ + + + Export the data in the current tab to a file + ส่งออกข้อมูลที่อยู่ในแท็บไปที่ไฟล์ + + + &Export + &ส่งออก + &Delete &ลบ + + Choose the address to send coins to + เลือกที่อยู่เพื่อส่งเหรียญไปไว้ + + + Choose the address to receive coins with + เลือกที่อยู่เพื่อรับเหรียญไว้ + + + C&hoose + &เลือก + + + Sending addresses + ส่งที่อยู่ + + + Receiving addresses + กำลังรับที่อยู่ + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + ที่อยู่เหล่านี้เป็นที่อยู่ Bitcoin ของคุณ สำหรับใช้เพื่อส่งเงิน กรุณาตรวจสอบจำนวนเงินและที่อยู่สำหรับรับเงินก่อนส่งเหรียญไป + + + Copy &Label + คัดลอก &ป้ายชื่อ + + + &Edit + &แก้ไข + + + Export Address List + ส่งออกรายการที่อยู่ + Comma separated file (*.csv) คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv) - + + Exporting Failed + ส่งออกข้อมูลล้มเหลว + + + There was an error trying to save the address list to %1. Please try again. + พบข้อผิดพลาดบางกระการในการพยายามบันทึกรายชื่อที่อยู่ไปยัง %1. กรุณาลองใหม่อีกครั้ง + + AddressTableModel @@ -75,6 +151,10 @@ Confirm wallet encryption ยืนยันการเข้ารหัสกระเป๋าสตางค์ + + Are you sure you wish to encrypt your wallet? + คุณแน่ใจแล้วหรือว่าต้องการเข้ารหัสกระเป๋าสตางค์ของคุณ? + Wallet encrypted กระเป๋าสตางค์ถูกเข้ารหัสเรียบร้อยแล้ว @@ -129,10 +209,18 @@ Browse transaction history เรียกดูประวัติการทำธุรกรรม + + E&xit + E&ออก + Quit application ออกจากโปรแกรม + + About &Qt + เกี่ยวกับ &Qt + &Options... &ตัวเลือก... @@ -141,6 +229,30 @@ Change the passphrase used for wallet encryption เปลี่ยนรหัสผ่านที่ใช้สำหรับการเข้ารหัสกระเป๋าเงิน + + &Debug window + &หน้าต่างตรวจสอบข้อผิดพลาด + + + &Verify message... + &ยืนยันข้อความ... + + + Bitcoin + Bitcoin + + + Wallet + กระเป๋าสตางค์ + + + &Send + &ส่ง + + + &Receive + &รับ + &File &ไฟล์ @@ -191,6 +303,26 @@ CoinControlDialog + + Amount + จำนวน + + + Date + วันที่ + + + Confirmations + การยืนยัน + + + Confirmed + ยืนยันแล้ว + + + Priority + ระดับความสำคัญ + (no label) (ไม่มีชื่อ) @@ -273,6 +405,10 @@ QObject + + Amount + จำนวน + QRImageWidget @@ -293,6 +429,10 @@ Address ที่อยู่ + + Amount + จำนวน + Label ชื่อ @@ -300,10 +440,18 @@ RecentRequestsTableModel + + Date + วันที่ + Label ชื่อ + + Amount + จำนวน + (no label) (ไม่มีชื่อ) @@ -345,12 +493,24 @@ TransactionDesc + + Date + วันที่ + + + Amount + จำนวน + TransactionDescDialog TransactionTableModel + + Date + วันที่ + Label ชื่อ @@ -362,10 +522,22 @@ Today วันนี้ + + Exporting Failed + ส่งออกข้อมูลล้มเหลว + Comma separated file (*.csv) คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv) + + Confirmed + ยืนยันแล้ว + + + Date + วันที่ + Label ชื่อ @@ -390,6 +562,14 @@ WalletView + + &Export + &ส่งออก + + + Export the data in the current tab to a file + ส่งออกข้อมูลที่อยู่ในแท็บไปที่ไฟล์ + bitcoin-core diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 96fca8bb2..240677677 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1473,10 +1473,6 @@ General Genel - - Using OpenSSL version - Kullanılan OpenSSL sürümü - Using BerkeleyDB version Kullanılan BerkeleyDB sürümü @@ -2941,7 +2937,7 @@ Prune configured below the minimum of %d MiB. Please use a higher number. - Prune, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. + Budama, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) @@ -2979,6 +2975,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Dışarıdan gelen bağlantıları kabul et (varsayılan: -proxy veya -connect yoksa 1) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee çok yüksek bir değere ayarlanmış! Ücret tahminleri mevcut değilken ödeyebileceğiniz muamele ücretidir bu. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Ücret tahmini için yetersiz veri bulunduğunda kullanılacak ücret oranı (%s/kB olarak) (varsayılan: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Muameleler aktarılmadığında dahi beyaz listedeki eşlerden aktarılan muameleleri kabul et (varsayılan: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız @@ -2995,6 +3003,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Yerel aktarma politikasını ihlal ettiklerinde bile beyaz listedeki eşlerden gelen muamelelerin aktarılmasını zorla (varsayılan: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) @@ -3011,6 +3023,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Desteklenmeyen argüman -whitelistalwaysrelay görmezden gelindi, -whitelistrelay ve/veya -whitelistforcerelay kullanın. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) @@ -3027,6 +3043,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Uyarı: şebeke tamamen mutabık değil gibi görünüyor! Bazı madenciler sorun yaşıyor gibi görünüyor. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + İkaz: bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Uyarı: eşlerimizle tamamen mutabık değiliz gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir. @@ -3047,6 +3067,10 @@ <category> can be: <kategori> şunlar olabilir: + + Append comment to the user agent string + Kullanıcı aracı zincirine yorumu ekle + Block creation options: Blok oluşturma seçenekleri: @@ -3091,6 +3115,10 @@ Enable publish raw transaction in <address> Ham muamelenin <adres>te yayınlanmasını etkinleştir + + Enable transaction replacement in the memory pool (default: %u) + Bellek alanında muamele değiştirmeyi etkinleştir (varsayılan: %u) + Error initializing block database Blok veritabanını başlatılırken bir hata meydana geldi @@ -3127,10 +3155,22 @@ Invalid -onion address: '%s' Geçersiz -onion adresi: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + -fallbackfee=<meblağ> için geçersiz meblağ: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u) + + Location of the auth cookie (default: data dir) + auth çerezinin konumu (varsayılan: veri klasörü) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Aktardığımız ve oluşturduğumuz muamelelerdeki sigop başına asgari bayt (varsayılan: %u) + Not enough file descriptors available. Kafi derecede dosya tanımlayıcıları mevcut değil. @@ -3139,13 +3179,17 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Sadece <net> şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion) + + Print version and exit + Sürümü yaz ve çık + Prune cannot be configured with a negative value. - Prune negatif bir değerle yapılandırılamaz. + Budama negatif bir değerle yapılandırılamaz. Prune mode is incompatible with -txindex. - Prune kipi -txindex ile uyumsuzdur. + Budama kipi -txindex ile uyumsuzdur. Set database cache size in megabytes (%d to %d, default: %d) @@ -3195,10 +3239,6 @@ Wallet options: Cüzdan seçenekleri: - - Warning: This version is obsolete; upgrade required! - Uyarı: Bu sürüm çok eskidir; güncellemeniz gerekir! - You need to rebuild the database using -reindex to change -txindex -txindex'i değiştirmek için veritabanını -reindex kullanarak tekrar inşa etmeniz gerekmektedir @@ -3281,7 +3321,7 @@ You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - Prune olmayan kipe dönmek için veritabanını -reindex ile tekrar derlemeniz gerekir. Bu, tüm blok zincirini tekrar indirecektir + Budama olmayan kipe dönmek için veritabanını -reindex ile tekrar derlemeniz gerekir. Bu, tüm blok zincirini tekrar indirecektir (default: %u) @@ -3295,10 +3335,6 @@ Activating best chain... En iyi zincir etkinleştiriliyor... - - Always relay transactions received from whitelisted peers (default: %d) - Beyaz listedeki eşlerden gelen muameleleri daima aktar (varsayılan: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Başlangıçta bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene @@ -3463,6 +3499,10 @@ Warning Uyarı + + Warning: unknown new rules activated (versionbit %i) + İkaz: bilinmeyen yeni kurallar etkinleştirilmiştir (versionbit %i) + Whether to operate in a blocks only mode (default: %u) Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index 10866b011..979aeea03 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -85,6 +85,10 @@ Export Address List Adres Listesini Dışa Aktar + + Comma separated file (*.csv) + Virgül ile ayrılmış dosya (*.csv) + Exporting Failed Dışa Aktarma Başarısız Oldu @@ -246,6 +250,10 @@ Exporting Failed Dışa Aktarma Başarısız Oldu + + Comma separated file (*.csv) + Virgül ile ayrılmış dosya (*.csv) + Label Etiket diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index ea783aa85..64df7b5ba 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1473,10 +1473,6 @@ General Загальна - - Using OpenSSL version - Використовується OpenSSL версії - Using BerkeleyDB version Використовується BerkeleyDB версії @@ -3139,6 +3135,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Підключатися тільки до вузлів в мережі <net> (ipv4, ipv6 або onion) + + Print version and exit + Версія для друку і виходу + Prune cannot be configured with a negative value. Розмір скороченого ланцюжка блоків не може бути від'ємним. @@ -3195,10 +3195,6 @@ Wallet options: Параметри гаманця: - - Warning: This version is obsolete; upgrade required! - Увага: Поточна версія застаріла, необхідне оновлення! - You need to rebuild the database using -reindex to change -txindex Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex @@ -3295,10 +3291,6 @@ Activating best chain... Активація найкращого ланцюжка... - - Always relay transactions received from whitelisted peers (default: %d) - Завжди передавайте транзакції отримані від пірів з білого списку (типово: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup Спочатку спробуйте відновити приватні ключі в пошкодженому wallet.dat diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 86724564f..a9f9af668 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -1167,10 +1167,6 @@ General Асосий - - Using OpenSSL version - Фойдаланилаётган OpenSSL версияси - Using BerkeleyDB version Фойдаланилаётган BerkeleyDB версияси diff --git a/src/qt/locale/bitcoin_uz@Latn.ts b/src/qt/locale/bitcoin_uz@Latn.ts new file mode 100644 index 000000000..2e4dabb59 --- /dev/null +++ b/src/qt/locale/bitcoin_uz@Latn.ts @@ -0,0 +1,169 @@ + + + AddressBookPage + + Create a new address + Yangi manzil yaratish + + + &New + &Yangi + + + &Copy + &Nusxalash + + + C&lose + Yo&pish + + + &Copy Address + &Manzillarni nusxalash + + + &Delete + &O'chirish + + + + AddressTableModel + + Label + Yorliq + + + Address + Manzil + + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + + ClientModel + + + CoinControlDialog + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + Manzil + + + Label + Yorliq + + + + RecentRequestsTableModel + + Label + Yorliq + + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Yorliq + + + + TransactionView + + Label + Yorliq + + + Address + Manzil + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 0ae2c95c6..cc1b03356 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -1473,10 +1473,6 @@ General 常规 - - Using OpenSSL version - 使用 OpenSSL 版本 - Using BerkeleyDB version 使用的 BerkeleyDB 版本 @@ -2942,6 +2938,14 @@ Prune configured below the minimum of %d MiB. Please use a higher number. 修剪值被设置为低于最小值%d MiB,请使用更大的数值。 + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + 修剪:最后的钱包同步超过了修剪的数据。你需要通过 -reindex (重新下载整个区块链以防修剪节点) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + 通过修剪(删除)旧数据块减少存储需求。此模式与 -txindex 和 -rescan不兼容。警告:还原此设置需要重新下载整个区块链。(默认: 0 = 禁用修剪数据块, >%u = 数据块文件目标大小,单位 MiB) + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. 无法在开启修剪的状态下重扫描,请使用 -reindex重新下载完整的区块链。 @@ -2972,6 +2976,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 接受来自外部的连接 (缺省: 如果不带 -proxy or -connect 参数设置为1) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfree 交易费设置得很高!这是在费用估计不可用时你可能会支付的交易费。 + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + 当费用估计数据(default: %s)不足时将会启用的费率 (in %s/kB) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + 即使在无关联交易(默认: %d)时也接受来自白名单同行的关联交易 + Bind to given address and always listen on it. Use [host]:port notation for IPv6 绑定指定的IP地址开始监听。IPv6地址请使用[host]:port 格式 @@ -2988,6 +3004,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + 强制关联来自白名单同行的交易即使他们违反本地关联政策(默认: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d) @@ -3004,6 +3024,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. 无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 一个不被支持的参数 -whitelistalwaysrelay 被忽略了。请使用 -whitelistrelay 或者 -whitelistforcerelay. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) 使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理) @@ -3020,6 +3044,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告:网络似乎并不完全同意!有些矿工似乎遇到了问题。 + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 未知的区块版本被挖掘!未知规则可能已生效 + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 警告:我们的同行似乎不完全同意!您可能需要升级,或者其他节点可能需要升级。 @@ -3040,6 +3068,10 @@ <category> can be: <category> 可能是: + + Append comment to the user agent string + 为用户代理字符串附加说明 + Block creation options: 数据块创建选项: @@ -3084,6 +3116,10 @@ Enable publish raw transaction in <address> 允许在<address>广播原始交易 + + Enable transaction replacement in the memory pool (default: %u) + 保证内存池中的交易更换(默认:%u) + Error initializing block database 初始化数据块数据库出错 @@ -3120,10 +3156,22 @@ Invalid -onion address: '%s' 无效的 -onion 地址:“%s” + + Invalid amount for -fallbackfee=<amount>: '%s' + -fallbackfee 的无效数额=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) 保持交易内存池大小低于<n>MB(默认:%u) + + Location of the auth cookie (default: data dir) + 认证Cookie的位置 (默认: data目录) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + 我们关联和挖掘的每sigop的最低交易字节(默认: %u) + Not enough file descriptors available. 没有足够的文件描述符可用。 @@ -3132,6 +3180,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) 只连接 <net>网络中的节点 (ipv4, ipv6 或 onion) + + Print version and exit + 打印版本信息并退出 + Prune cannot be configured with a negative value. 修剪不能配置一个负数。 @@ -3168,6 +3220,10 @@ Use UPnP to map the listening port (default: %u) 使用UPnp映射监听端口 (默认: %u) + + User Agent comment (%s) contains unsafe characters. + 用户代理评论(%s)包含不安全的字符。 + Verifying blocks... 正在验证数据库的完整性... @@ -3184,10 +3240,6 @@ Wallet options: 钱包选项: - - Warning: This version is obsolete; upgrade required! - 警告:此版本已过时,必须升级! - You need to rebuild the database using -reindex to change -txindex 您需要将 -reindex 改为 -txindex 以重建数据库 @@ -3224,6 +3276,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) 当收到相关提醒或者我们看到一个长分叉时执行命令(%s 将替换为消息) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + 交易费(in %s/kB)比这更小的在关联、挖掘和生成交易时将被视为零费交易 (默认: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) @@ -3280,6 +3336,14 @@ Activating best chain... 正在激活最佳数据链... + + Attempt to recover private keys from a corrupt wallet.dat on startup + 尝试从启动页上的损坏钱包文件中恢复私钥 + + + Automatically create Tor hidden service (default: %d) + 自动建立Tor隐藏服务 (默认:%d) + Cannot resolve -whitebind address: '%s' 无法解析 -whitebind 地址: '%s' diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts new file mode 100644 index 000000000..740a86e11 --- /dev/null +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -0,0 +1,521 @@ + + + AddressBookPage + + Right-click to edit address or label + 按右擊修改位址或標記 + + + Create a new address + 新增一個位址 + + + &New + 新增 &N + + + Copy the currently selected address to the system clipboard + 複製目前選擇的位址到系統剪貼簿 + + + &Copy + 複製 &C + + + C&lose + 關閉 &l + + + &Copy Address + 複製位址 &C + + + Delete the currently selected address from the list + 把目前選擇的位址從列表中刪除 + + + Export the data in the current tab to a file + 把目前分頁的資料匯出至檔案 + + + &Export + 匯出 &E + + + &Delete + 刪除 &D + + + Choose the address to send coins to + 選擇要付錢過去的位址 + + + Choose the address to receive coins with + 選擇要收錢的位址 + + + C&hoose + 選取 &h + + + Sending addresses + 付款位址 + + + Receiving addresses + 收款位址 + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + 這些是你要付款過去的 Bitcoin 位址。在付款之前,務必要檢查金額和收款位址是否正確。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 + + + Copy &Label + 複製標記 &L + + + &Edit + 編輯 &E + + + Export Address List + 匯出位址清單 + + + Comma separated file (*.csv) + 逗號分隔檔(*.csv) + + + Exporting Failed + 匯出失敗 + + + There was an error trying to save the address list to %1. Please try again. + 儲存位址列表到 %1 時發生錯誤。請再試一次。 + + + + AddressTableModel + + Label + 標記 + + + Address + 位址 + + + (no label) + (無標記) + + + + AskPassphraseDialog + + Passphrase Dialog + 複雜密碼對話方塊 + + + Enter passphrase + 請輸入密碼 + + + New passphrase + 新密碼 + + + Repeat new passphrase + 重複新密碼 + + + Encrypt wallet + 加密錢包 + + + This operation needs your wallet passphrase to unlock the wallet. + 這個動作需要你的錢包密碼來將錢包解鎖。 + + + Unlock wallet + 解鎖錢包 + + + This operation needs your wallet passphrase to decrypt the wallet. + 這個動作需要你的錢包密碼來將錢包解密。 + + + Decrypt wallet + 解密錢包 + + + Change passphrase + 改變密碼 + + + Confirm wallet encryption + 確認錢包加密 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: 如果把錢包加密後又忘記密碼,你就會<b>失去所有 Bitcoin 了</b>! + + + Are you sure you wish to encrypt your wallet? + 你確定要把錢包加密嗎? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core 現在要關閉以完成加密程序。請記得將錢包加密不能完全防止你的 Bitcoin 經被入侵電腦的惡意程式偷取。 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 重要: 請改用新產生的加密錢包檔,來取代所以舊錢包檔的備份。為安全計,當你開始使用新的加密錢包檔後,舊錢包檔的備份就不能再使用了。 + + + Warning: The Caps Lock key is on! + 警告: Caps Lock 已啟用! + + + Wallet encrypted + 錢包已加密 + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 輸入錢包的新密碼。<br/>密碼請用<b>10 個或以上的隨機字元</b>,或是<b>8 個或以上的字詞</b>。 + + + Enter the old passphrase and new passphrase to the wallet. + 請輸入舊密碼和新密碼至錢包。 + + + Wallet encryption failed + 錢包加密失敗 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 因內部錯誤導致錢包加密失敗。你的錢包尚未加密。 + + + The supplied passphrases do not match. + 提供的密碼不一樣。 + + + Wallet unlock failed + 錢包解鎖失敗 + + + The passphrase entered for the wallet decryption was incorrect. + 用來解密錢包的密碼不對。 + + + Wallet decryption failed + 錢包解密失敗 + + + Wallet passphrase was successfully changed. + 錢包密碼已成功更改。 + + + + BanTableModel + + IP/Netmask + IP位址/遮罩 + + + Banned Until + 封鎖至 + + + + BitcoinGUI + + Sign &message... + 簽署訊息... &m + + + Synchronizing with network... + 與網絡同步中... + + + &Overview + 總覽 &O + + + Node + 節點 + + + Show general overview of wallet + 顯示錢包一般總覽 + + + &Transactions + 交易 &T + + + Browse transaction history + 瀏覽交易紀錄 + + + E&xit + 結束 &x + + + Quit application + 結束應用程式 + + + About &Qt + 關於 Qt &Q + + + Show information about Qt + 顯示 Qt 相關資訊 + + + &Options... + 選項... &O + + + &Encrypt Wallet... + 加密錢包... &E + + + &Backup Wallet... + 備份錢包... &B + + + &Change Passphrase... + 改變密碼... &C + + + &Sending addresses... + 付款位址... &S + + + &Receiving addresses... + 收款位址... &R + + + Open &URI... + 開啓網址... &U + + + Bitcoin Core client + Bitcoin Core 客戶端 + + + Importing blocks from disk... + 正在從磁碟匯入區塊資料... + + + Reindexing blocks on disk... + 正在為磁碟區塊重建索引... + + + Send coins to a Bitcoin address + 付款至一個 Bitcoin 位址 + + + Backup wallet to another location + 把錢包備份到其它地方 + + + Change the passphrase used for wallet encryption + 改變錢包加密用的密碼 + + + &Debug window + 除錯視窗 &D + + + Open debugging and diagnostic console + 開啓除錯和診斷主控台 + + + &Verify message... + 驗證訊息... &V + + + Bitcoin + Bitcoin + + + Wallet + 錢包 + + + &Send + 付款 &S + + + &Receive + 收款 &R + + + Show information about Bitcoin Core + 顯示 Bitcoin Core 的相關資訊 + + + &Show / Hide + 顯示 / 隱藏 &S + + + Show or hide the main Window + 顯示或隱藏主視窗 + + + + ClientModel + + + CoinControlDialog + + (no label) + (無標記) + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Address + 位址 + + + Label + 標記 + + + + RecentRequestsTableModel + + Label + 標記 + + + (no label) + (無標記) + + + + SendCoinsDialog + + (no label) + (無標記) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + 標記 + + + + TransactionView + + Exporting Failed + 匯出失敗 + + + Comma separated file (*.csv) + 逗號分隔檔(*.csv) + + + Label + 標記 + + + Address + 位址 + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + 匯出 &E + + + Export the data in the current tab to a file + 把目前分頁的資料匯出至檔案 + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 402609592..107e7034e 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -7,7 +7,7 @@ Create a new address - 新增新的位址 + 產生一個新位址 &New @@ -67,11 +67,11 @@ These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 這些是你要付款過去的位元幣位址。在付錢之前,務必要檢查金額和收款位址是否正確。 + 這些是你要付款過去的 Bitcoin 位址。在付錢之前,務必要檢查金額和收款位址是否正確。 These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - 這些是你用來收款的位元幣位址。建議在每次交易時,都使用一個新的收款位址。 + 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 Copy &Label @@ -161,7 +161,7 @@ Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 警告: 如果把錢包加密後又忘記密碼,你就會從此<b>失去其中所有的位元幣了</b>! + 警告: 如果把錢包加密後又忘記密碼,你就會從此<b>失去其中所有的 Bitcoin 了</b>! Are you sure you wish to encrypt your wallet? @@ -169,7 +169,7 @@ Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - 位元幣核心現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取位元幣。 + Bitcoin Core 現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取錢幣。 IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. @@ -307,7 +307,7 @@ Bitcoin Core client - 位元幣核心客戶端軟體 + Bitcoin Core 客戶端軟體 Importing blocks from disk... @@ -319,7 +319,7 @@ Send coins to a Bitcoin address - 付錢給一個位元幣位址 + 付錢給一個 Bitcoin 位址 Backup wallet to another location @@ -343,7 +343,7 @@ Bitcoin - 位元幣 + Bitcoin Wallet @@ -359,7 +359,7 @@ Show information about Bitcoin Core - 顯示位元幣核心的相關資訊 + 顯示 Bitcoin Core 的相關資訊 &Show / Hide @@ -375,11 +375,11 @@ Sign messages with your Bitcoin addresses to prove you own them - 用位元幣位址簽署訊息來證明位址是你的 + 用 Bitcoin 位址簽署訊息來證明位址是你的 Verify messages to ensure they were signed with specified Bitcoin addresses - 驗證訊息是用來確定訊息是用指定的位元幣位址簽署的 + 驗證訊息是用來確定訊息是用指定的 Bitcoin 位址簽署的 &File @@ -399,19 +399,19 @@ Bitcoin Core - 位元幣核心 + Bitcoin Core Request payments (generates QR codes and bitcoin: URIs) - 要求付款(產生 QR Code 和位元幣付款協議的資源識別碼: URI) + 要求付款(產生 QR Code 和 bitcoin 付款協議的資源識別碼: URI) &About Bitcoin Core - 關於位元幣核心 + 關於 Bitcoin Core Modify configuration options for Bitcoin Core - 修改位元幣核心的設定選項 + 修改 Bitcoin Core 的設定選項 Show the list of used sending addresses and labels @@ -431,11 +431,11 @@ Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 顯示位元幣核心的說明訊息,來取得可用命令列選項的列表 + 顯示 Bitcoin Core 的說明訊息,來取得可用命令列選項的列表 %n active connection(s) to Bitcoin network - %n 個運作中的位元幣網路連線 + %n 個運作中的 Bitcoin 網路連線 No block source available... @@ -818,7 +818,7 @@ The entered address "%1" is not a valid Bitcoin address. - 輸入的位址 %1 並不是有效的位元幣位址。 + 輸入的位址 %1 並不是有效的 Bitcoin 位址。 Could not unlock wallet. @@ -856,7 +856,7 @@ HelpMessageDialog Bitcoin Core - 位元幣核心 + Bitcoin Core version @@ -868,7 +868,7 @@ About Bitcoin Core - 關於位元幣核心 + 關於 Bitcoin Core Command-line options @@ -919,15 +919,15 @@ Welcome to Bitcoin Core. - 歡迎使用位元幣核心 + 歡迎使用 Bitcoin Core As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - 因為這是程式第一次啓動,你可以選擇位元幣核心儲存資料的地方。 + 因為這是程式第一次啓動,你可以選擇 Bitcoin Core 儲存資料的地方。 Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - 位元幣核心會下載並儲存一份位元幣區塊鏈的拷貝。至少有 %1GB 的資料會儲存到這個目錄中,並且還會持續增長。另外錢包資料也會儲存在這個目錄。 + Bitcoin Core 會下載並儲存一份 Bitcoin 區塊鏈的拷貝。至少有 %1GB 的資料會儲存到這個目錄中,並且還會持續增長。另外錢包資料也會儲存在這個目錄。 Use the default data directory @@ -939,7 +939,7 @@ Bitcoin Core - 位元幣核心 + Bitcoin Core Error: Specified data directory "%1" cannot be created. @@ -1021,7 +1021,7 @@ The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - 可以在這裡設定使用者介面的語言。這個設定在重啓位元幣核心後才會生效。 + 可以在這裡設定使用者介面的語言。這個設定在重啓 Bitcoin Core 後才會生效。 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 |. @@ -1049,11 +1049,11 @@ Automatically start Bitcoin Core after logging in to the system. - 在登入系統後自動啓動位元幣核心。 + 在登入系統後自動啓動 Bitcoin Core。 &Start Bitcoin Core on system login - 系統登入時啟動位元幣核心 + 系統登入時啟動 Bitcoin Core (0 = auto, <0 = leave that many cores free) @@ -1081,7 +1081,7 @@ Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - 自動在路由器上開放位元幣的客戶端通訊埠。只有在你的路由器支援且開啓「通用即插即用」協定(UPnP)時才有作用。 + 自動在路由器上開放 Bitcoin 的客戶端通訊埠。只有在你的路由器支援且開啓「通用即插即用」協定(UPnP)時才有作用。 Map port using &UPnP @@ -1089,7 +1089,7 @@ Connect to the Bitcoin network through a SOCKS5 proxy. - 透過 SOCKS5 代理伺服器來連線到位元幣網路。 + 透過 SOCKS5 代理伺服器來連線到 Bitcoin 網路。 &Connect through SOCKS5 proxy (default proxy): @@ -1129,7 +1129,7 @@ Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. - 透過另外的 SOCKS5 代理伺服器來連線到位元幣網路中的 Tor 隱藏服務。 + 透過另外的 SOCKS5 代理伺服器來連線到 Bitcoin 網路中的 Tor 隱藏服務。 Use separate SOCKS5 proxy to reach peers via Tor hidden services: @@ -1216,7 +1216,7 @@ 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. - 顯示的資訊可能是過期的。跟位元幣網路的連線建立後,你的錢包會自動和網路同步,但是這個步驟還沒完成。 + 顯示的資訊可能是過期的。跟 Bitcoin 網路的連線建立後,你的錢包會自動和網路同步,但是這個步驟還沒完成。 Watch-only: @@ -1323,7 +1323,7 @@ URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - 沒辦法解析資源識別碼(URI)!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。 + 沒辦法解析資源識別碼(URI)!可能是因為 Bitcoin 位址無效,或是 URI 參數格式錯誤。 Payment request file handling @@ -1397,7 +1397,7 @@ Enter a Bitcoin address (e.g. %1) - 輸入位元幣位址 (比如說 %1) + 輸入 Bitcoin 位址 (比如說 %1) %1 d @@ -1473,10 +1473,6 @@ General 普通 - - Using OpenSSL version - 使用的 OpenSSL 版本 - Using BerkeleyDB version 使用 BerkeleyDB 版本 @@ -1519,7 +1515,7 @@ Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - 從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 + 從目前的資料目錄下開啓 Bitcoin Core 的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 Received @@ -1679,7 +1675,7 @@ Welcome to the Bitcoin Core RPC console. - 歡迎使用位元幣核心 RPC 主控台。 + 歡迎使用 Bitcoin Core 的 RPC 主控台。 Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1762,7 +1758,7 @@ 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. - 附加在付款要求中的訊息,可以不填,打開要求內容時會顯示。注意: 這個訊息不會隨著付款送到位元幣網路上。 + 附加在付款要求中的訊息,可以不填,打開要求內容時會顯示。注意: 這個訊息不會隨著付款送到 Bitcoin 網路上。 An optional label to associate with the new receiving address. @@ -2155,7 +2151,7 @@ Warning: Invalid Bitcoin address - 警告: 位元幣位址無效 + 警告: Bitcoin 位址無效 (no label) @@ -2206,7 +2202,7 @@ The Bitcoin address to send the payment to - 接收付款的位元幣位址 + 接收付款的 Bitcoin 位址 Alt+A @@ -2226,7 +2222,7 @@ 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. - 手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的位元幣。如果有多個收款人的話,手續費會平均分配來扣除。 + 手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的 bitcoin。如果有多個收款人的話,手續費會平均分配來扣除。 S&ubtract fee from amount @@ -2250,7 +2246,7 @@ 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. - 附加在位元幣付款協議的資源識別碼(URI)中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。 + 附加在 Bitcoin 付款協議的資源識別碼(URI)中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到 Bitcoin 網路上。 Pay To: @@ -2265,7 +2261,7 @@ ShutdownWindow Bitcoin Core is shutting down... - 正在關閉位元幣核心中... + 正在關閉 Bitcoin Core 中... Do not shut down the computer until this window disappears. @@ -2288,7 +2284,7 @@ The Bitcoin address to sign the message with - 用來簽署訊息的位元幣位址 + 用來簽署訊息的 Bitcoin 位址 Choose previously used address @@ -2320,7 +2316,7 @@ Sign the message to prove you own this Bitcoin address - 簽署這個訊息來證明這個位元幣位址是你的 + 簽署這個訊息來證明這個 Bitcoin 位址是你的 Sign &Message @@ -2344,11 +2340,11 @@ The Bitcoin address the message was signed with - 簽署這個訊息的位元幣位址 + 簽署這個訊息的 Bitcoin 位址 Verify the message to ensure it was signed with the specified Bitcoin address - 驗證這個訊息來確定是用指定的位元幣位址簽署的 + 驗證這個訊息來確定是用指定的 Bitcoin 位址簽署的 Verify &Message @@ -2415,11 +2411,11 @@ SplashScreen Bitcoin Core - 位元幣核心 + Bitcoin Core The Bitcoin Core developers - 位元幣核心開發人員 + Bitcoin Core 開發人員 [testnet] @@ -2938,7 +2934,7 @@ Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - 請檢查電腦日期和時間是否正確!位元幣核心沒辦法在時鐘不準的情況下正常運作。 + 請檢查電腦日期和時間是否正確!Bitcoin Core 沒辦法在時鐘不準的情況下正常運作。 Prune configured below the minimum of %d MiB. Please use a higher number. @@ -2970,7 +2966,7 @@ Run in the background as a daemon and accept commands - 用護靈模式在背後執行並接受指令 + 用護靈模式在背景執行並接受指令 Unable to start HTTP server. See debug log for details. @@ -2980,6 +2976,18 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 是否接受外來連線(預設值: 當沒有 -proxy 或 -connect 時為 1) + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + 警告: -fallbackfee 設定了很高的金額!這是當預估手續費還沒計算出來時,交易付款預設會付的手續費。 + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + 當沒有足夠的資料計算預估手續費時,所使用的手續費費率(單位是 %s/kB, 預設值: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + 接受從白名點節點收到的轉發交易,即使沒有(符合準則)轉發出去(預設值: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 和指定的位址繫結,並且一直在指定位址聽候連線。IPv6 請用 [主機]:通訊埠 這種格式 @@ -2996,6 +3004,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 設定指令碼驗證的執行緒數目 (%u 到 %d,0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目,預設值: %d) @@ -3010,7 +3022,11 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. - 沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。 + 沒辦法繫結在這台電腦上的 %s 。Bitcoin Core 可能已經在執行了。 + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 忽略不支援的參數 -whitelistalwaysrelay,請改用 -whitelistrelay 和 -whitelistforcerelay​ 的組合。 Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -3026,7 +3042,11 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. - 警告: 位元幣網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。 + 警告: 節點網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。 + + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 有礦工正在開採不明版本的區塊!這表示有不明的交易規則正在作用中 Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. @@ -3048,6 +3068,10 @@ <category> can be: <category> 可以是: + + Append comment to the user agent string + 對使用者代理字串添加註解 + Block creation options: 區塊製造選項: @@ -3092,6 +3116,10 @@ Enable publish raw transaction in <address> 開啟傳送交易原始資料到目標 ZeroMQ 位址 <address> 去 + + Enable transaction replacement in the memory pool (default: %u) + 對交易暫存池啟用替代交易(預設值: %u) + Error initializing block database 初始化區塊資料庫時發生錯誤 @@ -3128,10 +3156,22 @@ Invalid -onion address: '%s' 無效的 -onion 位址: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' + 設定 -fallbackfee=<金額> 的金額無效: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) 在記憶體暫存池中保持最多 <n> 個百萬位元組的交易(預設值: %u) + + Location of the auth cookie (default: data dir) + 認證 cookie 資料的位置(預設值: 同資料目錄) + + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + 轉發和開採時,對交易資料的 sigop 平均位元組數下限(預設值: %u) + Not enough file descriptors available. 檔案描述元不足。 @@ -3140,6 +3180,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) 只和 <net> 網路上的節點連線(ipv4, ipv6, 或 onion) + + Print version and exit + 顯示版本後結束 + Prune cannot be configured with a negative value. 修剪值不能設定為負的。 @@ -3196,10 +3240,6 @@ Wallet options: 錢包選項: - - Warning: This version is obsolete; upgrade required! - 警告: 這個版本已經被淘汰了;必須要升級! - You need to rebuild the database using -reindex to change -txindex 改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫 @@ -3218,7 +3258,7 @@ Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - 沒辦法鎖定資料目錄 %s。位元幣核心可能已經在執行了。 + 沒辦法鎖定資料目錄 %s。Bitcoin Core 可能已經在執行了。 Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) @@ -3296,10 +3336,6 @@ Activating best chain... 啟用最佳鏈結... - - Always relay transactions received from whitelisted peers (default: %d) - 無條件轉發從白名點節點收到的交易(預設值: %d) - Attempt to recover private keys from a corrupt wallet.dat on startup 啟動時嘗試從壞掉的錢包檔 wallet.dat 復原密鑰 @@ -3318,11 +3354,11 @@ Copyright (C) 2009-%i The Bitcoin Core Developers - 版權為位元幣核心開發人員自西元 2009 至 %i 年起所有 + 版權為 Bitcoin Core 開發人員自西元 2009 至 %i 年起所有 Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - 載入 wallet.dat 檔案時發生錯誤: 這個錢包需要新版的位元幣核心 + 載入 wallet.dat 檔案時發生錯誤: 這個錢包需要新版的 Bitcoin Core Error reading from database, shutting down. @@ -3338,7 +3374,7 @@ Initialization sanity check failed. Bitcoin Core is shutting down. - 初始化時的基本檢查失敗了。位元幣核心就要關閉了。 + 初始化時的基本檢查失敗了。Bitcoin Core 就要關閉了。 Invalid amount for -maxtxfee=<amount>: '%s' @@ -3458,12 +3494,16 @@ Wallet needed to be rewritten: restart Bitcoin Core to complete - 錢包需要重寫: 請重新啓動位元幣核心來完成 + 錢包需要重寫: 請重新啓動 Bitcoin Core 來完成 Warning 警告 + + Warning: unknown new rules activated (versionbit %i) + 警告: 不明的交易規則被啟用了(versionbit %i) + Whether to operate in a blocks only mode (default: %u) 是否要用只要區塊模式運作(預設值: %u) @@ -3582,7 +3622,7 @@ Generate coins (default: %u) - 生產位元幣(預設值: %u) + 生產錢幣(預設值: %u) How many blocks to check at startup (default: %u, 0 = all) From 48efec82f3a18364c019577495914fcebb425e35 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 21 Jun 2016 16:09:46 -0700 Subject: [PATCH 0837/1223] Fix some minor compact block issues that came up in review --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 60a33f9c2..f5b141011 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4613,7 +4613,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // Track requests for our stuff. GetMainSignals().Inventory(inv.hash); - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) + if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) break; } } @@ -5077,8 +5077,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - if (it->second->nHeight < chainActive.Height() - 10) { - LogPrint("net", "Peer %d sent us a getblocktxn for a block > 10 deep", pfrom->id); + if (it->second->nHeight < chainActive.Height() - 15) { + LogPrint("net", "Peer %d sent us a getblocktxn for a block > 15 deep", pfrom->id); return true; } From 06f40ef324ce0d4e43b89f7106e50965263aa2c7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Jun 2016 14:37:39 +0200 Subject: [PATCH 0838/1223] depends: Mention aarch64 as common cross-compile target --- depends/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/depends/README.md b/depends/README.md index 271bbd80b..6053c531b 100644 --- a/depends/README.md +++ b/depends/README.md @@ -23,7 +23,8 @@ Common `host-platform-triplets` for cross compilation are: - `i686-w64-mingw32` for Win32 - `x86_64-w64-mingw32` for Win64 - `x86_64-apple-darwin11` for MacOSX -- `arm-linux-gnueabihf` for Linux ARM +- `arm-linux-gnueabihf` for Linux ARM 32 bit +- `aarch64-linux-gnu` for Linux ARM 64 bit No other options are needed, the paths are automatically configured. From ecacfd98e657c5819a1bcb1da93b25d3ad4e5045 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 31 Mar 2016 14:43:23 +0200 Subject: [PATCH 0839/1223] --- [SEGWIT] begin: P2P/node/consensus --- From 7030d9eb47254499bba14f1c00abc6bf493efd91 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 Nov 2015 01:32:04 +0100 Subject: [PATCH 0840/1223] BIP144: Serialization, hashes, relay (sender side) Contains refactorings by Eric Lombrozo. Contains fixup by Nicolas Dorier. Contains cleanup of CInv::GetCommand by Alex Morcos --- src/core_io.h | 2 +- src/core_memusage.h | 24 ++++- src/core_read.cpp | 16 +++- src/main.cpp | 28 +++--- src/net.h | 17 ++++ src/primitives/block.h | 2 - src/primitives/transaction.cpp | 16 +++- src/primitives/transaction.h | 151 +++++++++++++++++++++++++++--- src/protocol.cpp | 46 +++------ src/protocol.h | 30 +++--- src/qt/coincontroldialog.cpp | 18 +++- src/qt/walletmodeltransaction.cpp | 3 +- src/rpc/rawtransaction.cpp | 6 +- src/script/script.cpp | 12 +++ src/script/script.h | 14 +++ src/streams.h | 33 +++++++ src/test/data/tx_invalid.json | 4 - src/test/sighash_tests.cpp | 2 +- src/test/transaction_tests.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/walletdb.h | 1 + 21 files changed, 339 insertions(+), 90 deletions(-) diff --git a/src/core_io.h b/src/core_io.h index e8c0c49e8..b559d44bf 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -17,7 +17,7 @@ class UniValue; // core_read.cpp extern CScript ParseScript(const std::string& s); extern std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false); -extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); +extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx, bool fTryNoWitness = false); extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); extern uint256 ParseHashStr(const std::string&, const std::string& strName); diff --git a/src/core_memusage.h b/src/core_memusage.h index 450537d05..dd86f805f 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -25,8 +25,28 @@ static inline size_t RecursiveDynamicUsage(const CTxOut& out) { return RecursiveDynamicUsage(out.scriptPubKey); } +static inline size_t RecursiveDynamicUsage(const CScriptWitness& scriptWit) { + size_t mem = memusage::DynamicUsage(scriptWit.stack); + for (std::vector >::const_iterator it = scriptWit.stack.begin(); it != scriptWit.stack.end(); it++) { + mem += memusage::DynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CTxinWitness& txinwit) { + return RecursiveDynamicUsage(txinwit.scriptWitness); +} + +static inline size_t RecursiveDynamicUsage(const CTxWitness& txwit) { + size_t mem = memusage::DynamicUsage(txwit.vtxinwit); + for (std::vector::const_iterator it = txwit.vtxinwit.begin(); it != txwit.vtxinwit.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + static inline size_t RecursiveDynamicUsage(const CTransaction& tx) { - size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout) + RecursiveDynamicUsage(tx.wit); for (std::vector::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { mem += RecursiveDynamicUsage(*it); } @@ -37,7 +57,7 @@ static inline size_t RecursiveDynamicUsage(const CTransaction& tx) { } static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) { - size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout) + RecursiveDynamicUsage(tx.wit); for (std::vector::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { mem += RecursiveDynamicUsage(*it); } diff --git a/src/core_read.cpp b/src/core_read.cpp index 444a4c7eb..7cfda6dd6 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -90,12 +90,26 @@ CScript ParseScript(const std::string& s) return result; } -bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) +bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx, bool fTryNoWitness) { if (!IsHex(strHexTx)) return false; vector txData(ParseHex(strHexTx)); + + if (fTryNoWitness) { + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); + try { + ssData >> tx; + if (ssData.eof()) { + return true; + } + } + catch (const std::exception&) { + // Fall through. + } + } + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); try { ssData >> tx; diff --git a/src/main.cpp b/src/main.cpp index ae195ecc4..218494023 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1029,8 +1029,8 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); - // Size limits - if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) + if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values @@ -3396,7 +3396,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // because we receive the wrong transactions for it. // Size limits - if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // First transaction must be coinbase, the rest must not be @@ -4508,6 +4508,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) switch (inv.type) { case MSG_TX: + case MSG_WITNESS_TX: { assert(recentRejects); if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip) @@ -4528,6 +4529,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) pcoinsTip->HaveCoinsInCache(inv.hash); } case MSG_BLOCK: + case MSG_WITNESS_BLOCK: return mapBlockIndex.count(inv.hash); } // Don't know what it is, just say we already got one @@ -4552,7 +4554,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam boost::this_thread::interruption_point(); it++; - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) + if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) { bool send = false; BlockMap::iterator mi = mapBlockIndex.find(inv.hash); @@ -4593,6 +4595,8 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); + else if (inv.type == MSG_WITNESS_BLOCK) pfrom->PushMessage(NetMsgType::BLOCK, block); else if (inv.type == MSG_FILTERED_BLOCK) { @@ -4609,7 +4613,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) - pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -4622,9 +4626,9 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // instead we respond with the full, non-compact block. if (mi->second->nHeight >= chainActive.Height() - 10) { CBlockHeaderAndShortTxIDs cmpctblock(block); - pfrom->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock); + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); } else - pfrom->PushMessage(NetMsgType::BLOCK, block); + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); } // Trigger the peer node to send a getblocks request for the next batch of inventory @@ -4640,20 +4644,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } } - else if (inv.type == MSG_TX) + else if (inv.type == MSG_TX || inv.type == MSG_WITNESS_TX) { // Send stream from relay memory bool push = false; auto mi = mapRelay.find(inv.hash); if (mi != mapRelay.end()) { - pfrom->PushMessage(NetMsgType::TX, *mi->second); + pfrom->PushMessageWithFlag(inv.type == MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0, NetMsgType::TX, *mi->second); push = true; } else if (pfrom->timeLastMempoolReq) { auto txinfo = mempool.info(inv.hash); // To protect privacy, do not answer getdata using the mempool when // that TX couldn't have been INVed in reply to a MEMPOOL request. if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) { - pfrom->PushMessage(NetMsgType::TX, *txinfo.tx); + pfrom->PushMessageWithFlag(inv.type == MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0, NetMsgType::TX, *txinfo.tx); push = true; } } @@ -4665,7 +4669,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // Track requests for our stuff. GetMainSignals().Inventory(inv.hash); - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) + if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) break; } } @@ -5146,7 +5150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } resp.txn[i] = block.vtx[req.indexes[i]]; } - pfrom->PushMessage(NetMsgType::BLOCKTXN, resp); + pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp); } diff --git a/src/net.h b/src/net.h index aa9b2c11a..cb35d8c4f 100644 --- a/src/net.h +++ b/src/net.h @@ -598,6 +598,23 @@ public: } } + /** Send a message containing a1, serialized with flag flag. */ + template + void PushMessageWithFlag(int flag, const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + WithOrVersion(&ssSend, flag) << a1; + EndMessage(pszCommand); + } + catch (...) + { + AbortMessage(); + throw; + } + } + template void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) { diff --git a/src/primitives/block.h b/src/primitives/block.h index 42276b2bc..29307aed5 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -38,7 +38,6 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); - nVersion = this->nVersion; READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); READWRITE(nTime); @@ -120,7 +119,6 @@ public: std::string ToString() const; }; - /** Describes a place in the block chain to another node such that if the * other node doesn't have the same branch, it can find a recent common trunk. * The further back it is, the further before the fork it may be. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 947f2e6a7..b0230530e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -60,21 +60,26 @@ std::string CTxOut::ToString() const } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} -CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {} +CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), wit(tx.wit), nLockTime(tx.nLockTime) {} uint256 CMutableTransaction::GetHash() const { - return SerializeHash(*this); + return SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS); } void CTransaction::UpdateHash() const { - *const_cast(&hash) = SerializeHash(*this); + *const_cast(&hash) = SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS); +} + +uint256 CTransaction::GetWitnessHash() const +{ + return SerializeHash(*this, SER_GETHASH, 0); } CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } -CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { +CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), wit(tx.wit), nLockTime(tx.nLockTime) { UpdateHash(); } @@ -82,6 +87,7 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) { *const_cast(&nVersion) = tx.nVersion; *const_cast*>(&vin) = tx.vin; *const_cast*>(&vout) = tx.vout; + *const_cast(&wit) = tx.wit; *const_cast(&nLockTime) = tx.nLockTime; *const_cast(&hash) = tx.hash; return *this; @@ -136,6 +142,8 @@ std::string CTransaction::ToString() const nLockTime); for (unsigned int i = 0; i < vin.size(); i++) str += " " + vin[i].ToString() + "\n"; + for (unsigned int i = 0; i < wit.vtxinwit.size(); i++) + str += " " + wit.vtxinwit[i].scriptWitness.ToString() + "\n"; for (unsigned int i = 0; i < vout.size(); i++) str += " " + vout[i].ToString() + "\n"; return str; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 149816406..d8ae41ad7 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -11,6 +11,8 @@ #include "serialize.h" #include "uint256.h" +static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000; + /** An outpoint - a combination of a transaction hash and an index n into its vout */ class COutPoint { @@ -194,8 +196,137 @@ public: std::string ToString() const; }; +class CTxinWitness +{ +public: + CScriptWitness scriptWitness; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + READWRITE(scriptWitness.stack); + } + + bool IsNull() const { return scriptWitness.IsNull(); } + + CTxinWitness() { } +}; + +class CTxWitness +{ +public: + /** In case vtxinwit is missing, all entries are treated as if they were empty CTxInWitnesses */ + std::vector vtxinwit; + + ADD_SERIALIZE_METHODS; + + bool IsEmpty() const { return vtxinwit.empty(); } + + bool IsNull() const + { + for (size_t n = 0; n < vtxinwit.size(); n++) { + if (!vtxinwit[n].IsNull()) { + return false; + } + } + return true; + } + + void SetNull() + { + vtxinwit.clear(); + } + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + { + for (size_t n = 0; n < vtxinwit.size(); n++) { + READWRITE(vtxinwit[n]); + } + if (IsNull()) { + /* It's illegal to encode a witness when all vtxinwit entries are empty. */ + throw std::ios_base::failure("Superfluous witness record"); + } + } +}; + struct CMutableTransaction; +/** + * Basic transaction serialization format: + * - int32_t nVersion + * - std::vector vin + * - std::vector vout + * - uint32_t nLockTime + * + * Extended transaction serialization format: + * - int32_t nVersion + * - unsigned char dummy = 0x00 + * - unsigned char flags (!= 0) + * - std::vector vin + * - std::vector vout + * - if (flags & 1): + * - CTxWitness wit; + * - uint32_t nLockTime + */ +template +inline void SerializeTransaction(TxType& tx, Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*const_cast(&tx.nVersion)); + unsigned char flags = 0; + if (ser_action.ForRead()) { + const_cast*>(&tx.vin)->clear(); + const_cast*>(&tx.vout)->clear(); + const_cast(&tx.wit)->SetNull(); + /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */ + READWRITE(*const_cast*>(&tx.vin)); + if (tx.vin.size() == 0 && !(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) { + /* We read a dummy or an empty vin. */ + READWRITE(flags); + if (flags != 0) { + READWRITE(*const_cast*>(&tx.vin)); + READWRITE(*const_cast*>(&tx.vout)); + } + } else { + /* We read a non-empty vin. Assume a normal vout follows. */ + READWRITE(*const_cast*>(&tx.vout)); + } + if ((flags & 1) && !(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) { + /* The witness flag is present, and we support witnesses. */ + flags ^= 1; + const_cast(&tx.wit)->vtxinwit.resize(tx.vin.size()); + READWRITE(tx.wit); + } + if (flags) { + /* Unknown flag in the serialization */ + throw std::ios_base::failure("Unknown transaction optional data"); + } + } else { + // Consistency check + assert(tx.wit.vtxinwit.size() <= tx.vin.size()); + if (!(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) { + /* Check whether witnesses need to be serialized. */ + if (!tx.wit.IsNull()) { + flags |= 1; + } + } + if (flags) { + /* Use extended format in case witnesses are to be serialized. */ + std::vector vinDummy; + READWRITE(vinDummy); + READWRITE(flags); + } + READWRITE(*const_cast*>(&tx.vin)); + READWRITE(*const_cast*>(&tx.vout)); + if (flags & 1) { + const_cast(&tx.wit)->vtxinwit.resize(tx.vin.size()); + READWRITE(tx.wit); + } + } + READWRITE(*const_cast(&tx.nLockTime)); +} + /** The basic transaction that is broadcasted on the network and contained in * blocks. A transaction can contain multiple inputs and outputs. */ @@ -224,6 +355,7 @@ public: const int32_t nVersion; const std::vector vin; const std::vector vout; + CTxWitness wit; // Not const: can change without invalidating the txid cache const uint32_t nLockTime; /** Construct a CTransaction that qualifies as IsNull() */ @@ -238,13 +370,10 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*const_cast(&this->nVersion)); - nVersion = this->nVersion; - READWRITE(*const_cast*>(&vin)); - READWRITE(*const_cast*>(&vout)); - READWRITE(*const_cast(&nLockTime)); - if (ser_action.ForRead()) + SerializeTransaction(*this, s, ser_action, nType, nVersion); + if (ser_action.ForRead()) { UpdateHash(); + } } bool IsNull() const { @@ -255,6 +384,9 @@ public: return hash; } + // Compute a hash that includes both transaction and witness data + uint256 GetWitnessHash() const; + // Return sum of txouts. CAmount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because @@ -290,6 +422,7 @@ struct CMutableTransaction int32_t nVersion; std::vector vin; std::vector vout; + CTxWitness wit; uint32_t nLockTime; CMutableTransaction(); @@ -299,11 +432,7 @@ struct CMutableTransaction template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(vin); - READWRITE(vout); - READWRITE(nLockTime); + SerializeTransaction(*this, s, ser_action, nType, nVersion); } /** Compute the hash of this CMutableTransaction. This is computed on the diff --git a/src/protocol.cpp b/src/protocol.cpp index 2f90fb764..247c6c212 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -41,15 +41,6 @@ const char *GETBLOCKTXN="getblocktxn"; const char *BLOCKTXN="blocktxn"; }; -static const char* ppszTypeName[] = -{ - "ERROR", // Should never occur - NetMsgType::TX, - NetMsgType::BLOCK, - "filtered block", // Should never occur - "compact block" // Should never occur -}; - /** All known message types. Keep this in the same order as the list of * messages above and in protocol.h. */ @@ -166,37 +157,26 @@ CInv::CInv(int typeIn, const uint256& hashIn) hash = hashIn; } -CInv::CInv(const std::string& strType, const uint256& hashIn) -{ - unsigned int i; - for (i = 1; i < ARRAYLEN(ppszTypeName); i++) - { - if (strType == ppszTypeName[i]) - { - type = i; - break; - } - } - if (i == ARRAYLEN(ppszTypeName)) - throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType)); - hash = hashIn; -} - bool operator<(const CInv& a, const CInv& b) { return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); } -bool CInv::IsKnownType() const +std::string CInv::GetCommand() const { - return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName)); -} - -const char* CInv::GetCommand() const -{ - if (!IsKnownType()) + std::string cmd; + if (type & MSG_WITNESS_FLAG) + cmd.append("witness-"); + int masked = type & MSG_TYPE_MASK; + switch (masked) + { + case MSG_TX: return cmd.append(NetMsgType::TX); + case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK); + case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK); + case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK); + default: throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type)); - return ppszTypeName[type]; + } } std::string CInv::ToString() const diff --git a/src/protocol.h b/src/protocol.h index a72813e95..dd07092f5 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -309,13 +309,29 @@ public: unsigned int nTime; }; +/** getdata message types */ +const uint32_t MSG_WITNESS_FLAG = 1 << 30; +const uint32_t MSG_TYPE_MASK = 0xffffffff >> 2; +enum GetDataMsg +{ + UNDEFINED = 0, + MSG_TX, + MSG_BLOCK, + MSG_TYPE_MAX = MSG_BLOCK, + // The following can only occur in getdata. Invs always use TX or BLOCK. + MSG_FILTERED_BLOCK, + MSG_CMPCT_BLOCK, + MSG_WITNESS_BLOCK = MSG_BLOCK | MSG_WITNESS_FLAG, + MSG_WITNESS_TX = MSG_TX | MSG_WITNESS_FLAG, + MSG_FILTERED_WITNESS_BLOCK = MSG_FILTERED_BLOCK | MSG_WITNESS_FLAG, +}; + /** inv message data */ class CInv { public: CInv(); CInv(int typeIn, const uint256& hashIn); - CInv(const std::string& strType, const uint256& hashIn); ADD_SERIALIZE_METHODS; @@ -328,8 +344,7 @@ public: friend bool operator<(const CInv& a, const CInv& b); - bool IsKnownType() const; - const char* GetCommand() const; + std::string GetCommand() const; std::string ToString() const; // TODO: make private (improves encapsulation) @@ -338,13 +353,4 @@ public: uint256 hash; }; -enum { - MSG_TX = 1, - MSG_BLOCK, - // Nodes may always request a MSG_FILTERED_BLOCK/MSG_CMPCT_BLOCK in a getdata, however, - // MSG_FILTERED_BLOCK/MSG_CMPCT_BLOCK should not appear in any invs except as a part of getdata. - MSG_FILTERED_BLOCK, - MSG_CMPCT_BLOCK, -}; - #endif // BITCOIN_PROTOCOL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index f90949995..837f8ba6c 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -485,6 +485,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) unsigned int nQuantity = 0; int nQuantityUncompressed = 0; bool fAllowFree = false; + bool fWitness = false; std::vector vCoinControl; std::vector vOutputs; @@ -513,7 +514,14 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Bytes CTxDestination address; - if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + int witnessversion = 0; + std::vector witnessprogram; + if (out.tx->vout[out.i].scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) + { + nBytesInputs += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4); + fWitness = true; + } + else if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { CPubKey pubkey; CKeyID *keyid = boost::get(&address); @@ -534,6 +542,14 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) { // Bytes nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here + if (fWitness) + { + // there is some fudging in these numbers related to the actual virtual transaction size calculation that will keep this estimate from being exact. + // usually, the result will be an overestimate within a couple of satoshis so that the confirmation dialog ends up displaying a slightly smaller fee. + // also, the witness stack size value value is a variable sized integer. usually, the number of stack items will be well under the single byte var int limit. + nBytes += 2; // account for the serialized marker and flag bytes + nBytes += nQuantity; // account for the witness byte that holds the number of stack items for each input. + } // Priority double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 8c970ee8a..ffadf89cc 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -4,6 +4,7 @@ #include "walletmodeltransaction.h" +#include "policy/policy.h" #include "wallet/wallet.h" WalletModelTransaction::WalletModelTransaction(const QList &recipients) : @@ -33,7 +34,7 @@ CWalletTx *WalletModelTransaction::getTransaction() unsigned int WalletModelTransaction::getTransactionSize() { - return (!walletTransaction ? 0 : (::GetSerializeSize(*(CTransaction*)walletTransaction, SER_NETWORK, PROTOCOL_VERSION))); + return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction)); } CAmount WalletModelTransaction::getTransactionFee() diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 9723e394d..e4a6e0f39 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -276,7 +276,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) if (ntxFound != setTxids.size()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block"); - CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); CMerkleBlock mb(block, setTxids); ssMB << mb; std::string strHex = HexStr(ssMB.begin(), ssMB.end()); @@ -296,7 +296,7 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp) "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n" ); - CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); CMerkleBlock merkleBlock; ssMB >> merkleBlock; @@ -487,7 +487,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) + if (!DecodeHexTx(tx, params[0].get_str(), true)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); diff --git a/src/script/script.cpp b/src/script/script.cpp index 9f2809e59..6b1eb52bb 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -231,3 +231,15 @@ bool CScript::IsPushOnly() const { return this->IsPushOnly(begin()); } + +std::string CScriptWitness::ToString() const +{ + std::string ret = "CScriptWitness("; + for (unsigned int i = 0; i < stack.size(); i++) { + if (i) { + ret += ", "; + } + ret += HexStr(stack[i]); + } + return ret + ")"; +} diff --git a/src/script/script.h b/src/script/script.h index a2941ce90..0b6d822d8 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -643,6 +643,20 @@ public: } }; +struct CScriptWitness +{ + // Note that this encodes the data elements being pushed, rather than + // encoding them as a CScript that pushes them. + std::vector > stack; + + // Some compilers complain without a default constructor + CScriptWitness() { } + + bool IsNull() const { return stack.empty(); } + + std::string ToString() const; +}; + class CReserveScript { public: diff --git a/src/streams.h b/src/streams.h index ed14f3f41..7132364eb 100644 --- a/src/streams.h +++ b/src/streams.h @@ -22,6 +22,39 @@ #include #include +template +class OverrideStream +{ + Stream* stream; +public: + const int nType; + const int nVersion; + + OverrideStream(Stream* stream_, int nType_, int nVersion_) : stream(stream_), nType(nType_), nVersion(nVersion_) {} + + template + OverrideStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this->stream, obj, nType, nVersion); + return (*this); + } + + template + OverrideStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this->stream, obj, nType, nVersion); + return (*this); + } +}; + +template +OverrideStream WithOrVersion(S* s, int nVersionFlag) +{ + return OverrideStream(s, s->GetType(), s->GetVersion() | nVersionFlag); +} + /** Double ended buffer combining vector and stream-like interfaces. * * >> and << read and write unformatted data using the above serialization templates. diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 2d7d9b958..4719f2b38 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -30,10 +30,6 @@ "010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "P2SH"], ["Tests for CheckTransaction()"], -["No inputs"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], -"0100000000010000000000000000015100000000", "P2SH"], - ["No outputs"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", "P2SH"], diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index e43b2ff6c..375accbac 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -82,7 +82,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un } // Serialize and hash - CHashWriter ss(SER_GETHASH, 0); + CHashWriter ss(SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS); ss << txTmp << nHashType; return ss.GetHash(); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d9195bf34..318fddc1a 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } string transaction = test[1].get_str(); - CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION); + CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION ); CTransaction tx; stream >> tx; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2d4e95911..3666c37ac 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2451,7 +2451,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) // parse hex string from parameter CTransaction origTx; - if (!DecodeHexTx(origTx, params[0].get_str())) + if (!DecodeHexTx(origTx, params[0].get_str(), true)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); if (origTx.vout.size() == 0) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 71b0ff26d..d083722dd 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -7,6 +7,7 @@ #define BITCOIN_WALLET_WALLETDB_H #include "amount.h" +#include "primitives/transaction.h" #include "wallet/db.h" #include "key.h" From 449f9b8debcceb61a92043bc7031528a53627c47 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 8 Nov 2015 01:16:45 +0100 Subject: [PATCH 0841/1223] BIP141: Witness program --- src/bitcoin-tx.cpp | 2 +- src/main.cpp | 3 +- src/policy/policy.h | 4 +- src/rpc/rawtransaction.cpp | 2 +- src/script/bitcoinconsensus.cpp | 2 +- src/script/interpreter.cpp | 111 +++++++++++++++++++++++++++++++- src/script/interpreter.h | 12 +++- src/script/script.cpp | 18 ++++++ src/script/script.h | 1 + src/script/script_error.cpp | 14 ++++ src/script/script_error.h | 9 +++ src/script/sign.cpp | 2 +- src/test/multisig_tests.cpp | 16 ++--- src/test/script_P2SH_tests.cpp | 2 +- src/test/script_tests.cpp | 36 ++++++----- src/test/transaction_tests.cpp | 4 +- 16 files changed, 201 insertions(+), 37 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index f9ea94b9f..82a5583dd 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -472,7 +472,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) fComplete = false; } diff --git a/src/main.cpp b/src/main.cpp index 218494023..d1945a509 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1867,7 +1867,8 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { + const CScriptWitness *witness = (nIn < ptxTo->wit.vtxinwit.size()) ? &ptxTo->wit.vtxinwit[nIn].scriptWitness : NULL; + if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { return false; } return true; diff --git a/src/policy/policy.h b/src/policy/policy.h index 4f9354e36..a6bcc777f 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -41,7 +41,9 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | - SCRIPT_VERIFY_LOW_S; + SCRIPT_VERIFY_LOW_S | + SCRIPT_VERIFY_WITNESS | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index e4a6e0f39..17c9a8460 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -789,7 +789,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, txin.scriptSig, txv.vin[i].scriptSig); } ScriptError serror = SCRIPT_ERR_OK; - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i), &serror)) { + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i), &serror)) { TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); } } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 47ad1d080..5c9e7c0a5 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -85,7 +85,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index fd4a5674c..be649fca2 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1239,8 +1239,67 @@ bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) con return true; } -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { + vector > stack; + CScript scriptPubKey; + + if (witversion == 0) { + if (program.size() == 32) { + // Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness + if (witness.stack.size() == 0) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY); + } + scriptPubKey = CScript(witness.stack.back().begin(), witness.stack.back().end()); + stack = std::vector >(witness.stack.begin(), witness.stack.end() - 1); + uint256 hashScriptPubKey; + CSHA256().Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(hashScriptPubKey.begin()); + if (memcmp(hashScriptPubKey.begin(), &program[0], 32)) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); + } + } else if (program.size() == 20) { + // Special case for pay-to-pubkeyhash; signature + pubkey in witness + if (witness.stack.size() != 2) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness + } + scriptPubKey << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG; + stack = witness.stack; + } else { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH); + } + } else if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); + } else { + // Higher version witness scripts return true for future softfork compatibility + return set_success(serror); + } + + // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack + for (unsigned int i = 0; i < stack.size(); i++) { + if (stack.at(i).size() > MAX_SCRIPT_ELEMENT_SIZE) + return set_error(serror, SCRIPT_ERR_PUSH_SIZE); + } + + if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) { + return false; + } + + // Scripts inside witness implicitly require cleanstack behaviour + if (stack.size() != 1) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (!CastToBool(stack.back())) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return true; +} + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +{ + static const CScriptWitness emptyWitness; + if (witness == NULL) { + witness = &emptyWitness; + } + bool hadWitness = false; + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { @@ -1261,6 +1320,25 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne if (CastToBool(stack.back()) == false) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + // Bare witness programs + int witnessversion; + std::vector witnessprogram; + if (flags & SCRIPT_VERIFY_WITNESS) { + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + hadWitness = true; + if (scriptSig.size() != 0) { + // The scriptSig must be _exactly_ CScript(), otherwise we reintroduce malleability. + return set_error(serror, SCRIPT_ERR_WITNESS_MALLEATED); + } + if (!VerifyWitnessProgram(*witness, witnessversion, witnessprogram, flags, checker, serror)) { + return false; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not clean + // for witness programs. + stack.resize(1); + } + } + // Additional validation for spend-to-script-hash transactions: if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { @@ -1287,19 +1365,48 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne return set_error(serror, SCRIPT_ERR_EVAL_FALSE); if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + + // P2SH witness program + if (flags & SCRIPT_VERIFY_WITNESS) { + if (pubKey2.IsWitnessProgram(witnessversion, witnessprogram)) { + hadWitness = true; + if (scriptSig != CScript() << std::vector(pubKey2.begin(), pubKey2.end())) { + // The scriptSig must be _exactly_ a single push of the redeemScript. Otherwise we + // reintroduce malleability. + return set_error(serror, SCRIPT_ERR_WITNESS_MALLEATED_P2SH); + } + if (!VerifyWitnessProgram(*witness, witnessversion, witnessprogram, flags, checker, serror)) { + return false; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not clean + // for witness programs. + stack.resize(1); + } + } } // The CLEANSTACK check is only performed after potential P2SH evaluation, // as the non-P2SH evaluation of a P2SH script will obviously not result in - // a clean stack (the P2SH inputs remain). + // a clean stack (the P2SH inputs remain). The same holds for witness evaluation. if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK // would be possible, which is not a softfork (and P2SH should be one). assert((flags & SCRIPT_VERIFY_P2SH) != 0); + assert((flags & SCRIPT_VERIFY_WITNESS) != 0); if (stack.size() != 1) { return set_error(serror, SCRIPT_ERR_CLEANSTACK); } } + if (flags & SCRIPT_VERIFY_WITNESS) { + // We can't check for correct unexpected witness data if P2SH was off, so require + // that WITNESS implies P2SH. Otherwise, going from WITNESS->P2SH+WITNESS would be + // possible, which is not a softfork. + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + if (!hadWitness && !witness->IsNull()) { + return set_error(serror, SCRIPT_ERR_WITNESS_UNEXPECTED); + } + } + return set_success(serror); } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e5cb7290f..d1459ed62 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -74,7 +74,7 @@ enum // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". // (softfork safe, BIP62 rule 6) - // Note: CLEANSTACK should never be used without P2SH. + // Note: CLEANSTACK should never be used without P2SH or WITNESS. SCRIPT_VERIFY_CLEANSTACK = (1U << 8), // Verify CHECKLOCKTIMEVERIFY @@ -86,6 +86,14 @@ enum // // See BIP112 for details SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), + + // Support segregated witness + // + SCRIPT_VERIFY_WITNESS = (1U << 11), + + // Making v1-v16 witness program non-standard + // + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); @@ -139,6 +147,6 @@ public: }; bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL); #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/script.cpp b/src/script/script.cpp index 6b1eb52bb..73f5a61bf 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -210,6 +210,24 @@ bool CScript::IsPayToScriptHash() const (*this)[22] == OP_EQUAL); } +// A witness program is any valid CScript that consists of a 1-byte push opcode +// followed by a data push between 2 and 40 bytes. +bool CScript::IsWitnessProgram(int& version, std::vector& program) const +{ + if (this->size() < 4 || this->size() > 42) { + return false; + } + if ((*this)[0] != OP_0 && ((*this)[0] < OP_1 || (*this)[0] > OP_16)) { + return false; + } + if ((size_t)((*this)[1] + 2) == this->size()) { + version = DecodeOP_N((opcodetype)(*this)[0]); + program = std::vector(this->begin() + 2, this->end()); + return true; + } + return false; +} + bool CScript::IsPushOnly(const_iterator pc) const { while (pc < end()) diff --git a/src/script/script.h b/src/script/script.h index 0b6d822d8..b9b5be901 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -621,6 +621,7 @@ public: unsigned int GetSigOpCount(const CScript& scriptSig) const; bool IsPayToScriptHash() const; + bool IsWitnessProgram(int& version, std::vector& program) const; /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ bool IsPushOnly(const_iterator pc) const; diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index f1aa1fb40..cef807edc 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -65,8 +65,22 @@ const char* ScriptErrorString(const ScriptError serror) return "Dummy CHECKMULTISIG argument must be zero"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: return "NOPx reserved for soft-fork upgrades"; + case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: + return "Witness version reserved for soft-fork upgrades"; case SCRIPT_ERR_PUBKEYTYPE: return "Public key is neither compressed or uncompressed"; + case SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH: + return "Witness program has incorrect length"; + case SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY: + return "Witness program was passed an empty witness"; + case SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH: + return "Witness program hash mismatch"; + case SCRIPT_ERR_WITNESS_MALLEATED: + return "Witness requires empty scriptSig"; + case SCRIPT_ERR_WITNESS_MALLEATED_P2SH: + return "Witness requires only-redeemscript scriptSig"; + case SCRIPT_ERR_WITNESS_UNEXPECTED: + return "Witness provided for non-witness script"; case SCRIPT_ERR_UNKNOWN_ERROR: case SCRIPT_ERR_ERROR_COUNT: default: break; diff --git a/src/script/script_error.h b/src/script/script_error.h index 26df33932..09dc6945a 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -51,6 +51,15 @@ typedef enum ScriptError_t /* softfork safeness */ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, + SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, + + /* segregated witness */ + SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, + SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY, + SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH, + SCRIPT_ERR_WITNESS_MALLEATED, + SCRIPT_ERR_WITNESS_MALLEATED_P2SH, + SCRIPT_ERR_WITNESS_UNEXPECTED, SCRIPT_ERR_ERROR_COUNT } ScriptError; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 2f4111f78..37b702de1 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu } // Test solution - return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); + return VerifyScript(scriptSig, fromPubKey, NULL, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); } bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType) diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index d48a68ba5..a6435d94d 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -81,20 +81,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.assign(1,key[0]); keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err)); + BOOST_CHECK(VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -105,18 +105,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -128,12 +128,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index d10284fe9..d6b5f41d4 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err); + return VerifyScript(scriptSig, scriptPubKey, NULL, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 39089f103..d402ba56b 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -147,10 +147,14 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, const std::string& message, int scriptError) { bool expect = (scriptError == SCRIPT_ERR_OK); + if (flags & SCRIPT_VERIFY_CLEANSTACK) { + flags |= SCRIPT_VERIFY_P2SH; + flags |= SCRIPT_VERIFY_WITNESS; + } ScriptError err; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -799,18 +803,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -832,54 +836,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } @@ -999,7 +1003,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push) CScript script; script << i; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -1008,7 +1012,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push) CScript script; script << data; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 318fddc1a..9a24a613e 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(&tx, i), &err), + NULL, verify_flags, TransactionSignatureChecker(&tx, i), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -225,7 +225,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(&tx, i), &err); + NULL, verify_flags, TransactionSignatureChecker(&tx, i), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); From 8b49040854be2e26b66366aeae1cba4716f93d93 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 6 Nov 2015 01:42:38 +0100 Subject: [PATCH 0842/1223] BIP141: Commitment structure and deployment Includes a fix by Suhas Daftuar and LongShao007 --- src/chainparams.cpp | 14 ++++ src/consensus/merkle.cpp | 11 +++ src/consensus/merkle.h | 6 ++ src/consensus/params.h | 1 + src/consensus/validation.h | 3 + src/main.cpp | 146 +++++++++++++++++++++++++++++++++-- src/main.h | 9 +++ src/miner.cpp | 18 +++++ src/miner.h | 2 + src/primitives/transaction.h | 3 +- src/rpc/blockchain.cpp | 1 + src/rpc/mining.cpp | 20 ++++- src/versionbits.cpp | 4 + 13 files changed, 225 insertions(+), 13 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8c27a578b..2a198e855 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -92,6 +92,11 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 + // Deployment of SegWit (BIP141 and BIP143) + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 0; // Never / undefined + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -183,6 +188,11 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 + // Deployment of SegWit (BIP141 and BIP143) + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 2000000000; // Far in the future + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 2100000000; + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -255,6 +265,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; @@ -317,3 +330,4 @@ void SelectParams(const std::string& network) SelectBaseParams(network); pCurrentParams = &Params(network); } + diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 22eb7159a..35f7d2e05 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -165,6 +165,17 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) return ComputeMerkleRoot(leaves, mutated); } +uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) +{ + std::vector leaves; + leaves.resize(block.vtx.size()); + leaves[0].SetNull(); // The witness hash of the coinbase is 0. + for (size_t s = 1; s < block.vtx.size(); s++) { + leaves[s] = block.vtx[s].GetWitnessHash(); + } + return ComputeMerkleRoot(leaves, mutated); +} + std::vector BlockMerkleBranch(const CBlock& block, uint32_t position) { std::vector leaves; diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 6ef59745a..194aea9b7 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -22,6 +22,12 @@ uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vectorpprev, chainparams.GetConsensus())) { + flags |= SCRIPT_VERIFY_WITNESS; + } + int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); @@ -3441,6 +3462,71 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati return true; } +bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params) +{ + LOCK(cs_main); + return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); +} + +// Compute at which vout of the block's coinbase transaction the witness +// commitment occurs, or -1 if not found. +static int GetWitnessCommitmentIndex(const CBlock& block) +{ + int commitpos = -1; + for (size_t o = 0; o < block.vtx[0].vout.size(); o++) { + if (block.vtx[0].vout[o].scriptPubKey.size() >= 38 && block.vtx[0].vout[o].scriptPubKey[0] == OP_RETURN && block.vtx[0].vout[o].scriptPubKey[1] == 0x24 && block.vtx[0].vout[o].scriptPubKey[2] == 0xaa && block.vtx[0].vout[o].scriptPubKey[3] == 0x21 && block.vtx[0].vout[o].scriptPubKey[4] == 0xa9 && block.vtx[0].vout[o].scriptPubKey[5] == 0xed) { + commitpos = o; + } + } + return commitpos; +} + +void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) +{ + int commitpos = GetWitnessCommitmentIndex(block); + static const std::vector nonce(32, 0x00); + if (commitpos != -1 && IsWitnessEnabled(pindexPrev, consensusParams) && block.vtx[0].wit.IsEmpty()) { + block.vtx[0].wit.vtxinwit.resize(1); + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.resize(1); + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack[0] = nonce; + } +} + +std::vector GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) +{ + std::vector commitment; + int commitpos = GetWitnessCommitmentIndex(block); + bool fHaveWitness = false; + for (size_t t = 1; t < block.vtx.size(); t++) { + if (!block.vtx[t].wit.IsNull()) { + fHaveWitness = true; + break; + } + } + std::vector ret(32, 0x00); + if (fHaveWitness && IsWitnessEnabled(pindexPrev, consensusParams)) { + if (commitpos == -1) { + uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL); + CHash256().Write(witnessroot.begin(), 32).Write(&ret[0], 32).Finalize(witnessroot.begin()); + CTxOut out; + out.nValue = 0; + out.scriptPubKey.resize(38); + out.scriptPubKey[0] = OP_RETURN; + out.scriptPubKey[1] = 0x24; + out.scriptPubKey[2] = 0xaa; + out.scriptPubKey[3] = 0x21; + out.scriptPubKey[4] = 0xa9; + out.scriptPubKey[5] = 0xed; + memcpy(&out.scriptPubKey[6], witnessroot.begin(), 32); + commitment = std::vector(out.scriptPubKey.begin(), out.scriptPubKey.end()); + const_cast*>(&block.vtx[0].vout)->push_back(out); + block.vtx[0].UpdateHash(); + } + } + UpdateUncommittedBlockStructures(block, pindexPrev, consensusParams); + return commitment; +} + bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex * const pindexPrev, int64_t nAdjustedTime) { // Check proof of work @@ -3497,6 +3583,43 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } } + // Validation for witness commitments. + // * We compute the witness hash (which is the hash including witnesses) of all the block's transactions, except the + // coinbase (where 0x0000....0000 is used instead). + // * The coinbase scriptWitness is a stack of a single 32-byte vector, containing a witness nonce (unconstrained). + // * We build a merkle tree with all those witness hashes as leaves (similar to the hashMerkleRoot in the block header). + // * There must be at least one output whose scriptPubKey is a single 36-byte push, the first 4 bytes of which are + // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are + // multiple, the last one is used. + bool fHaveWitness = false; + if (IsWitnessEnabled(pindexPrev, consensusParams)) { + int commitpos = GetWitnessCommitmentIndex(block); + if (commitpos != -1) { + bool malleated = false; + uint256 hashWitness = BlockWitnessMerkleRoot(block, &malleated); + // The malleation check is ignored; as the transaction tree itself + // already does not permit it, it is impossible to trigger in the + // witness tree. + if (block.vtx[0].wit.vtxinwit.size() != 1 || block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.size() != 1 || block.vtx[0].wit.vtxinwit[0].scriptWitness.stack[0].size() != 32) { + return state.DoS(100, error("%s : invalid witness nonce size", __func__), REJECT_INVALID, "bad-witness-nonce-size", true); + } + CHash256().Write(hashWitness.begin(), 32).Write(&block.vtx[0].wit.vtxinwit[0].scriptWitness.stack[0][0], 32).Finalize(hashWitness.begin()); + if (memcmp(hashWitness.begin(), &block.vtx[0].vout[commitpos].scriptPubKey[6], 32)) { + return state.DoS(100, error("%s : witness merkle commitment mismatch", __func__), REJECT_INVALID, "bad-witness-merkle-match", true); + } + fHaveWitness = true; + } + } + + // No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room for spam + if (!fHaveWitness) { + for (size_t i = 0; i < block.vtx.size(); i++) { + if (!block.vtx[i].wit.IsNull()) { + return state.DoS(100, error("%s : unexpected witness data found", __func__), REJECT_INVALID, "unexpected-witness", true); + } + } + } + return true; } @@ -5278,7 +5401,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (!fMissingInputs2) { int nDos = 0; - if (stateDummy.IsInvalid(nDos) && nDos > 0) + if (stateDummy.IsInvalid(nDos) && nDos > 0 && (!state.CorruptionPossible() || State(fromPeer)->fHaveWitness)) { // Punish peer that gave us an invalid orphan tx Misbehaving(fromPeer, nDos); @@ -5289,8 +5412,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Probably non-standard or insufficient fee/priority LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString()); vEraseQueue.push_back(orphanHash); - assert(recentRejects); - recentRejects->insert(orphanHash); + if (!stateDummy.CorruptionPossible()) { + assert(recentRejects); + recentRejects->insert(orphanHash); + } } mempool.check(pcoinsTip); } @@ -5325,8 +5450,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); } } else { - assert(recentRejects); - recentRejects->insert(tx.GetHash()); + if (!state.CorruptionPossible()) { + assert(recentRejects); + recentRejects->insert(tx.GetHash()); + } if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { // Always relay transactions received from whitelisted peers, even @@ -5355,8 +5482,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); - if (nDoS > 0) + if (nDoS > 0 && (!state.CorruptionPossible() || State(pfrom->id)->fHaveWitness)) { + // When a non-witness-supporting peer gives us a transaction that would + // be accepted if witness validation was off, we can't blame them for it. Misbehaving(pfrom->GetId(), nDoS); + } } FlushStateToDisk(state, FLUSH_STATE_PERIODIC); } diff --git a/src/main.h b/src/main.h index f004a29bb..d0dce7068 100644 --- a/src/main.h +++ b/src/main.h @@ -453,6 +453,15 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +/** Check whether witness commitments are required for block. */ +bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params); + +/** Update uncommitted block structures (currently: only the witness nonce). This is safe for submitted blocks. */ +void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); + +/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */ +std::vector GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); + /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: diff --git a/src/miner.cpp b/src/miner.cpp index 989ad11a2..a7bf9ae84 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -93,6 +93,7 @@ void BlockAssembler::resetBlock() // Reserve space for coinbase tx nBlockSize = 1000; nBlockSigOps = 100; + fIncludeWitness = false; // These counters do not include coinbase tx nBlockTx = 0; @@ -134,6 +135,14 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) ? nMedianTimePast : pblock->GetBlockTime(); + // Decide whether to include witness transactions + // This is only needed in case the witness softfork activation is reverted + // (which would require a very deep reorganization) or when + // -promiscuousmempoolflags is used. + // TODO: replace this with a call to main to assess validity of a mempool + // transaction (which in most cases can be a no-op). + fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); + addPriorityTxs(); addPackageTxs(); @@ -150,6 +159,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = coinbaseTx; + pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; // Fill in header @@ -299,6 +309,10 @@ void BlockAssembler::addScoreTxs() continue; } + // cannot accept witness transactions into a non-witness block + if (!fIncludeWitness && !iter->GetTx().wit.IsNull()) + continue; + // If tx is dependent on other mempool txs which haven't yet been included // then put it in the waitSet if (isStillDependent(iter)) { @@ -543,6 +557,10 @@ void BlockAssembler::addPriorityTxs() continue; } + // cannot accept witness transactions into a non-witness block + if (!fIncludeWitness && !iter->GetTx().wit.IsNull()) + continue; + // If tx is dependent on other mempool txs which haven't yet been included // then put it in the waitSet if (isStillDependent(iter)) { diff --git a/src/miner.h b/src/miner.h index a9fea8530..8bfc1493d 100644 --- a/src/miner.h +++ b/src/miner.h @@ -29,6 +29,7 @@ struct CBlockTemplate CBlock block; std::vector vTxFees; std::vector vTxSigOps; + std::vector vchCoinbaseCommitment; }; // Container for tracking updates to ancestor feerate as we include (parent) @@ -139,6 +140,7 @@ private: CBlock* pblock; // Configuration parameters for the block size + bool fIncludeWitness; unsigned int nBlockMaxSize, nBlockMinSize; // Information on the current status of the block diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index d8ae41ad7..5a5824134 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -335,7 +335,6 @@ class CTransaction private: /** Memory only. */ const uint256 hash; - void UpdateHash() const; public: // Default transaction version. @@ -414,6 +413,8 @@ public: } std::string ToString() const; + + void UpdateHash() const; }; /** A mutable version of CTransaction. */ diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1bb365d36..dae283fb6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -930,6 +930,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); + bip9_softforks.push_back(Pair("segwit", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_SEGWIT))); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 94eeea91f..291314b8b 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -348,7 +348,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" - " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n" + " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" + " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" @@ -546,7 +547,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue transactions(UniValue::VARR); map setTxIndex; int i = 0; - BOOST_FOREACH (const CTransaction& tx, pblock->vtx) { + BOOST_FOREACH (CTransaction& tx, pblock->vtx) { uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; @@ -556,8 +557,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); - - entry.push_back(Pair("hash", txHash.GetHex())); + entry.push_back(Pair("txid", txHash.GetHex())); + entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex())); UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) @@ -656,6 +657,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + if (!pblocktemplate->vchCoinbaseCommitment.empty()) { + result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()))); + } return result; } @@ -719,6 +723,14 @@ UniValue submitblock(const UniValue& params, bool fHelp) } } + { + LOCK(cs_main); + BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); + if (mi != mapBlockIndex.end()) { + UpdateUncommittedBlockStructures(block, mi->second, Params().GetConsensus()); + } + } + CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 043819c65..bf32ae662 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -14,6 +14,10 @@ const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION { /*.name =*/ "csv", /*.gbt_force =*/ true, + }, + { + /*.name =*/ "segwit", + /*.gbt_force =*/ false, } }; From b8a97498df1e83f8dcc49bc3fa4344f9e9799242 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 17 Nov 2015 00:20:49 +0100 Subject: [PATCH 0843/1223] BIP144: Handshake and relay (receiver side) Service bit logic by Nicolas Dorier. Only download blocks from witness peers after fork. --- src/init.cpp | 12 ++++++++++++ src/main.cpp | 44 ++++++++++++++++++++++++++++++++++++-------- src/net.cpp | 6 +++++- src/net.h | 1 + src/protocol.h | 3 +++ src/qt/guiutil.cpp | 3 +++ 6 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b572bfc32..6bce0a9b4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1377,6 +1377,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } + if (Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { + // Only advertize witness capabilities if they have a reasonable start time. + // This allows us to have the code merged without a defined softfork, by setting its + // end time to 0. + // Note that setting NODE_WITNESS is never required: the only downside from not + // doing so is that after activation, no upgraded nodes will fetch from you. + nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS); + // Only care about others providing witness capabilities if there is a softfork + // defined. + nRelevantServices = ServiceFlags(nRelevantServices | NODE_WITNESS); + } + // ********************************************************* Step 10: import blocks if (mapArgs.count("-blocknotify")) diff --git a/src/main.cpp b/src/main.cpp index 8d91d6d62..73e4c8f51 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -313,6 +313,7 @@ struct CNodeState { fPreferHeaders = false; fPreferHeaderAndIDs = false; fProvidesHeaderAndIDs = false; + fHaveWitness = false; } }; @@ -4812,6 +4813,14 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } +uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params& chainparams) { + uint32_t nFetchFlags = 0; + if (IsWitnessEnabled(pprev, chainparams) && State(pfrom->GetId())->fHaveWitness) { + nFetchFlags |= MSG_WITNESS_FLAG; + } + return nFetchFlags; +} + bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams) { LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); @@ -4918,6 +4927,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + if((pfrom->nServices & NODE_WITNESS)) + { + LOCK(cs_main); + State(pfrom->GetId())->fHaveWitness = true; + } + // Potentially mark this peer as a preferred download peer. { LOCK(cs_main); @@ -5119,17 +5134,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); + std::vector vToFetch; for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { - const CInv &inv = vInv[nInv]; + CInv &inv = vInv[nInv]; boost::this_thread::interruption_point(); bool fAlreadyHave = AlreadyHave(inv); LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id); + if (inv.type == MSG_TX) { + inv.type |= nFetchFlags; + } + if (inv.type == MSG_BLOCK) { UpdateBlockAvailability(pfrom->GetId(), inv.hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) { @@ -5144,7 +5165,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); if (CanDirectFetch(chainparams.GetConsensus()) && - nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER && + (!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { + inv.type |= nFetchFlags; if (nodestate->fProvidesHeaderAndIDs) vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); else @@ -5730,7 +5753,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Calculate all the blocks we'd need to switch to pindexLast, up to a limit. while (pindexWalk && !chainActive.Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) && - !mapBlocksInFlight.count(pindexWalk->GetBlockHash())) { + !mapBlocksInFlight.count(pindexWalk->GetBlockHash()) && + (!IsWitnessEnabled(pindexWalk->pprev, chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { // We don't have this block, and it's not yet in flight. vToFetch.push_back(pindexWalk); } @@ -5752,7 +5776,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Can't download any more from this peer break; } - vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + uint32_t nFetchFlags = GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()); + vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex); LogPrint("net", "Requesting block %s from peer=%d\n", pindex->GetBlockHash().ToString(), pfrom->id); @@ -6598,10 +6623,13 @@ bool SendMessages(CNode* pto) NodeId staller = -1; FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { - vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); - MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); - LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), - pindex->nHeight, pto->id); + if (State(pto->GetId())->fHaveWitness || !IsWitnessEnabled(pindex->pprev, consensusParams)) { + uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams); + vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); + MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); + LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), + pindex->nHeight, pto->id); + } } if (state.nBlocksInFlight == 0 && staller != -1) { if (State(staller)->nStallingSince == 0) { diff --git a/src/net.cpp b/src/net.cpp index 336163a89..dc83f19be 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -72,7 +72,7 @@ namespace { const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; /** Services this node implementation cares about */ -static const ServiceFlags nRelevantServices = NODE_NETWORK; +ServiceFlags nRelevantServices = NODE_NETWORK; // // Global state variables @@ -1676,6 +1676,10 @@ void ThreadOpenConnections() if (nANow - addr.nLastTry < 600 && nTries < 30) continue; + // only consider nodes missing relevant services after 40 failed attemps + if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) + continue; + // do not allow non-default ports, unless after 50 invalid addresses selected already if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) continue; diff --git a/src/net.h b/src/net.h index cb35d8c4f..7ed18b205 100644 --- a/src/net.h +++ b/src/net.h @@ -156,6 +156,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); extern bool fDiscover; extern bool fListen; extern ServiceFlags nLocalServices; +extern ServiceFlags nRelevantServices; extern bool fRelayTxes; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; diff --git a/src/protocol.h b/src/protocol.h index dd07092f5..15f27e2d2 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -264,6 +264,9 @@ enum ServiceFlags : uint64_t { // Bitcoin Core nodes used to support this by default, without advertising this bit, // but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION) NODE_BLOOM = (1 << 2), + // Indicates that a node can be asked for blocks and transactions including + // witness data. + NODE_WITNESS = (1 << 3), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ff4320b36..4327de9b0 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -909,6 +909,9 @@ QString formatServicesStr(quint64 mask) case NODE_BLOOM: strList.append("BLOOM"); break; + case NODE_WITNESS: + strList.append("WITNESS"); + break; default: strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); } From 0ef1dd3e11dd573b6e443852ef0c72e34093ac68 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 31 Mar 2016 14:51:29 +0200 Subject: [PATCH 0844/1223] Refactor script validation to observe amounts This is a preparation for BIP143 support. --- src/bitcoin-tx.cpp | 3 ++- src/main.cpp | 2 +- src/main.h | 6 ++++-- src/rpc/rawtransaction.cpp | 3 ++- src/script/bitcoinconsensus.cpp | 3 ++- src/script/bitcoinconsensus.h | 2 ++ src/script/interpreter.h | 4 ++-- src/script/sigcache.h | 2 +- src/script/sign.cpp | 5 +++-- src/test/multisig_tests.cpp | 17 +++++++++-------- src/test/script_P2SH_tests.cpp | 2 +- src/test/script_tests.cpp | 29 +++++++++++++++-------------- src/test/transaction_tests.cpp | 6 ++++-- 13 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 82a5583dd..68c069659 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -462,6 +462,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) continue; } const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; txin.scriptSig.clear(); // Only sign SIGHASH_SINGLE if there's a corresponding output: @@ -472,7 +473,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount))) fComplete = false; } diff --git a/src/main.cpp b/src/main.cpp index 73e4c8f51..c22faf6db 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1885,7 +1885,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; const CScriptWitness *witness = (nIn < ptxTo->wit.vtxinwit.size()) ? &ptxTo->wit.vtxinwit[nIn].scriptWitness : NULL; - if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore), &error)) { return false; } return true; diff --git a/src/main.h b/src/main.h index d0dce7068..6dd4b1aa3 100644 --- a/src/main.h +++ b/src/main.h @@ -394,6 +394,7 @@ class CScriptCheck { private: CScript scriptPubKey; + CAmount amount; const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; @@ -401,9 +402,9 @@ private: ScriptError error; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} + CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : - scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), + scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), amount(txFromIn.vout[txToIn.vin[nInIn].prevout.n].nValue), ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { } bool operator()(); @@ -411,6 +412,7 @@ public: void swap(CScriptCheck &check) { scriptPubKey.swap(check.scriptPubKey); std::swap(ptxTo, check.ptxTo); + std::swap(amount, check.amount); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); std::swap(cacheStore, check.cacheStore); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 17c9a8460..ebfc828d4 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -778,6 +778,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) continue; } const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; txin.scriptSig.clear(); // Only sign SIGHASH_SINGLE if there's a corresponding output: @@ -789,7 +790,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, txin.scriptSig, txv.vin[i].scriptSig); } ScriptError serror = SCRIPT_ERR_OK; - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i), &serror)) { + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) { TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); } } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 5c9e7c0a5..26e7a85b7 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -85,7 +85,8 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn), NULL); + CAmount am(0); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, am), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 5b8c33c6b..cd3e2f773 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_BITCOINCONSENSUS_H #define BITCOIN_BITCOINCONSENSUS_H +#include + #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #if defined(_WIN32) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index d1459ed62..6f13e75d7 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -131,7 +131,7 @@ protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; bool CheckLockTime(const CScriptNum& nLockTime) const; bool CheckSequence(const CScriptNum& nSequence) const; @@ -143,7 +143,7 @@ private: const CTransaction txTo; public: - MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {} + MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {} }; bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); diff --git a/src/script/sigcache.h b/src/script/sigcache.h index be1df09c2..050bf8cc4 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -22,7 +22,7 @@ private: bool store; public: - CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, nInIn, amount), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 37b702de1..62d874eed 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -18,7 +18,8 @@ using namespace std; typedef std::vector valtype; -TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {} +static const CAmount amountZero = 0; +TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn, amountZero) {} bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode) const { @@ -258,7 +259,7 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatur CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2) { - TransactionSignatureChecker checker(&txTo, nIn); + TransactionSignatureChecker checker(&txTo, nIn, amountZero); return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2); } diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index a6435d94d..8c95601ea 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -46,6 +46,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify) ScriptError err; CKey key[4]; + CAmount amount = 0; for (int i = 0; i < 4; i++) key[i].MakeNewKey(true); @@ -81,20 +82,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.assign(1,key[0]); keys.push_back(key[1]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err)); + BOOST_CHECK(VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -105,18 +106,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -128,12 +129,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify) s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index d6b5f41d4..62deb736a 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, NULL, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err); + return VerifyScript(scriptSig, scriptPubKey, NULL, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index d402ba56b..9587fecfd 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -154,7 +154,8 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, co ScriptError err; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); + static const CAmount amountZero = 0; + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0, amountZero), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -803,18 +804,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -836,54 +837,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 9a24a613e..9fb23d8ed 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -149,9 +149,10 @@ BOOST_AUTO_TEST_CASE(tx_valid) break; } + CAmount amount = 0; unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - NULL, verify_flags, TransactionSignatureChecker(&tx, i), &err), + NULL, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -224,8 +225,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); + CAmount amount = 0; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - NULL, verify_flags, TransactionSignatureChecker(&tx, i), &err); + NULL, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); From 3dd410294d42f251e4808ef1dfcfcd64817edbac Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 27 Dec 2015 19:49:08 +0100 Subject: [PATCH 0845/1223] BIP143: Verification logic Includes simplifications by Eric Lombrozo. --- src/bitcoin-tx.cpp | 2 +- src/policy/policy.cpp | 2 +- src/rpc/rawtransaction.cpp | 2 +- src/script/interpreter.cpp | 84 ++++++++++++++++++++++++---- src/script/interpreter.h | 17 ++++-- src/script/sign.cpp | 17 +++--- src/script/sign.h | 5 +- src/test/multisig_tests.cpp | 2 +- src/test/script_tests.cpp | 57 +++++++++---------- src/test/sighash_tests.cpp | 4 +- src/test/txvalidationcache_tests.cpp | 2 +- 11 files changed, 131 insertions(+), 63 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 68c069659..424812a6d 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -471,7 +471,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) // ... and merge in other signatures: BOOST_FOREACH(const CTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); + txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, amount, txin.scriptSig, txv.vin[i].scriptSig); } if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount))) fComplete = false; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index d1a15451d..67434a38f 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -137,7 +137,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) { std::vector > stack; // convert the scriptSig into a stack, so we can inspect the redeemScript - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0)) + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) return false; if (stack.empty()) return false; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index ebfc828d4..38fd98055 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -787,7 +787,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // ... and merge in other signatures: BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, txin.scriptSig, txv.vin[i].scriptSig); + txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, amount, txin.scriptSig, txv.vin[i].scriptSig); } ScriptError serror = SCRIPT_ERR_OK; if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) { diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index be649fca2..4deebd050 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -229,7 +229,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { return true; } -bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror) { static const CScriptNum bnZero(0); static const CScriptNum bnOne(1); @@ -869,13 +869,15 @@ bool EvalScript(vector >& stack, const CScript& script, un CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself - scriptCode.FindAndDelete(CScript(vchSig)); + if (sigversion == SIGVERSION_BASE) { + scriptCode.FindAndDelete(CScript(vchSig)); + } if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { //serror is set return false; } - bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode); + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); popstack(stack); popstack(stack); @@ -925,7 +927,9 @@ bool EvalScript(vector >& stack, const CScript& script, un for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); - scriptCode.FindAndDelete(CScript(vchSig)); + if (sigversion == SIGVERSION_BASE) { + scriptCode.FindAndDelete(CScript(vchSig)); + } } bool fSuccess = true; @@ -943,7 +947,7 @@ bool EvalScript(vector >& stack, const CScript& script, un } // Check signature - bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode); + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); if (fOk) { isig++; @@ -1106,8 +1110,64 @@ public: } // anon namespace -uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion) { + if (sigversion == SIGVERSION_WITNESS_V0) { + uint256 hashPrevouts; + uint256 hashSequence; + uint256 hashOutputs; + + if (!(nHashType & SIGHASH_ANYONECANPAY)) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + hashPrevouts = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + } + + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + hashSequence = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + } + + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + hashOutputs = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { + CHashWriter ss(SER_GETHASH, 0); + ss << txTo.vout[nIn]; + hashOutputs = ss.GetHash(); + } + + CHashWriter ss(SER_GETHASH, 0); + // Version + ss << txTo.nVersion; + // Input prevouts/nSequence (none/all, depending on flags) + ss << hashPrevouts; + ss << hashSequence; + // The input being signed (replacing the scriptSig with scriptCode + amount) + // The prevout may already be contained in hashPrevout, and the nSequence + // may already be contain in hashSequence. + ss << txTo.vin[nIn].prevout; + ss << static_cast(scriptCode); + ss << amount; + ss << txTo.vin[nIn].nSequence; + // Outputs (none/one/all, depending on flags) + ss << hashOutputs; + // Locktime + ss << txTo.nLockTime; + // Sighash type + ss << nHashType; + + return ss.GetHash(); + } + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { // nIn out of range @@ -1136,7 +1196,7 @@ bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSigIn, const vector& vchPubKey, const CScript& scriptCode) const +bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const { CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) @@ -1149,7 +1209,7 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn int nHashType = vchSig.back(); vchSig.pop_back(); - uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType); + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); if (!VerifySignature(vchSig, pubkey, sighash)) return false; @@ -1280,7 +1340,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, return set_error(serror, SCRIPT_ERR_PUSH_SIZE); } - if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) { + if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_WITNESS_V0, serror)) { return false; } @@ -1307,12 +1367,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C } vector > stack, stackCopy; - if (!EvalScript(stack, scriptSig, flags, checker, serror)) + if (!EvalScript(stack, scriptSig, flags, checker, SIGVERSION_BASE, serror)) // serror is set return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) + if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_BASE, serror)) // serror is set return false; if (stack.empty()) @@ -1358,7 +1418,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); - if (!EvalScript(stack, pubKey2, flags, checker, serror)) + if (!EvalScript(stack, pubKey2, flags, checker, SIGVERSION_BASE, serror)) // serror is set return false; if (stack.empty()) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 6f13e75d7..864372942 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -98,12 +98,18 @@ enum bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +enum SigVersion +{ + SIGVERSION_BASE = 0, + SIGVERSION_WITNESS_V0 = 1, +}; + +uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion); class BaseSignatureChecker { public: - virtual bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const + virtual bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const { return false; } @@ -126,13 +132,14 @@ class TransactionSignatureChecker : public BaseSignatureChecker private: const CTransaction* txTo; unsigned int nIn; + const CAmount amount; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : txTo(txToIn), nIn(nInIn) {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const; bool CheckLockTime(const CScriptNum& nLockTime) const; bool CheckSequence(const CScriptNum& nSequence) const; }; @@ -146,7 +153,7 @@ public: MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {} }; -bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); +bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL); #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 62d874eed..83bb0cfa2 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -18,8 +18,7 @@ using namespace std; typedef std::vector valtype; -static const CAmount amountZero = 0; -TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn, amountZero) {} +TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {} bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode) const { @@ -27,7 +26,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, if (!keystore->GetKey(address, key)) return false; - uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType); + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, SIGVERSION_BASE); if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); @@ -186,7 +185,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (checker.CheckSig(sig, pubkey, scriptPubKey)) + if (checker.CheckSig(sig, pubkey, scriptPubKey, SIGVERSION_BASE)) { sigs[pubkey] = sig; break; @@ -256,10 +255,10 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatur return CScript(); } -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, +CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CAmount& amount, const CScript& scriptSig1, const CScript& scriptSig2) { - TransactionSignatureChecker checker(&txTo, nIn, amountZero); + TransactionSignatureChecker checker(&txTo, nIn, amount); return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2); } @@ -271,9 +270,9 @@ CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecke Solver(scriptPubKey, txType, vSolutions); vector stack1; - EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); + EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); vector stack2; - EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); + EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); } @@ -285,7 +284,7 @@ class DummySignatureChecker : public BaseSignatureChecker public: DummySignatureChecker() {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const { return true; } diff --git a/src/script/sign.h b/src/script/sign.h index 47a9cde7f..f54511f7a 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -35,10 +35,11 @@ class TransactionSignatureCreator : public BaseSignatureCreator { const CTransaction* txTo; unsigned int nIn; int nHashType; + CAmount amount; const TransactionSignatureChecker checker; public: - TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL); + TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL); const BaseSignatureChecker& Checker() const { return checker; } bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; }; @@ -62,6 +63,6 @@ bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutab CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const CScript& scriptSig1, const CScript& scriptSig2); /** Combine two script signatures on transactions. */ -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); +CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CAmount& amount, const CScript& scriptSig1, const CScript& scriptSig2); #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 8c95601ea..876b90e4b 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -26,7 +26,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup) CScript sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn) { - uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL); + uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE); CScript result; result << OP_0; // CHECKMULTISIG bug workaround diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 9587fecfd..c56b9da4e 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -306,7 +306,7 @@ public: TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) { - uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType); + uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType, 0, SIGVERSION_BASE); std::vector vchSig, r, s; uint32_t iter = 0; do { @@ -738,21 +738,21 @@ BOOST_AUTO_TEST_CASE(script_PushData) ScriptError err; vector > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -760,7 +760,7 @@ BOOST_AUTO_TEST_CASE(script_PushData) CScript sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transaction) { - uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); + uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); CScript result; // @@ -891,6 +891,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) BOOST_AUTO_TEST_CASE(script_combineSigs) { // Test the CombineSignatures function + CAmount amount; CBasicKeyStore keystore; vector keys; vector pubkeys; @@ -909,19 +910,19 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript& scriptSig = txTo.vin[0].scriptSig; CScript empty; - CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty); + CScript combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, empty); BOOST_CHECK(combined.empty()); // Single signature case: SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); BOOST_CHECK(combined == scriptSig); CScript scriptSigCopy = scriptSig; // Signing again will give a different, valid signature: SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); // P2SH, single-signature case: @@ -929,41 +930,41 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) keystore.AddCScript(pkSingle); scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); BOOST_CHECK(combined == scriptSig); scriptSigCopy = scriptSig; SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); // dummy scriptSigCopy with placeholder, should always choose non-placeholder: scriptSigCopy = CScript() << OP_0 << vector(pkSingle.begin(), pkSingle.end()); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, scriptSigCopy); BOOST_CHECK(combined == scriptSig); // Hardest case: Multisig 2-of-3 scriptPubKey = GetScriptForMultisig(2, pubkeys); keystore.AddCScript(scriptPubKey); SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); BOOST_CHECK(combined == scriptSig); // A couple of partially-signed versions: vector sig1; - uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL); + uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); BOOST_CHECK(keys[0].Sign(hash1, sig1)); sig1.push_back(SIGHASH_ALL); vector sig2; - uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE); + uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SIGVERSION_BASE); BOOST_CHECK(keys[1].Sign(hash2, sig2)); sig2.push_back(SIGHASH_NONE); vector sig3; - uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE); + uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SIGVERSION_BASE); BOOST_CHECK(keys[2].Sign(hash3, sig3)); sig3.push_back(SIGHASH_SINGLE); @@ -979,21 +980,21 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript complete13 = CScript() << OP_0 << sig1 << sig3; CScript complete23 = CScript() << OP_0 << sig2 << sig3; - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1a, partial1b); BOOST_CHECK(combined == partial1a); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1a, partial2a); BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial2a, partial1a); BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1b, partial2b); BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial1b); BOOST_CHECK(combined == complete13); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial2a, partial3a); BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial2b); BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a); + combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial3a); BOOST_CHECK(combined == partial3c); } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 375accbac..4a48347b7 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(sighash_test) uint256 sh, sho; sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType); - sh = SignatureHash(scriptCode, txTo, nIn, nHashType); + sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, SIGVERSION_BASE); #if defined(PRINT_SIGHASH_JSON) CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << txTo; @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) continue; } - sh = SignatureHash(scriptCode, tx, nIn, nHashType); + sh = SignatureHash(scriptCode, tx, nIn, nHashType, 0, SIGVERSION_BASE); BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); } } diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index c29e30792..76e4e7a4b 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -48,7 +48,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) // Sign: std::vector vchSig; - uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL); + uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SIGVERSION_BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); spends[i].vin[0].scriptSig << vchSig; From 7c4bf779e8b74e474551982a24f5acc265293abd Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 23 Jan 2016 01:46:11 +0800 Subject: [PATCH 0846/1223] [RPC] Return witness data in blockchain RPCs Includes RPC field name changes by Luke-jr. --- src/rpc/blockchain.cpp | 2 ++ src/rpc/rawtransaction.cpp | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index dae283fb6..f11af876f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -99,6 +99,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -558,6 +559,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" + " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 38fd98055..12e3eaa92 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -62,11 +62,14 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex())); entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); + UniValue vin(UniValue::VARR); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const CTxIn& txin = tx.vin[i]; UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); @@ -78,6 +81,17 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } + if (!tx.wit.IsNull()) { + if (!tx.wit.vtxinwit[i].IsNull()) { + UniValue txinwitness(UniValue::VARR); + for (unsigned int j = 0; j < tx.wit.vtxinwit[i].scriptWitness.stack.size(); j++) { + std::vector item = tx.wit.vtxinwit[i].scriptWitness.stack[j]; + txinwitness.push_back(HexStr(item.begin(), item.end())); + } + in.push_back(Pair("txinwitness", txinwitness)); + } + + } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); } @@ -134,7 +148,8 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) "{\n" " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n" " \"txid\" : \"id\", (string) The transaction id (same as provided)\n" - " \"size\" : n, (numeric) The transaction size\n" + " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" + " \"size\" : n, (numeric) The serialized transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" @@ -146,6 +161,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " \"hex\": \"hex\" (string) hex\n" " },\n" " \"sequence\": n (numeric) The script sequence number\n" + " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n" " }\n" " ,...\n" " ],\n" @@ -443,6 +459,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"txid\" : \"id\", (string) The transaction id\n" + " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" " \"size\" : n, (numeric) The transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" @@ -454,6 +471,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " \"asm\": \"asm\", (string) asm\n" " \"hex\": \"hex\" (string) hex\n" " },\n" + " \"txinwitness\": [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n" " \"sequence\": n (numeric) The script sequence number\n" " }\n" " ,...\n" From 2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 3 Jan 2016 18:54:50 +0100 Subject: [PATCH 0847/1223] BIP141: Other consensus critical limits, and BIP145 Includes changes by Suhas Daftuar, Luke-jr, and mruddy. --- qa/rpc-tests/maxuploadtarget.py | 14 ++-- src/bitcoin-tx.cpp | 2 +- src/blockencodings.cpp | 4 +- src/consensus/consensus.h | 12 +++- src/init.cpp | 1 + src/main.cpp | 78 ++++++++++++++-------- src/main.h | 1 + src/merkleblock.cpp | 2 +- src/miner.cpp | 101 +++++++++++++++++++++-------- src/miner.h | 16 +++-- src/net.cpp | 4 +- src/net.h | 4 +- src/policy/policy.cpp | 14 +++- src/policy/policy.h | 10 ++- src/primitives/block.cpp | 9 +++ src/primitives/block.h | 3 + src/primitives/transaction.cpp | 7 +- src/primitives/transaction.h | 28 ++++++-- src/rpc/blockchain.cpp | 2 + src/rpc/mining.cpp | 18 +++-- src/rpc/rawtransaction.cpp | 3 + src/script/interpreter.cpp | 47 ++++++++++++++ src/script/interpreter.h | 2 + src/test/mempool_tests.cpp | 11 ++-- src/test/miner_tests.cpp | 5 +- src/test/policyestimator_tests.cpp | 3 +- src/test/test_bitcoin.cpp | 2 +- src/test/test_bitcoin.h | 6 +- src/txmempool.cpp | 44 +++++++------ src/txmempool.h | 23 +++---- src/wallet/wallet.cpp | 4 +- 31 files changed, 344 insertions(+), 136 deletions(-) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 5087f0762..125d4eb27 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -97,7 +97,7 @@ class MaxUploadTest(BitcoinTestFramework): def setup_network(self): # Start a node with maxuploadtarget of 200 MB (/24h) self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-maxuploadtarget=200", "-blockmaxsize=999000"])) + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-maxuploadtarget=800", "-blockmaxsize=999000"])) def mine_full_block(self, node, address): # Want to create a full block @@ -175,13 +175,13 @@ class MaxUploadTest(BitcoinTestFramework): getdata_request = msg_getdata() getdata_request.inv.append(CInv(2, big_old_block)) - max_bytes_per_day = 200*1024*1024 - daily_buffer = 144 * MAX_BLOCK_SIZE + max_bytes_per_day = 800*1024*1024 + daily_buffer = 144 * 4000000 max_bytes_available = max_bytes_per_day - daily_buffer success_count = max_bytes_available // old_block_size - # 144MB will be reserved for relaying new blocks, so expect this to - # succeed for ~70 tries. + # 576MB will be reserved for relaying new blocks, so expect this to + # succeed for ~235 tries. for i in range(success_count): test_nodes[0].send_message(getdata_request) test_nodes[0].sync_with_ping() @@ -198,9 +198,9 @@ class MaxUploadTest(BitcoinTestFramework): # Requesting the current block on test_nodes[1] should succeed indefinitely, # even when over the max upload target. - # We'll try 200 times + # We'll try 800 times getdata_request.inv = [CInv(2, big_new_block)] - for i in range(200): + for i in range(800): test_nodes[1].send_message(getdata_request) test_nodes[1].sync_with_ping() assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 424812a6d..e77aa6c72 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -195,7 +195,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) uint256 txid(uint256S(strTxid)); static const unsigned int minTxOutSz = 9; - static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; + static const unsigned int maxVout = MAX_BLOCK_BASE_SIZE / minTxOutSz; // extract and validate vout string strVout = vStrInputParts[1]; diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 7fd6a9cf5..5c4c3bd27 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -15,7 +15,7 @@ #include -#define MIN_TRANSACTION_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION)) +#define MIN_TRANSACTION_BASE_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)) CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : nonce(GetRand(std::numeric_limits::max())), @@ -50,7 +50,7 @@ uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const { ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock) { if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty())) return READ_STATUS_INVALID; - if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_SIZE / MIN_TRANSACTION_SIZE) + if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_BASE_SIZE / MIN_TRANSACTION_BASE_SIZE) return READ_STATUS_INVALID; assert(header.IsNull() && txn_available.empty()); diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index ad9cc2617..81f40593b 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -6,10 +6,16 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H -/** The maximum allowed size for a serialized block, in bytes (network rule) */ -static const unsigned int MAX_BLOCK_SIZE = 1000000; +#include + +/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ +static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; +/** The maximum allowed cost for a block, see BIP 141 (network rule) */ +static const unsigned int MAX_BLOCK_COST = 4000000; +/** The maximum allowed size for a block excluding witness data, in bytes (network rule) */ +static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000; /** The maximum allowed number of signature check operations in a block (network rule) */ -static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +static const int64_t MAX_BLOCK_SIGOPS_COST = 80000; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ static const int COINBASE_MATURITY = 100; diff --git a/src/init.cpp b/src/init.cpp index 6bce0a9b4..e924d504b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -452,6 +452,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); + strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); diff --git a/src/main.cpp b/src/main.cpp index c22faf6db..df758bc41 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -684,8 +684,8 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // have been mined or received. // 100 orphans, each of which is at most 99,999 bytes big is // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): - unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz >= MAX_STANDARD_TX_SIZE) + unsigned int sz = GetTransactionCost(tx); + if (sz >= MAX_STANDARD_TX_COST) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; @@ -1018,8 +1018,24 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in return nSigOps; } +int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags) +{ + int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; + if (tx.IsCoinBase()) + return nSigOps; + if (flags & SCRIPT_VERIFY_P2SH) { + nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR; + } + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]); + nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, i < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[i].scriptWitness : NULL, flags); + } + return nSigOps; +} @@ -1033,7 +1049,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) if (tx.vout.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) - if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE) + if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values @@ -1239,8 +1255,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); - unsigned int nSigOps = GetLegacySigOpCount(tx); - nSigOps += GetP2SHSigOpCount(tx, view); + int64_t nSigOpsCost = GetTransactionSigOpCost(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; @@ -1263,7 +1278,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } } - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps, lp); + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp); unsigned int nSize = entry.GetTxSize(); // Check that the transaction doesn't have an excessive number of @@ -1271,9 +1286,9 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than // merely non-standard transaction. - if ((nSigOps > MAX_STANDARD_TX_SIGOPS) || (nBytesPerSigOp && nSigOps > nSize / nBytesPerSigOp)) + if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOp && nSigOpsCost > nSize * WITNESS_SCALE_FACTOR / nBytesPerSigOp)) return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, - strprintf("%d", nSigOps)); + strprintf("%d", nSigOpsCost)); CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { @@ -2439,7 +2454,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector prevheights; CAmount nFees = 0; int nInputs = 0; - unsigned int nSigOps = 0; + int64_t nSigOpsCost = 0; CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); std::vector > vPos; vPos.reserve(block.vtx.size()); @@ -2449,10 +2464,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin const CTransaction &tx = block.vtx[i]; nInputs += tx.vin.size(); - nSigOps += GetLegacySigOpCount(tx); - if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("ConnectBlock(): too many sigops"), - REJECT_INVALID, "bad-blk-sigops"); if (!tx.IsCoinBase()) { @@ -2483,18 +2494,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); } + } - if (fStrictPayToScriptHash) - { - // Add in sigops done by pay-to-script-hash inputs; - // this is to prevent a "rogue miner" from creating - // an incredibly-expensive-to-validate block. - nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("ConnectBlock(): too many sigops"), - REJECT_INVALID, "bad-blk-sigops"); - } + // GetTransactionSigOpCost counts 3 types of sigops: + // * legacy (always) + // * p2sh (when P2SH enabled in flags and excludes coinbase) + // * witness (when witness enabled in flags and excludes coinbase) + nSigOpsCost += GetTransactionSigOpCost(tx, view, flags); + if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) + return state.DoS(100, error("ConnectBlock(): too many sigops"), + REJECT_INVALID, "bad-blk-sigops"); + if (!tx.IsCoinBase()) + { nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector vChecks; @@ -3417,9 +3429,11 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // All potential-corruption validation must be done before we do any // transaction validation, as otherwise we may mark the header as invalid // because we receive the wrong transactions for it. + // Note that witness malleability is checked in ContextualCheckBlock, so no + // checks that use witness data may be performed here. // Size limits - if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SIZE) + if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_BASE_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // First transaction must be coinbase, the rest must not be @@ -3440,7 +3454,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P { nSigOps += GetLegacySigOpCount(tx); } - if (nSigOps > MAX_BLOCK_SIGOPS) + if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST) return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount"); if (fCheckPOW && fCheckMerkleRoot) @@ -3621,6 +3635,16 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } } + // After the coinbase witness nonce and commitment are verified, + // we can check if the block cost passes (before we've checked the + // coinbase witness, it would be possible for the cost to be too + // large by filling up the coinbase witness, which doesn't change + // the block hash, so we couldn't mark the block as permanently + // failed). + if (GetBlockCost(block) > MAX_BLOCK_COST) { + return state.DoS(100, error("ContextualCheckBlock(): cost limit failed"), REJECT_INVALID, "bad-blk-cost"); + } + return true; } @@ -4284,7 +4308,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB int nLoaded = 0; try { // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor - CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); + CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SERIALIZED_SIZE, MAX_BLOCK_SERIALIZED_SIZE+8, SER_DISK, CLIENT_VERSION); uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); @@ -4303,7 +4327,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB continue; // read size blkdat >> nSize; - if (nSize < 80 || nSize > MAX_BLOCK_SIZE) + if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE) continue; } catch (const std::exception&) { // no valid block header found; don't complain diff --git a/src/main.h b/src/main.h index 6dd4b1aa3..317470e3c 100644 --- a/src/main.h +++ b/src/main.h @@ -152,6 +152,7 @@ typedef boost::unordered_map BlockMap; extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockSize; +extern uint64_t nLastBlockCost; extern const std::string strMessageMagic; extern CWaitableCriticalSection csBestBlock; extern CConditionVariable cvBlockChange; diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index dca4973cc..31332526a 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -155,7 +155,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::ve if (nTransactions == 0) return uint256(); // check for excessively high numbers of transactions - if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction + if (nTransactions > MAX_BLOCK_BASE_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction return uint256(); // there can never be more hashes provided than one for every txid if (vHash.size() > nTransactions) diff --git a/src/miner.cpp b/src/miner.cpp index a7bf9ae84..cfc2dae56 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -45,6 +45,7 @@ using namespace std; uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; +uint64_t nLastBlockCost = 0; class ScoreCompare { @@ -75,15 +76,36 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam BlockAssembler::BlockAssembler(const CChainParams& _chainparams) : chainparams(_chainparams) { - // Largest block you're willing to create: - nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + // Block resource limits + // If neither -blockmaxsize or -blockmaxcost is given, limit to DEFAULT_BLOCK_MAX_* + // If only one is given, only restrict the specified resource. + // If both are given, restrict both. + nBlockMaxCost = DEFAULT_BLOCK_MAX_COST; + nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; + bool fCostSet = false; + if (mapArgs.count("-blockmaxcost")) { + nBlockMaxCost = GetArg("-blockmaxcost", DEFAULT_BLOCK_MAX_COST); + nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; + fCostSet = true; + } + if (mapArgs.count("-blockmaxsize")) { + nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); + if (!fCostSet) { + nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR; + } + } + // Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity: + nBlockMaxCost = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_COST-4000), nBlockMaxCost)); + // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize)); // Minimum block size you want to create; block will be filled with free transactions // until there are no more or the block reaches this size: nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); + + // Whether we need to account for byte usage (in addition to cost usage) + fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000) || (nBlockMinSize > 0); } void BlockAssembler::resetBlock() @@ -92,7 +114,8 @@ void BlockAssembler::resetBlock() // Reserve space for coinbase tx nBlockSize = 1000; - nBlockSigOps = 100; + nBlockCost = 4000; + nBlockSigOpsCost = 400; fIncludeWitness = false; // These counters do not include coinbase tx @@ -116,7 +139,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) // Add dummy coinbase tx as first transaction pblock->vtx.push_back(CTransaction()); pblocktemplate->vTxFees.push_back(-1); // updated at end - pblocktemplate->vTxSigOps.push_back(-1); // updated at end + pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); @@ -144,11 +167,18 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); addPriorityTxs(); - addPackageTxs(); + if (fNeedSizeAccounting) { + // addPackageTxs (the CPFP-based algorithm) cannot deal with size based + // accounting, so fall back to the old algorithm. + addScoreTxs(); + } else { + addPackageTxs(); + } nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps); + nLastBlockCost = nBlockCost; + LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOpsCost); // Create coinbase transaction. CMutableTransaction coinbaseTx; @@ -167,7 +197,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; - pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); + pblocktemplate->vTxSigOpsCost[0] = GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { @@ -201,11 +231,12 @@ void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) } } -bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps) +bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) { - if (nBlockSize + packageSize >= nBlockMaxSize) + // TODO: switch to cost-based accounting for packages instead of vsize-based accounting. + if (nBlockCost + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxCost) return false; - if (nBlockSigOps + packageSigOps >= MAX_BLOCK_SIGOPS) + if (nBlockSigOpsCost + packageSigOpsCost >= MAX_BLOCK_SIGOPS_COST) return false; return true; } @@ -223,26 +254,39 @@ bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package) bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { - if (nBlockSize + iter->GetTxSize() >= nBlockMaxSize) { + if (nBlockCost + iter->GetTxCost() >= nBlockMaxCost) { // If the block is so close to full that no more txs will fit // or if we've tried more than 50 times to fill remaining space // then flag that the block is finished - if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { + if (nBlockCost > nBlockMaxCost - 400 || lastFewTxs > 50) { blockFinished = true; return false; } - // Once we're within 1000 bytes of a full block, only look at 50 more txs + // Once we're within 4000 cost of a full block, only look at 50 more txs // to try to fill the remaining space. - if (nBlockSize > nBlockMaxSize - 1000) { + if (nBlockCost > nBlockMaxCost - 4000) { lastFewTxs++; } return false; } - if (nBlockSigOps + iter->GetSigOpCount() >= MAX_BLOCK_SIGOPS) { + if (fNeedSizeAccounting) { + if (nBlockSize + ::GetSerializeSize(iter->GetTx(), SER_NETWORK, PROTOCOL_VERSION) >= nBlockMaxSize) { + if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { + blockFinished = true; + return false; + } + if (nBlockSize > nBlockMaxSize - 1000) { + lastFewTxs++; + } + return false; + } + } + + if (nBlockSigOpsCost + iter->GetSigOpCost() >= MAX_BLOCK_SIGOPS_COST) { // If the block has room for no more sig ops then // flag that the block is finished - if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) { + if (nBlockSigOpsCost > MAX_BLOCK_SIGOPS_COST - 8) { blockFinished = true; return false; } @@ -264,10 +308,13 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) { pblock->vtx.push_back(iter->GetTx()); pblocktemplate->vTxFees.push_back(iter->GetFee()); - pblocktemplate->vTxSigOps.push_back(iter->GetSigOpCount()); - nBlockSize += iter->GetTxSize(); + pblocktemplate->vTxSigOpsCost.push_back(iter->GetSigOpCost()); + if (fNeedSizeAccounting) { + nBlockSize += ::GetSerializeSize(iter->GetTx(), SER_NETWORK, PROTOCOL_VERSION); + } + nBlockCost += iter->GetTxCost(); ++nBlockTx; - nBlockSigOps += iter->GetSigOpCount(); + nBlockSigOpsCost += iter->GetSigOpCost(); nFees += iter->GetFee(); inBlock.insert(iter); @@ -358,7 +405,7 @@ void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alread CTxMemPoolModifiedEntry modEntry(desc); modEntry.nSizeWithAncestors -= it->GetTxSize(); modEntry.nModFeesWithAncestors -= it->GetModifiedFee(); - modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount(); + modEntry.nSigOpCostWithAncestors -= it->GetSigOpCost(); mapModifiedTx.insert(modEntry); } else { mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); @@ -460,19 +507,19 @@ void BlockAssembler::addPackageTxs() uint64_t packageSize = iter->GetSizeWithAncestors(); CAmount packageFees = iter->GetModFeesWithAncestors(); - unsigned int packageSigOps = iter->GetSigOpCountWithAncestors(); + int64_t packageSigOpsCost = iter->GetSigOpCostWithAncestors(); if (fUsingModified) { packageSize = modit->nSizeWithAncestors; packageFees = modit->nModFeesWithAncestors; - packageSigOps = modit->nSigOpCountWithAncestors; + packageSigOpsCost = modit->nSigOpCostWithAncestors; } - if (packageFees < ::minRelayTxFee.GetFee(packageSize) && nBlockSize >= nBlockMinSize) { + if (packageFees < ::minRelayTxFee.GetFee(packageSize)) { // Everything else we might consider has a lower fee rate return; } - if (!TestPackage(packageSize, packageSigOps)) { + if (!TestPackage(packageSize, packageSigOpsCost)) { if (fUsingModified) { // Since we always look at the best entry in mapModifiedTx, // we must erase failed entries so that we can consider the @@ -526,6 +573,8 @@ void BlockAssembler::addPriorityTxs() return; } + fNeedSizeAccounting = true; + // This vector will be sorted into a priority queue: vector vecPriority; TxCoinAgePriorityCompare pricomparer; diff --git a/src/miner.h b/src/miner.h index 8bfc1493d..b303a8fa3 100644 --- a/src/miner.h +++ b/src/miner.h @@ -28,7 +28,7 @@ struct CBlockTemplate { CBlock block; std::vector vTxFees; - std::vector vTxSigOps; + std::vector vTxSigOpsCost; std::vector vchCoinbaseCommitment; }; @@ -40,13 +40,13 @@ struct CTxMemPoolModifiedEntry { iter = entry; nSizeWithAncestors = entry->GetSizeWithAncestors(); nModFeesWithAncestors = entry->GetModFeesWithAncestors(); - nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); + nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors(); } CTxMemPool::txiter iter; uint64_t nSizeWithAncestors; CAmount nModFeesWithAncestors; - unsigned int nSigOpCountWithAncestors; + int64_t nSigOpCostWithAncestors; }; /** Comparator for CTxMemPool::txiter objects. @@ -124,7 +124,7 @@ struct update_for_parent_inclusion { e.nModFeesWithAncestors -= iter->GetFee(); e.nSizeWithAncestors -= iter->GetTxSize(); - e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); + e.nSigOpCostWithAncestors -= iter->GetSigOpCost(); } CTxMemPool::txiter iter; @@ -141,12 +141,14 @@ private: // Configuration parameters for the block size bool fIncludeWitness; - unsigned int nBlockMaxSize, nBlockMinSize; + unsigned int nBlockMaxCost, nBlockMaxSize, nBlockMinSize; + bool fNeedSizeAccounting; // Information on the current status of the block + uint64_t nBlockCost; uint64_t nBlockSize; uint64_t nBlockTx; - unsigned int nBlockSigOps; + uint64_t nBlockSigOpsCost; CAmount nFees; CTxMemPool::setEntries inBlock; @@ -189,7 +191,7 @@ private: /** Remove confirmed (inBlock) entries from given set */ void onlyUnconfirmed(CTxMemPool::setEntries& testSet); /** Test if a new package would "fit" in the block */ - bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); + bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost); /** Test if a set of transactions are all final */ bool TestPackageFinality(const CTxMemPool::setEntries& package); /** Return true if given transaction from mapTx has already been evaluated, diff --git a/src/net.cpp b/src/net.cpp index dc83f19be..4cbc43e4d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2182,7 +2182,7 @@ void CNode::RecordBytesSent(uint64_t bytes) void CNode::SetMaxOutboundTarget(uint64_t limit) { LOCK(cs_totalBytesSent); - uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE; + uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SERIALIZED_SIZE; nMaxOutboundLimit = limit; if (limit > 0 && limit < recommendedMinimum) @@ -2237,7 +2237,7 @@ bool CNode::OutboundTargetReached(bool historicalBlockServingLimit) { // keep a large enough buffer to at least relay each block once uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); - uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE; + uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE; if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) return true; } diff --git a/src/net.h b/src/net.h index 7ed18b205..41315fc9b 100644 --- a/src/net.h +++ b/src/net.h @@ -45,8 +45,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60; static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ static const unsigned int MAX_ADDR_TO_SEND = 1000; -/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ -static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; +/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */ +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000; /** Maximum length of strSubVer in `version` message */ static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** -listen default */ diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 67434a38f..f2148bfe1 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -64,8 +64,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. - unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz >= MAX_STANDARD_TX_SIZE) { + unsigned int sz = GetTransactionCost(tx); + if (sz >= MAX_STANDARD_TX_COST) { reason = "tx-size"; return false; } @@ -150,3 +150,13 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } + +int64_t GetVirtualTransactionSize(int64_t nCost) +{ + return (nCost + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; +} + +int64_t GetVirtualTransactionSize(const CTransaction& tx) +{ + return GetVirtualTransactionSize(GetTransactionCost(tx)); +} diff --git a/src/policy/policy.h b/src/policy/policy.h index a6bcc777f..fefb562ff 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -19,12 +19,14 @@ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; +/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/ +static const unsigned int DEFAULT_BLOCK_MAX_COST = 3000000; /** The maximum size for transactions we're willing to relay/mine */ -static const unsigned int MAX_STANDARD_TX_SIZE = 100000; +static const unsigned int MAX_STANDARD_TX_COST = 400000; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ -static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; +static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; /** @@ -65,4 +67,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason); */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); +/** Compute the virtual transaction size (cost reinterpreted as bytes). */ +int64_t GetVirtualTransactionSize(int64_t nCost); +int64_t GetVirtualTransactionSize(const CTransaction& tx); + #endif // BITCOIN_POLICY_POLICY_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 6fb33230a..df900388f 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -31,3 +31,12 @@ std::string CBlock::ToString() const } return s.str(); } + +int64_t GetBlockCost(const CBlock& block) +{ + // This implements the cost = (stripped_size * 4) + witness_size formula, + // using only serialization with and without witness data. As witness_size + // is equal to total_size - stripped_size, this formula is identical to: + // cost = (stripped_size * 3) + total_size. + return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); +} diff --git a/src/primitives/block.h b/src/primitives/block.h index 29307aed5..e2a309e63 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -154,4 +154,7 @@ struct CBlockLocator } }; +/** Compute the consensus-critical block cost (see BIP 141). */ +int64_t GetBlockCost(const CBlock& tx); + #endif // BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index b0230530e..7f10409c0 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -121,7 +121,7 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const // Providing any more cleanup incentive than making additional inputs free would // risk encouraging people to create junk outputs to redeem later. if (nTxSize == 0) - nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + nTxSize = (GetTransactionCost(*this) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; for (std::vector::const_iterator it(vin.begin()); it != vin.end(); ++it) { unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); @@ -148,3 +148,8 @@ std::string CTransaction::ToString() const str += " " + vout[i].ToString() + "\n"; return str; } + +int64_t GetTransactionCost(const CTransaction& tx) +{ + return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR -1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); +} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 5a5824134..e87ad90f0 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -13,6 +13,8 @@ static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000; +static const int WITNESS_SCALE_FACTOR = 4; + /** An outpoint - a combination of a transaction hash and an index n into its vout */ class COutPoint { @@ -166,15 +168,30 @@ public: // which has units satoshis-per-kilobyte. // If you'd pay more than 1/3 in fees // to spend something, then we consider it dust. - // A typical spendable txout is 34 bytes big, and will + // A typical spendable non-segwit txout is 34 bytes big, and will // need a CTxIn of at least 148 bytes to spend: // so dust is a spendable txout less than - // 546*minRelayTxFee/1000 (in satoshis) + // 546*minRelayTxFee/1000 (in satoshis). + // A typical spendable segwit txout is 31 bytes big, and will + // need a CTxIn of at least 67 bytes to spend: + // so dust is a spendable txout less than + // 294*minRelayTxFee/1000 (in satoshis). if (scriptPubKey.IsUnspendable()) return 0; - size_t nSize = GetSerializeSize(SER_DISK,0)+148u; - return 3*minRelayTxFee.GetFee(nSize); + size_t nSize = GetSerializeSize(SER_DISK, 0); + int witnessversion = 0; + std::vector witnessprogram; + + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + // sum the sizes of the parts of a transaction input + // with 75% segwit discount applied to the script size. + nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4); + } else { + nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above + } + + return 3 * minRelayTxFee.GetFee(nSize); } bool IsDust(const CFeeRate &minRelayTxFee) const @@ -442,4 +459,7 @@ struct CMutableTransaction uint256 GetHash() const; }; +/** Compute the cost of a transaction, as defined by BIP 141 */ +int64_t GetTransactionCost(const CTransaction &tx); + #endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f11af876f..43ba4edd7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -101,6 +101,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("cost", (int)::GetBlockCost(block))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); @@ -560,6 +561,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" + " \"cost\" : n (numeric) The block cost\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 291314b8b..4c4e59978 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -224,6 +224,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) "{\n" " \"blocks\": nnn, (numeric) The current block\n" " \"currentblocksize\": nnn, (numeric) The last block size\n" + " \"currentblockcost\": nnn, (numeric) The last block cost\n" " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" @@ -242,6 +243,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblockcost", (uint64_t)nLastBlockCost)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); @@ -349,13 +351,14 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" - " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal\n" + " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" - " \"sigops\" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any\n" + " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" + " \"cost\" : n, (numeric) total transaction size cost, as counted for purposes of block limits\n" " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" " }\n" " ,...\n" @@ -372,8 +375,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) " ,...\n" " ],\n" " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n" - " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" + " \"sigoplimit\" : n, (numeric) cost limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" + " \"costlimit\" : n, (numeric) limit of block cost\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" @@ -570,7 +574,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) int index_in_template = i - 1; entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.push_back(Pair("sigops", pblocktemplate->vTxSigOpsCost[index_in_template])); + entry.push_back(Pair("cost", GetTransactionCost(tx))); transactions.push_back(entry); } @@ -652,8 +657,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_COST)); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); + result.push_back(Pair("costlimit", (int64_t)MAX_BLOCK_COST)); result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 12e3eaa92..b36179943 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -64,6 +64,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex())); entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); + entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); @@ -150,6 +151,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " \"txid\" : \"id\", (string) The transaction id (same as provided)\n" " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" " \"size\" : n, (numeric) The serialized transaction size\n" + " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" @@ -461,6 +463,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " \"txid\" : \"id\", (string) The transaction id\n" " \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" " \"size\" : n, (numeric) The transaction size\n" + " \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 4deebd050..bc027e9f0 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1470,3 +1470,50 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C return set_success(serror); } + +size_t static WitnessSigOps(int witversion, const std::vector& witprogram, const CScriptWitness& witness, int flags) +{ + if (witversion == 0) { + if (witprogram.size() == 20) + return 1; + + if (witprogram.size() == 32 && witness.stack.size() > 0) { + CScript subscript(witness.stack.back().begin(), witness.stack.back().end()); + return subscript.GetSigOpCount(true); + } + } + + // Future flags may be implemented here. + return 0; +} + +size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags) +{ + static const CScriptWitness witnessEmpty; + + if ((flags & SCRIPT_VERIFY_WITNESS) == 0) { + return 0; + } + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + + int witnessversion; + std::vector witnessprogram; + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags); + } + + if (scriptPubKey.IsPayToScriptHash() && scriptSig.IsPushOnly()) { + CScript::const_iterator pc = scriptSig.begin(); + vector data; + while (pc < scriptSig.end()) { + opcodetype opcode; + scriptSig.GetOp(pc, opcode, data); + } + CScript subscript(data.begin(), data.end()); + if (subscript.IsWitnessProgram(witnessversion, witnessprogram)) { + return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags); + } + } + + return 0; +} diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 864372942..bd2f21166 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -156,4 +156,6 @@ public: bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL); +size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags); + #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index c8b43df26..033a50f94 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_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 "policy/policy.h" #include "txmempool.h" #include "util.h" @@ -336,7 +337,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); - uint64_t tx2Size = ::GetSerializeSize(tx2, SER_NETWORK, PROTOCOL_VERSION); + uint64_t tx2Size = GetVirtualTransactionSize(tx2); /* lowest fee */ CMutableTransaction tx3 = CMutableTransaction(); @@ -384,7 +385,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx6.vout.resize(1); tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx6.vout[0].nValue = 20 * COIN; - uint64_t tx6Size = ::GetSerializeSize(tx6, SER_NETWORK, PROTOCOL_VERSION); + uint64_t tx6Size = GetVirtualTransactionSize(tx6); pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6); @@ -398,7 +399,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx7.vout.resize(1); tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx7.vout[0].nValue = 10 * COIN; - uint64_t tx7Size = ::GetSerializeSize(tx7, SER_NETWORK, PROTOCOL_VERSION); + uint64_t tx7Size = GetVirtualTransactionSize(tx7); /* set the fee to just below tx2's feerate when including ancestor */ CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1; @@ -467,12 +468,12 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(tx2.GetHash())); BOOST_CHECK(pool.exists(tx3.GetHash())); - pool.TrimToSize(::GetSerializeSize(CTransaction(tx1), SER_NETWORK, PROTOCOL_VERSION)); // mempool is limited to tx1's size in memory usage, so nothing fits + pool.TrimToSize(GetVirtualTransactionSize(tx1)); // mempool is limited to tx1's size in memory usage, so nothing fits BOOST_CHECK(!pool.exists(tx1.GetHash())); BOOST_CHECK(!pool.exists(tx2.GetHash())); BOOST_CHECK(!pool.exists(tx3.GetHash())); - CFeeRate maxFeeRateRemoved(25000, ::GetSerializeSize(CTransaction(tx3), SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(CTransaction(tx2), SER_NETWORK, PROTOCOL_VERSION)); + CFeeRate maxFeeRateRemoved(25000, GetVirtualTransactionSize(tx3) + GetVirtualTransactionSize(tx2)); BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000); CMutableTransaction tx4 = CMutableTransaction(); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index ca8d6d2e0..fd581db52 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -181,6 +181,9 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { + // Disable size accounting (CPFP does not support it) + mapArgs["-blockmaxsize"] = strprintf("%u", MAX_BLOCK_SERIALIZED_SIZE); + const CChainParams& chainparams = Params(CBaseChainParams::MAIN); CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; @@ -264,7 +267,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes - mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 2b00e6f56..5c902387f 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_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 "policy/policy.h" #include "policy/fees.h" #include "txmempool.h" #include "uint256.h" @@ -50,7 +51,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) tx.vin[0].scriptSig = garbage; tx.vout.resize(1); tx.vout[0].nValue=0LL; - CFeeRate baseRate(basefee, ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + CFeeRate baseRate(basefee, GetVirtualTransactionSize(tx)); // Create a fake block std::vector block; diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 1f3b19880..856f9b842 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -136,7 +136,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CTransaction &txn, CTxMemPool *po CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, - hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount, lp); + hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp); } void Shutdown(void* parg) diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 78b87e710..bc0d2fe31 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -70,12 +70,12 @@ struct TestMemPoolEntryHelper unsigned int nHeight; bool hadNoDependencies; bool spendsCoinbase; - unsigned int sigOpCount; + unsigned int sigOpCost; LockPoints lp; TestMemPoolEntryHelper() : nFee(0), nTime(0), dPriority(0.0), nHeight(1), - hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { } + hadNoDependencies(false), spendsCoinbase(false), sigOpCost(4) { } CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL); CTxMemPoolEntry FromTx(CTransaction &tx, CTxMemPool *pool = NULL); @@ -87,6 +87,6 @@ struct TestMemPoolEntryHelper TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; } TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } - TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; } + TestMemPoolEntryHelper &SigOpsCost(unsigned int _sigopsCost) { sigOpCost = _sigopsCost; return *this; } }; #endif diff --git a/src/txmempool.cpp b/src/txmempool.cpp index ead28546d..a48a6d946 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -9,6 +9,7 @@ #include "consensus/consensus.h" #include "consensus/validation.h" #include "main.h" +#include "policy/policy.h" #include "policy/fees.h" #include "streams.h" #include "timedata.h" @@ -22,17 +23,17 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, - bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp): + bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp): tx(std::make_shared(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), - spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp) + spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) { - nTxSize = ::GetSerializeSize(_tx, SER_NETWORK, PROTOCOL_VERSION); - nModSize = _tx.CalculateModifiedSize(nTxSize); + nTxCost = GetTransactionCost(_tx); + nModSize = _tx.CalculateModifiedSize(GetTxSize()); nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); nCountWithDescendants = 1; - nSizeWithDescendants = nTxSize; + nSizeWithDescendants = GetTxSize(); nModFeesWithDescendants = nFee; CAmount nValueIn = _tx.GetValueOut()+nFee; assert(inChainInputValue <= nValueIn); @@ -40,9 +41,9 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, feeDelta = 0; nCountWithAncestors = 1; - nSizeWithAncestors = nTxSize; + nSizeWithAncestors = GetTxSize(); nModFeesWithAncestors = nFee; - nSigOpCountWithAncestors = sigOpCount; + nSigOpCostWithAncestors = sigOpCost; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -72,6 +73,11 @@ void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp) lockPoints = lp; } +size_t CTxMemPoolEntry::GetTxSize() const +{ + return GetVirtualTransactionSize(nTxCost); +} + // Update the given tx for any in-mempool descendants. // Assumes that setMemPoolChildren is correct for the given tx and all // descendants. @@ -111,7 +117,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan modifyCount++; cachedDescendants[updateIt].insert(cit); // Update ancestor state for each descendant - mapTx.modify(cit, update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCount())); + mapTx.modify(cit, update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost())); } } mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); @@ -247,13 +253,13 @@ void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncesto int64_t updateCount = setAncestors.size(); int64_t updateSize = 0; CAmount updateFee = 0; - int updateSigOps = 0; + int64_t updateSigOpsCost = 0; BOOST_FOREACH(txiter ancestorIt, setAncestors) { updateSize += ancestorIt->GetTxSize(); updateFee += ancestorIt->GetModifiedFee(); - updateSigOps += ancestorIt->GetSigOpCount(); + updateSigOpsCost += ancestorIt->GetSigOpCost(); } - mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOps)); + mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost)); } void CTxMemPool::UpdateChildrenForRemoval(txiter it) @@ -282,7 +288,7 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, b setDescendants.erase(removeIt); // don't update state for self int64_t modifySize = -((int64_t)removeIt->GetTxSize()); CAmount modifyFee = -removeIt->GetModifiedFee(); - int modifySigOps = -removeIt->GetSigOpCount(); + int modifySigOps = -removeIt->GetSigOpCost(); BOOST_FOREACH(txiter dit, setDescendants) { mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps)); } @@ -338,8 +344,8 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, nModFeesWithAncestors += modifyFee; nCountWithAncestors += modifyCount; assert(int64_t(nCountWithAncestors) > 0); - nSigOpCountWithAncestors += modifySigOps; - assert(int(nSigOpCountWithAncestors) >= 0); + nSigOpCostWithAncestors += modifySigOps; + assert(int(nSigOpCostWithAncestors) >= 0); } CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) : @@ -666,7 +672,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const bool fDependsWait = false; setEntries setParentCheck; int64_t parentSizes = 0; - unsigned int parentSigOpCount = 0; + int64_t parentSigOpCost = 0; BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); @@ -676,7 +682,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const fDependsWait = true; if (setParentCheck.insert(it2).second) { parentSizes += it2->GetTxSize(); - parentSigOpCount += it2->GetSigOpCount(); + parentSigOpCost += it2->GetSigOpCost(); } } else { const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); @@ -698,17 +704,17 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const uint64_t nCountCheck = setAncestors.size() + 1; uint64_t nSizeCheck = it->GetTxSize(); CAmount nFeesCheck = it->GetModifiedFee(); - unsigned int nSigOpCheck = it->GetSigOpCount(); + int64_t nSigOpCheck = it->GetSigOpCost(); BOOST_FOREACH(txiter ancestorIt, setAncestors) { nSizeCheck += ancestorIt->GetTxSize(); nFeesCheck += ancestorIt->GetModifiedFee(); - nSigOpCheck += ancestorIt->GetSigOpCount(); + nSigOpCheck += ancestorIt->GetSigOpCost(); } assert(it->GetCountWithAncestors() == nCountCheck); assert(it->GetSizeWithAncestors() == nSizeCheck); - assert(it->GetSigOpCountWithAncestors() == nSigOpCheck); + assert(it->GetSigOpCostWithAncestors() == nSigOpCheck); assert(it->GetModFeesWithAncestors() == nFeesCheck); // Check children against mapNextTx diff --git a/src/txmempool.h b/src/txmempool.h index d6d0d72ff..e5a500e19 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -78,7 +78,7 @@ class CTxMemPoolEntry private: std::shared_ptr tx; CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups - size_t nTxSize; //!< ... and avoid recomputing tx size + size_t nTxCost; //!< ... and avoid recomputing tx cost (also used for GetTxSize()) size_t nModSize; //!< ... and modified size for priority size_t nUsageSize; //!< ... and total memory usage int64_t nTime; //!< Local time when entering the mempool @@ -87,7 +87,7 @@ private: bool hadNoDependencies; //!< Not dependent on any other txs when it entered the mempool CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain bool spendsCoinbase; //!< keep track of transactions that spend a coinbase - unsigned int sigOpCount; //!< Legacy sig ops plus P2SH sig op count + int64_t sigOpCost; //!< Total sigop cost int64_t feeDelta; //!< Used for determining the priority of the transaction for mining in a block LockPoints lockPoints; //!< Track the height and time at which tx was final @@ -104,13 +104,13 @@ private: uint64_t nCountWithAncestors; uint64_t nSizeWithAncestors; CAmount nModFeesWithAncestors; - unsigned int nSigOpCountWithAncestors; + int64_t nSigOpCostWithAncestors; public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _entryPriority, unsigned int _entryHeight, bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase, - unsigned int nSigOps, LockPoints lp); + int64_t nSigOpsCost, LockPoints lp); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return *this->tx; } @@ -121,11 +121,12 @@ public: */ double GetPriority(unsigned int currentHeight) const; const CAmount& GetFee() const { return nFee; } - size_t GetTxSize() const { return nTxSize; } + size_t GetTxSize() const; + size_t GetTxCost() const { return nTxCost; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return entryHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } - unsigned int GetSigOpCount() const { return sigOpCount; } + int64_t GetSigOpCost() const { return sigOpCost; } int64_t GetModifiedFee() const { return nFee + feeDelta; } size_t DynamicMemoryUsage() const { return nUsageSize; } const LockPoints& GetLockPoints() const { return lockPoints; } @@ -149,7 +150,7 @@ public: uint64_t GetCountWithAncestors() const { return nCountWithAncestors; } uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } - unsigned int GetSigOpCountWithAncestors() const { return nSigOpCountWithAncestors; } + int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes }; @@ -172,18 +173,18 @@ struct update_descendant_state struct update_ancestor_state { - update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int _modifySigOps) : - modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOps(_modifySigOps) + update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost) : + modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost) {} void operator() (CTxMemPoolEntry &e) - { e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOps); } + { e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost); } private: int64_t modifySize; CAmount modifyFee; int64_t modifyCount; - int modifySigOps; + int64_t modifySigOpsCost; }; struct update_fee_delta diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 723b2ecef..babde1a02 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2348,7 +2348,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt nIn++; } - unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + unsigned int nBytes = GetVirtualTransactionSize(txNew); // Remove scriptSigs if we used dummy signatures for fee calculation if (!sign) { @@ -2360,7 +2360,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt *static_cast(&wtxNew) = CTransaction(txNew); // Limit size - if (nBytes >= MAX_STANDARD_TX_SIZE) + if (GetTransactionCost(txNew) >= MAX_STANDARD_TX_COST) { strFailReason = _("Transaction too large"); return false; From b7dbeb24ebff16198b2925d906c06771e167bd9e Mon Sep 17 00:00:00 2001 From: Thomas Kerin Date: Sun, 24 Jan 2016 16:29:39 +0000 Subject: [PATCH 0848/1223] [libconsensus] Script verification API with amounts script_tests: always test bitcoinconsensus_verify_script_with_amount if VERIFY_WITNESS isn't set Rename internal method + make it static trim bitcoinconsensus_ prefix Add SERIALIZE_TRANSACTION_WITNESS flag --- src/script/bitcoinconsensus.cpp | 30 +++++++++++++++++++++++++----- src/script/bitcoinconsensus.h | 8 +++++++- src/test/script_tests.cpp | 7 ++++++- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 26e7a85b7..62fd9031f 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -69,7 +69,7 @@ struct ECCryptoClosure ECCryptoClosure instance_of_eccryptoclosure; } -int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, +static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CAmount amount, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) { @@ -82,16 +82,36 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != txToLen) return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); - // Regardless of the verification result, the tx did not error. - set_error(err, bitcoinconsensus_ERR_OK); + // Regardless of the verification result, the tx did not error. + set_error(err, bitcoinconsensus_ERR_OK); - CAmount am(0); - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, am), NULL); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, amount), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } } +int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) +{ + CAmount am(amount); + return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); +} + + +int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) +{ + if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { + return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED); + } + + CAmount am(0); + return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); +} + unsigned int bitcoinconsensus_version() { // Just use the API version for now diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index cd3e2f773..6f868d0d6 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -33,7 +33,7 @@ extern "C" { #endif -#define BITCOINCONSENSUS_API_VER 0 +#define BITCOINCONSENSUS_API_VER 1 typedef enum bitcoinconsensus_error_t { @@ -41,6 +41,7 @@ typedef enum bitcoinconsensus_error_t bitcoinconsensus_ERR_TX_INDEX, bitcoinconsensus_ERR_TX_SIZE_MISMATCH, bitcoinconsensus_ERR_TX_DESERIALIZE, + bitcoinconsensus_ERR_AMOUNT_REQUIRED, } bitcoinconsensus_error; /** Script verification flags */ @@ -50,6 +51,7 @@ enum bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141) }; /// Returns 1 if the input nIn of the serialized transaction pointed to by @@ -57,6 +59,10 @@ enum /// the additional constraints specified by flags. /// If not NULL, err will contain an error/success code for the operation EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); + +EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index c56b9da4e..7fd7614e2 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -160,7 +160,12 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, co #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << tx2; - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message); + if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), amountZero, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); + } else { + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message); + } #endif } From 6032f6930a56c107dad8f30c05fec4aab79c8c22 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 18 Mar 2016 17:20:12 +0100 Subject: [PATCH 0849/1223] Add rewind logic to deal with post-fork software updates Includes logic for dealing with pruning by Suhas Daftuar. --- src/chain.h | 2 + src/init.cpp | 8 ++++ src/main.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++++------- src/main.h | 3 ++ 4 files changed, 124 insertions(+), 17 deletions(-) diff --git a/src/chain.h b/src/chain.h index a13dae33d..76a774c12 100644 --- a/src/chain.h +++ b/src/chain.h @@ -144,6 +144,8 @@ enum BlockStatus: uint32_t { BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed BLOCK_FAILED_CHILD = 64, //! descends from failed block BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, + + BLOCK_OPT_WITNESS = 128, //! block data in blk*.data was received with a witness-enforcing client }; /** The block chain is a tree shaped structure starting with the diff --git a/src/init.cpp b/src/init.cpp index e924d504b..5d29f14eb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1284,6 +1284,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } + if (!fReindex) { + uiInterface.InitMessage(_("Rewinding blocks...")); + if (!RewindBlockIndex(chainparams)) { + strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain"); + break; + } + } + uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", diff --git a/src/main.cpp b/src/main.cpp index df758bc41..ec43a6670 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -658,6 +658,9 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc CBlockIndex* pindex = (*mi).second; if (chain.Contains(pindex)) return pindex; + if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { + return chain.Tip(); + } } } return chain.Genesis(); @@ -2777,7 +2780,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { } /** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ -bool static DisconnectTip(CValidationState& state, const CChainParams& chainparams) +bool static DisconnectTip(CValidationState& state, const CChainParams& chainparams, bool fBare = false) { CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); @@ -2797,24 +2800,28 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara // Write the chain state to disk, if necessary. if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; - // Resurrect mempool transactions from the disconnected block. - std::vector vHashUpdate; - BOOST_FOREACH(const CTransaction &tx, block.vtx) { - // ignore validation errors in resurrected transactions - list removed; - CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { - mempool.removeRecursive(tx, removed); - } else if (mempool.exists(tx.GetHash())) { - vHashUpdate.push_back(tx.GetHash()); + + if (!fBare) { + // Resurrect mempool transactions from the disconnected block. + std::vector vHashUpdate; + BOOST_FOREACH(const CTransaction &tx, block.vtx) { + // ignore validation errors in resurrected transactions + list removed; + CValidationState stateDummy; + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { + mempool.removeRecursive(tx, removed); + } else if (mempool.exists(tx.GetHash())) { + vHashUpdate.push_back(tx.GetHash()); + } } + // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have + // no in-mempool children, which is generally not true when adding + // previously-confirmed transactions back to the mempool. + // UpdateTransactionsFromBlock finds descendants of any transactions in this + // block that were added back and cleans up the mempool state. + mempool.UpdateTransactionsFromBlock(vHashUpdate); } - // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have - // no in-mempool children, which is generally not true when adding - // previously-confirmed transactions back to the mempool. - // UpdateTransactionsFromBlock finds descendants of any transactions in this - // block that were added back and cleans up the mempool state. - mempool.UpdateTransactionsFromBlock(vHashUpdate); + // Update chainActive and related variables. UpdateTip(pindexDelete->pprev, chainparams); // Let wallets know transactions went from 1-confirmed to @@ -3266,6 +3273,9 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindexNew->nDataPos = pos.nPos; pindexNew->nUndoPos = 0; pindexNew->nStatus |= BLOCK_HAVE_DATA; + if (IsWitnessEnabled(pindexNew->pprev, Params().GetConsensus())) { + pindexNew->nStatus |= BLOCK_OPT_WITNESS; + } pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); setDirtyBlockIndex.insert(pindexNew); @@ -4214,6 +4224,90 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, return true; } +bool RewindBlockIndex(const CChainParams& params) +{ + LOCK(cs_main); + + int nHeight = 1; + while (nHeight <= chainActive.Height()) { + if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) { + break; + } + nHeight++; + } + + // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1 + CValidationState state; + CBlockIndex* pindex = chainActive.Tip(); + while (chainActive.Height() >= nHeight) { + if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) { + // If pruning, don't try rewinding past the HAVE_DATA point; + // since older blocks can't be served anyway, there's + // no need to walk further, and trying to DisconnectTip() + // will fail (and require a needless reindex/redownload + // of the blockchain). + break; + } + if (!DisconnectTip(state, params, true)) { + return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight); + } + // Occasionally flush state to disk. + if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) + return false; + } + + // Reduce validity flag and have-data flags. + // We do this after actual disconnecting, otherwise we'll end up writing the lack of data + // to disk before writing the chainstate, resulting in a failure to continue if interrupted. + for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { + CBlockIndex* pindexIter = it->second; + + // Note: If we encounter an insufficiently validated block that + // is on chainActive, it must be because we are a pruning node, and + // this block or some successor doesn't HAVE_DATA, so we were unable to + // rewind all the way. Blocks remaining on chainActive at this point + // must not have their validity reduced. + if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus()) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) { + // Reduce validity + pindexIter->nStatus = std::min(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | (pindexIter->nStatus & ~BLOCK_VALID_MASK); + // Remove have-data flags. + pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO); + // Remove storage location. + pindexIter->nFile = 0; + pindexIter->nDataPos = 0; + pindexIter->nUndoPos = 0; + // Remove various other things + pindexIter->nTx = 0; + pindexIter->nChainTx = 0; + pindexIter->nSequenceId = 0; + // Make sure it gets written. + setDirtyBlockIndex.insert(pindexIter); + // Update indexes + setBlockIndexCandidates.erase(pindexIter); + std::pair::iterator, std::multimap::iterator> ret = mapBlocksUnlinked.equal_range(pindexIter->pprev); + while (ret.first != ret.second) { + if (ret.first->second == pindexIter) { + mapBlocksUnlinked.erase(ret.first++); + } else { + ++ret.first; + } + } + } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) { + setBlockIndexCandidates.insert(pindexIter); + } + } + + PruneBlockIndexCandidates(); + + CheckBlockIndex(params.GetConsensus()); + + if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) { + return false; + } + + return true; +} + void UnloadBlockIndex() { LOCK(cs_main); diff --git a/src/main.h b/src/main.h index 317470e3c..84a6044bc 100644 --- a/src/main.h +++ b/src/main.h @@ -459,6 +459,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, /** Check whether witness commitments are required for block. */ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params); +/** When there are blocks in the active chain with missing data, rewind the chainstate and remove them from the block index */ +bool RewindBlockIndex(const CChainParams& params); + /** Update uncommitted block structures (currently: only the witness nonce). This is safe for submitted blocks. */ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); From af87a67eff8ce7bf2c7fb29f760da9fc610f162f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 22 Jun 2016 15:39:26 +0200 Subject: [PATCH 0850/1223] Do not use compact blocks when segwit is enabled --- src/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ec43a6670..d1ba70313 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -473,6 +473,10 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom) { + if (nLocalServices & NODE_WITNESS) { + // Don't ever request compact blocks when segwit is enabled. + return; + } if (nodestate->fProvidesHeaderAndIDs) { BOOST_FOREACH(const NodeId nodeid, lNodesAnnouncingHeaderAndIDs) if (nodeid == pfrom->GetId()) @@ -5286,7 +5290,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER && (!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { inv.type |= nFetchFlags; - if (nodestate->fProvidesHeaderAndIDs) + if (nodestate->fProvidesHeaderAndIDs && !(nLocalServices & NODE_WITNESS)) vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); else vToFetch.push_back(inv); @@ -5905,7 +5909,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { - if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) { + if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(nLocalServices & NODE_WITNESS)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); From 9757b57c25c67de611b8f5d0a19f409c2e8753a6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 31 Mar 2016 14:43:39 +0200 Subject: [PATCH 0851/1223] --- [SEGWIT] begin: wallet --- From 605e8473a7ddca13b24a4020c7bd630aa5d374e2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 31 Mar 2016 14:54:58 +0200 Subject: [PATCH 0852/1223] BIP143: Signing logic --- src/bitcoin-tx.cpp | 28 ++- src/rpc/rawtransaction.cpp | 17 +- src/script/ismine.cpp | 19 ++- src/script/sign.cpp | 303 ++++++++++++++++++++++----------- src/script/sign.h | 34 +++- src/script/standard.cpp | 41 +++++ src/script/standard.h | 3 + src/test/DoS_tests.cpp | 4 +- src/test/multisig_tests.cpp | 2 +- src/test/script_P2SH_tests.cpp | 11 +- src/test/script_tests.cpp | 100 +++++------ src/wallet/wallet.cpp | 10 +- 12 files changed, 394 insertions(+), 178 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index e77aa6c72..f457ea2bc 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -363,6 +363,18 @@ vector ParseHexUO(map& o, string strKey) return ParseHexUV(o[strKey], strKey); } +static CAmount AmountFromValue(const UniValue& value) +{ + if (!value.isNum() && !value.isStr()) + throw runtime_error("Amount is not a number or string"); + CAmount amount; + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) + throw runtime_error("Invalid amount"); + if (!MoneyRange(amount)) + throw runtime_error("Amount out of range"); + return amount; +} + static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) { int nHashType = SIGHASH_ALL; @@ -434,7 +446,10 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) if ((unsigned int)nOut >= coins->vout.size()) coins->vout.resize(nOut+1); coins->vout[nOut].scriptPubKey = scriptPubKey; - coins->vout[nOut].nValue = 0; // we don't know the actual output value + coins->vout[nOut].nValue = 0; + if (prevOut.exists("amount")) { + coins->vout[nOut].nValue = AmountFromValue(prevOut["amount"]); + } } // if redeemScript given and private keys given, @@ -464,15 +479,16 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; const CAmount& amount = coins->vout[txin.prevout.n].nValue; - txin.scriptSig.clear(); + SignatureData sigdata; // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mergedTx.vout.size())) - SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata); // ... and merge in other signatures: - BOOST_FOREACH(const CTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, amount, txin.scriptSig, txv.vin[i].scriptSig); - } + BOOST_FOREACH(const CTransaction& txv, txVariants) + sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i)); + UpdateTransaction(mergedTx, i, sigdata); + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount))) fComplete = false; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b36179943..56ba805b1 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -592,7 +592,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n, (numeric, required) The output number\n" " \"scriptPubKey\": \"hex\", (string, required) script key\n" - " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n" + " \"redeemScript\": \"hex\", (string, required for P2SH) redeem script\n" + " \"amount\": value (numeric, required) The amount spent\n" " }\n" " ,...\n" " ]\n" @@ -735,7 +736,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) if ((unsigned int)nOut >= coins->vout.size()) coins->vout.resize(nOut+1); coins->vout[nOut].scriptPubKey = scriptPubKey; - coins->vout[nOut].nValue = 0; // we don't know the actual output value + coins->vout[nOut].nValue = 0; + if (prevOut.exists("amount")) { + coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount")); + } } // if redeemScript given and not using the local wallet (private keys @@ -801,15 +805,18 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; const CAmount& amount = coins->vout[txin.prevout.n].nValue; - txin.scriptSig.clear(); + SignatureData sigdata; // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mergedTx.vout.size())) - SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata); // ... and merge in other signatures: BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, amount, txin.scriptSig, txv.vin[i].scriptSig); + sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i)); } + + UpdateTransaction(mergedTx, i, sigdata); + ScriptError serror = SCRIPT_ERR_OK; if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx.wit.vtxinwit.size() > i ? &mergedTx.wit.vtxinwit[i].scriptWitness : NULL, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) { TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 535c56b57..0bf180341 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -57,6 +57,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) return ISMINE_SPENDABLE; break; case TX_PUBKEYHASH: + case TX_WITNESS_V0_KEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; @@ -72,6 +73,20 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) } break; } + case TX_WITNESS_V0_SCRIPTHASH: + { + uint160 hash; + CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin()); + CScriptID scriptID = CScriptID(hash); + CScript subscript; + if (keystore.GetCScript(scriptID, subscript)) { + isminetype ret = IsMine(keystore, subscript); + if (ret == ISMINE_SPENDABLE) + return ret; + } + break; + } + case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the @@ -88,8 +103,8 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) if (keystore.HaveWatchOnly(scriptPubKey)) { // TODO: This could be optimized some by doing some work after the above solver - CScript scriptSig; - return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, scriptSig) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; + SignatureData sigs; + return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; } return ISMINE_NO; } diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 83bb0cfa2..87f38d9c7 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -20,29 +20,29 @@ typedef std::vector valtype; TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {} -bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode) const +bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const { CKey key; if (!keystore->GetKey(address, key)) return false; - uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, SIGVERSION_BASE); + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); return true; } -static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) +static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector& ret, SigVersion sigversion) { vector vchSig; - if (!creator.CreateSig(vchSig, address, scriptCode)) + if (!creator.CreateSig(vchSig, address, scriptCode, sigversion)) return false; - scriptSigRet << vchSig; + ret.push_back(vchSig); return true; } -static bool SignN(const vector& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) +static bool SignN(const vector& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector& ret, SigVersion sigversion) { int nSigned = 0; int nRequired = multisigdata.front()[0]; @@ -50,7 +50,7 @@ static bool SignN(const vector& multisigdata, const BaseSignatureCreato { const valtype& pubkey = multisigdata[i]; CKeyID keyID = CPubKey(pubkey).GetID(); - if (Sign1(keyID, creator, scriptCode, scriptSigRet)) + if (Sign1(keyID, creator, scriptCode, ret, sigversion)) ++nSigned; } return nSigned==nRequired; @@ -63,9 +63,11 @@ static bool SignN(const vector& multisigdata, const BaseSignatureCreato * Returns false if scriptPubKey could not be completely satisfied. */ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey, - CScript& scriptSigRet, txnouttype& whichTypeRet) + std::vector& ret, txnouttype& whichTypeRet, SigVersion sigversion) { - scriptSigRet.clear(); + CScript scriptRet; + uint160 h160; + ret.clear(); vector vSolutions; if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) @@ -79,62 +81,142 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); - return Sign1(keyID, creator, scriptPubKey, scriptSigRet); + return Sign1(keyID, creator, scriptPubKey, ret, sigversion); case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); - if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet)) + if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion)) return false; else { CPubKey vch; creator.KeyStore().GetPubKey(keyID, vch); - scriptSigRet << ToByteVector(vch); + ret.push_back(ToByteVector(vch)); } return true; case TX_SCRIPTHASH: - return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet); - - case TX_MULTISIG: - scriptSigRet << OP_0; // workaround CHECKMULTISIG bug - return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet)); - } - return false; -} - -bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig) -{ - txnouttype whichType; - if (!SignStep(creator, fromPubKey, scriptSig, whichType)) + if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) { + ret.push_back(std::vector(scriptRet.begin(), scriptRet.end())); + return true; + } return false; - if (whichType == TX_SCRIPTHASH) - { - // Solver returns the subscript that need to be evaluated; - // the final scriptSig is the signatures from that - // and then the serialized subscript: - CScript subscript = scriptSig; + case TX_MULTISIG: + ret.push_back(valtype()); // workaround CHECKMULTISIG bug + return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion)); - txnouttype subType; - bool fSolved = - SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH; - // Append serialized subscript whether or not it is completely signed: - scriptSig << valtype(subscript.begin(), subscript.end()); - if (!fSolved) return false; + case TX_WITNESS_V0_KEYHASH: + ret.push_back(vSolutions[0]); + return true; + + case TX_WITNESS_V0_SCRIPTHASH: + CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin()); + if (creator.KeyStore().GetCScript(h160, scriptRet)) { + ret.push_back(std::vector(scriptRet.begin(), scriptRet.end())); + return true; + } + return false; + + default: + return false; } - - // Test solution - return VerifyScript(scriptSig, fromPubKey, NULL, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); } -bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType) +static CScript PushAll(const vector& values) +{ + CScript result; + BOOST_FOREACH(const valtype& v, values) { + if (v.size() == 0) { + result << OP_0; + } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { + result << CScript::EncodeOP_N(v[0]); + } else { + result << v; + } + } + return result; +} + +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata) +{ + CScript script = fromPubKey; + bool solved = true; + std::vector result; + txnouttype whichType; + solved = SignStep(creator, script, result, whichType, SIGVERSION_BASE); + bool P2SH = false; + CScript subscript; + sigdata.scriptWitness.stack.clear(); + + if (solved && whichType == TX_SCRIPTHASH) + { + // Solver returns the subscript that needs to be evaluated; + // the final scriptSig is the signatures from that + // and then the serialized subscript: + script = subscript = CScript(result[0].begin(), result[0].end()); + solved = solved && SignStep(creator, script, result, whichType, SIGVERSION_BASE) && whichType != TX_SCRIPTHASH; + P2SH = true; + } + + if (solved && whichType == TX_WITNESS_V0_KEYHASH) + { + CScript witnessscript; + witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG; + txnouttype subType; + solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0); + sigdata.scriptWitness.stack = result; + result.clear(); + } + else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH) + { + CScript witnessscript(result[0].begin(), result[0].end()); + txnouttype subType; + solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH; + result.push_back(std::vector(witnessscript.begin(), witnessscript.end())); + sigdata.scriptWitness.stack = result; + result.clear(); + } + + if (P2SH) { + result.push_back(std::vector(subscript.begin(), subscript.end())); + } + sigdata.scriptSig = PushAll(result); + + // Test solution + return solved && VerifyScript(sigdata.scriptSig, fromPubKey, &sigdata.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); +} + +SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn) +{ + SignatureData data; + assert(tx.vin.size() > nIn); + data.scriptSig = tx.vin[nIn].scriptSig; + if (tx.wit.vtxinwit.size() > nIn) { + data.scriptWitness = tx.wit.vtxinwit[nIn].scriptWitness; + } + return data; +} + +void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data) +{ + assert(tx.vin.size() > nIn); + tx.vin[nIn].scriptSig = data.scriptSig; + if (!data.scriptWitness.IsNull() || tx.wit.vtxinwit.size() > nIn) { + tx.wit.vtxinwit.resize(tx.vin.size()); + tx.wit.vtxinwit[nIn].scriptWitness = data.scriptWitness; + } +} + +bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType) { assert(nIn < txTo.vin.size()); - CTxIn& txin = txTo.vin[nIn]; CTransaction txToConst(txTo); - TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType); + TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType); - return ProduceSignature(creator, fromPubKey, txin.scriptSig); + SignatureData sigdata; + bool ret = ProduceSignature(creator, fromPubKey, sigdata); + UpdateTransaction(txTo, nIn, sigdata); + return ret; } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -144,20 +226,12 @@ bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutab assert(txin.prevout.n < txFrom.vout.size()); const CTxOut& txout = txFrom.vout[txin.prevout.n]; - return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); + return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType); } -static CScript PushAll(const vector& values) -{ - CScript result; - BOOST_FOREACH(const valtype& v, values) - result << v; - return result; -} - -static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, +static vector CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const vector& vSolutions, - const vector& sigs1, const vector& sigs2) + const vector& sigs1, const vector& sigs2, SigVersion sigversion) { // Combine all the signatures we've got: set allsigs; @@ -185,7 +259,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (checker.CheckSig(sig, pubkey, scriptPubKey, SIGVERSION_BASE)) + if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion)) { sigs[pubkey] = sig; break; @@ -194,87 +268,126 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC } // Now build a merged CScript: unsigned int nSigsHave = 0; - CScript result; result << OP_0; // pop-one-too-many workaround + std::vector result; result.push_back(valtype()); // pop-one-too-many workaround for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) { if (sigs.count(vSolutions[i+1])) { - result << sigs[vSolutions[i+1]]; + result.push_back(sigs[vSolutions[i+1]]); ++nSigsHave; } } // Fill any missing with OP_0: for (unsigned int i = nSigsHave; i < nSigsRequired; i++) - result << OP_0; + result.push_back(valtype()); return result; } -static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, +namespace +{ +struct Stacks +{ + std::vector script; + std::vector witness; + + Stacks() {} + explicit Stacks(const std::vector& scriptSigStack_) : script(scriptSigStack_), witness() {} + explicit Stacks(const SignatureData& data) : witness(data.scriptWitness.stack) { + EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); + } + + SignatureData Output() const { + SignatureData result; + result.scriptSig = PushAll(script); + result.scriptWitness.stack = witness; + return result; + } +}; +} + +static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const txnouttype txType, const vector& vSolutions, - vector& sigs1, vector& sigs2) + Stacks sigs1, Stacks sigs2, SigVersion sigversion) { switch (txType) { case TX_NONSTANDARD: case TX_NULL_DATA: // Don't know anything about this, assume bigger one is correct: - if (sigs1.size() >= sigs2.size()) - return PushAll(sigs1); - return PushAll(sigs2); + if (sigs1.script.size() >= sigs2.script.size()) + return sigs1; + return sigs2; case TX_PUBKEY: case TX_PUBKEYHASH: // Signatures are bigger than placeholders or empty scripts: - if (sigs1.empty() || sigs1[0].empty()) - return PushAll(sigs2); - return PushAll(sigs1); + if (sigs1.script.empty() || sigs1.script[0].empty()) + return sigs2; + return sigs1; + case TX_WITNESS_V0_KEYHASH: + // Signatures are bigger than placeholders or empty scripts: + if (sigs1.witness.empty() || sigs1.witness[0].empty()) + return sigs2; + return sigs1; case TX_SCRIPTHASH: - if (sigs1.empty() || sigs1.back().empty()) - return PushAll(sigs2); - else if (sigs2.empty() || sigs2.back().empty()) - return PushAll(sigs1); + if (sigs1.script.empty() || sigs1.script.back().empty()) + return sigs2; + else if (sigs2.script.empty() || sigs2.script.back().empty()) + return sigs1; else { // Recur to combine: - valtype spk = sigs1.back(); + valtype spk = sigs1.script.back(); CScript pubKey2(spk.begin(), spk.end()); txnouttype txType2; vector > vSolutions2; Solver(pubKey2, txType2, vSolutions2); - sigs1.pop_back(); - sigs2.pop_back(); - CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2); - result << spk; + sigs1.script.pop_back(); + sigs2.script.pop_back(); + Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, sigversion); + result.script.push_back(spk); return result; } case TX_MULTISIG: - return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2); + return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, sigversion)); + case TX_WITNESS_V0_SCRIPTHASH: + if (sigs1.witness.empty() || sigs1.witness.back().empty()) + return sigs2; + else if (sigs2.witness.empty() || sigs2.witness.back().empty()) + return sigs1; + else + { + // Recur to combine: + CScript pubKey2(sigs1.witness.back().begin(), sigs1.witness.back().end()); + txnouttype txType2; + vector vSolutions2; + Solver(pubKey2, txType2, vSolutions2); + sigs1.witness.pop_back(); + sigs1.script = sigs1.witness; + sigs1.witness.clear(); + sigs2.witness.pop_back(); + sigs2.script = sigs2.witness; + sigs2.witness.clear(); + Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, SIGVERSION_WITNESS_V0); + result.witness = result.script; + result.script.clear(); + result.witness.push_back(valtype(pubKey2.begin(), pubKey2.end())); + return result; + } + default: + return Stacks(); } - - return CScript(); } -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CAmount& amount, - const CScript& scriptSig1, const CScript& scriptSig2) -{ - TransactionSignatureChecker checker(&txTo, nIn, amount); - return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2); -} - -CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, - const CScript& scriptSig1, const CScript& scriptSig2) +SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, + const SignatureData& scriptSig1, const SignatureData& scriptSig2) { txnouttype txType; vector > vSolutions; Solver(scriptPubKey, txType, vSolutions); - vector stack1; - EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); - vector stack2; - EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); - - return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); + return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1), Stacks(scriptSig2), SIGVERSION_BASE).Output(); } namespace { @@ -297,7 +410,7 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const return dummyChecker; } -bool DummySignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const +bool DummySignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const { // Create a dummy signature that is a valid DER-encoding vchSig.assign(72, '\000'); diff --git a/src/script/sign.h b/src/script/sign.h index f54511f7a..6404b4523 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -27,7 +27,7 @@ public: virtual const BaseSignatureChecker& Checker() const =0; /** Create a singular (non-script) signature. */ - virtual bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const =0; + virtual bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0; }; /** A signature creator for transactions. */ @@ -41,7 +41,14 @@ class TransactionSignatureCreator : public BaseSignatureCreator { public: TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL); const BaseSignatureChecker& Checker() const { return checker; } - bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; + bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const; +}; + +class MutableTransactionSignatureCreator : public TransactionSignatureCreator { + CTransaction tx; + +public: + MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {} }; /** A signature creator that just produces 72-byte empty signatyres. */ @@ -49,20 +56,29 @@ class DummySignatureCreator : public BaseSignatureCreator { public: DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} const BaseSignatureChecker& Checker() const; - bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; + bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const; +}; + +struct SignatureData { + CScript scriptSig; + CScriptWitness scriptWitness; + + SignatureData() {} + explicit SignatureData(const CScript& script) : scriptSig(script) {} }; /** Produce a script signature using a generic signature creator. */ -bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, CScript& scriptSig); +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata); /** Produce a script signature for a transaction. */ -bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); -bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType); +bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType); /** Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 placeholders. */ -CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const CScript& scriptSig1, const CScript& scriptSig2); +SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const SignatureData& scriptSig1, const SignatureData& scriptSig2); -/** Combine two script signatures on transactions. */ -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CAmount& amount, const CScript& scriptSig1, const CScript& scriptSig2); +/** Extract signature data from a transaction, and insert it. */ +SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn); +void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data); #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 67b6af327..bb178f49f 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -31,6 +31,8 @@ const char* GetTxnOutputType(txnouttype t) case TX_SCRIPTHASH: return "scripthash"; case TX_MULTISIG: return "multisig"; case TX_NULL_DATA: return "nulldata"; + case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash"; + case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash"; } return NULL; } @@ -66,6 +68,22 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector witnessprogram; + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + if (witnessversion == 0 && witnessprogram.size() == 20) { + typeRet = TX_WITNESS_V0_KEYHASH; + vSolutionsRet.push_back(witnessprogram); + return true; + } + if (witnessversion == 0 && witnessprogram.size() == 32) { + typeRet = TX_WITNESS_V0_SCRIPTHASH; + vSolutionsRet.push_back(witnessprogram); + return true; + } + return false; + } + // Provably prunable, data-carrying output // // So long as script passes the IsUnspendable() test and all but the first @@ -282,3 +300,26 @@ CScript GetScriptForMultisig(int nRequired, const std::vector& keys) script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; return script; } + +CScript GetScriptForWitness(const CScript& redeemscript) +{ + CScript ret; + + txnouttype typ; + std::vector > vSolutions; + if (Solver(redeemscript, typ, vSolutions)) { + if (typ == TX_PUBKEY) { + unsigned char h160[20]; + CHash160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160); + ret << OP_0 << std::vector(&h160[0], &h160[20]); + return ret; + } else if (typ == TX_PUBKEYHASH) { + ret << OP_0 << vSolutions[0]; + return ret; + } + } + uint256 hash; + CSHA256().Write(&redeemscript[0], redeemscript.size()).Finalize(hash.begin()); + ret << OP_0 << ToByteVector(hash); + return ret; +} diff --git a/src/script/standard.h b/src/script/standard.h index f348da8e1..72aaea0b7 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -51,6 +51,8 @@ enum txnouttype TX_SCRIPTHASH, TX_MULTISIG, TX_NULL_DATA, + TX_WITNESS_V0_SCRIPTHASH, + TX_WITNESS_V0_KEYHASH, }; class CNoDestination { @@ -77,5 +79,6 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std:: CScript GetScriptForDestination(const CTxDestination& dest); CScript GetScriptForRawPubKey(const CPubKey& pubkey); CScript GetScriptForMultisig(int nRequired, const std::vector& keys); +CScript GetScriptForWitness(const CScript& redeemscript); #endif // BITCOIN_SCRIPT_STANDARD_H diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 93f7ae09d..a8c5f95ac 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - SignSignature(keystore, txPrev, tx, 0); + SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL); AddOrphanTx(tx, i); } @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vin[j].prevout.n = j; tx.vin[j].prevout.hash = txPrev.GetHash(); } - SignSignature(keystore, txPrev, tx, 0); + SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL); // Re-use same signature for other inputs // (they don't have to be valid for this test) for (unsigned int j = 1; j < tx.vin.size(); j++) diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 876b90e4b..581b0cee1 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -303,7 +303,7 @@ BOOST_AUTO_TEST_CASE(multisig_Sign) for (int i = 0; i < 3; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 62deb736a..5224b57ca 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_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 "core_io.h" #include "key.h" #include "keystore.h" #include "main.h" @@ -102,7 +103,7 @@ BOOST_AUTO_TEST_CASE(sign) } for (int i = 0; i < 8; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i)); } // All of the above should be OK, and the txTos have valid signatures // Check to make sure signature verification fails if we use the wrong ScriptSig: @@ -197,7 +198,7 @@ BOOST_AUTO_TEST_CASE(set) } for (int i = 0; i < 4; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i)); BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i)); } } @@ -326,9 +327,9 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txTo.vin[i].prevout.n = i; txTo.vin[i].prevout.hash = txFrom.GetHash(); } - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0)); - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1)); - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1, SIGHASH_ALL)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2, SIGHASH_ALL)); // SignSignature doesn't know how to sign these. We're // not testing validating signatures, so just create // dummy signatures that DO include the correct P2SH scripts: diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 7fd7614e2..1d69194c3 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -152,16 +152,16 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, co flags |= SCRIPT_VERIFY_WITNESS; } ScriptError err; - CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); + CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey); + CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit); CMutableTransaction tx2 = tx; - static const CAmount amountZero = 0; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0, amountZero), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << tx2; if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), amountZero, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); } else { BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message); @@ -896,7 +896,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) BOOST_AUTO_TEST_CASE(script_combineSigs) { // Test the CombineSignatures function - CAmount amount; + CAmount amount = 0; CBasicKeyStore keystore; vector keys; vector pubkeys; @@ -914,50 +914,50 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; CScript& scriptSig = txTo.vin[0].scriptSig; - CScript empty; - CScript combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, empty); - BOOST_CHECK(combined.empty()); + SignatureData empty; + SignatureData combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, empty); + BOOST_CHECK(combined.scriptSig.empty()); // Single signature case: - SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); // changes scriptSig + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSig); CScript scriptSigCopy = scriptSig; // Signing again will give a different, valid signature: - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig); // P2SH, single-signature case: CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG; keystore.AddCScript(pkSingle); scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSig); scriptSigCopy = scriptSig; - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig); // dummy scriptSigCopy with placeholder, should always choose non-placeholder: - scriptSigCopy = CScript() << OP_0 << vector(pkSingle.begin(), pkSingle.end()); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, scriptSigCopy); - BOOST_CHECK(combined == scriptSig); + scriptSigCopy = CScript() << OP_0 << std::vector(pkSingle.begin(), pkSingle.end()); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy)); + BOOST_CHECK(combined.scriptSig == scriptSig); // Hardest case: Multisig 2-of-3 scriptPubKey = GetScriptForMultisig(2, pubkeys); keystore.AddCScript(scriptPubKey); - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig)); + BOOST_CHECK(combined.scriptSig == scriptSig); // A couple of partially-signed versions: vector sig1; @@ -985,22 +985,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript complete13 = CScript() << OP_0 << sig1 << sig3; CScript complete23 = CScript() << OP_0 << sig2 << sig3; - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1a, partial1b); - BOOST_CHECK(combined == partial1a); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1a, partial2a); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial2a, partial1a); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial1b, partial2b); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial1b); - BOOST_CHECK(combined == complete13); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial2a, partial3a); - BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial2b); - BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, amount, partial3b, partial3a); - BOOST_CHECK(combined == partial3c); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial1b)); + BOOST_CHECK(combined.scriptSig == partial1a); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial2a)); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial1a)); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1b), SignatureData(partial2b)); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial1b)); + BOOST_CHECK(combined.scriptSig == complete13); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial3a)); + BOOST_CHECK(combined.scriptSig == complete23); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial2b)); + BOOST_CHECK(combined.scriptSig == complete23); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial3a)); + BOOST_CHECK(combined.scriptSig == partial3c); } BOOST_AUTO_TEST_CASE(script_standard_push) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index babde1a02..b36c6f025 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2334,17 +2334,20 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt { bool signSuccess; const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey; - CScript& scriptSigRes = txNew.vin[nIn].scriptSig; + SignatureData sigdata; if (sign) - signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes); + signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata); else - signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes); + signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata); if (!signSuccess) { strFailReason = _("Signing transaction failed"); return false; + } else { + UpdateTransaction(txNew, nIn, sigdata); } + nIn++; } @@ -2354,6 +2357,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt if (!sign) { BOOST_FOREACH (CTxIn& vin, txNew.vin) vin.scriptSig = CScript(); + txNew.wit.SetNull(); } // Embed the constructed transaction data in wtxNew. From f4691ab3a9d4f3321afa024984c03fe6e10bfdbc Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 30 Dec 2015 01:13:08 +0100 Subject: [PATCH 0853/1223] [RPC] Add wallet support for witness transactions (using P2SH) Includes support for pushkeyhash wit v0 by Alex Morcos. --- src/rpc/misc.cpp | 38 +++++++++++++++++++ src/wallet/rpcwallet.cpp | 80 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 09f518578..f2a29416e 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -312,6 +312,43 @@ UniValue createmultisig(const UniValue& params, bool fHelp) return result; } +UniValue createwitnessaddress(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + { + string msg = "createwitnessaddress \"script\"\n" + "\nCreates a witness address for a particular script.\n" + "It returns a json object with the address and witness script.\n" + + "\nArguments:\n" + "1. \"script\" (string, required) A hex encoded script\n" + + "\nResult:\n" + "{\n" + " \"address\":\"multisigaddress\", (string) The value of the new address (P2SH of witness script).\n" + " \"witnessScript\":\"script\" (string) The string value of the hex-encoded witness script.\n" + "}\n" + ; + throw runtime_error(msg); + } + + if (!IsHex(params[0].get_str())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Script must be hex-encoded"); + } + + std::vector code = ParseHex(params[0].get_str()); + CScript script(code.begin(), code.end()); + CScript witscript = GetScriptForWitness(script); + CScriptID witscriptid(witscript); + CBitcoinAddress address(witscriptid); + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("address", address.ToString())); + result.push_back(Pair("witnessScript", HexStr(witscript.begin(), witscript.end()))); + + return result; +} + UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) @@ -445,6 +482,7 @@ static const CRPCCommand commands[] = { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, + { "util", "createwitnessaddress", &createwitnessaddress, true }, { "util", "verifymessage", &verifymessage, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3666c37ac..afbb9a111 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1011,6 +1011,85 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) return CBitcoinAddress(innerID).ToString(); } +class Witnessifier : public boost::static_visitor +{ +public: + CScriptID result; + + bool operator()(const CNoDestination &dest) const { return false; } + + bool operator()(const CKeyID &keyID) { + CPubKey pubkey; + if (pwalletMain && pwalletMain->GetPubKey(keyID, pubkey)) { + CScript basescript; + basescript << ToByteVector(pubkey) << OP_CHECKSIG; + CScript witscript = GetScriptForWitness(basescript); + pwalletMain->AddCScript(witscript); + result = CScriptID(witscript); + return true; + } + return false; + } + + bool operator()(const CScriptID &scriptID) { + CScript subscript; + if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { + int witnessversion; + std::vector witprog; + if (subscript.IsWitnessProgram(witnessversion, witprog)) { + result = scriptID; + return true; + } + CScript witscript = GetScriptForWitness(subscript); + pwalletMain->AddCScript(witscript); + result = CScriptID(witscript); + return true; + } + return false; + } +}; + +UniValue addwitnessaddress(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 1) + { + string msg = "addwitnessaddress \"address\"\n" + "\nAdd a witness address for a script (with pubkey or redeemscript known).\n" + "It returns the witness script.\n" + + "\nArguments:\n" + "1. \"address\" (string, required) An address known to the wallet\n" + + "\nResult:\n" + "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n" + "}\n" + ; + throw runtime_error(msg); + } + + { + LOCK(cs_main); + if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { + throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network"); + } + } + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); + + Witnessifier w; + CTxDestination dest = address.Get(); + bool ret = boost::apply_visitor(w, dest); + if (!ret) { + throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet"); + } + + return CBitcoinAddress(w.result).ToString(); +} struct tallyitem { @@ -2491,6 +2570,7 @@ static const CRPCCommand commands[] = { "hidden", "resendwallettransactions", &resendwallettransactions, true }, { "wallet", "abandontransaction", &abandontransaction, false }, { "wallet", "addmultisigaddress", &addmultisigaddress, true }, + { "wallet", "addwitnessaddress", &addwitnessaddress, true }, { "wallet", "backupwallet", &backupwallet, true }, { "wallet", "dumpprivkey", &dumpprivkey, true }, { "wallet", "dumpwallet", &dumpwallet, true }, From 745eb678ef5d52c74edcd9c322ebd1f3232a9310 Mon Sep 17 00:00:00 2001 From: NicolasDorier Date: Sun, 10 Apr 2016 15:59:23 +0900 Subject: [PATCH 0854/1223] [RPC] signrawtransaction can sign P2WSH --- src/bitcoin-tx.cpp | 2 +- src/rpc/rawtransaction.cpp | 4 ++-- src/script/script.cpp | 8 ++++++++ src/script/script.h | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index f457ea2bc..8e8ac4745 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -454,7 +454,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) // if redeemScript given and private keys given, // add redeemScript to the tempKeystore so it can be signed: - if (fGivenKeys && scriptPubKey.IsPayToScriptHash() && + if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash()) && prevOut.exists("redeemScript")) { UniValue v = prevOut["redeemScript"]; vector rsData(ParseHexUV(v, "redeemScript")); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 56ba805b1..3270cd384 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -592,7 +592,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n, (numeric, required) The output number\n" " \"scriptPubKey\": \"hex\", (string, required) script key\n" - " \"redeemScript\": \"hex\", (string, required for P2SH) redeem script\n" + " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n" " \"amount\": value (numeric, required) The amount spent\n" " }\n" " ,...\n" @@ -744,7 +744,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: - if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { + if (fGivenKeys && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) { RPCTypeCheckObj(prevOut, { {"txid", UniValueType(UniValue::VSTR)}, diff --git a/src/script/script.cpp b/src/script/script.cpp index 73f5a61bf..da551c23e 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -210,6 +210,14 @@ bool CScript::IsPayToScriptHash() const (*this)[22] == OP_EQUAL); } +bool CScript::IsPayToWitnessScriptHash() const +{ + // Extra-fast test for pay-to-witness-script-hash CScripts: + return (this->size() == 34 && + (*this)[0] == OP_0 && + (*this)[1] == 0x20); +} + // A witness program is any valid CScript that consists of a 1-byte push opcode // followed by a data push between 2 and 40 bytes. bool CScript::IsWitnessProgram(int& version, std::vector& program) const diff --git a/src/script/script.h b/src/script/script.h index b9b5be901..71af3754b 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -621,6 +621,7 @@ public: unsigned int GetSigOpCount(const CScript& scriptSig) const; bool IsPayToScriptHash() const; + bool IsPayToWitnessScriptHash() const; bool IsWitnessProgram(int& version, std::vector& program) const; /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ From 978e2004ad659ad216d820dbd79e212e276405f4 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 31 Mar 2016 14:43:46 +0200 Subject: [PATCH 0855/1223] --- [SEGWIT] begin: tests --- From 0aa92074516c37a10d4150d68918e20db91289a5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 20 Nov 2015 16:22:47 +0100 Subject: [PATCH 0856/1223] [qa] Witness version 0 signing unit tests --- src/test/transaction_tests.cpp | 276 +++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 9fb23d8ed..76f998ac2 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -14,7 +14,9 @@ #include "main.h" // For CheckTransaction #include "policy/policy.h" #include "script/script.h" +#include "script/sign.h" #include "script/script_error.h" +#include "script/standard.h" #include "utilstrencodings.h" #include @@ -25,11 +27,14 @@ #include #include #include +#include #include using namespace std; +typedef vector valtype; + // In script_tests.cpp extern UniValue read_json(const std::string& jsondata); @@ -315,6 +320,277 @@ BOOST_AUTO_TEST_CASE(test_Get) BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); } +void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, CTransaction& output, CMutableTransaction& input, bool success = true) +{ + CMutableTransaction outputm; + outputm.nVersion = 1; + outputm.vin.resize(1); + outputm.vin[0].prevout.SetNull(); + outputm.vin[0].scriptSig = CScript(); + outputm.wit.vtxinwit.resize(1); + outputm.vout.resize(1); + outputm.vout[0].nValue = 1; + outputm.vout[0].scriptPubKey = outscript; + CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); + ssout << outputm; + ssout >> output; + assert(output.vin.size() == 1); + assert(output.vin[0] == outputm.vin[0]); + assert(output.vout.size() == 1); + assert(output.vout[0] == outputm.vout[0]); + assert(output.wit.vtxinwit.size() == 0); + + CMutableTransaction inputm; + inputm.nVersion = 1; + inputm.vin.resize(1); + inputm.vin[0].prevout.hash = output.GetHash(); + inputm.vin[0].prevout.n = 0; + inputm.wit.vtxinwit.resize(1); + inputm.vout.resize(1); + inputm.vout[0].nValue = 1; + inputm.vout[0].scriptPubKey = CScript(); + bool ret = SignSignature(keystore, output, inputm, 0, SIGHASH_ALL); + assert(ret == success); + CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION); + ssin << inputm; + ssin >> input; + assert(input.vin.size() == 1); + assert(input.vin[0] == inputm.vin[0]); + assert(input.vout.size() == 1); + assert(input.vout[0] == inputm.vout[0]); + if (inputm.wit.IsNull()) { + assert(input.wit.IsNull()); + } else { + assert(!input.wit.IsNull()); + assert(input.wit.vtxinwit.size() == 1); + assert(input.wit.vtxinwit[0].scriptWitness.stack == inputm.wit.vtxinwit[0].scriptWitness.stack); + } +} + +void CheckWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags, bool success) +{ + ScriptError error; + CTransaction inputi(input); + bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); + assert(ret == success); +} + +static CScript PushAll(const vector& values) +{ + CScript result; + BOOST_FOREACH(const valtype& v, values) { + if (v.size() == 0) { + result << OP_0; + } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { + result << CScript::EncodeOP_N(v[0]); + } else { + result << v; + } + } + return result; +} + +void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) +{ + vector stack; + EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); + assert(stack.size() > 0); + stack.back() = std::vector(redeemScript.begin(), redeemScript.end()); + script = PushAll(stack); +} + +BOOST_AUTO_TEST_CASE(test_witness) +{ + CBasicKeyStore keystore, keystore2; + CKey key1, key2, key3, key1L, key2L; + CPubKey pubkey1, pubkey2, pubkey3, pubkey1L, pubkey2L; + key1.MakeNewKey(true); + key2.MakeNewKey(true); + key3.MakeNewKey(true); + key1L.MakeNewKey(false); + key2L.MakeNewKey(false); + pubkey1 = key1.GetPubKey(); + pubkey2 = key2.GetPubKey(); + pubkey3 = key3.GetPubKey(); + pubkey1L = key1L.GetPubKey(); + pubkey2L = key2L.GetPubKey(); + keystore.AddKeyPubKey(key1, pubkey1); + keystore.AddKeyPubKey(key2, pubkey2); + keystore.AddKeyPubKey(key1L, pubkey1L); + keystore.AddKeyPubKey(key2L, pubkey2L); + CScript scriptPubkey1, scriptPubkey2, scriptPubkey1L, scriptPubkey2L, scriptMulti; + scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG; + scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG; + scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG; + scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG; + std::vector oneandthree; + oneandthree.push_back(pubkey1); + oneandthree.push_back(pubkey3); + scriptMulti = GetScriptForMultisig(2, oneandthree); + keystore.AddCScript(scriptPubkey1); + keystore.AddCScript(scriptPubkey2); + keystore.AddCScript(scriptPubkey1L); + keystore.AddCScript(scriptPubkey2L); + keystore.AddCScript(scriptMulti); + keystore.AddCScript(GetScriptForWitness(scriptPubkey1)); + keystore.AddCScript(GetScriptForWitness(scriptPubkey2)); + keystore.AddCScript(GetScriptForWitness(scriptPubkey1L)); + keystore.AddCScript(GetScriptForWitness(scriptPubkey2L)); + keystore.AddCScript(GetScriptForWitness(scriptMulti)); + keystore2.AddCScript(scriptMulti); + keystore2.AddCScript(GetScriptForWitness(scriptMulti)); + keystore2.AddKeyPubKey(key3, pubkey3); + + CTransaction output1, output2; + CMutableTransaction input1, input2; + SignatureData sigdata; + + // Normal pay-to-compressed-pubkey. + CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1); + CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // P2SH pay-to-compressed-pubkey. + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey1)), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey2)), output2, input2); + ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // Witness pay-to-compressed-pubkey (v0). + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2), output2, input2); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // P2SH witness pay-to-compressed-pubkey (v0). + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1))), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2))), output2, input2); + ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1)); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // Normal pay-to-uncompressed-pubkey. + CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1); + CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // P2SH pay-to-uncompressed-pubkey. + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey1L)), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey2L)), output2, input2); + ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // Witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // P2SH witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2); + ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1L)); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); + CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + + // Normal 2-of-2 multisig + CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false); + CheckWithFlag(output1, input1, 0, false); + CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false); + CheckWithFlag(output2, input2, 0, false); + BOOST_CHECK(output1 == output2); + UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0))); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + + // P2SH 2-of-2 multisig + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptMulti)), output1, input1, false); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false); + CreateCreditAndSpend(keystore2, GetScriptForDestination(CScriptID(scriptMulti)), output2, input2, false); + CheckWithFlag(output2, input2, 0, true); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false); + BOOST_CHECK(output1 == output2); + UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0))); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + + // Witness 2-of-2 multisig + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptMulti), output1, input1, false); + CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); + CreateCreditAndSpend(keystore2, GetScriptForWitness(scriptMulti), output2, input2, false); + CheckWithFlag(output2, input2, 0, true); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); + BOOST_CHECK(output1 == output2); + UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0))); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); + + // P2SH witness 2-of-2 multisig + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptMulti))), output1, input1, false); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); + CreateCreditAndSpend(keystore2, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptMulti))), output2, input2, false); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); + BOOST_CHECK(output1 == output2); + UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0))); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true); + CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); +} + BOOST_AUTO_TEST_CASE(test_IsStandard) { LOCK(cs_main); From 00f46cbcd9d33fadfeb391e764bda3ac220be3ea Mon Sep 17 00:00:00 2001 From: NicolasDorier Date: Sun, 3 Apr 2016 23:48:50 +0900 Subject: [PATCH 0857/1223] [qa] Add transaction tests for segwit Including BIP143 P2WSH examples by jl2012. --- src/test/data/tx_invalid.json | 63 ++++++++++++ src/test/data/tx_valid.json | 170 +++++++++++++++++++++++++++++++++ src/test/transaction_tests.cpp | 40 ++++++-- 3 files changed, 263 insertions(+), 10 deletions(-) diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 4719f2b38..05502a83f 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -251,5 +251,68 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +["Unknown witness program version (with DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["Unknown length for witness program v0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x15 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3fff", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay (same index output value changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e80300000000000001516c070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay (input sequence changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff000100000000000000000000000000000000000000000000000000000000000001000000000100000000010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay (third output value changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151540b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with a push of 521 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd0902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], + +["Witness with unknown version which push false on the stack should be invalid (even without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0000", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101010100000000", "P2SH,WITNESS"], + +["Witness program should leave clean stack"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x2f04a3aa051f1f60d695f6c44c0c3d383973dfd446ace8962664a76bb10e31a8", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01000000000000000001510102515100000000", "P2SH,WITNESS"], + +["Witness v0 with a push of 2 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x02 0x0001", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101040002000100000000", "P2SH,WITNESS"], + +["Unknown witness version with non empty scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0001", 2000]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000151ffffffff010000000000000000015100000000", "P2SH,WITNESS"], + +["Non witness Single|AnyoneCanPay hash input's position (permutation)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]], +"010000000200010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff0001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff02e9030000000000000151e803000000000000015100000000", "P2SH,WITNESS"], + +["P2WSH with a redeem representing a witness scriptPubKey should fail"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x34b6c399093e06cf9f0f7f660a1abcfe78fcf7b576f43993208edd9518a0ae9b", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0001045102010100000000", "P2SH,WITNESS"], + +["33 bytes push should be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 717ad1954..c9fe4e313 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -317,5 +317,175 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], "0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +["Valid P2WPKH (Private key of segwit tests is L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2WSH"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3db", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WPKH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xfe9c7dacc9fcfbf7e3b7d5ad06aa2b28c5a7b7e3 EQUAL", 1000]], +"01000000000101000100000000000000000000000000000000000000000000000000000000000000000000171600144c9c3dfac4207d5d8cb89df5722cb3d712385e3fffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WSH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x2135ab4f0981830311e35600eebc7376dce3a914 EQUAL", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000023220020ff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff05540b0000000000000151d0070000000000000151840300000000000001513c0f00000000000001512c010000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71000000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff0484030000000000000151d0070000000000000151540b0000000000000151c800000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff04b60300000000000001519e070000000000000151860b00000000000001009600000000000000015100000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature, only sequences changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"01000000000103000100000000000000000000000000000000000000000000000000000000000000000000000200000000010000000000000000000000000000000000000000000000000000000000000100000000ffffffff000100000000000000000000000000000000000000000000000000000000000002000000000200000003e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Unknown witness program version (without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with a push of 520 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd08020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], + +["Transaction mixing all SigHash, segwit and normal inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1002], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1003], +["0000000000000000000000000000000000000000000000000000000000000100", 4, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1004], +["0000000000000000000000000000000000000000000000000000000000000100", 5, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1005], +["0000000000000000000000000000000000000000000000000000000000000100", 6, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1006], +["0000000000000000000000000000000000000000000000000000000000000100", 7, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1007], +["0000000000000000000000000000000000000000000000000000000000000100", 8, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1008], +["0000000000000000000000000000000000000000000000000000000000000100", 9, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1009], +["0000000000000000000000000000000000000000000000000000000000000100", 10, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1010], +["0000000000000000000000000000000000000000000000000000000000000100", 11, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1011]], +"0100000000010c00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff0001000000000000000000000000000000000000000000000000000000000000020000006a473044022026c2e65b33fcd03b2a3b0f25030f0244bd23cc45ae4dec0f48ae62255b1998a00220463aa3982b718d593a6b9e0044513fd67a5009c2fdccc59992cffc2b167889f4012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000030000006a4730440220008bd8382911218dcb4c9f2e75bf5c5c3635f2f2df49b36994fde85b0be21a1a02205a539ef10fb4c778b522c1be852352ea06c67ab74200977c722b0bc68972575a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000040000006b483045022100d9436c32ff065127d71e1a20e319e4fe0a103ba0272743dbd8580be4659ab5d302203fd62571ee1fe790b182d078ecfd092a509eac112bea558d122974ef9cc012c7012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000050000006a47304402200e2c149b114ec546015c13b2b464bbcb0cdc5872e6775787527af6cbc4830b6c02207e9396c6979fb15a9a2b96ca08a633866eaf20dc0ff3c03e512c1d5a1654f148012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000060000006b483045022100b20e70d897dc15420bccb5e0d3e208d27bdd676af109abbd3f88dbdb7721e6d6022005836e663173fbdfe069f54cde3c2decd3d0ea84378092a5d9d85ec8642e8a41012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff00010000000000000000000000000000000000000000000000000000000000000700000000ffffffff00010000000000000000000000000000000000000000000000000000000000000800000000ffffffff00010000000000000000000000000000000000000000000000000000000000000900000000ffffffff00010000000000000000000000000000000000000000000000000000000000000a00000000ffffffff00010000000000000000000000000000000000000000000000000000000000000b0000006a47304402206639c6e05e3b9d2675a7f3876286bdf7584fe2bbd15e0ce52dd4e02c0092cdc60220757d60b0a61fc95ada79d23746744c72bac1545a75ff6c2c7cdb6ae04e7e9592012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0ce8030000000000000151e9030000000000000151ea030000000000000151eb030000000000000151ec030000000000000151ed030000000000000151ee030000000000000151ef030000000000000151f0030000000000000151f1030000000000000151f2030000000000000151f30300000000000001510248304502210082219a54f61bf126bfc3fa068c6e33831222d1d7138c6faa9d33ca87fd4202d6022063f9902519624254d7c2c8ea7ba2d66ae975e4e229ae38043973ec707d5d4a83012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022017fb58502475848c1b09f162cb1688d0920ff7f142bed0ef904da2ccc88b168f02201798afa61850c65e77889cbcd648a5703b487895517c88f85cdd18b021ee246a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000000247304402202830b7926e488da75782c81a54cd281720890d1af064629ebf2e31bf9f5435f30220089afaa8b455bbeb7d9b9c3fe1ed37d07685ade8455c76472cda424d93e4074a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022026326fcdae9207b596c2b05921dbac11d81040c4d40378513670f19d9f4af893022034ecd7a282c0163b89aaa62c22ec202cef4736c58cd251649bad0d8139bcbf55012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71024730440220214978daeb2f38cd426ee6e2f44131a33d6b191af1c216247f1dd7d74c16d84a02205fdc05529b0bc0c430b4d5987264d9d075351c4f4484c16e91662e90a72aab24012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402204a6e9f199dc9672cf2ff8094aaa784363be1eb62b679f7ff2df361124f1dca3302205eeb11f70fab5355c9c8ad1a0700ea355d315e334822fa182227e9815308ee8f012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Unknown version witness program with empty witness"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS"], + +["Witness SIGHASH_SINGLE with output out of bound"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x20 0x4d6c2a32c87821d68fc016fca70797abdb80df6cd84651d40a9300c6bad79e62", 1000]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff01d00700000000000001510003483045022100e078de4e96a0e05dcdc0a414124dd8475782b5f3f0ed3f607919e9a5eeeb22bf02201de309b3a3109adb3de8074b3610d4cf454c49b61247a2779a0bcbf31c889333032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc711976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac00000000", "P2SH,WITNESS"], + +["1 byte push should not be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x01 0x01", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["41 bytes push should not be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x29 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff0000000000000000", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["The witness version must use OP_1 to OP_16 only"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x01 0x10 0x02 0x0001", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["The witness program push must be canonical"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x4c02 0x0001", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["Witness Single|AnyoneCanPay does not hash input's position"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff02e8030000000000000151e90300000000000001510247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Witness Single|AnyoneCanPay does not hash input's position (permutation)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff02e9030000000000000151e80300000000000001510248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Non witness Single|AnyoneCanPay hash input's position"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]], +"01000000020001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff00010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff02e8030000000000000151e903000000000000015100000000", "P2SH,WITNESS"], + +["BIP143 examples: details and private keys are available in BIP143"], +["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."], +[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000], +["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]], +"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS"], + +["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"], +[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215], +["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]], +"01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], + +["BIP143 example: Same as the previous example with input-output paris swapped"], +[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215], +["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]], +"0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], + +["BIP143 example: P2SH-P2WSH 6-of-6 multisig signed with 6 different SIGHASH types"], +[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]], +"0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 76f998ac2..fd4f174b4 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -50,7 +50,9 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) - (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY); + (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) + (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) + (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); unsigned int ParseScriptFlags(string strFlags) { @@ -113,6 +115,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) } map mapprevOutScriptPubKeys; + map mapprevOutValues; UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { @@ -123,13 +126,17 @@ BOOST_AUTO_TEST_CASE(tx_valid) break; } UniValue vinput = input.get_array(); - if (vinput.size() != 3) + if (vinput.size() < 3 || vinput.size() > 4) { fValid = false; break; } - - mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int()); + mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str()); + if (vinput.size() >= 4) + { + mapprevOutValues[outpoint] = vinput[3].get_int64(); + } } if (!fValid) { @@ -155,9 +162,13 @@ BOOST_AUTO_TEST_CASE(tx_valid) } CAmount amount = 0; + if (mapprevOutValues.count(tx.vin[i].prevout)) { + amount = mapprevOutValues[tx.vin[i].prevout]; + } unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); + const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - NULL, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err), + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -189,6 +200,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } map mapprevOutScriptPubKeys; + map mapprevOutValues; UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { @@ -199,13 +211,17 @@ BOOST_AUTO_TEST_CASE(tx_invalid) break; } UniValue vinput = input.get_array(); - if (vinput.size() != 3) + if (vinput.size() < 3 || vinput.size() > 4) { fValid = false; break; } - - mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int()); + mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str()); + if (vinput.size() >= 4) + { + mapprevOutValues[outpoint] = vinput[3].get_int64(); + } } if (!fValid) { @@ -231,8 +247,12 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); CAmount amount = 0; + if (mapprevOutValues.count(tx.vin[i].prevout)) { + amount = mapprevOutValues[tx.vin[i].prevout]; + } + const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - NULL, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err); + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -422,7 +442,7 @@ BOOST_AUTO_TEST_CASE(test_witness) scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG; scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG; scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG; - scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG; + scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG; std::vector oneandthree; oneandthree.push_back(pubkey1); oneandthree.push_back(pubkey3); From 06d3805c1a44aae39ad95538063e6882249b7633 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 4 Apr 2016 16:01:27 +0200 Subject: [PATCH 0858/1223] [qa] Add segwit support to script_tests Contains fix by Johnson Lau. --- src/test/data/script_tests.json | 8 ++++- src/test/script_tests.cpp | 53 ++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 0bdac182e..f6ee7ade4 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1,5 +1,5 @@ [ -["Format is: [scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], +["Format is: [[wit...]?, scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], @@ -1253,6 +1253,12 @@ ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], +["Some basic segwit checks"], +[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "EVAL_FALSE", "Invalid witness script"], +[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "WITNESS_PROGRAM_MISMATCH", "Witness script hash mismatch"], +[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Invalid witness script without WITNESS"], +[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Witness script hash mismatch without WITNESS"], + ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 1d69194c3..88f1562b1 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -88,7 +88,14 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"}, {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"}, {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"}, - {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"} + {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}, + {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"}, + {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"}, + {SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY, "WITNESS_PROGRAM_WITNESS_EMPTY"}, + {SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH, "WITNESS_PROGRAM_MISMATCH"}, + {SCRIPT_ERR_WITNESS_MALLEATED, "WITNESS_MALLEATED"}, + {SCRIPT_ERR_WITNESS_MALLEATED_P2SH, "WITNESS_MALLEATED_P2SH"}, + {SCRIPT_ERR_WITNESS_UNEXPECTED, "WITNESS_UNEXPECTED"}, }; const char *FormatScriptError(ScriptError_t err) @@ -127,13 +134,15 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) return txCredit; } -CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit) +CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CMutableTransaction& txCredit) { CMutableTransaction txSpend; txSpend.nVersion = 1; txSpend.nLockTime = 0; txSpend.vin.resize(1); txSpend.vout.resize(1); + txSpend.wit.vtxinwit.resize(1); + txSpend.wit.vtxinwit[0].scriptWitness = scriptWitness; txSpend.vin[0].prevout.hash = txCredit.GetHash(); txSpend.vin[0].prevout.n = 0; txSpend.vin[0].scriptSig = scriptSig; @@ -144,7 +153,7 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu return txSpend; } -void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, const std::string& message, int scriptError) +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, const std::string& message, int scriptError) { bool expect = (scriptError == SCRIPT_ERR_OK); if (flags & SCRIPT_VERIFY_CLEANSTACK) { @@ -153,12 +162,12 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, co } ScriptError err; CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey); - CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit); + CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) - CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_WITNESS); stream << tx2; if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); @@ -280,7 +289,7 @@ public: } else { creditTx = BuildCreditingTransaction(redeemScript); } - spendTx = BuildSpendingTransaction(CScript(), creditTx); + spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), creditTx); } TestBuilder& ScriptError(ScriptError_t err) @@ -363,7 +372,7 @@ public: { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, comment, scriptError); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, CScriptWitness(), flags, comment, scriptError); *this = copy; return *this; } @@ -706,7 +715,7 @@ BOOST_AUTO_TEST_CASE(script_json_test) { // Read tests from test/data/script_tests.json // Format is an array of arrays - // Inner arrays are [ "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] + // Inner arrays are [ ["wit"...]?, "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] // ... where scriptSig and scriptPubKey are stringified // scripts. UniValue tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests))); @@ -714,21 +723,29 @@ BOOST_AUTO_TEST_CASE(script_json_test) for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); - if (test.size() < 4) // Allow size > 3; extra stuff ignored (useful for comments) + CScriptWitness witness; + unsigned int pos = 0; + if (test.size() > 0 && test[pos].isArray()) { + for (unsigned int i = 0; i < test[pos].size(); i++) { + witness.stack.push_back(ParseHex(test[pos][i].get_str())); + } + pos++; + } + if (test.size() < 4 + pos) // Allow size > 3; extra stuff ignored (useful for comments) { if (test.size() != 1) { BOOST_ERROR("Bad test: " << strTest); } continue; } - string scriptSigString = test[0].get_str(); + string scriptSigString = test[pos++].get_str(); CScript scriptSig = ParseScript(scriptSigString); - string scriptPubKeyString = test[1].get_str(); + string scriptPubKeyString = test[pos++].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); - unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - int scriptError = ParseScriptError(test[3].get_str()); + unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str()); + int scriptError = ParseScriptError(test[pos++].get_str()); - DoTest(scriptPubKey, scriptSig, scriptflags, strTest, scriptError); + DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError); } } @@ -806,7 +823,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG; CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12); - CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); + CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err)); @@ -837,7 +854,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG; CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23); - CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23); + CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom23); std::vector keys; keys.push_back(key1); keys.push_back(key2); @@ -910,7 +927,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) } CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID())); - CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); + CMutableTransaction txTo = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom); CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; CScript& scriptSig = txTo.vin[0].scriptSig; From 66cca79130a204277e61088b7844b405dc3868a5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 5 Apr 2016 13:37:24 +0200 Subject: [PATCH 0859/1223] [qa] Autogeneration support for witness in script_tests --- src/test/data/script_tests.json | 132 ++++++++++++++++++++++++++++++++ src/test/script_tests.cpp | 107 +++++++++++++++++++++++--- 2 files changed, 228 insertions(+), 11 deletions(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index f6ee7ade4..4311b0923 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1834,6 +1834,138 @@ "OK", "P2SH with CLEANSTACK" ], +[ + [ + "3044022039105b995a5f448639a997a5c90fda06f50b49df30c3bdb6663217bf79323db002206fecd54269dec569fcc517178880eb58bb40f381a282bb75766ff3637d5f4b4301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac" + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "OK", + "Basic P2WSH" +], +[ + [ + "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "OK", + "Basic P2WPKH" +], +[ + [ + "3044022061fc1a144e221ec77a58a4281936eb6a1b715b9349e446e74d106ec26c8633ba022008064a0d112e8ad514440fcdfaa1006e48305d6844f50a65873fb4b2cf9c035f01", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac" + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS", + "OK", + "Basic P2SH(P2WSH)" +], +[ + [ + "3044022014e69768e174972f21d32d93002ca6fc26133cb9e819ceef7efb970798bde7b4022078b86849dbbec692ec9355aa2a763fce7ea11bf72fdd8ea5ea8083de6f8a77fe01", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS", + "OK", + "Basic P2SH(P2WPKH)" +], +[ + [ + "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + ], + "", + "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WSH with the wrong key" +], +[ + [ + "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + ], + "", + "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WPKH with the wrong key" +], +[ + [ + "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + ], + "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WSH) with the wrong key" +], +[ + [ + "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + ], + "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WPKH) with the wrong key" +], +[ + [ + "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + ], + "", + "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "P2SH", + "OK", + "Basic P2WSH with the wrong key but no WITNESS" +], +[ + [ + "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + ], + "", + "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "P2SH", + "OK", + "Basic P2WPKH with the wrong key but no WITNESS" +], +[ + [ + "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + ], + "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", + "P2SH", + "OK", + "Basic P2SH(P2WSH) with the wrong key but no WITNESS" +], +[ + [ + "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + ], + "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", + "P2SH", + "OK", + "Basic P2SH(P2WPKH) with the wrong key but no WITNESS" +], ["CHECKSEQUENCEVERIFY tests"], ["", "NOP3", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 88f1562b1..ab373edc9 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -167,7 +167,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); #if defined(HAVE_CONSENSUS_LIB) - CDataStream stream(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_WITNESS); + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << tx2; if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message); @@ -253,11 +253,22 @@ struct KeyData } }; +enum WitnessMode { + WITNESS_NONE, + WITNESS_PKH, + WITNESS_SH +}; class TestBuilder { private: - CScript scriptPubKey; + //! Actually executed script + CScript script; + //! The P2SH redeemscript + CScript redeemscript; + //! The Witness embedded script + CScript witscript; + CScriptWitness scriptWitness; CTransaction creditTx; CMutableTransaction spendTx; bool havePush; @@ -282,13 +293,25 @@ private: } public: - TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK) + TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WITNESS_NONE) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK) { - if (P2SH) { - creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL); - } else { - creditTx = BuildCreditingTransaction(redeemScript); + CScript scriptPubKey = script; + if (wm == WITNESS_PKH) { + uint160 hash; + CHash160().Write(&script[1], script.size() - 1).Finalize(hash.begin()); + script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG; + scriptPubKey = CScript() << OP_0 << ToByteVector(hash); + } else if (wm == WITNESS_SH) { + witscript = scriptPubKey; + uint256 hash; + CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin()); + scriptPubKey = CScript() << OP_0 << ToByteVector(hash); } + if (P2SH) { + redeemscript = scriptPubKey; + scriptPubKey = CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemscript)) << OP_EQUAL; + } + creditTx = BuildCreditingTransaction(scriptPubKey); spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), creditTx); } @@ -318,9 +341,9 @@ public: return *this; } - TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) + TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE) { - uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType, 0, SIGVERSION_BASE); + uint256 hash = SignatureHash(script, spendTx, 0, nHashType, 0, sigversion); std::vector vchSig, r, s; uint32_t iter = 0; do { @@ -336,6 +359,11 @@ public: return *this; } + TestBuilder& PushWitSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_WITNESS_V0) + { + return PushSig(key, nHashType, lenR, lenS, sigversion).AsWit(); + } + TestBuilder& Push(const CPubKey& pubkey) { DoPush(std::vector(pubkey.begin(), pubkey.end())); @@ -344,10 +372,16 @@ public: TestBuilder& PushRedeem() { - DoPush(std::vector(scriptPubKey.begin(), scriptPubKey.end())); + DoPush(std::vector(redeemscript.begin(), redeemscript.end())); return *this; } + TestBuilder& PushWitRedeem() + { + DoPush(std::vector(witscript.begin(), witscript.end())); + return AsWit(); + } + TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout) { assert(havePush); @@ -372,15 +406,30 @@ public: { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, CScriptWitness(), flags, comment, scriptError); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError); *this = copy; return *this; } + TestBuilder& AsWit() + { + assert(havePush); + scriptWitness.stack.push_back(push); + havePush = false; + return *this; + } + UniValue GetJSON() { DoPush(); UniValue array(UniValue::VARR); + if (!scriptWitness.stack.empty()) { + UniValue wit(UniValue::VARR); + for (unsigned i = 0; i < scriptWitness.stack.size(); i++) { + wit.push_back(HexStr(scriptWitness.stack[i])); + } + array.push_back(wit); + } array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); @@ -679,6 +728,42 @@ BOOST_AUTO_TEST_CASE(script_build) "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true ).PushSig(keys.key0).PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), + "Basic P2WPKH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "Basic P2SH(P2WSH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), + "Basic P2SH(P2WPKH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "Basic P2WSH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), + "Basic P2WPKH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "Basic P2SH(P2WSH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_SH + ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), + "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem()); std::set tests_set; From 4f7ff00497803fddc5a0fb5340502a73e395134d Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 1 Jan 2016 23:18:34 -0600 Subject: [PATCH 0860/1223] [qa] Add rpc test for segwit Amended by Pieter Wuille to use multisig 1-of-1 for P2WSH tests, and BIP9 based switchover logic. Fixes and py3 conversion by Marco Falke. --- contrib/devtools/check-doc.py | 2 +- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/segwit.py | 209 ++++++++++++++++++++++++++++++++++ src/main.cpp | 15 ++- src/wallet/rpcwallet.cpp | 2 +- 5 files changed, 222 insertions(+), 7 deletions(-) create mode 100755 qa/rpc-tests/segwit.py diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 8c73cf1e8..06c9551ce 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_RO REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags']) def main(): used = check_output(CMD_GREP_ARGS, shell=True) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 6c0ed4510..8fa20945e 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -136,6 +136,7 @@ testScripts = [ 'invalidtxrequest.py', 'abandonconflict.py', 'p2p-versionbits-warning.py', + 'segwit.py', 'importprunedfunds.py', 'signmessages.py', ] diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py new file mode 100755 index 000000000..d4c9a8afe --- /dev/null +++ b/qa/rpc-tests/segwit.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test the SegWit changeover logic +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.mininode import sha256, ripemd160 +import os +import shutil + +NODE_0 = 0 +NODE_1 = 1 +NODE_2 = 2 +WIT_V0 = 0 +WIT_V1 = 1 + +def witness_script(version, pubkey): + if (version == 0): + pubkeyhash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pubkey)))) + pkscript = "0014" + pubkeyhash + elif (version == 1): + # 1-of-1 multisig + scripthash = bytes_to_hex_str(sha256(hex_str_to_bytes("5121" + pubkey + "51ae"))) + pkscript = "0020" + scripthash + else: + assert("Wrong version" == "0 or 1") + return pkscript + +def addlength(script): + scriptlen = format(len(script)//2, 'x') + assert(len(scriptlen) == 2) + return scriptlen + script + +def create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount): + pkscript = witness_script(version, pubkey); + if (encode_p2sh): + p2sh_hash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pkscript)))) + pkscript = "a914"+p2sh_hash+"87" + inputs = [] + outputs = {} + inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]} ) + DUMMY_P2SH = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP" + outputs[DUMMY_P2SH] = amount + tx_to_witness = node.createrawtransaction(inputs,outputs) + #replace dummy output with our own + tx_to_witness = tx_to_witness[0:110] + addlength(pkscript) + tx_to_witness[-8:] + return tx_to_witness + +def send_to_witness(version, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""): + tx_to_witness = create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount) + if (sign): + signed = node.signrawtransaction(tx_to_witness) + assert("errors" not in signed or len(["errors"]) == 0) + return node.sendrawtransaction(signed["hex"]) + else: + if (insert_redeem_script): + tx_to_witness = tx_to_witness[0:82] + addlength(insert_redeem_script) + tx_to_witness[84:] + + return node.sendrawtransaction(tx_to_witness) + +def getutxo(txid): + utxo = {} + utxo["vout"] = 0 + utxo["txid"] = txid + return utxo + +class SegWitTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) + self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) + connect_nodes(self.nodes[1], 0) + connect_nodes(self.nodes[2], 1) + connect_nodes(self.nodes[0], 2) + self.is_network_split = False + self.sync_all() + + def success_mine(self, node, txid, sign, redeem_script=""): + send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script) + block = node.generate(1) + assert_equal(len(node.getblock(block[0])["tx"]), 2) + sync_blocks(self.nodes) + + def skip_mine(self, node, txid, sign, redeem_script=""): + send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script) + block = node.generate(1) + assert_equal(len(node.getblock(block[0])["tx"]), 1) + sync_blocks(self.nodes) + + def fail_accept(self, node, txid, sign, redeem_script=""): + try: + send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script) + except JSONRPCException as exp: + assert(exp.error["code"] == -26) + else: + raise AssertionError("Tx should not have been accepted") + + def fail_mine(self, node, txid, sign, redeem_script=""): + send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script) + try: + node.generate(1) + except JSONRPCException as exp: + assert(exp.error["code"] == -1) + else: + raise AssertionError("Created valid block when TestBlockValidity should have failed") + sync_blocks(self.nodes) + + def run_test(self): + self.nodes[0].generate(160) #block 160 + + self.pubkey = [] + p2sh_ids = [] # p2sh_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE embedded in p2sh + wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness + for i in range(3): + newaddress = self.nodes[i].getnewaddress() + self.pubkey.append(self.nodes[i].validateaddress(newaddress)["pubkey"]) + multiaddress = self.nodes[i].addmultisigaddress(1, [self.pubkey[-1]]) + self.nodes[i].addwitnessaddress(newaddress) + self.nodes[i].addwitnessaddress(multiaddress) + p2sh_ids.append([]) + wit_ids.append([]) + for v in range(2): + p2sh_ids[i].append([]) + wit_ids[i].append([]) + + for i in range(5): + for n in range(3): + for v in range(2): + wit_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], False, Decimal("49.999"))) + p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], True, Decimal("49.999"))) + + self.nodes[0].generate(1) #block 161 + sync_blocks(self.nodes) + + # Make sure all nodes recognize the transactions as theirs + assert_equal(self.nodes[0].getbalance(), 60*50 - 60*50 + 20*Decimal("49.999") + 50) + assert_equal(self.nodes[1].getbalance(), 20*Decimal("49.999")) + assert_equal(self.nodes[2].getbalance(), 20*Decimal("49.999")) + + self.nodes[0].generate(262) #block 423 + sync_blocks(self.nodes) + + print("Verify default node can't accept any witness format txs before fork") + # unsigned, no scriptsig + self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], False) + self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], False) + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False) + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False) + # unsigned with redeem script + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False, addlength(witness_script(0, self.pubkey[0]))) + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False, addlength(witness_script(1, self.pubkey[0]))) + # signed + self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) + self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True) + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True) + self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True) + + print("Verify witness txs are skipped for mining before the fork") + self.skip_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][0], True) #block 424 + self.skip_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][0], True) #block 425 + self.skip_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][0], True) #block 426 + self.skip_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][0], True) #block 427 + + # TODO: An old node would see these txs without witnesses and be able to mine them + + print("Verify unsigned bare witness txs in versionbits-setting blocks are valid before the fork") + self.success_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][1], False) #block 428 + self.success_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][1], False) #block 429 + + print("Verify unsigned p2sh witness txs without a redeem script are invalid") + self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False) + self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False) + + print("Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork") + self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False, addlength(witness_script(0, self.pubkey[2]))) #block 430 + self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False, addlength(witness_script(1, self.pubkey[2]))) #block 431 + + print("Verify previous witness txs skipped for mining can now be mined") + assert_equal(len(self.nodes[2].getrawmempool()), 4) + block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3) + sync_blocks(self.nodes) + assert_equal(len(self.nodes[2].getrawmempool()), 0) + assert_equal(len(self.nodes[2].getblock(block[0])["tx"]), 5) + + print("Verify witness txs without witness data are invalid after the fork") + self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False) + self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][2], False) + self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False, addlength(witness_script(0, self.pubkey[2]))) + self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False, addlength(witness_script(1, self.pubkey[2]))) + + print("Verify default node can now use witness txs") + self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) #block 432 + self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True) #block 433 + self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True) #block 434 + self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True) #block 435 + +if __name__ == '__main__': + SegWitTest().main() diff --git a/src/main.cpp b/src/main.cpp index d1ba70313..6cdd55e39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1145,8 +1145,8 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(0, false, REJECT_NONSTANDARD, "premature-version2-tx"); } - // Don't accept witness transactions before the final threshold passes - if (!tx.wit.IsNull() && !IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { + // Reject transactions with witness before segregated witness activates (override with -prematurewitness) + if (!GetBoolArg("-prematurewitness",false) && !tx.wit.IsNull() && !IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } @@ -1487,14 +1487,19 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } } + unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; + if (!Params().RequireStandard()) { + scriptVerifyFlags = GetArg("-promiscuousmempoolflags", scriptVerifyFlags); + } + // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) { + if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true)) { // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. - if (CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true) && - !CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS & ~SCRIPT_VERIFY_CLEANSTACK, true)) { + if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true) && + !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true)) { // Only the witness is wrong, so the transaction itself may be fine. state.SetCorruptionPossible(); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index afbb9a111..8538f880f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1072,7 +1072,7 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) { LOCK(cs_main); - if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { + if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) { throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network"); } } From 330b0f31ee5719d94f9e52dfc83c5d82168241f9 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 8 Apr 2016 21:02:24 -0400 Subject: [PATCH 0861/1223] [qa] p2p segwit tests mininode now supports witness transactions/blocks, blocktools has a helper for adding witness commitments to blocks, and script has a function to calculate hashes for signature under sigversion 1, used by segwit. Py3 conversion by Marco Falke Test to make sure upgraded nodes don't ask for non-wit blocks by Gregory Sanders. --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/p2p-segwit.py | 1646 +++++++++++++++++++++ qa/rpc-tests/test_framework/blocktools.py | 25 +- qa/rpc-tests/test_framework/mininode.py | 212 ++- qa/rpc-tests/test_framework/script.py | 52 +- src/test/data/script_tests.json | 84 ++ src/test/script_tests.cpp | 47 +- 7 files changed, 2037 insertions(+), 30 deletions(-) create mode 100755 qa/rpc-tests/p2p-segwit.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 8fa20945e..37979a933 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -136,6 +136,7 @@ testScripts = [ 'invalidtxrequest.py', 'abandonconflict.py', 'p2p-versionbits-warning.py', + 'p2p-segwit.py', 'segwit.py', 'importprunedfunds.py', 'signmessages.py', diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py new file mode 100755 index 000000000..cf78954f2 --- /dev/null +++ b/qa/rpc-tests/p2p-segwit.py @@ -0,0 +1,1646 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment, WITNESS_COMMITMENT_HEADER +from test_framework.key import CECKey, CPubKey +import time +import random +from binascii import hexlify + +# The versionbit bit used to signal activation of SegWit +VB_WITNESS_BIT = 1 +VB_PERIOD = 144 +VB_ACTIVATION_THRESHOLD = 108 +VB_TOP_BITS = 0x20000000 + +MAX_SIGOP_COST = 80000 + +''' +SegWit p2p test. +''' + +# Calculate the virtual size of a witness block: +# (base + witness/4) +def get_virtual_size(witness_block): + base_size = len(witness_block.serialize()) + total_size = len(witness_block.serialize(with_witness=True)) + # the "+3" is so we round up + vsize = int((3*base_size + total_size + 3)/4) + return vsize + +# Note: we can reduce code by using SingleNodeConnCB (in master, not 0.12) +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong(0) + self.sleep_time = 0.05 + self.getdataset = set() + + def add_connection(self, conn): + self.connection = conn + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_inv(self, conn, message): + self.last_inv = message + + def on_block(self, conn, message): + self.last_block = message.block + self.last_block.calc_sha256() + + def on_getdata(self, conn, message): + for inv in message.inv: + self.getdataset.add(inv.hash) + self.last_getdata = message + + def on_pong(self, conn, message): + self.last_pong = message + + def on_reject(self, conn, message): + self.last_reject = message + #print message + + # Syncing helpers + def sync(self, test_function, timeout=60): + while timeout > 0: + with mininode_lock: + if test_function(): + return + time.sleep(self.sleep_time) + timeout -= self.sleep_time + raise AssertionError("Sync failed to complete") + + def sync_with_ping(self, timeout=60): + self.send_message(msg_ping(nonce=self.ping_counter)) + test_function = lambda: self.last_pong.nonce == self.ping_counter + self.sync(test_function, timeout) + self.ping_counter += 1 + return + + def wait_for_block(self, blockhash, timeout=60): + test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash + self.sync(test_function, timeout) + return + + def wait_for_getdata(self, timeout=60): + test_function = lambda: self.last_getdata != None + self.sync(test_function, timeout) + + def wait_for_inv(self, expected_inv, timeout=60): + test_function = lambda: self.last_inv != expected_inv + self.sync(test_function, timeout) + + def announce_tx_and_wait_for_getdata(self, tx, timeout=60): + with mininode_lock: + self.last_getdata = None + self.send_message(msg_inv(inv=[CInv(1, tx.sha256)])) + self.wait_for_getdata(timeout) + return + + def announce_block_and_wait_for_getdata(self, block, use_header, timeout=60): + with mininode_lock: + self.last_getdata = None + if use_header: + msg = msg_headers() + msg.headers = [ CBlockHeader(block) ] + self.send_message(msg) + else: + self.send_message(msg_inv(inv=[CInv(2, block.sha256)])) + self.wait_for_getdata() + return + + def announce_block(self, block, use_header): + with mininode_lock: + self.last_getdata = None + if use_header: + msg = msg_headers() + msg.headers = [ CBlockHeader(block) ] + self.send_message(msg) + else: + self.send_message(msg_inv(inv=[CInv(2, block.sha256)])) + + def request_block(self, blockhash, inv_type, timeout=60): + with mininode_lock: + self.last_block = None + self.send_message(msg_getdata(inv=[CInv(inv_type, blockhash)])) + self.wait_for_block(blockhash, timeout) + return self.last_block + + def test_transaction_acceptance(self, tx, with_witness, accepted): + tx_message = msg_tx(tx) + if with_witness: + tx_message = msg_witness_tx(tx) + self.send_message(tx_message) + self.sync_with_ping() + assert_equal(tx.hash in self.connection.rpc.getrawmempool(), accepted) + + # Test whether a witness block had the correct effect on the tip + def test_witness_block(self, block, accepted, with_witness=True): + if with_witness: + self.send_message(msg_witness_block(block)) + else: + self.send_message(msg_block(block)) + self.sync_with_ping() + assert_equal(self.connection.rpc.getbestblockhash() == block.hash, accepted) + + +# Used to keep track of anyone-can-spend outputs that we can use in the tests +class UTXO(object): + def __init__(self, sha256, n, nValue): + self.sha256 = sha256 + self.n = n + self.nValue = nValue + + +class SegWitTest(BitcoinTestFramework): + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 3) + + def add_options(self, parser): + parser.add_option("--oldbinary", dest="oldbinary", + default=None, + help="pre-segwit bitcoind binary for upgrade testing") + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1"])) + # Start a node for testing IsStandard rules. + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1", "-acceptnonstdtxn=0"])) + connect_nodes(self.nodes[0], 1) + + # If an old bitcoind is given, do the upgrade-after-activation test. + self.test_upgrade = False + if (self.options.oldbinary != None): + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1"], binary=self.options.oldbinary)) + connect_nodes(self.nodes[0], 2) + self.test_upgrade = True + + ''' Helpers ''' + # Build a block on top of node0's tip. + def build_next_block(self, nVersion=4): + tip = self.nodes[0].getbestblockhash() + height = self.nodes[0].getblockcount() + 1 + block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1 + block = create_block(int(tip, 16), create_coinbase(height), block_time) + block.nVersion = nVersion + block.rehash() + return block + + # Adds list of transactions to block, adds witness commitment, then solves. + def update_witness_block_with_transactions(self, block, tx_list, nonce=0): + block.vtx.extend(tx_list) + add_witness_commitment(block, nonce) + block.solve() + return + + ''' Individual tests ''' + def test_witness_services(self): + print("\tVerifying NODE_WITNESS service bit") + assert((self.test_node.connection.nServices & NODE_WITNESS) != 0) + + + # See if sending a regular transaction works, and create a utxo + # to use in later tests. + def test_non_witness_transaction(self): + # Mine a block with an anyone-can-spend coinbase, + # let it mature, then try to spend it. + print("\tTesting non-witness transaction") + block = self.build_next_block(nVersion=1) + block.solve() + self.test_node.send_message(msg_block(block)) + self.test_node.sync_with_ping() # make sure the block was processed + txid = block.vtx[0].sha256 + + self.nodes[0].generate(99) # let the block mature + + # Create a transaction that spends the coinbase + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(txid, 0), b"")) + tx.vout.append(CTxOut(49*100000000, CScript([OP_TRUE]))) + tx.calc_sha256() + + # Check that serializing it with or without witness is the same + # This is a sanity check of our testing framework. + assert_equal(msg_tx(tx).serialize(), msg_witness_tx(tx).serialize()) + + self.test_node.send_message(msg_witness_tx(tx)) + self.test_node.sync_with_ping() # make sure the tx was processed + assert(tx.hash in self.nodes[0].getrawmempool()) + # Save this transaction for later + self.utxo.append(UTXO(tx.sha256, 0, 49*100000000)) + self.nodes[0].generate(1) + + + # Verify that blocks with witnesses are rejected before activation. + def test_unnecessary_witness_before_segwit_activation(self): + print("\tTesting behavior of unnecessary witnesses") + # For now, rely on earlier tests to have created at least one utxo for + # us to use + assert(len(self.utxo) > 0) + assert(get_bip9_status(self.nodes[0], 'segwit')['status'] != 'active') + + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, CScript([OP_TRUE]))) + tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)])] + + # Verify the hash with witness differs from the txid + # (otherwise our testing framework must be broken!) + tx.rehash() + assert(tx.sha256 != tx.calc_sha256(with_witness=True)) + + # Construct a segwit-signaling block that includes the transaction. + block = self.build_next_block(nVersion=(VB_TOP_BITS|(1 << VB_WITNESS_BIT))) + self.update_witness_block_with_transactions(block, [tx]) + # Sending witness data before activation is not allowed (anti-spam + # rule). + self.test_node.test_witness_block(block, accepted=False) + # TODO: fix synchronization so we can test reject reason + # Right now, bitcoind delays sending reject messages for blocks + # until the future, making synchronization here difficult. + #assert_equal(self.test_node.last_reject.reason, "unexpected-witness") + + # But it should not be permanently marked bad... + # Resend without witness information. + self.test_node.send_message(msg_block(block)) + self.test_node.sync_with_ping() + assert_equal(self.nodes[0].getbestblockhash(), block.hash) + + # Update our utxo list; we spent the first entry. + self.utxo.pop(0) + self.utxo.append(UTXO(tx.sha256, 0, tx.vout[0].nValue)) + + + # Mine enough blocks for segwit's vb state to be 'started'. + def advance_to_segwit_started(self): + height = self.nodes[0].getblockcount() + # Will need to rewrite the tests here if we are past the first period + assert(height < VB_PERIOD - 1) + # Genesis block is 'defined'. + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'defined') + # Advance to end of period, status should now be 'started' + self.nodes[0].generate(VB_PERIOD-height-1) + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') + + # Mine enough blocks to lock in segwit, but don't activate. + # TODO: we could verify that lockin only happens at the right threshold of + # signalling blocks, rather than just at the right period boundary. + def advance_to_segwit_lockin(self): + height = self.nodes[0].getblockcount() + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') + # Advance to end of period, and verify lock-in happens at the end + self.nodes[0].generate(VB_PERIOD-1) + height = self.nodes[0].getblockcount() + assert((height % VB_PERIOD) == VB_PERIOD - 2) + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') + self.nodes[0].generate(1) + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') + + + # Mine enough blocks to activate segwit. + # TODO: we could verify that activation only happens at the right threshold + # of signalling blocks, rather than just at the right period boundary. + def advance_to_segwit_active(self): + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') + height = self.nodes[0].getblockcount() + self.nodes[0].generate(VB_PERIOD - (height%VB_PERIOD) - 2) + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') + self.nodes[0].generate(1) + assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active') + + + # This test can only be run after segwit has activated + def test_witness_commitments(self): + print("\tTesting witness commitments") + + # First try a correct witness commitment. + block = self.build_next_block() + add_witness_commitment(block) + block.solve() + + # Test the test -- witness serialization should be different + assert(msg_witness_block(block).serialize() != msg_block(block).serialize()) + + # This empty block should be valid. + self.test_node.test_witness_block(block, accepted=True) + + # Try to tweak the nonce + block_2 = self.build_next_block() + add_witness_commitment(block_2, nonce=28) + block_2.solve() + + # The commitment should have changed! + assert(block_2.vtx[0].vout[-1] != block.vtx[0].vout[-1]) + + # This should also be valid. + self.test_node.test_witness_block(block_2, accepted=True) + + # Now test commitments with actual transactions + assert (len(self.utxo) > 0) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + + # Let's construct a witness program + witness_program = CScript([OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) + tx.rehash() + + # tx2 will spend tx1, and send back to a regular anyone-can-spend address + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, witness_program)) + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] + tx2.rehash() + + block_3 = self.build_next_block() + self.update_witness_block_with_transactions(block_3, [tx, tx2], nonce=1) + # Add an extra OP_RETURN output that matches the witness commitment template, + # even though it has extra data after the incorrect commitment. + # This block should fail. + block_3.vtx[0].vout.append(CTxOut(0, CScript([OP_RETURN, WITNESS_COMMITMENT_HEADER + ser_uint256(2), 10]))) + block_3.vtx[0].rehash() + block_3.hashMerkleRoot = block_3.calc_merkle_root() + block_3.rehash() + block_3.solve() + + self.test_node.test_witness_block(block_3, accepted=False) + + # Add a different commitment with different nonce, but in the + # right location, and with some funds burned(!). + # This should succeed (nValue shouldn't affect finding the + # witness commitment). + add_witness_commitment(block_3, nonce=0) + block_3.vtx[0].vout[0].nValue -= 1 + block_3.vtx[0].vout[-1].nValue += 1 + block_3.vtx[0].rehash() + block_3.hashMerkleRoot = block_3.calc_merkle_root() + block_3.rehash() + assert(len(block_3.vtx[0].vout) == 4) # 3 OP_returns + block_3.solve() + self.test_node.test_witness_block(block_3, accepted=True) + + # Finally test that a block with no witness transactions can + # omit the commitment. + block_4 = self.build_next_block() + tx3 = CTransaction() + tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) + tx3.vout.append(CTxOut(tx.vout[0].nValue-1000, witness_program)) + tx3.rehash() + block_4.vtx.append(tx3) + block_4.hashMerkleRoot = block_4.calc_merkle_root() + block_4.solve() + self.test_node.test_witness_block(block_4, with_witness=False, accepted=True) + + # Update available utxo's for use in later test. + self.utxo.pop(0) + self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) + + + def test_block_malleability(self): + print("\tTesting witness block malleability") + + # Make sure that a block that has too big a virtual size + # because of a too-large coinbase witness is not permanently + # marked bad. + block = self.build_next_block() + add_witness_commitment(block) + block.solve() + + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.append(b'a'*5000000) + assert(get_virtual_size(block) > MAX_BLOCK_SIZE) + + # We can't send over the p2p network, because this is too big to relay + # TODO: repeat this test with a block that can be relayed + self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) + + assert(self.nodes[0].getbestblockhash() != block.hash) + + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop() + assert(get_virtual_size(block) < MAX_BLOCK_SIZE) + self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) + + assert(self.nodes[0].getbestblockhash() == block.hash) + + # Now make sure that malleating the witness nonce doesn't + # result in a block permanently marked bad. + block = self.build_next_block() + add_witness_commitment(block) + block.solve() + + # Change the nonce -- should not cause the block to be permanently + # failed + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ ser_uint256(1) ] + self.test_node.test_witness_block(block, accepted=False) + + # Changing the witness nonce doesn't change the block hash + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ ser_uint256(0) ] + self.test_node.test_witness_block(block, accepted=True) + + + def test_witness_block_size(self): + print("\tTesting witness block size limit") + # TODO: Test that non-witness carrying blocks can't exceed 1MB + # Skipping this test for now; this is covered in p2p-fullblocktest.py + + # Test that witness-bearing blocks are limited at ceil(base + wit/4) <= 1MB. + block = self.build_next_block() + + assert(len(self.utxo) > 0) + + # Create a P2WSH transaction. + # The witness program will be a bunch of OP_2DROP's, followed by OP_TRUE. + # This should give us plenty of room to tweak the spending tx's + # virtual size. + NUM_DROPS = 200 # 201 max ops per script! + NUM_OUTPUTS = 50 + + witness_program = CScript([OP_2DROP]*NUM_DROPS + [OP_TRUE]) + witness_hash = uint256_from_str(sha256(witness_program)) + scriptPubKey = CScript([OP_0, ser_uint256(witness_hash)]) + + prevout = COutPoint(self.utxo[0].sha256, self.utxo[0].n) + value = self.utxo[0].nValue + + parent_tx = CTransaction() + parent_tx.vin.append(CTxIn(prevout, b"")) + child_value = int(value/NUM_OUTPUTS) + for i in range(NUM_OUTPUTS): + parent_tx.vout.append(CTxOut(child_value, scriptPubKey)) + parent_tx.vout[0].nValue -= 50000 + assert(parent_tx.vout[0].nValue > 0) + parent_tx.rehash() + + child_tx = CTransaction() + for i in range(NUM_OUTPUTS): + child_tx.vin.append(CTxIn(COutPoint(parent_tx.sha256, i), b"")) + child_tx.vout = [CTxOut(value - 100000, CScript([OP_TRUE]))] + for i in range(NUM_OUTPUTS): + child_tx.wit.vtxinwit.append(CTxinWitness()) + child_tx.wit.vtxinwit[-1].scriptWitness.stack = [b'a'*195]*(2*NUM_DROPS) + [witness_program] + child_tx.rehash() + self.update_witness_block_with_transactions(block, [parent_tx, child_tx]) + + vsize = get_virtual_size(block) + additional_bytes = (MAX_BLOCK_SIZE - vsize)*4 + i = 0 + while additional_bytes > 0: + # Add some more bytes to each input until we hit MAX_BLOCK_SIZE+1 + extra_bytes = min(additional_bytes+1, 55) + block.vtx[-1].wit.vtxinwit[int(i/(2*NUM_DROPS))].scriptWitness.stack[i%(2*NUM_DROPS)] = b'a'*(195+extra_bytes) + additional_bytes -= extra_bytes + i += 1 + + block.vtx[0].vout.pop() # Remove old commitment + add_witness_commitment(block) + block.solve() + vsize = get_virtual_size(block) + assert_equal(vsize, MAX_BLOCK_SIZE + 1) + # Make sure that our test case would exceed the old max-network-message + # limit + assert(len(block.serialize(True)) > 2*1024*1024) + + self.test_node.test_witness_block(block, accepted=False) + + # Now resize the second transaction to make the block fit. + cur_length = len(block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0]) + block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0] = b'a'*(cur_length-1) + block.vtx[0].vout.pop() + add_witness_commitment(block) + block.solve() + assert(get_virtual_size(block) == MAX_BLOCK_SIZE) + + self.test_node.test_witness_block(block, accepted=True) + + # Update available utxo's + self.utxo.pop(0) + self.utxo.append(UTXO(block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue)) + + + # submitblock will try to add the nonce automatically, so that mining + # software doesn't need to worry about doing so itself. + def test_submit_block(self): + block = self.build_next_block() + + # Try using a custom nonce and then don't supply it. + # This shouldn't possibly work. + add_witness_commitment(block, nonce=1) + block.vtx[0].wit = CTxWitness() # drop the nonce + block.solve() + self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) + assert(self.nodes[0].getbestblockhash() != block.hash) + + # Now redo commitment with the standard nonce, but let bitcoind fill it in. + add_witness_commitment(block, nonce=0) + block.vtx[0].wit = CTxWitness() + block.solve() + self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) + assert_equal(self.nodes[0].getbestblockhash(), block.hash) + + # This time, add a tx with non-empty witness, but don't supply + # the commitment. + block_2 = self.build_next_block() + + add_witness_commitment(block_2) + + block_2.solve() + + # Drop commitment and nonce -- submitblock should not fill in. + block_2.vtx[0].vout.pop() + block_2.vtx[0].wit = CTxWitness() + + self.nodes[0].submitblock(bytes_to_hex_str(block_2.serialize(True))) + # Tip should not advance! + assert(self.nodes[0].getbestblockhash() != block_2.hash) + + + # Consensus tests of extra witness data in a transaction. + def test_extra_witness_data(self): + print("\tTesting extra witness data in tx") + + assert(len(self.utxo) > 0) + + block = self.build_next_block() + + witness_program = CScript([OP_DROP, OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + # First try extra witness data on a tx that doesn't require a witness + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-2000, scriptPubKey)) + tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output + tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])] + tx.rehash() + self.update_witness_block_with_transactions(block, [tx]) + + # Extra witness data should not be allowed. + self.test_node.test_witness_block(block, accepted=False) + + # Try extra signature data. Ok if we're not spending a witness output. + block.vtx[1].wit.vtxinwit = [] + block.vtx[1].vin[0].scriptSig = CScript([OP_0]) + block.vtx[1].rehash() + add_witness_commitment(block) + block.solve() + + self.test_node.test_witness_block(block, accepted=True) + + # Now try extra witness/signature data on an input that DOES require a + # witness + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) # witness output + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 1), b"")) # non-witness + tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) + tx2.wit.vtxinwit.extend([CTxinWitness(), CTxinWitness()]) + tx2.wit.vtxinwit[0].scriptWitness.stack = [ CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_program ] + tx2.wit.vtxinwit[1].scriptWitness.stack = [ CScript([OP_TRUE]) ] + + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx2]) + + # This has extra witness data, so it should fail. + self.test_node.test_witness_block(block, accepted=False) + + # Now get rid of the extra witness, but add extra scriptSig data + tx2.vin[0].scriptSig = CScript([OP_TRUE]) + tx2.vin[1].scriptSig = CScript([OP_TRUE]) + tx2.wit.vtxinwit[0].scriptWitness.stack.pop(0) + tx2.wit.vtxinwit[1].scriptWitness.stack = [] + tx2.rehash() + add_witness_commitment(block) + block.solve() + + # This has extra signature data for a witness input, so it should fail. + self.test_node.test_witness_block(block, accepted=False) + + # Now get rid of the extra scriptsig on the witness input, and verify + # success (even with extra scriptsig data in the non-witness input) + tx2.vin[0].scriptSig = b"" + tx2.rehash() + add_witness_commitment(block) + block.solve() + + self.test_node.test_witness_block(block, accepted=True) + + # Update utxo for later tests + self.utxo.pop(0) + self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) + + + def test_max_witness_push_length(self): + ''' Should only allow up to 520 byte pushes in witness stack ''' + print("\tTesting maximum witness push size") + MAX_SCRIPT_ELEMENT_SIZE = 520 + assert(len(self.utxo)) + + block = self.build_next_block() + + witness_program = CScript([OP_DROP, OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) + tx.rehash() + + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) + tx2.wit.vtxinwit.append(CTxinWitness()) + # First try a 521-byte stack element + tx2.wit.vtxinwit[0].scriptWitness.stack = [ b'a'*(MAX_SCRIPT_ELEMENT_SIZE+1), witness_program ] + tx2.rehash() + + self.update_witness_block_with_transactions(block, [tx, tx2]) + self.test_node.test_witness_block(block, accepted=False) + + # Now reduce the length of the stack element + tx2.wit.vtxinwit[0].scriptWitness.stack[0] = b'a'*(MAX_SCRIPT_ELEMENT_SIZE) + + add_witness_commitment(block) + block.solve() + self.test_node.test_witness_block(block, accepted=True) + + # Update the utxo for later tests + self.utxo.pop() + self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) + + def test_max_witness_program_length(self): + # Can create witness outputs that are long, but can't be greater than + # 10k bytes to successfully spend + print("\tTesting maximum witness program length") + assert(len(self.utxo)) + MAX_PROGRAM_LENGTH = 10000 + + # This program is 19 max pushes (9937 bytes), then 64 more opcode-bytes. + long_witness_program = CScript([b'a'*520]*19 + [OP_DROP]*63 + [OP_TRUE]) + assert(len(long_witness_program) == MAX_PROGRAM_LENGTH+1) + long_witness_hash = sha256(long_witness_program) + long_scriptPubKey = CScript([OP_0, long_witness_hash]) + + block = self.build_next_block() + + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, long_scriptPubKey)) + tx.rehash() + + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a']*44 + [long_witness_program] + tx2.rehash() + + self.update_witness_block_with_transactions(block, [tx, tx2]) + + self.test_node.test_witness_block(block, accepted=False) + + # Try again with one less byte in the witness program + witness_program = CScript([b'a'*520]*19 + [OP_DROP]*62 + [OP_TRUE]) + assert(len(witness_program) == MAX_PROGRAM_LENGTH) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + tx.vout[0] = CTxOut(tx.vout[0].nValue, scriptPubKey) + tx.rehash() + tx2.vin[0].prevout.hash = tx.sha256 + tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a']*43 + [witness_program] + tx2.rehash() + block.vtx = [block.vtx[0]] + self.update_witness_block_with_transactions(block, [tx, tx2]) + self.test_node.test_witness_block(block, accepted=True) + + self.utxo.pop() + self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) + + + def test_witness_input_length(self): + ''' Ensure that vin length must match vtxinwit length ''' + print("\tTesting witness input length") + assert(len(self.utxo)) + + witness_program = CScript([OP_DROP, OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + # Create a transaction that splits our utxo into many outputs + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + nValue = self.utxo[0].nValue + for i in range(10): + tx.vout.append(CTxOut(int(nValue/10), scriptPubKey)) + tx.vout[0].nValue -= 1000 + assert(tx.vout[0].nValue >= 0) + + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + # Try various ways to spend tx that should all break. + # This "broken" transaction serializer will not normalize + # the length of vtxinwit. + class BrokenCTransaction(CTransaction): + def serialize_with_witness(self): + flags = 0 + if not self.wit.is_null(): + flags |= 1 + r = b"" + r += struct.pack(" version 1 transactions + # are non-standard + scriptPubKey = CScript([CScriptOp(OP_1), witness_hash]) + tx2 = CTransaction() + tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] + tx2.vout = [CTxOut(tx.vout[0].nValue-1000, scriptPubKey)] + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] + tx2.rehash() + # Gets accepted to test_node, because standardness of outputs isn't + # checked with fRequireStandard + self.test_node.test_transaction_acceptance(tx2, with_witness=True, accepted=True) + self.std_node.test_transaction_acceptance(tx2, with_witness=True, accepted=False) + temp_utxo.pop() # last entry in temp_utxo was the output we just spent + temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) + + # Spend everything in temp_utxo back to an OP_TRUE output. + tx3 = CTransaction() + total_value = 0 + for i in temp_utxo: + tx3.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) + tx3.wit.vtxinwit.append(CTxinWitness()) + total_value += i.nValue + tx3.wit.vtxinwit[-1].scriptWitness.stack = [witness_program] + tx3.vout.append(CTxOut(total_value - 1000, CScript([OP_TRUE]))) + tx3.rehash() + # Spending a higher version witness output is not allowed by policy, + # even with fRequireStandard=false. + self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=False) + self.test_node.sync_with_ping() + with mininode_lock: + assert(b"reserved for soft-fork upgrades" in self.test_node.last_reject.reason) + + # Building a block with the transaction must be valid, however. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx2, tx3]) + self.test_node.test_witness_block(block, accepted=True) + sync_blocks(self.nodes) + + # Add utxo to our list + self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) + + + def test_premature_coinbase_witness_spend(self): + print("\tTesting premature coinbase witness spend") + block = self.build_next_block() + # Change the output of the block to be a witness output. + witness_program = CScript([OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + block.vtx[0].vout[0].scriptPubKey = scriptPubKey + # This next line will rehash the coinbase and update the merkle + # root, and solve. + self.update_witness_block_with_transactions(block, []) + self.test_node.test_witness_block(block, accepted=True) + + spend_tx = CTransaction() + spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")] + spend_tx.vout = [CTxOut(block.vtx[0].vout[0].nValue, witness_program)] + spend_tx.wit.vtxinwit.append(CTxinWitness()) + spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] + spend_tx.rehash() + + # Now test a premature spend. + self.nodes[0].generate(98) + sync_blocks(self.nodes) + block2 = self.build_next_block() + self.update_witness_block_with_transactions(block2, [spend_tx]) + self.test_node.test_witness_block(block2, accepted=False) + + # Advancing one more block should allow the spend. + self.nodes[0].generate(1) + block2 = self.build_next_block() + self.update_witness_block_with_transactions(block2, [spend_tx]) + self.test_node.test_witness_block(block2, accepted=True) + sync_blocks(self.nodes) + + + def test_signature_version_1(self): + print("\tTesting segwit signature hash version 1") + key = CECKey() + key.set_secretbytes(b"9") + pubkey = CPubKey(key.get_pubkey()) + + witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + # First create a witness output for use in the tests. + assert(len(self.utxo)) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) + tx.rehash() + + self.test_node.test_transaction_acceptance(tx, with_witness=True, accepted=True) + # Mine this transaction in preparation for following tests. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + sync_blocks(self.nodes) + self.utxo.pop(0) + + # Add signature for a P2PK witness program. + def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): + tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) + signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') + txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] + txTo.rehash() + + # Test each hashtype + prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue) + for sigflag in [ 0, SIGHASH_ANYONECANPAY ]: + for hashtype in [SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE]: + hashtype |= sigflag + block = self.build_next_block() + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) + tx.vout.append(CTxOut(prev_utxo.nValue - 1000, scriptPubKey)) + tx.wit.vtxinwit.append(CTxinWitness()) + # Too-large input value + sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue+1, key) + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=False) + + # Too-small input value + sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue-1, key) + block.vtx.pop() # remove last tx + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=False) + + # Now try correct value + sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key) + block.vtx.pop() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue) + + # Test combinations of signature hashes. + # Split the utxo into a lot of outputs. + # Randomly choose up to 10 to spend, sign with different hashtypes, and + # output to a random number of outputs. Repeat NUM_TESTS times. + # Ensure that we've tested a situation where we use SIGHASH_SINGLE with + # an input index > number of outputs. + NUM_TESTS = 500 + temp_utxos = [] + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) + split_value = prev_utxo.nValue // NUM_TESTS + for i in range(NUM_TESTS): + tx.vout.append(CTxOut(split_value, scriptPubKey)) + tx.wit.vtxinwit.append(CTxinWitness()) + sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, prev_utxo.nValue, key) + for i in range(NUM_TESTS): + temp_utxos.append(UTXO(tx.sha256, i, split_value)) + + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + block = self.build_next_block() + used_sighash_single_out_of_bounds = False + for i in range(NUM_TESTS): + # Choose random number of inputs to use. + num_inputs = random.randint(1, 10) + # Create a slight bias for producing more utxos + num_outputs = random.randint(1, 11) + random.shuffle(temp_utxos) + assert(len(temp_utxos) > num_inputs) + tx = CTransaction() + total_value = 0 + for i in range(num_inputs): + tx.vin.append(CTxIn(COutPoint(temp_utxos[i].sha256, temp_utxos[i].n), b"")) + tx.wit.vtxinwit.append(CTxinWitness()) + total_value += temp_utxos[i].nValue + split_value = total_value // num_outputs + for i in range(num_outputs): + tx.vout.append(CTxOut(split_value, scriptPubKey)) + for i in range(num_inputs): + # Now try to sign each input, using a random hashtype. + anyonecanpay = 0 + if random.randint(0, 1): + anyonecanpay = SIGHASH_ANYONECANPAY + hashtype = random.randint(1, 3) | anyonecanpay + sign_P2PK_witness_input(witness_program, tx, i, hashtype, temp_utxos[i].nValue, key) + if (hashtype == SIGHASH_SINGLE and i >= num_outputs): + used_sighash_single_out_of_bounds = True + tx.rehash() + for i in range(num_outputs): + temp_utxos.append(UTXO(tx.sha256, i, split_value)) + temp_utxos = temp_utxos[num_inputs:] + + block.vtx.append(tx) + + # Test the block periodically, if we're close to maxblocksize + if (get_virtual_size(block) > MAX_BLOCK_SIZE - 1000): + self.update_witness_block_with_transactions(block, []) + self.test_node.test_witness_block(block, accepted=True) + block = self.build_next_block() + + if (not used_sighash_single_out_of_bounds): + print("WARNING: this test run didn't attempt SIGHASH_SINGLE with out-of-bounds index value") + # Test the transactions we've added to the block + if (len(block.vtx) > 1): + self.update_witness_block_with_transactions(block, []) + self.test_node.test_witness_block(block, accepted=True) + + # Now test witness version 0 P2PKH transactions + pubkeyhash = hash160(pubkey) + scriptPKH = CScript([OP_0, pubkeyhash]) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b"")) + tx.vout.append(CTxOut(temp_utxos[0].nValue, scriptPKH)) + tx.wit.vtxinwit.append(CTxinWitness()) + sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, temp_utxos[0].nValue, key) + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) + + script = CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) + sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) + signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + + # Check that we can't have a scriptSig + tx2.vin[0].scriptSig = CScript([signature, pubkey]) + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx, tx2]) + self.test_node.test_witness_block(block, accepted=False) + + # Move the signature to the witness. + block.vtx.pop() + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [signature, pubkey] + tx2.vin[0].scriptSig = b"" + tx2.rehash() + + self.update_witness_block_with_transactions(block, [tx2]) + self.test_node.test_witness_block(block, accepted=True) + + temp_utxos.pop(0) + + # Update self.utxos for later tests. Just spend everything in + # temp_utxos to a corresponding entry in self.utxos + tx = CTransaction() + index = 0 + for i in temp_utxos: + # Just spend to our usual anyone-can-spend output + # Use SIGHASH_SINGLE|SIGHASH_ANYONECANPAY so we can build up + # the signatures as we go. + tx.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) + tx.vout.append(CTxOut(i.nValue, CScript([OP_TRUE]))) + tx.wit.vtxinwit.append(CTxinWitness()) + sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, i.nValue, key) + index += 1 + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + for i in range(len(tx.vout)): + self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue)) + + + # Test P2SH wrapped witness programs. + def test_p2sh_witness(self, segwit_activated): + print("\tTesting P2SH witness transactions") + + assert(len(self.utxo)) + + # Prepare the p2sh-wrapped witness output + witness_program = CScript([OP_DROP, OP_TRUE]) + witness_hash = sha256(witness_program) + p2wsh_pubkey = CScript([OP_0, witness_hash]) + p2sh_witness_hash = hash160(p2wsh_pubkey) + scriptPubKey = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) + scriptSig = CScript([p2wsh_pubkey]) # a push of the redeem script + + # Fund the P2SH output + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) + tx.rehash() + + # Verify mempool acceptance and block validity + self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True, with_witness=segwit_activated) + sync_blocks(self.nodes) + + # Now test attempts to spend the output. + spend_tx = CTransaction() + spend_tx.vin.append(CTxIn(COutPoint(tx.sha256, 0), scriptSig)) + spend_tx.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) + spend_tx.rehash() + + # This transaction should not be accepted into the mempool pre- or + # post-segwit. Mempool acceptance will use SCRIPT_VERIFY_WITNESS which + # will require a witness to spend a witness program regardless of + # segwit activation. Note that older bitcoind's that are not + # segwit-aware would also reject this for failing CLEANSTACK. + self.test_node.test_transaction_acceptance(spend_tx, with_witness=False, accepted=False) + + # Try to put the witness script in the scriptSig, should also fail. + spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a']) + spend_tx.rehash() + self.test_node.test_transaction_acceptance(spend_tx, with_witness=False, accepted=False) + + # Now put the witness script in the witness, should succeed after + # segwit activates. + spend_tx.vin[0].scriptSig = scriptSig + spend_tx.rehash() + spend_tx.wit.vtxinwit.append(CTxinWitness()) + spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a', witness_program ] + + # Verify mempool acceptance + self.test_node.test_transaction_acceptance(spend_tx, with_witness=True, accepted=segwit_activated) + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [spend_tx]) + + # If we're before activation, then sending this without witnesses + # should be valid. If we're after activation, then sending this with + # witnesses should be valid. + if segwit_activated: + self.test_node.test_witness_block(block, accepted=True) + else: + self.test_node.test_witness_block(block, accepted=True, with_witness=False) + + # Update self.utxo + self.utxo.pop(0) + self.utxo.append(UTXO(spend_tx.sha256, 0, spend_tx.vout[0].nValue)) + + # Test the behavior of starting up a segwit-aware node after the softfork + # has activated. As segwit requires different block data than pre-segwit + # nodes would have stored, this requires special handling. + # To enable this test, pass --oldbinary= to + # the test. + def test_upgrade_after_activation(self, node, node_id): + print("\tTesting software upgrade after softfork activation") + + assert(node_id != 0) # node0 is assumed to be a segwit-active bitcoind + + # Make sure the nodes are all up + sync_blocks(self.nodes) + + # Restart with the new binary + stop_node(node, node_id) + self.nodes[node_id] = start_node(node_id, self.options.tmpdir, ["-debug"]) + connect_nodes(self.nodes[0], node_id) + + sync_blocks(self.nodes) + + # Make sure that this peer thinks segwit has activated. + assert(get_bip9_status(node, 'segwit')['status'] == "active") + + # Make sure this peers blocks match those of node0. + height = node.getblockcount() + while height >= 0: + block_hash = node.getblockhash(height) + assert_equal(block_hash, self.nodes[0].getblockhash(height)) + assert_equal(self.nodes[0].getblock(block_hash), node.getblock(block_hash)) + height -= 1 + + + def test_witness_sigops(self): + '''Ensure sigop counting is correct inside witnesses.''' + print("\tTesting sigops limit") + + assert(len(self.utxo)) + + # Keep this under MAX_OPS_PER_SCRIPT (201) + witness_program = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKMULTISIG]*5 + [OP_CHECKSIG]*193 + [OP_ENDIF]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + sigops_per_script = 20*5 + 193*1 + # We'll produce 2 extra outputs, one with a program that would take us + # over max sig ops, and one with a program that would exactly reach max + # sig ops + outputs = (MAX_SIGOP_COST // sigops_per_script) + 2 + extra_sigops_available = MAX_SIGOP_COST % sigops_per_script + + # We chose the number of checkmultisigs/checksigs to make this work: + assert(extra_sigops_available < 100) # steer clear of MAX_OPS_PER_SCRIPT + + # This script, when spent with the first + # N(=MAX_SIGOP_COST//sigops_per_script) outputs of our transaction, + # would push us just over the block sigop limit. + witness_program_toomany = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG]*(extra_sigops_available + 1) + [OP_ENDIF]) + witness_hash_toomany = sha256(witness_program_toomany) + scriptPubKey_toomany = CScript([OP_0, witness_hash_toomany]) + + # If we spend this script instead, we would exactly reach our sigop + # limit (for witness sigops). + witness_program_justright = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG]*(extra_sigops_available) + [OP_ENDIF]) + witness_hash_justright = sha256(witness_program_justright) + scriptPubKey_justright = CScript([OP_0, witness_hash_justright]) + + # First split our available utxo into a bunch of outputs + split_value = self.utxo[0].nValue // outputs + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + for i in range(outputs): + tx.vout.append(CTxOut(split_value, scriptPubKey)) + tx.vout[-2].scriptPubKey = scriptPubKey_toomany + tx.vout[-1].scriptPubKey = scriptPubKey_justright + tx.rehash() + + block_1 = self.build_next_block() + self.update_witness_block_with_transactions(block_1, [tx]) + self.test_node.test_witness_block(block_1, accepted=True) + + tx2 = CTransaction() + # If we try to spend the first n-1 outputs from tx, that should be + # too many sigops. + total_value = 0 + for i in range(outputs-1): + tx2.vin.append(CTxIn(COutPoint(tx.sha256, i), b"")) + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program ] + total_value += tx.vout[i].nValue + tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_toomany ] + tx2.vout.append(CTxOut(total_value, CScript([OP_TRUE]))) + tx2.rehash() + + block_2 = self.build_next_block() + self.update_witness_block_with_transactions(block_2, [tx2]) + self.test_node.test_witness_block(block_2, accepted=False) + + # Try dropping the last input in tx2, and add an output that has + # too many sigops (contributing to legacy sigop count). + checksig_count = (extra_sigops_available // 4) + 1 + scriptPubKey_checksigs = CScript([OP_CHECKSIG]*checksig_count) + tx2.vout.append(CTxOut(0, scriptPubKey_checksigs)); + tx2.vin.pop() + tx2.wit.vtxinwit.pop() + tx2.vout[0].nValue -= tx.vout[-2].nValue + tx2.rehash() + block_3 = self.build_next_block() + self.update_witness_block_with_transactions(block_3, [tx2]) + self.test_node.test_witness_block(block_3, accepted=False) + + # If we drop the last checksig in this output, the tx should succeed. + block_4 = self.build_next_block() + tx2.vout[-1].scriptPubKey = CScript([OP_CHECKSIG]*(checksig_count-1)) + tx2.rehash() + self.update_witness_block_with_transactions(block_4, [tx2]) + self.test_node.test_witness_block(block_4, accepted=True) + + # Reset the tip back down for the next test + sync_blocks(self.nodes) + for x in self.nodes: + x.invalidateblock(block_4.hash) + + # Try replacing the last input of tx2 to be spending the last + # output of tx + block_5 = self.build_next_block() + tx2.vout.pop() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, outputs-1), b"")) + tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_justright ] + tx2.rehash() + self.update_witness_block_with_transactions(block_5, [tx2]) + self.test_node.test_witness_block(block_5, accepted=True) + + # TODO: test p2sh sigop counting + + def test_getblocktemplate_before_lockin(self): + print("\tTesting getblocktemplate setting of segwit versionbit (before lockin)") + block_version = (self.nodes[0].getblocktemplate())['version'] + assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + + # Workaround: + # Can either change the tip, or change the mempool and wait 5 seconds + # to trigger a recomputation of getblocktemplate. + self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + # Using mocktime lets us avoid sleep() + self.nodes[0].setmocktime(int(time.time())+10) + + block_version = self.nodes[0].getblocktemplate({"rules" : ["segwit"]})['version'] + assert(block_version & (1 << VB_WITNESS_BIT) != 0) + self.nodes[0].setmocktime(0) # undo mocktime + + def run_test(self): + # Setup the p2p connections and start up the network thread. + self.test_node = TestNode() # sets NODE_WITNESS|NODE_NETWORK + self.old_node = TestNode() # only NODE_NETWORK + self.std_node = TestNode() # for testing node1 (fRequireStandard=true) + + self.p2p_connections = [self.test_node, self.old_node] + + self.connections = [] + self.connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.test_node, services=NODE_NETWORK|NODE_WITNESS)) + self.connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.old_node, services=NODE_NETWORK)) + self.connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], self.std_node, services=NODE_NETWORK|NODE_WITNESS)) + self.test_node.add_connection(self.connections[0]) + self.old_node.add_connection(self.connections[1]) + self.std_node.add_connection(self.connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + # Keep a place to store utxo's that can be used in later tests + self.utxo = [] + + # Test logic begins here + self.test_node.wait_for_verack() + + print("\nStarting tests before segwit lock in:") + + self.test_witness_services() # Verifies NODE_WITNESS + self.test_non_witness_transaction() # non-witness tx's are accepted + self.test_unnecessary_witness_before_segwit_activation() + self.test_block_relay(segwit_activated=False) + + # Advance to segwit being 'started' + self.advance_to_segwit_started() + self.test_getblocktemplate_before_lockin() + + sync_blocks(self.nodes) + + # At lockin, nothing should change. + print("\nTesting behavior post lockin, pre-activation") + self.advance_to_segwit_lockin() + + # Retest unnecessary witnesses + self.test_unnecessary_witness_before_segwit_activation() + self.test_witness_tx_relay_before_segwit_activation() + self.test_block_relay(segwit_activated=False) + self.test_p2sh_witness(segwit_activated=False) + + sync_blocks(self.nodes) + + # Now activate segwit + print("\nTesting behavior after segwit activation") + self.advance_to_segwit_active() + + sync_blocks(self.nodes) + + # Test P2SH witness handling again + self.test_p2sh_witness(segwit_activated=True) + self.test_witness_commitments() + self.test_block_malleability() + self.test_witness_block_size() + self.test_submit_block() + self.test_extra_witness_data() + self.test_max_witness_push_length() + self.test_max_witness_program_length() + self.test_witness_input_length() + self.test_block_relay(segwit_activated=True) + self.test_tx_relay_after_segwit_activation() + self.test_segwit_versions() + self.test_premature_coinbase_witness_spend() + self.test_signature_version_1() + sync_blocks(self.nodes) + if self.test_upgrade: + self.test_upgrade_after_activation(self.nodes[2], 2) + else: + print("\tSkipping upgrade-after-activation test (use --oldbinary to enable)") + self.test_witness_sigops() + + +if __name__ == '__main__': + SegWitTest().main() diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 26cc39631..df4fe13e5 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -5,7 +5,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from .mininode import * -from .script import CScript, OP_TRUE, OP_CHECKSIG +from .script import CScript, OP_TRUE, OP_CHECKSIG, OP_RETURN # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): @@ -22,6 +22,29 @@ def create_block(hashprev, coinbase, nTime=None): block.calc_sha256() return block +# From BIP141 +WITNESS_COMMITMENT_HEADER = b"\xaa\x21\xa9\xed" + +# According to BIP141, blocks with witness rules active must commit to the +# hash of all in-block transactions including witness. +def add_witness_commitment(block, nonce=0): + # First calculate the merkle root of the block's + # transactions, with witnesses. + witness_nonce = nonce + witness_root = block.calc_witness_merkle_root() + witness_commitment = uint256_from_str(hash256(ser_uint256(witness_root)+ser_uint256(witness_nonce))) + # witness_nonce should go to coinbase witness. + block.vtx[0].wit.vtxinwit = [CTxinWitness()] + block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(witness_nonce)] + + # witness commitment is the last OP_RETURN output in coinbase + output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(witness_commitment) + block.vtx[0].vout.append(CTxOut(0, CScript([OP_RETURN, output_data]))) + block.vtx[0].rehash() + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + + def serialize_script_num(value): r = bytearray(0) if value == 0: diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 6612b99b8..4548e2e7c 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -28,7 +28,7 @@ import asyncore import time import sys import random -from binascii import hexlify, unhexlify +from .util import hex_str_to_bytes, bytes_to_hex_str from io import BytesIO from codecs import encode import hashlib @@ -46,6 +46,11 @@ MAX_BLOCK_SIZE = 1000000 COIN = 100000000 # 1 btc in satoshis +NODE_NETWORK = (1 << 0) +NODE_GETUTXO = (1 << 1) +NODE_BLOOM = (1 << 2) +NODE_WITNESS = (1 << 3) + # Keep our own socket map for asyncore, so that we can track disconnects # ourselves (to workaround an issue with closing an asyncore socket when # using select) @@ -63,6 +68,8 @@ mininode_lock = RLock() def sha256(s): return hashlib.new('sha256', s).digest() +def ripemd160(s): + return hashlib.new('ripemd160', s).digest() def hash256(s): return sha256(sha256(s)) @@ -133,7 +140,10 @@ def deser_vector(f, c): return r -def ser_vector(l): +# ser_function_name: Allow for an alternate serialization function on the +# entries in the vector (we use this for serializing the vector of transactions +# for a witness block). +def ser_vector(l, ser_function_name=None): r = b"" if len(l) < 253: r = struct.pack("B", len(l)) @@ -144,7 +154,10 @@ def ser_vector(l): else: r = struct.pack(" 1: newhashes = [] for i in range(0, len(hashes), 2): @@ -537,6 +663,24 @@ class CBlock(CBlockHeader): hashes = newhashes return uint256_from_str(hashes[0]) + def calc_merkle_root(self): + hashes = [] + for tx in self.vtx: + tx.calc_sha256() + hashes.append(ser_uint256(tx.sha256)) + return self.get_merkle_root(hashes) + + def calc_witness_merkle_root(self): + # For witness root purposes, the hash of the + # coinbase, with witness, is defined to be 0...0 + hashes = [ser_uint256(0)] + + for tx in self.vtx[1:]: + # Calculate the hashes with witness data + hashes.append(ser_uint256(tx.calc_sha256(True))) + + return self.get_merkle_root(hashes) + def is_valid(self): self.calc_sha256() target = uint256_from_compact(self.nBits) @@ -812,11 +956,16 @@ class msg_tx(object): self.tx.deserialize(f) def serialize(self): - return self.tx.serialize() + return self.tx.serialize_without_witness() def __repr__(self): return "msg_tx(tx=%s)" % (repr(self.tx)) +class msg_witness_tx(msg_tx): + + def serialize(self): + return self.tx.serialize_with_witness() + class msg_block(object): command = b"block" @@ -849,6 +998,12 @@ class msg_generic(object): def __repr__(self): return "msg_generic()" +class msg_witness_block(msg_block): + + def serialize(self): + r = self.block.serialize(with_witness=True) + return r + class msg_getaddr(object): command = b"getaddr" @@ -947,6 +1102,7 @@ class msg_sendheaders(object): def __repr__(self): return "msg_sendheaders()" + # getheaders message has # number of entries # vector of hashes @@ -1068,6 +1224,8 @@ class NodeConnCB(object): # tests; it causes message delivery to sleep for the specified time # before acquiring the global lock and delivering the next message. self.deliver_sleep_time = None + # Remember the services our peer has advertised + self.peer_services = None def set_deliver_sleep_time(self, value): with mininode_lock: @@ -1105,6 +1263,7 @@ class NodeConnCB(object): conn.ver_send = min(MY_VERSION, message.nVersion) if message.nVersion < 209: conn.ver_recv = conn.ver_send + conn.nServices = message.nServices def on_verack(self, conn, message): conn.ver_recv = conn.ver_send @@ -1135,6 +1294,7 @@ class NodeConnCB(object): def on_mempool(self, conn): pass def on_pong(self, conn, message): pass def on_feefilter(self, conn, message): pass + def on_sendheaders(self, conn, message): pass # More useful callbacks and functions for NodeConnCB's which have a single NodeConn class SingleNodeConnCB(NodeConnCB): @@ -1183,15 +1343,16 @@ class NodeConn(asyncore.dispatcher): b"getheaders": msg_getheaders, b"reject": msg_reject, b"mempool": msg_mempool, - b"feefilter": msg_feefilter + b"feefilter": msg_feefilter, + b"sendheaders": msg_sendheaders } MAGIC_BYTES = { "mainnet": b"\xf9\xbe\xb4\xd9", # mainnet "testnet3": b"\x0b\x11\x09\x07", # testnet3 - "regtest": b"\xfa\xbf\xb5\xda" # regtest + "regtest": b"\xfa\xbf\xb5\xda", # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=NODE_NETWORK): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1206,6 +1367,7 @@ class NodeConn(asyncore.dispatcher): self.network = net self.cb = callback self.disconnect = False + self.nServices = 0 # stuff version msg into sendbuf vt = msg_version() diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 44a894fc8..7678228c4 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -15,8 +15,9 @@ Functionality to build scripts, as well as SignatureHash(). """ -from .mininode import CTransaction, CTxOut, hash256 +from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string from binascii import hexlify +import hashlib import sys bchr = chr @@ -36,6 +37,10 @@ MAX_SCRIPT_OPCODES = 201 OPCODE_NAMES = {} +def hash160(s): + return hashlib.new('ripemd160', sha256(s)).digest() + + _opcode_instances = [] class CScriptOp(int): """A single script opcode""" @@ -895,3 +900,48 @@ def SignatureHash(script, txTo, inIdx, hashtype): hash = hash256(s) return (hash, None) + +# TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided. +# Performance optimization probably not necessary for python tests, however. +# Note that this corresponds to sigversion == 1 in EvalScript, which is used +# for version 0 witnesses. +def SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, amount): + + hashPrevouts = 0 + hashSequence = 0 + hashOutputs = 0 + + if not (hashtype & SIGHASH_ANYONECANPAY): + serialize_prevouts = bytes() + for i in txTo.vin: + serialize_prevouts += i.prevout.serialize() + hashPrevouts = uint256_from_str(hash256(serialize_prevouts)) + + if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): + serialize_sequence = bytes() + for i in txTo.vin: + serialize_sequence += struct.pack("(script.begin(), script.end())); + return *this; + } + TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE) { uint256 hash = SignatureHash(script, spendTx, 0, nHashType, 0, sigversion); @@ -765,6 +770,42 @@ BOOST_AUTO_TEST_CASE(script_build) "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_PKH ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, false, WITNESS_PKH, 1 + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)); + { + CScript witscript = CScript() << ToByteVector(keys.pubkey0); + uint256 hash; + CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin()); + vector hashBytes = ToByteVector(hash); + hashBytes.pop_back(); + tests.push_back(TestBuilder(CScript() << OP_0 << hashBytes, + "P2WPKH with wrong witness program length", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH)); + } + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2WSH with empty witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH + ).ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY)); + { + CScript witscript = CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG; + tests.push_back(TestBuilder(witscript, + "P2WSH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH + ).PushWitSig(keys.key0).Push(witscript).DamagePush(0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH)); + } + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "P2WPKH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "P2WPKH with non-empty scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Num(11).ScriptError(SCRIPT_ERR_WITNESS_MALLEATED)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), + "P2SH(P2WPKH) with superfluous push in scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH + ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().Num(11).PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_MALLEATED_P2SH)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH + ).PushSig(keys.key0).Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_UNEXPECTED)); + std::set tests_set; { From d846e0237256a4105199673d2eb90ed1dbb55b35 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Sun, 22 May 2016 07:35:43 -0400 Subject: [PATCH 0862/1223] [qa] script_tests: witness tests can specify tx amount Add tests that witness signatures cover value --- src/test/data/script_tests.json | 123 ++++++++++++++++++++++++-------- src/test/script_tests.cpp | 68 ++++++++++++------ 2 files changed, 140 insertions(+), 51 deletions(-) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index a59e1389f..9b81e0c77 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1,5 +1,5 @@ [ -["Format is: [[wit...]?, scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], +["Format is: [[wit..., amount]?, scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], @@ -1254,10 +1254,10 @@ ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], ["Some basic segwit checks"], -[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "EVAL_FALSE", "Invalid witness script"], -[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "WITNESS_PROGRAM_MISMATCH", "Witness script hash mismatch"], -[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Invalid witness script without WITNESS"], -[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Witness script hash mismatch without WITNESS"], +[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "EVAL_FALSE", "Invalid witness script"], +[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "WITNESS_PROGRAM_MISMATCH", "Witness script hash mismatch"], +[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Invalid witness script without WITNESS"], +[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Witness script hash mismatch without WITNESS"], ["Automatically generated test cases"], [ @@ -1836,8 +1836,9 @@ ], [ [ - "3044022039105b995a5f448639a997a5c90fda06f50b49df30c3bdb6663217bf79323db002206fecd54269dec569fcc517178880eb58bb40f381a282bb75766ff3637d5f4b4301", - "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac" + "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 ], "", "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", @@ -1847,8 +1848,9 @@ ], [ [ - "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 ], "", "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", @@ -1858,8 +1860,9 @@ ], [ [ - "3044022061fc1a144e221ec77a58a4281936eb6a1b715b9349e446e74d106ec26c8633ba022008064a0d112e8ad514440fcdfaa1006e48305d6844f50a65873fb4b2cf9c035f01", - "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac" + "3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 ], "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", @@ -1869,8 +1872,9 @@ ], [ [ - "3044022014e69768e174972f21d32d93002ca6fc26133cb9e819ceef7efb970798bde7b4022078b86849dbbec692ec9355aa2a763fce7ea11bf72fdd8ea5ea8083de6f8a77fe01", - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 ], "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", @@ -1881,7 +1885,8 @@ [ [ "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", - "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 ], "", "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", @@ -1892,7 +1897,8 @@ [ [ "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", - "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 ], "", "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", @@ -1903,7 +1909,8 @@ [ [ "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", - "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 ], "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", @@ -1914,7 +1921,8 @@ [ [ "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", - "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 ], "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", @@ -1925,7 +1933,8 @@ [ [ "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", - "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 ], "", "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", @@ -1936,7 +1945,8 @@ [ [ "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", - "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 ], "", "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", @@ -1947,7 +1957,8 @@ [ [ "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", - "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac" + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 ], "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", @@ -1958,7 +1969,8 @@ [ [ "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", - "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 ], "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", @@ -1966,10 +1978,59 @@ "OK", "Basic P2SH(P2WPKH) with the wrong key but no WITNESS" ], +[ + [ + "3044022066faa86e74e8b30e82691b985b373de4f9e26dc144ec399c4f066aa59308e7c202204712b86f28c32503faa051dbeabff2c238ece861abc36c5e0b40b1139ca222f001", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WSH with wrong value" +], +[ + [ + "304402203b3389b87448d7dfdb5e82fb854fcf92d7925f9938ea5444e36abef02c3d6a9602202410bc3265049abb07fd2e252c65ab7034d95c9d5acccabe9fadbdc63a52712601", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WPKH with wrong value" +], +[ + [ + "3044022000a30c4cfc10e4387be528613575434826ad3c15587475e0df8ce3b1746aa210022008149265e4f8e9dafe1f3ea50d90cb425e9e40ea7ebdd383069a7cfa2b77004701", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WSH) with wrong value" +], +[ + [ + "304402204fc3a2cd61a47913f2a5f9107d0ad4a504c7b31ee2d6b3b2f38c2b10ee031e940220055d58b7c3c281aaa381d8f486ac0f3e361939acfd568046cb6a311cdfa974cf01", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WPKH) with wrong value" +], [ [ "304402205ae57ae0534c05ca9981c8a6cdf353b505eaacb7375f96681a2d1a4ba6f02f84022056248e68643b7d8ce7c7d128c9f1f348bcab8be15d094ad5cadd24251a28df8001", - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 ], "", "1 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", @@ -1980,7 +2041,8 @@ [ [ "3044022064100ca0e2a33332136775a86cd83d0230e58b9aebb889c5ac952abff79a46ef02205f1bf900e022039ad3091bdaf27ac2aef3eae9ed9f190d821d3e508405b9513101", - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 ], "", "0 0x1f 0xb34b78da162751647974d5cb7410aa428ad339dbf7d1e16e833f68a0cbf1c3", @@ -1998,7 +2060,8 @@ [ [ "3044022039105b995a5f448639a997a5c90fda06f50b49df30c3bdb6663217bf79323db002206fecd54269dec569fcc517178880eb58bb40f381a282bb75766ff3637d5f4b4301", - "400479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac" + "400479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 ], "", "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", @@ -2010,7 +2073,8 @@ [ "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", - "" + "", + 0.00000000 ], "", "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", @@ -2021,7 +2085,8 @@ [ [ "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 ], "11", "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", @@ -2032,7 +2097,8 @@ [ [ "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", - "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 ], "11 0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", @@ -2042,7 +2108,8 @@ ], [ [ - "" + "", + 0.00000000 ], "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 1497bde9d..5a9aaf9bc 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -13,6 +13,7 @@ #include "util.h" #include "utilstrencodings.h" #include "test/test_bitcoin.h" +#include "rpc/server.h" #if defined(HAVE_CONSENSUS_LIB) #include "script/bitcoinconsensus.h" @@ -118,7 +119,7 @@ ScriptError_t ParseScriptError(const std::string &name) BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup) -CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) +CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue = 0) { CMutableTransaction txCredit; txCredit.nVersion = 1; @@ -129,7 +130,7 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0); txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; txCredit.vout[0].scriptPubKey = scriptPubKey; - txCredit.vout[0].nValue = 0; + txCredit.vout[0].nValue = nValue; return txCredit; } @@ -148,12 +149,12 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc txSpend.vin[0].scriptSig = scriptSig; txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; txSpend.vout[0].scriptPubKey = CScript(); - txSpend.vout[0].nValue = 0; + txSpend.vout[0].nValue = txCredit.vout[0].nValue; return txSpend; } -void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, const std::string& message, int scriptError) +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, const std::string& message, int scriptError, CAmount nValue = 0) { bool expect = (scriptError == SCRIPT_ERR_OK); if (flags & SCRIPT_VERIFY_CLEANSTACK) { @@ -161,7 +162,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript flags |= SCRIPT_VERIFY_WITNESS; } ScriptError err; - CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey); + CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey, nValue); CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit); CMutableTransaction tx2 = tx; BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); @@ -276,6 +277,7 @@ private: std::string comment; int flags; int scriptError; + CAmount nValue; void DoPush() { @@ -293,7 +295,7 @@ private: } public: - TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WITNESS_NONE, int witnessversion = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK) + TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WITNESS_NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_) { CScript scriptPubKey = script; if (wm == WITNESS_PKH) { @@ -311,7 +313,7 @@ public: redeemscript = scriptPubKey; scriptPubKey = CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemscript)) << OP_EQUAL; } - creditTx = BuildCreditingTransaction(scriptPubKey); + creditTx = BuildCreditingTransaction(scriptPubKey, nValue); spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), creditTx); } @@ -346,9 +348,9 @@ public: return *this; } - TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE) + TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE, CAmount amount = 0) { - uint256 hash = SignatureHash(script, spendTx, 0, nHashType, 0, sigversion); + uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion); std::vector vchSig, r, s; uint32_t iter = 0; do { @@ -364,9 +366,11 @@ public: return *this; } - TestBuilder& PushWitSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_WITNESS_V0) + TestBuilder& PushWitSig(const CKey& key, CAmount amount = -1, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_WITNESS_V0) { - return PushSig(key, nHashType, lenR, lenS, sigversion).AsWit(); + if (amount == -1) + amount = nValue; + return PushSig(key, nHashType, lenR, lenS, sigversion, amount).AsWit(); } TestBuilder& Push(const CPubKey& pubkey) @@ -411,7 +415,7 @@ public: { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError, nValue); *this = copy; return *this; } @@ -433,6 +437,7 @@ public: for (unsigned i = 0; i < scriptWitness.stack.size(); i++) { wit.push_back(HexStr(scriptWitness.stack[i])); } + wit.push_back(ValueFromAmount(nValue)); array.push_back(wit); } array.push_back(FormatScript(spendTx.vin[0].scriptSig)); @@ -734,17 +739,17 @@ BOOST_AUTO_TEST_CASE(script_build) ).PushSig(keys.key0).PushRedeem()); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH - ).PushWitSig(keys.key0).PushWitRedeem()); + "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem()); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), - "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH - ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit()); + "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit()); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, - "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH - ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); + "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), - "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH - ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem()); + "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem()); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH ).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); @@ -769,6 +774,18 @@ BOOST_AUTO_TEST_CASE(script_build) tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_PKH ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2WSH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2WPKH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH, + 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2SH(P2WSH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2SH(P2WPKH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH, + 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), "P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | @@ -841,20 +858,25 @@ BOOST_AUTO_TEST_CASE(script_json_test) { // Read tests from test/data/script_tests.json // Format is an array of arrays - // Inner arrays are [ ["wit"...]?, "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] + // Inner arrays are [ ["wit"..., nValue]?, "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ] // ... where scriptSig and scriptPubKey are stringified // scripts. + // If a witness is given, then the last value in the array should be the + // amount (nValue) to use in the crediting tx UniValue tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests))); for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); CScriptWitness witness; + CAmount nValue = 0; unsigned int pos = 0; if (test.size() > 0 && test[pos].isArray()) { - for (unsigned int i = 0; i < test[pos].size(); i++) { + unsigned int i=0; + for (i = 0; i < test[pos].size()-1; i++) { witness.stack.push_back(ParseHex(test[pos][i].get_str())); } + nValue = AmountFromValue(test[pos][i]); pos++; } if (test.size() < 4 + pos) // Allow size > 3; extra stuff ignored (useful for comments) @@ -871,7 +893,7 @@ BOOST_AUTO_TEST_CASE(script_json_test) unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str()); int scriptError = ParseScriptError(test[pos++].get_str()); - DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError); + DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError, nValue); } } From fdb43df23eb507d1c79b7ae9cc2e61c3e52c8988 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Sat, 28 May 2016 19:22:13 +0200 Subject: [PATCH 0863/1223] [qa] Add GetTransactionSigOpCost unit tests --- src/main.h | 8 ++ src/test/sigopcount_tests.cpp | 177 ++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/src/main.h b/src/main.h index 84a6044bc..2ffe5770d 100644 --- a/src/main.h +++ b/src/main.h @@ -333,6 +333,14 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx); */ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs); +/** + * Compute total signature operation cost of a transaction. + * @param[in] tx Transaction for which we are computing the cost + * @param[in] inputs Map of previous transactions that have outputs we're spending + * @param[out] flags Script verification flags + * @return Total signature operation cost of tx + */ +int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags); /** * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index a207fd921..8dea38833 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_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 "main.h" #include "pubkey.h" #include "key.h" #include "script/script.h" @@ -64,4 +65,180 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U); } +/** + * Verifies script execution of the zeroth scriptPubKey of tx output and + * zeroth scriptSig and witness of tx input. + */ +ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags) +{ + ScriptError error; + CTransaction inputi(input); + bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); + BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK)); + + return error; +} + +/** + * Builds a creationTx from scriptPubKey and a spendingTx from scriptSig + * and witness such that spendingTx spends output zero of creationTx. + * Also inserts creationTx's output into the coins view. + */ +void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxinWitness& witness) +{ + creationTx.nVersion = 1; + creationTx.vin.resize(1); + creationTx.vin[0].prevout.SetNull(); + creationTx.vin[0].scriptSig = CScript(); + creationTx.wit.vtxinwit.resize(1); + creationTx.vout.resize(1); + creationTx.vout[0].nValue = 1; + creationTx.vout[0].scriptPubKey = scriptPubKey; + + spendingTx.nVersion = 1; + spendingTx.vin.resize(1); + spendingTx.vin[0].prevout.hash = creationTx.GetHash(); + spendingTx.vin[0].prevout.n = 0; + spendingTx.vin[0].scriptSig = scriptSig; + spendingTx.wit.vtxinwit.resize(1); + spendingTx.wit.vtxinwit[0] = witness; + spendingTx.vout.resize(1); + spendingTx.vout[0].nValue = 1; + spendingTx.vout[0].scriptPubKey = CScript(); + + coins.ModifyCoins(creationTx.GetHash())->FromTx(creationTx, 0); +} + +BOOST_AUTO_TEST_CASE(GetTxSigOpCost) +{ + // Transaction creates outputs + CMutableTransaction creationTx; + // Transaction that spends outputs and whose + // sig op cost is going to be tested + CMutableTransaction spendingTx; + + // Create utxo set + CCoinsView coinsDummy; + CCoinsViewCache coins(&coinsDummy); + // Create key + CKey key; + key.MakeNewKey(true); + CPubKey pubkey = key.GetPubKey(); + // Default flags + int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH; + + // Multisig script (legacy counting) + { + CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; + // Do not use a valid signature to avoid using wallet operations. + CScript scriptSig = CScript() << OP_0 << OP_0; + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness()); + // Legacy counting only includes signature operations in scriptSigs and scriptPubKeys + // of a transaction and does not take the actual executed sig operations into account. + // spendingTx in itself does not contain a signature operation. + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0); + // creationTx contains two signature operations in its scriptPubKey, but legacy counting + // is not accurate. + assert(GetTransactionSigOpCost(CTransaction(creationTx), coins, flags) == MAX_PUBKEYS_PER_MULTISIG * WITNESS_SCALE_FACTOR); + // Sanity check: script verification fails because of an invalid signature. + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); + } + + // Multisig nested in P2SH + { + CScript redeemScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; + CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); + CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript); + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness()); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2 * WITNESS_SCALE_FACTOR); + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); + } + + // P2WPKH witness program + { + CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; + CScript scriptPubKey = GetScriptForWitness(p2pk); + CScript scriptSig = CScript(); + CTxinWitness witness; + CScriptWitness scriptWitness; + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(0)); + witness.scriptWitness = scriptWitness; + + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); + // No signature operations if we don't verify the witness. + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY); + + // The sig op cost for witness version != 0 is zero. + assert(scriptPubKey[0] == 0x00); + scriptPubKey[0] = 0x51; + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0); + scriptPubKey[0] = 0x00; + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + + // The witness of a coinbase transaction is not taken into account. + spendingTx.vin[0].prevout.SetNull(); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0); + } + + // P2WPKH nested in P2SH + { + CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; + CScript scriptSig = GetScriptForWitness(p2pk); + CScript scriptPubKey = GetScriptForDestination(CScriptID(scriptSig)); + scriptSig = CScript() << ToByteVector(scriptSig); + CTxinWitness witness; + CScriptWitness scriptWitness; + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(0)); + witness.scriptWitness = scriptWitness; + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY); + } + + // P2WSH witness program + { + CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; + CScript scriptPubKey = GetScriptForWitness(witnessScript); + CScript scriptSig = CScript(); + CTxinWitness witness; + CScriptWitness scriptWitness; + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(witnessScript.begin(), witnessScript.end())); + witness.scriptWitness = scriptWitness; + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); + } + + // P2WSH nested in P2SH + { + CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; + CScript redeemScript = GetScriptForWitness(witnessScript); + CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); + CScript scriptSig = CScript() << ToByteVector(redeemScript); + CTxinWitness witness; + CScriptWitness scriptWitness; + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(0)); + scriptWitness.stack.push_back(vector(witnessScript.begin(), witnessScript.end())); + witness.scriptWitness = scriptWitness; + + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); + assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); + } +} + BOOST_AUTO_TEST_SUITE_END() From 070dbc48a9338375fd7ce0a86ee05b476cf487a4 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 4 Jun 2016 22:38:36 +0200 Subject: [PATCH 0864/1223] --- [SEGWIT] begin: deployment --- From f8528134fc188abc5c7175a19680206964a8fade Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 6 May 2016 07:29:34 +0200 Subject: [PATCH 0865/1223] BIP9 parameters for testnet --- src/chainparams.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 2a198e855..69d4a9ecb 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -190,8 +190,8 @@ public: // Deployment of SegWit (BIP141 and BIP143) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 2000000000; // Far in the future - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 2100000000; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; From 27f8126ff37ec590c266adc6228d216857606536 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 23 Jun 2016 12:44:53 +1000 Subject: [PATCH 0866/1223] remove unnecessary LOCK(cs_main) --- src/rpc/blockchain.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1bb365d36..e63232b48 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -289,8 +289,6 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) + HelpExampleRpc("getrawmempool", "true") ); - LOCK(cs_main); - bool fVerbose = false; if (params.size() > 0) fVerbose = params[0].get_bool(); From a1c92c29fd1c242831867ede4c67e544377ae473 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 23 Jun 2016 12:25:04 +0200 Subject: [PATCH 0867/1223] trivial: capitalize BIP32 in option help For consistency, BIP32 should be in uppercase in translation message. Reported by @pryds on Transifex. --- src/qt/bitcoinstrings.cpp | 2 +- src/qt/locale/bitcoin_en.ts | 14 +++++++------- src/wallet/wallet.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index ce8753fc7..83901732a 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -173,7 +173,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Use UPnP to map the listening port (default: 1 when listening and no -proxy)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Use hierarchical deterministic key generation (HD) after bip32. Only has " +"Use hierarchical deterministic key generation (HD) after BIP32. Only has " "effect during wallet creation/first start"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index f122273a3..4e4c9f45e 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -2417,12 +2417,7 @@ - - Use hierarchical deterministic key generation (HD) after bip32. Only has effect during wallet creation/first start - - - - + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) @@ -2852,7 +2847,12 @@ - + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 723b2ecef..ba5f92a98 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3209,7 +3209,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after bip32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); From 133deb83dfedb09d1c5c477a01fb12665cbae16f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 23 Jun 2016 15:44:35 +0200 Subject: [PATCH 0868/1223] Mark my dnsseed as supporting filtering --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 6eb66c78e..d888aae09 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -109,7 +109,7 @@ public: assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); // Pieter Wuille + vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker From f70bcfc6c052bab8c7f78fae8aa69bbe64adaa94 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 24 Jun 2016 15:01:45 +0800 Subject: [PATCH 0869/1223] [trivial] Add aarch64 to depends .gitignore --- depends/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/.gitignore b/depends/.gitignore index 1f163897b..3cb4b9ac1 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -7,3 +7,4 @@ x86_64* i686* mips* arm* +aarch64* From d24148742e2e3df1011a65c1b4c5589609bab05e Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 24 Jun 2016 15:32:48 +0800 Subject: [PATCH 0870/1223] [doc] Add OS X ZMQ requirement to QA readme --- qa/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qa/README.md b/qa/README.md index 7489eb513..723660c6c 100644 --- a/qa/README.md +++ b/qa/README.md @@ -16,6 +16,12 @@ The python3-zmq library is required. On Ubuntu or Debian it can be installed via sudo apt-get install python3-zmq ``` +OS X +------ +``` +pip3 install pyzmq +``` + Running tests ============= @@ -36,7 +42,7 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended By default, tests will be run in parallel if you want to specify how many -tests should be run in parallel, append `-paralell=n` (default n=4). +tests should be run in parallel, append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. From d7828abd5b08ae17a42a7b8efe3b546fe2d09f4b Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Fri, 24 Jun 2016 17:05:45 +0700 Subject: [PATCH 0871/1223] check that transactionView->selectionModel()->selectedRows(0) exists --- src/qt/transactionview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 199a7b2d7..48cf94050 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -365,6 +365,8 @@ void TransactionView::contextualMenu(const QPoint &point) { QModelIndex index = transactionView->indexAt(point); QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + if (selection.empty()) + return; // check if transaction can be abandoned, disable context menu action in case it doesn't uint256 hash; From 1acf1db76fc3e07deb8f0f837934ea90383fedb5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 24 Jun 2016 16:35:21 +0200 Subject: [PATCH 0872/1223] Do not ask a UI question from bitcoind --- src/init.cpp | 3 ++- src/noui.cpp | 6 ++++++ src/qt/bitcoingui.cpp | 2 ++ src/ui_interface.h | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index b572bfc32..fe367c6a3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1317,8 +1317,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!fLoaded) { // first suggest a reindex if (!fReset) { - bool fRet = uiInterface.ThreadSafeMessageBox( + bool fRet = uiInterface.ThreadSafeQuestion( strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"), + strLoadError + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); if (fRet) { fReindex = true; diff --git a/src/noui.cpp b/src/noui.cpp index 3a7736191..0d9207c11 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -39,6 +39,11 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str return false; } +static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) +{ + return noui_ThreadSafeMessageBox(message, caption, style); +} + static void noui_InitMessage(const std::string& message) { LogPrintf("init message: %s\n", message); @@ -48,5 +53,6 @@ void noui_connect() { // Connect bitcoind signal handlers uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); + uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion); uiInterface.InitMessage.connect(noui_InitMessage); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 50c19c384..9042e3b56 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1105,12 +1105,14 @@ void BitcoinGUI::subscribeToCoreSignals() { // Connect signals to client uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); + uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4)); } void BitcoinGUI::unsubscribeFromCoreSignals() { // Disconnect signals from client uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); + uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4)); } UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) : diff --git a/src/ui_interface.h b/src/ui_interface.h index 7ebfc17e5..7e6557f8e 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -76,6 +76,9 @@ public: /** Show message box. */ boost::signals2::signal > ThreadSafeMessageBox; + /** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */ + boost::signals2::signal > ThreadSafeQuestion; + /** Progress message during initialization. */ boost::signals2::signal InitMessage; From b0be3a0186114c8f566292fc9001debcbe79a663 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Jun 2016 16:29:00 +0200 Subject: [PATCH 0873/1223] doc: Mention Windows XP end of support in release notes Closes #7681. --- doc/release-notes.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index df3c265dc..6e4f390cb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -16,6 +16,28 @@ To receive security and update notifications, please subscribe to: +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer verion of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + Notable changes =============== From 409f83322e9fe3257cf9f3f61813195ac1aaa20c Mon Sep 17 00:00:00 2001 From: jl2012 Date: Sat, 25 Jun 2016 00:55:07 +0800 Subject: [PATCH 0874/1223] RPC: Hide softfork if timeout is 0 --- src/rpc/blockchain.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 43ba4edd7..60462b9f8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -868,6 +868,15 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse return rv; } +void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + // Deployments with timeout value of 0 are hidden. + // A timeout value of 0 guarantees a softfork will never be activated. + // This is used when softfork codes are merged without specifying the deployment schedule. + if (consensusParams.vDeployments[id].nTimeout > 0) + bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -901,7 +910,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " ],\n" " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\n" - " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\n" + " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" @@ -933,8 +942,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); - bip9_softforks.push_back(Pair("segwit", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_SEGWIT))); + BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV); + BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); From 252675efc69ec0638d96a69fbc349a612cd1e2b7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 26 Jun 2016 20:19:00 +0200 Subject: [PATCH 0875/1223] Do not send witnesses in cmpctblock --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6cdd55e39..0bc90ab4a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6538,7 +6538,7 @@ bool SendMessages(CNode* pto) CBlock block; assert(ReadBlockFromDisk(block, pBestIndex, consensusParams)); CBlockHeaderAndShortTxIDs cmpctblock(block); - pto->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock); + pto->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); state.pindexBestHeaderSent = pBestIndex; } else if (state.fPreferHeaders) { if (vHeaders.size() > 1) { From f15c2cde455174c7c899833fd5792460ed49a472 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 27 Jun 2016 10:58:58 -0400 Subject: [PATCH 0876/1223] CreateNewBlock: add support for size-accounting to addPackageTxs Includes a change to not continue to use size-accounting in addScoreTxs or addPackageTxs just because addPriorityTxs() is used. --- src/miner.cpp | 25 +++++++++++++++---------- src/miner.h | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index cfc2dae56..a3e29431d 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -94,6 +94,7 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR; } } + // Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity: nBlockMaxCost = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_COST-4000), nBlockMaxCost)); // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: @@ -167,13 +168,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); addPriorityTxs(); - if (fNeedSizeAccounting) { - // addPackageTxs (the CPFP-based algorithm) cannot deal with size based - // accounting, so fall back to the old algorithm. - addScoreTxs(); - } else { - addPackageTxs(); - } + addPackageTxs(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; @@ -243,11 +238,19 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost // Block size and sigops have already been tested. Check that all transactions // are final. -bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package) +bool BlockAssembler::TestPackageFinalityAndSerializedSize(const CTxMemPool::setEntries& package) { + uint64_t nPotentialBlockSize = nBlockSize; // only used with fNeedSizeAccounting BOOST_FOREACH (const CTxMemPool::txiter it, package) { if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) return false; + if (fNeedSizeAccounting) { + uint64_t nTxSize = ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION); + if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) { + return false; + } + nPotentialBlockSize += nTxSize; + } } return true; } @@ -539,7 +542,7 @@ void BlockAssembler::addPackageTxs() ancestors.insert(iter); // Test if all tx's are Final - if (!TestPackageFinality(ancestors)) { + if (!TestPackageFinalityAndSerializedSize(ancestors)) { if (fUsingModified) { mapModifiedTx.get().erase(modit); failedTx.insert(iter); @@ -573,6 +576,7 @@ void BlockAssembler::addPriorityTxs() return; } + bool fSizeAccounting = fNeedSizeAccounting; fNeedSizeAccounting = true; // This vector will be sorted into a priority queue: @@ -624,7 +628,7 @@ void BlockAssembler::addPriorityTxs() // If now that this txs is added we've surpassed our desired priority size // or have dropped below the AllowFreeThreshold, then we're done adding priority txs if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) { - return; + break; } // This tx was successfully added, so @@ -640,6 +644,7 @@ void BlockAssembler::addPriorityTxs() } } } + fNeedSizeAccounting = fSizeAccounting; } void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) diff --git a/src/miner.h b/src/miner.h index b303a8fa3..bc4da63da 100644 --- a/src/miner.h +++ b/src/miner.h @@ -193,7 +193,7 @@ private: /** Test if a new package would "fit" in the block */ bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost); /** Test if a set of transactions are all final */ - bool TestPackageFinality(const CTxMemPool::setEntries& package); + bool TestPackageFinalityAndSerializedSize(const CTxMemPool::setEntries& package); /** Return true if given transaction from mapTx has already been evaluated, * or if the transaction's cached data in mapTx is incorrect. */ bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); From 2129fcea69ee0cf71c5e082607d101c3680af84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Sat, 25 Jun 2016 08:19:36 +0200 Subject: [PATCH 0877/1223] The bit field is shown only when status is "started" --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9d1d12a47..20eefa1c5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -909,7 +909,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\n" " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" - " \"bit\": xx, (numeric) the bit, 0-28, in the block version field used to signal this soft fork\n" + " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n" " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" From 9a227e95bb1dee07d20d1042f48f12db8cc048a6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 27 Jun 2016 12:49:40 +0000 Subject: [PATCH 0878/1223] tx: change slug to `bitcoin.qt-translation-013x` Fetch the 0.13 translations, not the 0.12 translations. --- .tx/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tx/config b/.tx/config index d6cc3aab8..3ce2ae71d 100644 --- a/.tx/config +++ b/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[bitcoin.qt-translation-012x] +[bitcoin.qt-translation-013x] file_filter = src/qt/locale/bitcoin_.ts source_file = src/qt/locale/bitcoin_en.ts source_lang = en From 3b2dadc8d5bbe1f2485fd9e9cef0df31dffa2f57 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Jun 2016 09:47:37 +0000 Subject: [PATCH 0879/1223] qt: Periodic translations update --- src/Makefile.qt.include | 6 +- src/qt/bitcoin_locale.qrc | 6 +- src/qt/bitcoinstrings.cpp | 5 + src/qt/locale/bitcoin_af.ts | 253 +--- src/qt/locale/bitcoin_af_ZA.ts | 403 +------ src/qt/locale/bitcoin_ar.ts | 943 +-------------- src/qt/locale/bitcoin_be_BY.ts | 725 +----------- src/qt/locale/bitcoin_bg.ts | 1135 +----------------- src/qt/locale/bitcoin_bg_BG.ts | 157 --- src/qt/locale/bitcoin_bs.ts | 169 --- src/qt/locale/bitcoin_ca.ts | 1371 +--------------------- src/qt/locale/bitcoin_ca@valencia.ts | 1345 +-------------------- src/qt/locale/bitcoin_ca_ES.ts | 1371 +--------------------- src/qt/locale/bitcoin_cs.ts | 1383 +--------------------- src/qt/locale/bitcoin_cs_CZ.ts | 371 +----- src/qt/locale/bitcoin_cy.ts | 333 +----- src/qt/locale/bitcoin_da.ts | 1575 ++++--------------------- src/qt/locale/bitcoin_de.ts | 1465 ++--------------------- src/qt/locale/bitcoin_el.ts | 149 +-- src/qt/locale/bitcoin_el_GR.ts | 1204 +------------------ src/qt/locale/bitcoin_en.ts | 69 +- src/qt/locale/bitcoin_en_GB.ts | 1577 ++++--------------------- src/qt/locale/bitcoin_eo.ts | 1069 +---------------- src/qt/locale/bitcoin_es.ts | 1578 ++++--------------------- src/qt/locale/bitcoin_es_419.ts | 173 --- src/qt/locale/bitcoin_es_AR.ts | 239 +--- src/qt/locale/bitcoin_es_CL.ts | 768 +----------- src/qt/locale/bitcoin_es_CO.ts | 266 +---- src/qt/locale/bitcoin_es_DO.ts | 1074 +---------------- src/qt/locale/bitcoin_es_ES.ts | 251 +--- src/qt/locale/bitcoin_es_MX.ts | 695 +---------- src/qt/locale/bitcoin_es_UY.ts | 274 +---- src/qt/locale/bitcoin_es_VE.ts | 583 +--------- src/qt/locale/bitcoin_et.ts | 837 +------------- src/qt/locale/bitcoin_eu_ES.ts | 479 +------- src/qt/locale/bitcoin_fa.ts | 1091 +++-------------- src/qt/locale/bitcoin_fa_IR.ts | 579 +--------- src/qt/locale/bitcoin_fi.ts | 1371 +--------------------- src/qt/locale/bitcoin_fil.ts | 157 --- src/qt/locale/bitcoin_fr.ts | 1607 ++++---------------------- src/qt/locale/bitcoin_fr_CA.ts | 121 +- src/qt/locale/bitcoin_fr_FR.ts | 1058 +---------------- src/qt/locale/bitcoin_gl.ts | 1015 +--------------- src/qt/locale/bitcoin_he.ts | 1425 ++++------------------- src/qt/locale/bitcoin_hi_IN.ts | 461 +------- src/qt/locale/bitcoin_hr.ts | 835 +------------ src/qt/locale/bitcoin_hu.ts | 1063 +---------------- src/qt/locale/bitcoin_id_ID.ts | 1203 +------------------ src/qt/locale/bitcoin_it.ts | 1383 +--------------------- src/qt/locale/bitcoin_it_IT.ts | 187 +-- src/qt/locale/bitcoin_ja.ts | 1579 ++++--------------------- src/qt/locale/bitcoin_ka.ts | 1121 +----------------- src/qt/locale/bitcoin_kk_KZ.ts | 159 +-- src/qt/locale/bitcoin_ko_KR.ts | 1399 +--------------------- src/qt/locale/bitcoin_ku_IQ.ts | 272 +++++ src/qt/locale/bitcoin_ky.ts | 101 +- src/qt/locale/bitcoin_la.ts | 749 +----------- src/qt/locale/bitcoin_lt.ts | 887 +------------- src/qt/locale/bitcoin_lv_LV.ts | 1069 +---------------- src/qt/locale/bitcoin_mk_MK.ts | 471 +------- src/qt/locale/bitcoin_mn.ts | 561 +-------- src/qt/locale/bitcoin_ms_MY.ts | 77 +- src/qt/locale/bitcoin_nb.ts | 1383 +--------------------- src/qt/locale/bitcoin_nl.ts | 1553 +++---------------------- src/qt/locale/bitcoin_pam.ts | 705 +---------- src/qt/locale/bitcoin_pl.ts | 1533 +++--------------------- src/qt/locale/bitcoin_pt_BR.ts | 1447 ++--------------------- src/qt/locale/bitcoin_pt_PT.ts | 1447 ++--------------------- src/qt/locale/bitcoin_ro.ts | 81 +- src/qt/locale/bitcoin_ro_RO.ts | 1319 +-------------------- src/qt/locale/bitcoin_ru.ts | 1415 +---------------------- src/qt/locale/bitcoin_ru_RU.ts | 115 +- src/qt/locale/bitcoin_sk.ts | 1379 +--------------------- src/qt/locale/bitcoin_sl_SI.ts | 1319 +-------------------- src/qt/locale/bitcoin_sq.ts | 407 +------ src/qt/locale/bitcoin_sr.ts | 447 +------ src/qt/locale/bitcoin_sr@latin.ts | 461 +------- src/qt/locale/bitcoin_sv.ts | 1574 ++++--------------------- src/qt/locale/bitcoin_ta.ts | 353 +----- src/qt/locale/bitcoin_th_TH.ts | 885 +++++++++----- src/qt/locale/bitcoin_tr.ts | 1557 +++---------------------- src/qt/locale/bitcoin_tr_TR.ts | 155 +-- src/qt/locale/bitcoin_uk.ts | 1383 +--------------------- src/qt/locale/bitcoin_ur_PK.ts | 209 +--- src/qt/locale/bitcoin_uz@Cyrl.ts | 927 +-------------- src/qt/locale/bitcoin_uz@Latn.ts | 169 --- src/qt/locale/bitcoin_vi.ts | 107 +- src/qt/locale/bitcoin_vi_VN.ts | 293 +---- src/qt/locale/bitcoin_zh.ts | 77 -- src/qt/locale/bitcoin_zh_CN.ts | 1396 +--------------------- src/qt/locale/bitcoin_zh_HK.ts | 253 ---- src/qt/locale/bitcoin_zh_TW.ts | 1581 ++++--------------------- 92 files changed, 4059 insertions(+), 68173 deletions(-) delete mode 100644 src/qt/locale/bitcoin_bg_BG.ts delete mode 100644 src/qt/locale/bitcoin_bs.ts delete mode 100644 src/qt/locale/bitcoin_es_419.ts delete mode 100644 src/qt/locale/bitcoin_fil.ts create mode 100644 src/qt/locale/bitcoin_ku_IQ.ts delete mode 100644 src/qt/locale/bitcoin_uz@Latn.ts diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index dc775a356..36a21dd06 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -7,9 +7,7 @@ QT_TS = \ qt/locale/bitcoin_af_ZA.ts \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ - qt/locale/bitcoin_bg_BG.ts \ qt/locale/bitcoin_bg.ts \ - qt/locale/bitcoin_bs.ts \ qt/locale/bitcoin_ca_ES.ts \ qt/locale/bitcoin_ca.ts \ qt/locale/bitcoin_ca@valencia.ts \ @@ -23,7 +21,6 @@ QT_TS = \ qt/locale/bitcoin_en_GB.ts \ qt/locale/bitcoin_en.ts \ qt/locale/bitcoin_eo.ts \ - qt/locale/bitcoin_es_419.ts \ qt/locale/bitcoin_es_AR.ts \ qt/locale/bitcoin_es_CL.ts \ qt/locale/bitcoin_es_CO.ts \ @@ -37,7 +34,6 @@ QT_TS = \ qt/locale/bitcoin_eu_ES.ts \ qt/locale/bitcoin_fa_IR.ts \ qt/locale/bitcoin_fa.ts \ - qt/locale/bitcoin_fil.ts \ qt/locale/bitcoin_fi.ts \ qt/locale/bitcoin_fr_CA.ts \ qt/locale/bitcoin_fr_FR.ts \ @@ -54,6 +50,7 @@ QT_TS = \ qt/locale/bitcoin_ka.ts \ qt/locale/bitcoin_kk_KZ.ts \ qt/locale/bitcoin_ko_KR.ts \ + qt/locale/bitcoin_ku_IQ.ts \ qt/locale/bitcoin_ky.ts \ qt/locale/bitcoin_la.ts \ qt/locale/bitcoin_lt.ts \ @@ -84,7 +81,6 @@ QT_TS = \ qt/locale/bitcoin_uk.ts \ qt/locale/bitcoin_ur_PK.ts \ qt/locale/bitcoin_uz@Cyrl.ts \ - qt/locale/bitcoin_uz@Latn.ts \ qt/locale/bitcoin_vi.ts \ qt/locale/bitcoin_vi_VN.ts \ qt/locale/bitcoin_zh_CN.ts \ diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index 1acda7f28..54d36ac01 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -4,9 +4,7 @@ locale/bitcoin_af_ZA.qm locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm - locale/bitcoin_bg_BG.qm locale/bitcoin_bg.qm - locale/bitcoin_bs.qm locale/bitcoin_ca_ES.qm locale/bitcoin_ca.qm locale/bitcoin_ca@valencia.qm @@ -20,7 +18,6 @@ locale/bitcoin_en_GB.qm locale/bitcoin_en.qm locale/bitcoin_eo.qm - locale/bitcoin_es_419.qm locale/bitcoin_es_AR.qm locale/bitcoin_es_CL.qm locale/bitcoin_es_CO.qm @@ -34,7 +31,6 @@ locale/bitcoin_eu_ES.qm locale/bitcoin_fa_IR.qm locale/bitcoin_fa.qm - locale/bitcoin_fil.qm locale/bitcoin_fi.qm locale/bitcoin_fr_CA.qm locale/bitcoin_fr_FR.qm @@ -51,6 +47,7 @@ locale/bitcoin_ka.qm locale/bitcoin_kk_KZ.qm locale/bitcoin_ko_KR.qm + locale/bitcoin_ku_IQ.qm locale/bitcoin_ky.qm locale/bitcoin_la.qm locale/bitcoin_lt.qm @@ -81,7 +78,6 @@ locale/bitcoin_uk.qm locale/bitcoin_ur_PK.qm locale/bitcoin_uz@Cyrl.qm - locale/bitcoin_uz@Latn.qm locale/bitcoin_vi.qm locale/bitcoin_vi_VN.qm locale/bitcoin_zh_CN.qm diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 83901732a..7cf32cd34 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -165,6 +165,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = " "no limit (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Unable to rewind the database to a pre-fork state. You will need to " +"redownload the blockchain"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Unsupported argument -socks found. Setting SOCKS version isn't possible " "anymore, only SOCKS5 proxies are supported."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -308,11 +311,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (def QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Rewinding blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block cost (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 492c7bccd..7c2d294c7 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -21,10 +21,6 @@ &Copy &Dupliseer - - &Copy Address - &Dupliseer Adres - Delete the currently selected address from the list Verwyder die adres wat u gekies het van die lys @@ -41,61 +37,6 @@ &Delete &Vee uit - - Choose the address to send coins to - Kies die adres waarheen u munte wil stuur - - - Choose the address to receive coins with - Kies die adres wat die munte moet ontvang - - - Sending addresses - Stuurders adresse - - - Receiving addresses - Ontvanger adresse - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Hierdie is die adresse vanwaar u Bitcoin betalings stuur. U moet altyd die bedrag en die adres van die ontvanger nagaan voordat u enige munte stuur. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Hierdie is die adresse waar u Bitcoins sal ontvang. Ons beveel aan dat u 'n nuwe adres kies vir elke transaksie - - - &Edit - &Verander - - - Export Address List - Voer adreslys uit - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Exporting Failed - Uitvoer was onsuksesvol - - - There was an error trying to save the address list to %1. Please try again. - Die adreslys kon nie in %1 gestoor word nie. Probeer asseblief weer. - - - - AddressTableModel - - Address - Adres - - - (no label) - (geen etiket) - AskPassphraseDialog @@ -115,87 +56,7 @@ Repeat new passphrase Herhaal nuwe wagwoord - - Encrypt wallet - Kodifiseer beursie - - - This operation needs your wallet passphrase to unlock the wallet. - U het u beursie se wagwoord nodig om toegang tot u beursie te verkry. - - - Unlock wallet - Sluit beursie oop - - - This operation needs your wallet passphrase to decrypt the wallet. - U het u beursie se wagwoord nodig om u beursie se kode te ontsyfer. - - - Decrypt wallet - Ontsleutel beursie - - - Change passphrase - Verander wagwoord - - - Confirm wallet encryption - Bevestig dat die beursie gekodifiseer is - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Waarskuwing: Indien u die beursie kodifiseer en u vergeet u wagwoord <b>VERLOOR U AL U BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Is u seker dat u die beursie wil kodifiseer? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Kern gaan nou toemaak om die kodifikasie af te handel. Onthou dat die kodifikasie van u beursie nie altyd u munte kan beskerm teen diefstal deur kwaadwillige sagteware op u rekenaar nie. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - BELANGRIK: Alle vorige kopieë en rugsteun-weergawes wat u tevore van die gemaak het, moet vervang word met die jongste weergawe van u nuutste gekodifiseerde beursie. Alle vorige weergawes en rugsteun-kopieë van u beursie sal nutteloos raak die oomblik wat u die nuut-gekodifiseerde beursie begin gebruik. - - - Warning: The Caps Lock key is on! - WAARSKUWING: Outomatiese Kapitalisering is aktief op u sleutelbord! - - - Wallet encrypted - Beursie gekodifiseer - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Tik die nuwe wagwoord vir u beursie.<br/>Gerbuik asseblief 'n wagwoord met <b>tien of meer lukrake karakters</b>, of <b>agt of meer woorde</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Tik die ou en die nuwe wagwoorde vir die beursie. - - - Wallet encryption failed - Kodifikasie was onsuksesvol - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Weens 'n interne fout het kodifikasie het nie geslaag nie. U beursie is nie gekodifiseer nie - - - The supplied passphrases do not match. - Die wagwoorde stem nie ooreen nie. - - - Wallet unlock failed - Die beursie is nie oopgesluit nie - - - The passphrase entered for the wallet decryption was incorrect. - U het die verkeerde wagwoord ingetik. - - + BanTableModel @@ -257,14 +118,6 @@ Open &URI... Oop & URI... - - Bitcoin Core client - Bitcoin Kern klient - - - Importing blocks from disk... - Besig om blokke vanaf die hardeskyf in te voer... - Reindexing blocks on disk... Besig met herindeksering van blokke op hardeskyf... @@ -297,10 +150,6 @@ &Receive &Ontvang - - Show information about Bitcoin Core - Vertoon inligting oor Bitcoin Kern - Show or hide the main Window Wys of versteek die hoofbladsy @@ -321,22 +170,10 @@ &Help &Help - - Bitcoin Core - Bitcoin Kern - Request payments (generates QR codes and bitcoin: URIs) Versoek betalings (genereer QR-kodes en bitcoin: URI's) - - &About Bitcoin Core - &Omtrent Bitcoin Kern - - - Modify configuration options for Bitcoin Core - Verander konfigurasie-opsies vir Bitcoin Kern - Show the list of used sending addresses and labels Vertoon die lys van gebruikte versendingsadresse en etikette @@ -350,15 +187,8 @@ Skep 'n bitcoin: URI of betalingsversoek - - ClientModel - CoinControlDialog - - (no label) - (geen etiket) - EditAddressDialog @@ -368,21 +198,9 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Kern - - - Reset all settings changes made over the GUI - Herstel al my veranderinge aan die stellings terug na die verstek-opsies - - + Intro - - Bitcoin Core - Bitcoin Kern - OpenURIDialog @@ -393,18 +211,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -413,24 +225,9 @@ ReceiveRequestDialog - - Address - Adres - - - - RecentRequestsTableModel - - (no label) - (geen etiket) - SendCoinsDialog - - (no label) - (geen etiket) - SendCoinsEntry @@ -443,60 +240,22 @@ SplashScreen - - Bitcoin Core - Bitcoin Kern - TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - - TransactionView - - Exporting Failed - Uitvoer was onsuksesvol - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Address - Adres - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Voer uit - - - Export the data in the current tab to a file - Voer die inligting op hierdie bladsy uit na 'n leer - - bitcoin-core + + Bitcoin Core + Bitcoin Kern + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) WAARSKUWING: toets die status van u netwerk, %d blokke ontvang in die laaste %d ure (%d verwag) diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index 12ac21eb8..e553fc775 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -13,21 +13,6 @@ &Delete &Verwyder - - - AddressTableModel - - Label - Etiket - - - Address - Adres - - - (no label) - (geen etiket) - AskPassphraseDialog @@ -47,70 +32,6 @@ Repeat new passphrase Herhaal nuwe wagfrase - - Encrypt wallet - Enkripteer beursie - - - This operation needs your wallet passphrase to unlock the wallet. - Hierdie operasie benodig 'n wagwoord om die beursie oop te sluit. - - - Unlock wallet - Sluit beursie oop - - - This operation needs your wallet passphrase to decrypt the wallet. - Hierdie operasie benodig 'n wagwoord om die beursie oop te sluit. - - - Decrypt wallet - Sluit beursie oop - - - Change passphrase - Verander wagfrase - - - Confirm wallet encryption - Bevestig beursie enkripsie. - - - Wallet encrypted - Die beursie is nou bewaak - - - Enter the old passphrase and new passphrase to the wallet. - Tik in die ou wagfrase en die nuwe wagfrase vir die beursie. - - - Wallet encryption failed - Die beursie kon nie bewaak word nie - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Beursie bewaaking het misluk as gevolg van 'n interne fout. Die beursie is nie bewaak nie! - - - The supplied passphrases do not match. - Die wagfrase stem nie ooreen nie - - - Wallet unlock failed - Beursie oopsluiting het misluk - - - The passphrase entered for the wallet decryption was incorrect. - Die wagfrase wat ingetik was om die beursie oop te sluit, was verkeerd. - - - Wallet decryption failed - Beursie dekripsie het misluk - - - Wallet passphrase was successfully changed. - Die beursie se wagfrase verandering was suksesvol. - BanTableModel @@ -194,9 +115,6 @@ Informasie - - ClientModel - CoinControlDialog @@ -211,18 +129,6 @@ Date Datum - - Copy address - Maak kopie van adres - - - Copy amount - Kopieer bedrag - - - (no label) - (geen etiket) - EditAddressDialog @@ -234,27 +140,7 @@ &Address &Adres - - New receiving address - Nuwe ontvangende adres - - - New sending address - Nuwe stuurende adres - - - Edit receiving address - Wysig ontvangende adres - - - Edit sending address - Wysig stuurende adres - - - Could not unlock wallet. - Kon nie die beursie oopsluit nie. - - + FreespaceChecker @@ -293,9 +179,6 @@ Vorm - - PaymentServer - PeerTableModel @@ -306,9 +189,6 @@ Bedrag - - QRImageWidget - RPCConsole @@ -326,52 +206,9 @@ &Message: &Boodskap: - - Copy amount - Kopieer bedrag - - - - ReceiveRequestDialog - - Address - Adres - - - Amount - Bedrag - - - Label - Etiket - - - Message - Boodskap - - RecentRequestsTableModel - - Date - Datum - - - Label - Etiket - - - Message - Boodskap - - - Amount - Bedrag - - - (no label) - (geen etiket) - + ReceiveRequestDialog SendCoinsDialog @@ -403,15 +240,7 @@ S&end S&tuur - - Copy amount - Kopieer bedrag - - - (no label) - (geen etiket) - - + SendCoinsEntry @@ -447,234 +276,12 @@ TrafficGraphWidget - - TransactionDesc - - Date - Datum - - - From - Van - - - To - Na - - - own address - eie adres - - - label - etiket - - - Credit - Krediet - - - not accepted - nie aanvaar nie - - - Debit - Debiet - - - Transaction fee - Transaksie fooi - - - Net amount - Netto bedrag - - - Message - Boodskap - - - Transaction ID - Transaksie ID - - - Transaction - Transaksie - - - Amount - Bedrag - - - true - waar - - - false - onwaar - - - unknown - onbekend - - TransactionDescDialog - - TransactionTableModel - - Date - Datum - - - Type - Tipe - - - Label - Etiket - - - Received with - Ontvang met - - - Received from - Ontvang van - - - Sent to - Gestuur na - - - Payment to yourself - Betalings Aan/na jouself - - - Mined - Gemyn - - - (n/a) - (n.v.t) - - - Date and time that the transaction was received. - Datum en tyd wat die transaksie ontvang was. - - - Type of transaction. - Tipe transaksie. - - - - TransactionView - - All - Alles - - - Today - Vandag - - - This week - Hierdie week - - - This month - Hierdie maand - - - Last month - Verlede maand - - - This year - Hierdie jaar - - - Range... - Reeks... - - - Received with - Ontvang met - - - Sent to - Gestuur na - - - To yourself - Aan/na jouself - - - Mined - Gemyn - - - Other - Ander - - - Min amount - Min bedrag - - - Copy address - Maak kopie van adres - - - Copy amount - Kopieer bedrag - - - Date - Datum - - - Type - Tipe - - - Label - Etiket - - - Address - Adres - - - ID - ID - - - Range: - Reeks: - - - to - aan - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Stuur Munstukke - - - - WalletView - bitcoin-core @@ -689,10 +296,6 @@ Information Informasie - - This help message - Hierdie help boodskap - Loading addresses... Laai adresse... diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 1e74564ed..78fd07443 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -25,10 +25,6 @@ C&lose &اغلاق - - &Copy Address - انسخ العنوان - Delete the currently selected address from the list حذف العنوان المحدد من القائمة @@ -45,73 +41,6 @@ &Delete &أمسح - - Choose the address to send coins to - اختر العنوان الذي سترسل له العملات - - - Choose the address to receive coins with - اختر العنوان الذي تستقبل عليه العملات - - - C&hoose - &اختر - - - Sending addresses - ارسال العناوين - - - Receiving addresses - استقبال العناوين - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - هذه هي عناوين Bitcion التابعة لك من أجل إرسال الدفعات. تحقق دائما من المبلغ و عنوان المرسل المستقبل قبل إرسال العملات - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - هذه هي عناوين Bitcion التابعة لك من أجل إستقبال الدفعات. ينصح استخدام عنوان جديد من أجل كل صفقة - - - Copy &Label - نسخ &الوصف - - - &Edit - تعديل - - - Export Address List - تصدير قائمة العناوين - - - Comma separated file (*.csv) - ملف مفصول بفواصل (*.csv) - - - Exporting Failed - فشل التصدير - - - There was an error trying to save the address list to %1. Please try again. - لقد حدث خطأ أثناء حفظ قائمة العناوين إلى %1. يرجى المحاولة مرة أخرى. - - - - AddressTableModel - - Label - وصف - - - Address - عنوان - - - (no label) - (لا وصف) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase ادخل كلمة المرور الجديدة مرة أخرى - - Encrypt wallet - تشفير المحفظة - - - This operation needs your wallet passphrase to unlock the wallet. - هذه العملية تحتاج كلمة مرور محفظتك لفتحها - - - Unlock wallet - إفتح المحفظة - - - This operation needs your wallet passphrase to decrypt the wallet. - هذه العملية تحتاج كلمة مرور محفظتك لفك تشفيرها - - - Decrypt wallet - فك تشفير المحفظة - - - Change passphrase - تغيير كلمة المرور - - - Confirm wallet encryption - تأكيد تشفير المحفظة - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - تحذير: إذا قمت بتشفير محفظتك وفقدت كلمة المرور الخاص بك, ستفقد كل عملات BITCOINS الخاصة بك. - - - Are you sure you wish to encrypt your wallet? - هل أنت متأكد من رغبتك في تشفير محفظتك ؟ - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - بتكوين سوف يغلق الآن لإنهاء عملية التشفير. تذكر أن التشفير لا يستطيع حماية محفظتك تمامًا من السرقة من خلال البرمجيات الخبيثة التي تصيب جهازك - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - هام: أي نسخة إحتياطية سابقة قمت بها لمحفظتك يجب استبدالها بأخرى حديثة، مشفرة. لأسباب أمنية، النسخ الاحتياطية السابقة لملفات المحفظة الغير مشفرة تصبح عديمة الفائدة مع بداية استخدام المحفظة المشفرة الجديدة. - - - Warning: The Caps Lock key is on! - تحذير: مفتاح الحروف الكبيرة مفعل - - - Wallet encrypted - محفظة مشفرة - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - أدخل عبارة مرور جديدة إلى المحفظة. الرجاء استخدام عبارة مرور تتكون من10 حروف عشوائية على الاقل, أو أكثر من 7 كلمات - - - Enter the old passphrase and new passphrase to the wallet. - أدخل كلمة المرور القديمة والجديدة للمحفظة. - - - Wallet encryption failed - فشل تشفير المحفظة - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - فشل تشفير المحفظة بسبب خطأ داخلي. لم يتم تشفير محفظتك. - - - The supplied passphrases do not match. - كلمتي المرور ليستا متطابقتان - - - Wallet unlock failed - فشل فتح المحفظة - - - The passphrase entered for the wallet decryption was incorrect. - كلمة المرور التي تم إدخالها لفك تشفير المحفظة غير صحيحة. - - - Wallet decryption failed - فشل فك التشفير المحفظة - - - Wallet passphrase was successfully changed. - لقد تم تغير عبارة مرور المحفظة بنجاح - BanTableModel @@ -269,9 +110,17 @@ Quit application الخروج من التطبيق + + &About %1 + &عن %1 + + + Show information about %1 + أظهر المعلومات حولة %1 + About &Qt - عن + عن &Qt Show information about Qt @@ -305,14 +154,6 @@ Open &URI... افتح &URI... - - Bitcoin Core client - عميل bitcion core - - - Importing blocks from disk... - استيراد كتل من القرص ... - Reindexing blocks on disk... إعادة الفهرسة الكتل على القرص ... @@ -357,10 +198,6 @@ &Receive &استقبل - - Show information about Bitcoin Core - اظهار معلومات حول bitcion core - &Show / Hide &عرض / اخفاء @@ -397,22 +234,10 @@ Tabs toolbar شريط أدوات علامات التبويب - - Bitcoin Core - جوهر البيت كوين - Request payments (generates QR codes and bitcoin: URIs) أطلب دفعات (يولد كودات الرمز المربع وبيت كوين: العناوين المعطاة) - - &About Bitcoin Core - حول bitcoin core - - - Modify configuration options for Bitcoin Core - تغيير خيارات الإعداد لأساس Bitcoin - Show the list of used sending addresses and labels عرض قائمة عناوين الإرسال المستخدمة والملصقات @@ -429,6 +254,14 @@ &Command-line options &خيارات سطر الأوامر + + Indexing blocks on disk... + ترتيب الفهرسة الكتل على القرص... + + + Processing blocks on disk... + معالجة الكتل على القرص... + No block source available... لا يوجد أي مصدر الكتلة @@ -490,13 +323,6 @@ المحفظة <b>مشفرة</b> و <b>مقفلة</b> حاليا - - ClientModel - - Network Alert - تنبيه من الشبكة - - CoinControlDialog @@ -551,114 +377,6 @@ Priority أفضلية - - Copy address - انسخ عنوان - - - Copy label - انسخ التسمية - - - Copy amount - نسخ الكمية - - - Copy transaction ID - نسخ رقم العملية - - - Copy quantity - نسخ الكمية - - - Copy fee - نسخ الرسوم - - - Copy after fee - نسخ بعد الرسوم - - - Copy priority - نسخ الافضلية - - - Copy change - نسخ التعديل - - - highest - الاعلى - - - higher - اعلى - - - high - عالي - - - medium-high - متوسط-مرتفع - - - medium - متوسط - - - low-medium - متوسط-منخفض - - - low - منخفض - - - lower - أدنى - - - lowest - الأدنى - - - none - لا شيء - - - This label turns red if the transaction size is greater than 1000 bytes. - هذا الملصق يصبح أخمرا إذا كان حجم المعاملة أكبر من 1000 بايت. - - - yes - نعم - - - no - لا - - - This means a fee of at least %1 per kB is required. - هذا يعني أن من المطلوب أن يكون الرسم ألى الأقل %1 لكل كيلوبايت. - - - Can vary +/- 1 byte per input. - يمكن أن يتفاوت بـ 1 بايت لكل مساهمة. - - - Transactions with higher priority are more likely to get included into a block. - المعاملات التي لديها أولوية أعلى على الأرجح سيتم إنضمامها في الكتلة. - - - (no label) - (لا وصف) - - - (change) - (تغير) - EditAddressDialog @@ -674,38 +392,6 @@ &Address &العنوان - - New receiving address - عنوان أستلام جديد - - - New sending address - عنوان إرسال جديد - - - Edit receiving address - تعديل عنوان الأستلام - - - Edit sending address - تعديل عنوان الارسال - - - The entered address "%1" is already in the address book. - هدا العنوان "%1" موجود مسبقا في دفتر العناوين - - - The entered address "%1" is not a valid Bitcoin address. - العنوان المدخل "%1" ليس عنوان بيت كوين صحيح. - - - Could not unlock wallet. - يمكن فتح المحفظة. - - - New key generation failed. - فشل توليد مفتاح جديد. - FreespaceChecker @@ -732,18 +418,10 @@ HelpMessageDialog - - Bitcoin Core - جوهر البيت كوين - version النسخة - - About Bitcoin Core - عن جوهر البيت كوين - Command-line options خيارات سطر الأوامر @@ -772,11 +450,7 @@ Show splash screen on startup (default: %u) أظهر شاشة البداية عند بدء التشغيل (افتراضي: %u) - - Reset all settings changes made over the GUI - إعادة تعيين كل الإعدادات تم تغييرها من خلال الواجهة الرسومية - - + Intro @@ -791,10 +465,6 @@ Use a custom data directory: استخدام دليل بيانات مخصص: - - Bitcoin Core - جوهر البيت كوين - Error خطأ @@ -806,10 +476,6 @@ Select payment request file حدد ملف طلب الدفع - - Select payment request file to open - حدد ملف طلب الدفع لفتحه - OptionsDialog @@ -925,13 +591,6 @@ رصيدك الكلي الحالي - - PaymentServer - - Bad response from server %1 - استجابة سيئة من الملقم %1 - - PeerTableModel @@ -954,25 +613,6 @@ غير معروف - - QRImageWidget - - &Save Image... - &حفظ الصورة - - - &Copy Image - &نسخ الصورة - - - Save QR Code - حفظ رمز الاستجابة السريعة QR - - - PNG Image (*.png) - صورة PNG (*.png) - - RPCConsole @@ -1063,10 +703,6 @@ Out: خارج: - - Build date - وقت البناء - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة @@ -1134,18 +770,6 @@ Remove ازل - - Copy label - انسخ التسمية - - - Copy message - انسخ الرسالة - - - Copy amount - نسخ الكمية - ReceiveRequestDialog @@ -1165,58 +789,7 @@ &Save Image... &حفظ الصورة - - Payment information - معلومات الدفع - - - URI - URI - - - Address - عنوان - - - Amount - المبلغ - - - Label - وصف - - - Message - رسالة - - - - RecentRequestsTableModel - - Date - التاريخ - - - Label - وصف - - - Message - رسالة - - - Amount - المبلغ - - - (no label) - (لا وصف) - - - (no message) - ( لا رسائل ) - - + SendCoinsDialog @@ -1259,6 +832,10 @@ Transaction Fee: رسوم المعاملة: + + Hide + إخفاء + Send to multiple recipients at once إرسال إلى عدة مستلمين في وقت واحد @@ -1287,59 +864,7 @@ S&end &ارسال - - Confirm send coins - تأكيد الإرسال Coins - - - %1 to %2 - %1 الى %2 - - - Copy quantity - نسخ الكمية - - - Copy amount - نسخ الكمية - - - Copy fee - نسخ الرسوم - - - Copy after fee - نسخ بعد الرسوم - - - Copy priority - نسخ الافضلية - - - Copy change - نسخ التعديل - - - or - أو - - - The amount to pay must be larger than 0. - المبلغ المدفوع يجب ان يكون اكبر من 0 - - - The amount exceeds your balance. - القيمة تتجاوز رصيدك - - - The total exceeds your balance when the %1 transaction fee is included. - المجموع يتجاوز رصيدك عندما يتم اضافة %1 رسوم العملية - - - (no label) - (لا وصف) - - + SendCoinsEntry @@ -1350,10 +875,6 @@ Pay &To: ادفع &الى : - - Enter a label for this address to add it to your address book - إدخال تسمية لهذا العنوان لإضافته إلى دفتر العناوين الخاص بك - &Label: &وصف : @@ -1432,61 +953,9 @@ Verify &Message تحقق &الرسالة - - Click "Sign Message" to generate signature - اضغط "توقيع الرسالة" لتوليد التوقيع - - - The entered address is invalid. - العنوان المدخل غير صالح - - - Please check the address and try again. - الرجاء التأكد من العنوان والمحاولة مرة اخرى - - - The entered address does not refer to a key. - العنوان المدخل لا يشير الى مفتاح - - - Wallet unlock was cancelled. - تم الغاء عملية فتح المحفظة - - - Private key for the entered address is not available. - المفتاح الخاص للعنوان المدخل غير موجود. - - - Message signing failed. - فشل توقيع الرسالة. - - - Message signed. - الرسالة موقعة. - - - Please check the signature and try again. - فضلا تاكد من التوقيع وحاول مرة اخرى - - - Message verification failed. - فشلت عملية التأكد من الرسالة. - - - Message verified. - تم تأكيد الرسالة. - - + SplashScreen - - Bitcoin Core - جوهر البيت كوين - - - The Bitcoin Core developers - مطوري جوهر البيت كوين - [testnet] [testnet] @@ -1495,362 +964,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - مفتوح حتى %1 - - - conflicted - يتعارض - - - %1/offline - %1 غير متواجد - - - %1/unconfirmed - غير مؤكدة/%1 - - - %1 confirmations - تأكيد %1 - - - Status - الحالة. - - - Date - التاريخ - - - Source - المصدر - - - Generated - تم اصداره. - - - From - من - - - To - الى - - - own address - عنوانه - - - label - علامة - - - not accepted - غير مقبولة - - - Debit - دين - - - Transaction fee - رسوم المعاملة - - - Message - رسالة - - - Comment - تعليق - - - Transaction ID - رقم المعاملة - - - Merchant - تاجر - - - Transaction - معاملة - - - Amount - المبلغ - - - true - صحيح - - - false - خاطئ - - - , has not been successfully broadcast yet - , لم يتم حتى الآن البث بنجاح - - - unknown - غير معروف - - TransactionDescDialog - - Transaction details - تفاصيل المعاملة - This pane shows a detailed description of the transaction يبين هذا الجزء وصفا مفصلا لهده المعاملة - - TransactionTableModel - - Date - التاريخ - - - Type - النوع - - - Open until %1 - مفتوح حتى %1 - - - This block was not received by any other nodes and will probably not be accepted! - لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة! - - - Generated but not accepted - ولدت ولكن لم تقبل - - - Offline - غير متصل - - - Label - وصف - - - Conflicted - يتعارض - - - Received with - استقبل مع - - - Received from - استقبل من - - - Sent to - أرسل إلى - - - Payment to yourself - دفع لنفسك - - - Mined - Mined - - - (n/a) - غير متوفر - - - Transaction status. Hover over this field to show number of confirmations. - حالة المعاملة. تحوم حول هذا الحقل لعرض عدد التأكيدات. - - - Date and time that the transaction was received. - التاريخ والوقت الذي تم فيه تلقي المعاملة. - - - Type of transaction. - نوع المعاملات - - - Amount removed from or added to balance. - المبلغ الذي أزيل أو أضيف الى الرصيد - - - - TransactionView - - All - الكل - - - Today - اليوم - - - This week - هدا الاسبوع - - - This month - هدا الشهر - - - Last month - الشهر الماضي - - - This year - هدا العام - - - Range... - المدى... - - - Received with - استقبل مع - - - Sent to - أرسل إلى - - - To yourself - إليك - - - Mined - Mined - - - Other - اخرى - - - Enter address or label to search - ادخل عنوان أووصف للبحث - - - Min amount - الحد الأدنى - - - Copy address - انسخ عنوان - - - Copy label - انسخ التسمية - - - Copy amount - نسخ الكمية - - - Copy transaction ID - نسخ رقم العملية - - - Edit label - عدل الوصف - - - Show transaction details - عرض تفاصيل المعاملة - - - Exporting Failed - فشل التصدير - - - Exporting Successful - نجح التصدير - - - Comma separated file (*.csv) - ملف مفصول بفواصل (*.csv) - - - Confirmed - تأكيد - - - Date - التاريخ - - - Type - النوع - - - Label - وصف - - - Address - عنوان - - - ID - العنوان - - - Range: - المدى: - - - to - الى - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - إرسال Coins - - - - WalletView - - &Export - &تصدير - - - Export the data in the current tab to a file - تحميل البيانات في علامة التبويب الحالية إلى ملف. - - - Backup Wallet - نسخ احتياط للمحفظة - - - Backup Failed - فشل النسخ الاحتياطي - - - Backup Successful - نجاح النسخ الاحتياطي - - bitcoin-core @@ -1865,6 +988,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) قبول الاتصالات من خارج + + Bitcoin Core + جوهر البيت كوين + Error: Disk space is low! تحذير: مساحة القرص منخفضة @@ -1909,22 +1036,10 @@ Warning تحذير - - This help message - رسالة المساعدة هذه - Loading addresses... تحميل العنوان - - Error loading wallet.dat: Wallet corrupted - خطأ عند تنزيل wallet.dat: المحفظة تالفة - - - Error loading wallet.dat - خطأ عند تنزيل wallet.dat - Invalid -proxy address: '%s' عنوان البروكسي غير صحيح : '%s' diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index 2709ff37e..5894148fe 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -25,10 +25,6 @@ C&lose Зачыніць - - &Copy Address - Капіяваць адрас - Delete the currently selected address from the list Выдаліць абраны адрас са спісу @@ -45,73 +41,6 @@ &Delete Выдаліць - - Choose the address to send coins to - Выбраць адрас, куды выслаць сродкі - - - Choose the address to receive coins with - Выбраць адрас, на які атрымаць сродкі - - - C&hoose - Выбраць - - - Sending addresses - адрасы Адпраўкі - - - Receiving addresses - адрасы Прымання - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Тут знаходзяцца Біткойн-адрасы для высылання плацяжоў. Заўсёды спраўджвайце колькасць і адрас прызначэння перад здзяйсненнем транзакцыі. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Тут знаходзяцца Біткойн-адрасы для прымання плацяжоў. Пажадана выкарыстоўваць новы адрас для кожнай транзакцыі. - - - Copy &Label - Капіяваць Метку - - - &Edit - Рэдагаваць - - - Export Address List - Экспартаваць Спіс Адрасоў - - - Comma separated file (*.csv) - Коскамі падзелены файл (*.csv) - - - Exporting Failed - Экспартаванне няўдалае - - - There was an error trying to save the address list to %1. Please try again. - Адбылася памылка падчас спробы захаваць адрас у %1. Паспрабуйце зноў. - - - - AddressTableModel - - Label - Метка - - - Address - Адрас - - - (no label) - непазначаны - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Паўтарыце новую кодавую фразу - - Encrypt wallet - Зашыфраваць гаманец. - - - This operation needs your wallet passphrase to unlock the wallet. - Гэтая аперацыя патрабуе кодавую фразу, каб рзблакаваць гаманец. - - - Unlock wallet - Разблакаваць гаманец - - - This operation needs your wallet passphrase to decrypt the wallet. - Гэтая аперацыя патрабуе пароль каб расшыфраваць гаманец. - - - Decrypt wallet - Рачшыфраваць гаманец - - - Change passphrase - Змяніць пароль - - - Confirm wallet encryption - Пацвердзіце шыфраванне гаманца - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Увага: калі вы зашыфруеце свой гаманец і страціце парольную фразу, то <b>СТРАЦІЦЕ ЎСЕ СВАЕ БІТКОЙНЫ</b>! - - - Are you sure you wish to encrypt your wallet? - Ці ўпэўненыя вы, што жадаеце зашыфраваць свой гаманец? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core зараз будзе зачынены, каб фіналізаваць працэс шыфравання. Памятайце, што шыфраванне вашага гаманца не гарантуе абсалютную абарону ад магчымасці крадзяжу біткойнаў шкоднымі праграмамі, якія могуць інфікаваць ваш камп'ютар. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ВАЖНА: Усе папярэднія копіі гаманца варта замяніць новым зашыфраваным файлам. У мэтах бяспекі папярэднія копіі незашыфраванага файла-гаманца стануць неўжывальнымі, калі вы станеце карыстацца новым зашыфраваным гаманцом. - - - Warning: The Caps Lock key is on! - Увага: Caps Lock уключаны! - - - Wallet encrypted - Гаманец зашыфраваны - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Увядзіце новы пароль для гаманца.<br/>Парольная фраза павинна складацца<b> не меньш чым з дзесяці сімвалаў</b>, ці <b>больш чым з васьмі слоў</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Увядзіце стары пароль і новы пароль для гаманца. - - - Wallet encryption failed - Шыфраванне гаманца няўдалае - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Шыфраванне гаманца не адбылося з-за ўнутранай памылкі. Гаманец незашыфраваны. - - - The supplied passphrases do not match. - Уведдзеныя паролі не супадаюць - - - Wallet unlock failed - Разблакаванне гаманца няўдалае - - - The passphrase entered for the wallet decryption was incorrect. - Уведзены пароль для расшыфравання гаманца памылковы - - - Wallet decryption failed - Расшыфраванне гаманца няўдалае - - - Wallet passphrase was successfully changed. - Парольная фраза гаманца паспяхова зменена. - BanTableModel @@ -297,14 +138,6 @@ Open &URI... Адчыниць &URI... - - Bitcoin Core client - Bitcoin Core кліент - - - Importing blocks from disk... - Імпартуюцца блокі з дыску... - Reindexing blocks on disk... Пераіндэксацыя блокаў на дыску... @@ -349,10 +182,6 @@ &Receive Атрымаць - - Show information about Bitcoin Core - Паказаць інфармацыю аб Bitcoin Core - &Show / Hide &Паказаць / Схаваць @@ -385,22 +214,10 @@ &Help Дапамога - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Запатрабаваць плацёж (генеруецца QR-код для біткойн URI) - - &About Bitcoin Core - Аб Bitcoin Core - - - Modify configuration options for Bitcoin Core - Мадыфікаваць опцыі канфігурацыі Bitcoin Core - Show the list of used sending addresses and labels Паказаць спіс адрасоў і метак для дасылання @@ -417,10 +234,6 @@ &Command-line options Опцыі каманднага радка - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Паказваць даведку Bitcoin Core каб атрымаць спіс магчымых опцый каманднага радка - %n active connection(s) to Bitcoin network %n актыўнае злучэнне з сецівам Bitcoin%n актыўных злучэнняў з сецівам Bitcoin%n актыўных злучэнняў з сецівам Bitcoin%n актыўных злучэнняў з сецівам Bitcoin @@ -532,13 +345,6 @@ Гаманец <b>зашыфраваны</b> і зараз <b>заблакаваны</b> - - ClientModel - - Network Alert - Трывога Сеціва - - CoinControlDialog @@ -609,111 +415,7 @@ Priority Прыярытэт - - Copy address - Капіяваць адрас - - - Copy label - Капіяваць пазнаку - - - Copy amount - Капіяваць колькасць - - - Copy transaction ID - Капіяваць ID транзакцыі - - - Lock unspent - Замкнуць непатрачанае - - - Unlock unspent - Адамкнуць непатрачанае - - - Copy quantity - Капіяваць колькасць - - - Copy fee - Капіяваць камісію - - - Copy after fee - Капіяваць з выняткам камісіі - - - Copy bytes - Капіяваць байты - - - Copy priority - Капіяваць прыярытэт - - - Copy dust - Капіяваць пыл - - - highest - найвышэйшы - - - higher - вышэйшы - - - high - высокі - - - medium-high - вышэй сярэдняга - - - medium - сярэдні - - - low-medium - ніжэй сярэдняга - - - low - нізкі - - - lower - ніжэйшы - - - lowest - найніжэйшы - - - yes - так - - - no - не - - - This means a fee of at least %1 per kB is required. - Гэта значыць патрэбную камісію мінімум %1 на Кб. - - - Transactions with higher priority are more likely to get included into a block. - Транзакцыя большага прыярытэту больш прываблівая для ўключэння ў блок. - - - (no label) - непазначаны - - + EditAddressDialog @@ -728,34 +430,6 @@ &Address Адрас - - New receiving address - Новы адрас для атрымання - - - New sending address - Новы адрас для дасылання - - - Edit receiving address - Рэдагаваць адрас прымання - - - Edit sending address - Рэдагаваць адрас дасылання - - - The entered address "%1" is already in the address book. - Уведзены адрас "%1" ужо ў кніге адрасоў - - - Could not unlock wallet. - Немагчыма разблакаваць гаманец - - - New key generation failed. - Генерацыя новага ключа няўдалая - FreespaceChecker @@ -774,18 +448,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - (%1-bit) (%1-біт) - - About Bitcoin Core - Аб Bitcoin Core - Command-line options Опцыі каманднага радка @@ -805,14 +471,6 @@ Welcome Вітаем - - Welcome to Bitcoin Core. - Вітаем у Bitcoin Core. - - - Bitcoin Core - Bitcoin Core - Error Памылка @@ -855,9 +513,6 @@ Форма - - PaymentServer - PeerTableModel @@ -868,9 +523,6 @@ Колькасць - - QRImageWidget - RPCConsole @@ -892,60 +544,13 @@ &Label: Метка: - - Copy label - Капіяваць пазнаку - - - Copy amount - Капіяваць колькасць - - + ReceiveRequestDialog Copy &Address Капіяваць адрас - - Address - Адрас - - - Amount - Колькасць - - - Label - Метка - - - Message - Паведамленне - - - - RecentRequestsTableModel - - Date - Дата - - - Label - Метка - - - Message - Паведамленне - - - Amount - Колькасць - - - (no label) - непазначаны - SendCoinsDialog @@ -997,46 +602,6 @@ Confirm the send action Пацвердзіць дасыланне - - Confirm send coins - Пацвердзіць дасыланне манет - - - Copy quantity - Капіяваць колькасць - - - Copy amount - Капіяваць колькасць - - - Copy fee - Капіяваць камісію - - - Copy after fee - Капіяваць з выняткам камісіі - - - Copy bytes - Капіяваць байты - - - Copy priority - Капіяваць прыярытэт - - - The amount to pay must be larger than 0. - Велічыня плацяжу мае быць больш за 0. - - - (no label) - непазначаны - - - Copy dust - Капіяваць пыл - SendCoinsEntry @@ -1048,10 +613,6 @@ Pay &To: Заплаціць да: - - Enter a label for this address to add it to your address book - Увядзіце пазнаку гэтаму адрасу, каб дадаць яго ў адрасную кнігу - &Label: Метка: @@ -1101,14 +662,6 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Распрацоўнікі Bitcoin Core - [testnet] [testnet] @@ -1121,274 +674,16 @@ Кб/с - - TransactionDesc - - %1/offline - %1/offline - - - %1/unconfirmed - %1/непацверджана - - - %1 confirmations - %1 пацверджанняў - - - Status - Статус - - - Date - Дата - - - Message - Паведамленне - - - Comment - Каментар - - - Transaction ID - ID - - - Amount - Колькасць - - - , has not been successfully broadcast yet - , пакуль не было паспяхова транслявана - - - unknown - невядома - - TransactionDescDialog - - Transaction details - Дэталі транзакцыі - This pane shows a detailed description of the transaction Гэтая панэль паказвае дэтальнае апісанне транзакцыі - - TransactionTableModel - - Date - Дата - - - Type - Тып - - - Confirmed (%1 confirmations) - Пацверджана (%1 пацверджанняў) - - - This block was not received by any other nodes and will probably not be accepted! - Гэты блок не быў прыняты іншымі вузламі і магчыма не будзе ўхвалены! - - - Generated but not accepted - Згенеравана, але не прынята - - - Label - Метка - - - Received with - Прынята з - - - Received from - Прынята ад - - - Sent to - Даслана да - - - Payment to yourself - Плацёж самому сабе - - - Mined - Здабыта - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Статус транзакцыі. Навядзіце курсар на гэтае поле, каб паказаць колькасць пацверджанняў. - - - Date and time that the transaction was received. - Дата і час, калі транзакцыя была прынята. - - - Type of transaction. - Тып транзакцыі - - - Amount removed from or added to balance. - Колькасць аднятая ці даданая да балансу. - - - - TransactionView - - All - Усё - - - Today - Сёння - - - This week - Гэты тыдзень - - - This month - Гэты месяц - - - Last month - Мінулы месяц - - - This year - Гэты год - - - Range... - Прамежак... - - - Received with - Прынята з - - - Sent to - Даслана да - - - To yourself - Да сябе - - - Mined - Здабыта - - - Other - Іншыя - - - Enter address or label to search - Увядзіце адрас ці пазнаку для пошуку - - - Min amount - Мін. колькасць - - - Copy address - Капіяваць адрас - - - Copy label - Капіяваць пазнаку - - - Copy amount - Капіяваць колькасць - - - Copy transaction ID - Капіяваць ID транзакцыі - - - Edit label - Рэдагаваць пазнаку - - - Exporting Failed - Экспартаванне няўдалае - - - Comma separated file (*.csv) - Коскамі падзелены файл (*.csv) - - - Confirmed - Пацверджана - - - Date - Дата - - - Type - Тып - - - Label - Метка - - - Address - Адрас - - - ID - ID - - - Range: - Прамежак: - - - to - да - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Даслаць Манеты - - - - WalletView - - &Export - Экспарт - - - Export the data in the current tab to a file - Экспартаваць гэтыя звесткі у файл - - bitcoin-core @@ -1407,6 +702,10 @@ Run in the background as a daemon and accept commands Запусціць у фоне як дэман і прымаць каманды + + Bitcoin Core + Bitcoin Core + Do you want to rebuild the block database now? Ці жадаеце вы перабудаваць зараз базу звестак блокаў? @@ -1455,10 +754,6 @@ Wallet options: Опцыі гаманца: - - Activating best chain... - Актывацыя лепшага ланцуга... - Information Інфармацыя @@ -1507,14 +802,6 @@ Loading addresses... Загружаем адрасы... - - Error loading wallet.dat: Wallet corrupted - Памылка загрузкі wallet.dat: гаманец пашкоджаны - - - Error loading wallet.dat - Памылка загрузкі wallet.dat - Insufficient funds Недастаткова сродкаў diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 54bf8136a..3bb881318 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -25,10 +25,6 @@ C&lose Затвори - - &Copy Address - &Копирай адрес - Delete the currently selected address from the list Изтрий избрания адрес от списъка @@ -45,73 +41,6 @@ &Delete &Изтриване - - Choose the address to send coins to - Изберете адрес, на който да се изпращат монети - - - Choose the address to receive coins with - Изберете адрес, на който ще получавате монети - - - C&hoose - Избери - - - Sending addresses - Адреси за изпращане - - - Receiving addresses - Адреси за получаване - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Това са адресите на получателите на плащания. Винаги проверявайте размера на сумата и адреса на получателя, преди да изпратите монети. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Това са Вашите Биткойн адреси,благодарение на които ще получавате плащания.Препоръчително е да използвате нови адреси за получаване на всяка транзакция. - - - Copy &Label - Копирай &име - - - &Edit - &Редактирай - - - Export Address List - Изнасяне на списъка с адреси - - - Comma separated file (*.csv) - CSV файл (*.csv) - - - Exporting Failed - Грешка при изнасянето - - - There was an error trying to save the address list to %1. Please try again. - Възникна грешка при опита за запазване на списъка с адреси в %1.Моля опитайте отново. - - - - AddressTableModel - - Label - Име - - - Address - Адрес - - - (no label) - (без име) - AskPassphraseDialog @@ -131,86 +60,6 @@ Repeat new passphrase Въведете новата парола повторно - - Encrypt wallet - Шифриране на портфейла - - - This operation needs your wallet passphrase to unlock the wallet. - Тази операция изисква Вашата парола за отключване на портфейла. - - - Unlock wallet - Отключване на портфейла - - - This operation needs your wallet passphrase to decrypt the wallet. - Тази операция изисква Вашата парола за дешифриране на портфейла. - - - Decrypt wallet - Дешифриране на портфейла - - - Change passphrase - Смяна на паролата - - - Confirm wallet encryption - Потвърдете на шифрирането на портфейла - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - ВНИМАНИЕ: Ако шифрирате вашият портфейл и изгубите паролата си, <b>ЩЕ ИЗГУБИТЕ ВСИЧКИТЕ СИ БИТКОИНИ</b>! - - - Are you sure you wish to encrypt your wallet? - Наистина ли желаете да шифрирате портфейла си? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Биткоин сега ще се затоври за да завърши процеса на криптиране. Запомнете, че криптирането на вашия портефейл не може напълно да предпази вашите монети от кражба чрез зловреден софтуер, инфектирал вашия компютър - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ВАЖНО: Всички стари запазвания, които сте направили на Вашият портфейл трябва да замените с запазване на новополучения, шифриран портфейл. От съображения за сигурност, предишните запазвания на нешифрирани портфейли ще станат неизползваеми веднага, щом започнете да използвате новият, шифриран портфейл. - - - Warning: The Caps Lock key is on! - Внимание: Caps Lock (главни букви) е включен. - - - Wallet encrypted - Портфейлът е шифриран - - - Wallet encryption failed - Шифрирането беше неуспешно - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Шифрирането на портфейла беше неуспешно, поради софтуерен проблем. Портфейлът не е шифриран. - - - The supplied passphrases do not match. - Паролите не съвпадат - - - Wallet unlock failed - Неуспешно отключване на портфейла - - - The passphrase entered for the wallet decryption was incorrect. - Паролата въведена за дешифриране на портфейла е грешна. - - - Wallet decryption failed - Дешифрирането на портфейла беше неуспешно - - - Wallet passphrase was successfully changed. - Паролата на портфейла беше променена успешно. - BanTableModel @@ -293,10 +142,6 @@ Open &URI... Отвори &URI... - - Bitcoin Core client - Bitcoin Core клиент - Send coins to a Bitcoin address Изпращане към Биткоин адрес @@ -337,10 +182,6 @@ &Receive &Получаване - - Show information about Bitcoin Core - Покажете информация за Биткойн ядрото - &Show / Hide &Показване / Скриване @@ -377,18 +218,10 @@ Tabs toolbar Раздели - - Bitcoin Core - Биткойн ядро - Request payments (generates QR codes and bitcoin: URIs) Изискване на плащания(генерира QR кодове и биткойн: URIs) - - &About Bitcoin Core - &Относно Bitcoin Core - Show the list of used sending addresses and labels Показване на списъка с използвани адреси и имена @@ -405,10 +238,6 @@ &Command-line options &Налични команди - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Покажи помощните съобщения на Биткойн за да видиш наличните и валидни команди - No block source available... Липсва източник на блоковете... @@ -496,13 +325,6 @@ Портфейлът е <b>криптиран</b> и <b>заключен</b> - - ClientModel - - Network Alert - Мрежови проблем - - CoinControlDialog @@ -581,134 +403,6 @@ Priority Приоритет - - Copy address - Копирай адрес - - - Copy label - Копирай име - - - Copy amount - Копирай сума - - - Copy transaction ID - Копирай транзакция с ID - - - Lock unspent - Заключване на неизхарченото - - - Unlock unspent - Отключване на неизхарченото - - - Copy quantity - Копиране на количеството - - - Copy fee - Копиране на данък добавена стойност - - - Copy after fee - Копиране след прилагане на данък добавена стойност - - - Copy bytes - Копиране на байтовете - - - Copy priority - Копиране на приоритет - - - Copy dust - Копирай прахта: - - - Copy change - Копирай рестото - - - highest - Най-висок - - - higher - По-висок - - - high - Висок - - - medium-high - Средно-висок - - - medium - Среден - - - low-medium - Ниско-среден - - - low - Нисък - - - lower - По-нисък - - - lowest - Най-нисък - - - (%1 locked) - (%1 заключен) - - - none - нищо - - - This label turns red if the transaction size is greater than 1000 bytes. - Този етикет става червен, когато размера на транзакцията е по-голяма от 1000 бита. - - - yes - да - - - no - не - - - This means a fee of at least %1 per kB is required. - Това означава че се изисква такса от поне %1 на килобайт. - - - Can vary +/- 1 byte per input. - Може да варира с +-1 байт - - - (no label) - (без име) - - - change from %1 (%2) - ресто от %1 (%2) - - - (change) - (промени) - EditAddressDialog @@ -724,38 +418,6 @@ &Address &Адрес - - New receiving address - Нов адрес за получаване - - - New sending address - Нов адрес за изпращане - - - Edit receiving address - Редактиране на адрес за получаване - - - Edit sending address - Редактиране на адрес за изпращане - - - The entered address "%1" is already in the address book. - Вече има адрес "%1" в списъка с адреси. - - - The entered address "%1" is not a valid Bitcoin address. - "%1" не е валиден Биткоин адрес. - - - Could not unlock wallet. - Отключването на портфейла беше неуспешно. - - - New key generation failed. - Създаването на ключ беше неуспешно. - FreespaceChecker @@ -782,10 +444,6 @@ HelpMessageDialog - - Bitcoin Core - Биткойн ядро - version версия @@ -794,10 +452,6 @@ (%1-bit) (%1-битов) - - About Bitcoin Core - Относно Bitcoin Core - Command-line options Списък с команди @@ -817,14 +471,6 @@ Welcome Добре дошли - - Welcome to Bitcoin Core. - Добре дошли в Биткойн ядрото. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Тъй като това е първото стартиране на програмата можете да изберете къде Биткон ядрото да запази данните си. - Use the default data directory Използване на директория по подразбиране @@ -833,10 +479,6 @@ Use a custom data directory: Използване на директория ръчно - - Bitcoin Core - Биткойн ядро - Error Грешка @@ -899,10 +541,6 @@ &Network &Мрежа - - Automatically start Bitcoin Core after logging in to the system. - Автоматично стартиране на Bitcoin Core след влизане в системата. - W&allet По&ртфейл @@ -1071,73 +709,6 @@ Скорошни транзакции - - PaymentServer - - URI handling - Справяне с URI - - - Invalid payment address %1 - Невалиден адрес на плащане %1 - - - Payment request rejected - Заявката за плащане беше отхвърлена - - - Payment request network doesn't match client network. - Мрежата от която се извършва заявката за плащане не съвпада с мрежата на клиента. - - - Requested payment amount of %1 is too small (considered dust). - Заявената сума за плащане: %1 е твърде малка (счита се за отпадък) - - - Payment request error - Възникна грешка по време назаявката за плащане - - - Cannot start bitcoin: click-to-pay handler - Биткойн не можe да се стартира: click-to-pay handler - - - Payment request file handling - Файл за справяне със заявки - - - Payment request expired. - Заявката за плащане е изтекла. - - - Invalid payment request. - Невалидна заявка за плащане. - - - Refund from %1 - Възстановяване на сума от %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Заявката за плащане %1 е твърде голям (%2 байта, позволени %3 байта). - - - Error communicating with %1: %2 - Грешка при комуникацията с %1: %2 - - - Bad response from server %1 - Възникна проблем при свързването със сървър %1 - - - Payment acknowledged - Плащането е прието - - - Network request error - Грешка в мрежата по време на заявката - - PeerTableModel @@ -1188,25 +759,6 @@ %1 милисекунда - - QRImageWidget - - &Save Image... - &Запиши изображение... - - - &Copy Image - &Копирай изображение - - - Save QR Code - Запази QR Код - - - PNG Image (*.png) - PNG Изображение (*.png) - - RPCConsole @@ -1337,10 +889,6 @@ Out: Изходящи - - Build date - Дата на създаване - Debug log file Лог файл,съдържащ грешките @@ -1448,18 +996,6 @@ Remove Премахване - - Copy label - Копирай име - - - Copy message - Копиране на съобщението - - - Copy amount - Копирай сума - ReceiveRequestDialog @@ -1479,65 +1015,6 @@ &Save Image... &Запиши изображение... - - Request payment to %1 - Изискване на плащане от %1 - - - Payment information - Данни за плащането - - - Address - Адрес - - - Amount - Сума - - - Label - Име - - - Message - Съобщение - - - Error encoding URI into QR Code. - Грешка при създаването на QR Code от URI. - - - - RecentRequestsTableModel - - Date - Дата - - - Label - Име - - - Message - Съобщение - - - Amount - Сума - - - (no label) - (без име) - - - (no message) - (без съобщение) - - - (no amount) - (липсва сума) - SendCoinsDialog @@ -1661,86 +1138,6 @@ S&end И&зпрати - - Confirm send coins - Потвърждаване - - - Copy quantity - Копиране на количеството - - - Copy amount - Копирай сума - - - Copy fee - Копиране на данък добавена стойност - - - Copy after fee - Копиране след прилагане на данък добавена стойност - - - Copy bytes - Копиране на байтовете - - - Copy priority - Копиране на приоритет - - - Copy change - Копирай рестото - - - or - или - - - The amount to pay must be larger than 0. - Сумата трябва да е по-голяма от 0. - - - The amount exceeds your balance. - Сумата надвишава текущия баланс - - - The total exceeds your balance when the %1 transaction fee is included. - Сумата при добавяне на данък добавена стойност по %1 транзакцията надвишава сумата по вашата сметка. - - - Transaction creation failed! - Грешка при създаването на транзакция! - - - Payment request expired. - Заявката за плащане е изтекла. - - - Warning: Invalid Bitcoin address - Внимание: Невалиден Биткойн адрес - - - (no label) - (без име) - - - Warning: Unknown change address - Внимание:Неизвестен адрес за промяна - - - Copy dust - Копирай прахта: - - - Are you sure you want to send? - Наистина ли искате да изпратите? - - - added as transaction fee - добавено като такса за транзакция - SendCoinsEntry @@ -1752,10 +1149,6 @@ Pay &To: Плати &На: - - Enter a label for this address to add it to your address book - Въведете име за този адрес, за да го добавите в списъка с адреси - &Label: &Име: @@ -1799,10 +1192,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Биткойн ядрото се изключва... - Do not shut down the computer until this window disappears. Не изключвайте компютъра докато този прозорец не изчезне. @@ -1870,69 +1259,9 @@ Verify &Message Потвърди &съобщението - - Click "Sign Message" to generate signature - Натиснете "Подписване на съобщение" за да създадете подпис - - - The entered address is invalid. - Въведеният адрес е невалиден. - - - Please check the address and try again. - Моля проверете адреса и опитайте отново. - - - The entered address does not refer to a key. - Въведеният адрес не може да се съпостави с валиден ключ. - - - Wallet unlock was cancelled. - Отключването на портфейла беше отменено. - - - Private key for the entered address is not available. - Не е наличен частен ключ за въведеният адрес. - - - Message signing failed. - Подписването на съобщение беше неуспешно. - - - Message signed. - Съобщението е подписано. - - - The signature could not be decoded. - Подписът не може да бъде декодиран. - - - Please check the signature and try again. - Проверете подписа и опитайте отново. - - - The signature did not match the message digest. - Подписът не отговаря на комбинацията от съобщение и адрес. - - - Message verification failed. - Проверката на съобщението беше неуспешна. - - - Message verified. - Съобщението е потвърдено. - - + SplashScreen - - Bitcoin Core - Биткойн ядро - - - The Bitcoin Core developers - Разработчици на Bitcoin Core - [testnet] [testnet] @@ -1945,438 +1274,16 @@ Килобайта в секунда - - TransactionDesc - - Open until %1 - Подлежи на промяна до %1 - - - conflicted - припокриващ се - - - %1/offline - %1/офлайн - - - %1/unconfirmed - %1/непотвърдени - - - %1 confirmations - включена в %1 блока - - - Status - Статус - - - Date - Дата - - - Source - Източник - - - Generated - Издадени - - - From - От - - - To - За - - - own address - собствен адрес - - - watch-only - само гледане - - - label - име - - - Credit - Кредит - - - not accepted - не е приет - - - Debit - Дебит - - - Total debit - Общ дълг - - - Total credit - Общ дълг - - - Transaction fee - Такса - - - Net amount - Нетна сума - - - Message - Съобщение - - - Comment - Коментар - - - Transaction ID - ID - - - Merchant - Търговец - - - 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. - Генерираните монети трябва да отлежат %1 блока преди да могат да бъдат похарчени. Когато генерираш блока, той се разпространява в мрежата, за да се добави в блок-веригата. Ако не успее да се добави във веригата, неговия статус ще се стане "неприет" и няма да може да се похарчи. Това е възможно да се случи случайно, ако друг възел генерира блок няколко секунди след твоя. - - - Debug information - Информация за грешките - - - Transaction - Транзакция - - - Amount - Сума - - - true - true - - - false - false - - - , has not been successfully broadcast yet - , все още не е изпратено - - - unknown - неизвестен - - TransactionDescDialog - - Transaction details - Транзакция - This pane shows a detailed description of the transaction Описание на транзакцията - - TransactionTableModel - - Date - Дата - - - Type - Тип - - - Immature (%1 confirmations, will be available after %2) - Неплатим (%1 потвърждения, ще бъде платим след %2) - - - Open until %1 - Подлежи на промяна до %1 - - - Confirmed (%1 confirmations) - Потвърдени (%1 потвърждения) - - - This block was not received by any other nodes and will probably not be accepted! - Блокът не е получен от останалите участници и най-вероятно няма да бъде одобрен. - - - Generated but not accepted - Генерирана, но отхвърлена от мрежата - - - Offline - Извън линия - - - Label - Име - - - Unconfirmed - Непотвърдено - - - Confirming (%1 of %2 recommended confirmations) - Потвърждаване (%1 от %2 препоръчвани потвърждения) - - - Conflicted - Конфликтно - - - Received with - Получени - - - Received from - Получен от - - - Sent to - Изпратени на - - - Payment to yourself - Плащане към себе си - - - Mined - Емитирани - - - watch-only - само гледане - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Състояние на транзакцията. Задръжте върху това поле за брой потвърждения. - - - Date and time that the transaction was received. - Дата и час на получаване на транзакцията. - - - Type of transaction. - Вид транзакция. - - - Amount removed from or added to balance. - Сума извадена или добавена към баланса. - - - - TransactionView - - All - Всички - - - Today - Днес - - - This week - Тази седмица - - - This month - Този месец - - - Last month - Предния месец - - - This year - Тази година - - - Range... - От - до... - - - Received with - Получени - - - Sent to - Изпратени на - - - To yourself - Собствени - - - Mined - Емитирани - - - Other - Други - - - Enter address or label to search - Търсене по адрес или име - - - Min amount - Минимална сума - - - Copy address - Копирай адрес - - - Copy label - Копирай име - - - Copy amount - Копирай сума - - - Copy transaction ID - Копирай транзакция с ID - - - Edit label - Редактирай име - - - Show transaction details - Подробности за транзакцията - - - Export Transaction History - Изнасяне историята на транзакциите - - - Watch-only - само гледане - - - Exporting Failed - Грешка при изнасянето - - - Exporting Successful - Изнасянето е успешна - - - The transaction history was successfully saved to %1. - Историята с транзакциите беше успешно запазена в %1. - - - Comma separated file (*.csv) - CSV файл (*.csv) - - - Confirmed - Потвърдени - - - Date - Дата - - - Type - Тип - - - Label - Име - - - Address - Адрес - - - ID - ИД - - - Range: - От: - - - to - до - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Няма зареден портфейл. - - - - WalletModel - - Send Coins - Изпращане - - - - WalletView - - &Export - Изнеси - - - Export the data in the current tab to a file - Запишете данните от текущия раздел във файл - - - Backup Wallet - Запазване на портфейла - - - Wallet Data (*.dat) - Информация за портфейла (*.dat) - - - Backup Failed - Неуспешно запазване на портфейла - - - There was an error trying to save the wallet data to %1. - Възникна грешка при запазването на информацията за портфейла в %1. - - - The wallet data was successfully saved to %1. - Информацията за портфейла беше успешно запазена в %1. - - - Backup Successful - Успешно запазване на портфейла - - bitcoin-core @@ -2399,6 +1306,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Приемайте връзки отвън.(по подразбиране:1 в противен случай -proxy или -connect) + + Bitcoin Core + Биткойн ядро + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Сложете в бял списък пиъри,свързващи се от дадената интернет маска или айпи адрес.Може да бъде заложено неколкократно. @@ -2443,34 +1354,14 @@ Wallet options: Настройки на портфейла: - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Заложете броя на нишки за генерация на монети ако е включено(-1 = всички ядра, по подразбиране: %d) - Connect through SOCKS5 proxy Свързване чрез SOCKS5 прокси - - Copyright (C) 2009-%i The Bitcoin Core Developers - Всички права запазени (C) 2009-%i Доставчиците на Биткойн - Information Информация - - Invalid amount for -maxtxfee=<amount>: '%s' - Невалидна сума за -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Невалидна сума за -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Невалидна сума за -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log @@ -2503,22 +1394,10 @@ Password for JSON-RPC connections Парола за JSON-RPC връзките - - This help message - Това помощно съобщение - Loading addresses... Зареждане на адреси... - - Error loading wallet.dat: Wallet corrupted - Грешка при зареждане на wallet.dat: портфейлът е повреден - - - Error loading wallet.dat - Грешка при зареждане на wallet.dat - Invalid -proxy address: '%s' Невалиден -proxy address: '%s' @@ -2535,10 +1414,6 @@ Specify pid file (default: %s) Задайте pid файл(по подразбиране: %s) - - Invalid amount for -paytxfee=<amount>: '%s' - Невалидна сума за -paytxfee=<amount>: '%s' - Insufficient funds Недостатъчно средства diff --git a/src/qt/locale/bitcoin_bg_BG.ts b/src/qt/locale/bitcoin_bg_BG.ts deleted file mode 100644 index 353f6d771..000000000 --- a/src/qt/locale/bitcoin_bg_BG.ts +++ /dev/null @@ -1,157 +0,0 @@ - - - AddressBookPage - - Right-click to edit address or label - Клик с десен бутон на мишката за промяна на адрес или етикет - - - Create a new address - Създай нов адрес - - - &New - Нов - - - &Copy - Копирай - - - C&lose - Затвори - - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - Bitcoin Core - Биткойн ядро - - - &About Bitcoin Core - За Биткойн ядрото - - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - Bitcoin Core - Биткойн ядро - - - About Bitcoin Core - За Биткойн ядрото - - - - Intro - - Bitcoin Core - Биткойн ядро - - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - Bitcoin Core - Биткойн ядро - - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts deleted file mode 100644 index a18684220..000000000 --- a/src/qt/locale/bitcoin_bs.ts +++ /dev/null @@ -1,169 +0,0 @@ - - - AddressBookPage - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - Bitcoin - Bitcoin - - - Bitcoin Core - Bitcoin Jezrga - - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - Bitcoin Core - Bitcoin Jezrga - - - - Intro - - Bitcoin Core - Bitcoin Jezrga - - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - Alt+A - Alt+A - - - Alt+P - Alt+P - - - - ShutdownWindow - - - SignVerifyMessageDialog - - Alt+A - Alt+A - - - Alt+P - Alt+P - - - - SplashScreen - - Bitcoin Core - Bitcoin Jezrga - - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - All - Sve - - - Today - Danas - - - This month - Ovaj mjesec - - - Last month - Prošli mjesec - - - This year - Ove godine - - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 8bc9281f1..3eb384868 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -25,10 +25,6 @@ C&lose &Tanca - - &Copy Address - &Copia l'adreça - Delete the currently selected address from the list Elimina l'adreça sel·leccionada actualment de la llista @@ -45,73 +41,6 @@ &Delete &Elimina - - Choose the address to send coins to - Trieu una adreça on voleu enviar monedes - - - Choose the address to receive coins with - Trieu l'adreça on voleu rebre monedes - - - C&hoose - T&ria - - - Sending addresses - S'estan enviant les adreces - - - Receiving addresses - S'estan rebent les adreces - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. - - - Copy &Label - Copia l'&etiqueta - - - &Edit - &Edita - - - Export Address List - Exporta la llista d'adreces - - - Comma separated file (*.csv) - Fitxer de separació amb comes (*.csv) - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the address list to %1. Please try again. - S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Adreça - - - (no label) - (sense etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repetiu la nova contrasenya - - Encrypt wallet - Encripta el moneder - - - This operation needs your wallet passphrase to unlock the wallet. - Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. - - - Unlock wallet - Desbloqueja el moneder - - - This operation needs your wallet passphrase to decrypt the wallet. - Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. - - - Decrypt wallet - Desencripta el moneder - - - Change passphrase - Canvia la contrasenya - - - Confirm wallet encryption - Confirma l'encriptació del moneder - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Esteu segur que voleu encriptar el vostre moneder? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. - - - Warning: The Caps Lock key is on! - Avís: Les lletres majúscules estan activades! - - - Wallet encrypted - Moneder encriptat - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduïu la contrasenya antiga i la contrasenya nova al moneder. - - - Wallet encryption failed - L'encriptació del moneder ha fallat - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. - - - The supplied passphrases do not match. - La contrasenya introduïda no coincideix. - - - Wallet unlock failed - El desbloqueig del moneder ha fallat - - - The passphrase entered for the wallet decryption was incorrect. - La contrasenya introduïda per a desencriptar el moneder és incorrecta. - - - Wallet decryption failed - La desencriptació del moneder ha fallat - - - Wallet passphrase was successfully changed. - La contrasenya del moneder ha estat modificada correctament. - BanTableModel @@ -305,14 +146,6 @@ Open &URI... Obre un &URI... - - Bitcoin Core client - Client del Bitcoin Core - - - Importing blocks from disk... - S'estan important els blocs del disc... - Reindexing blocks on disk... S'estan reindexant els blocs al disc... @@ -357,10 +190,6 @@ &Receive &Rep - - Show information about Bitcoin Core - Mostra informació del Bitcoin Core - &Show / Hide &Mostra / Amaga @@ -397,22 +226,10 @@ Tabs toolbar Barra d'eines de les pestanyes - - Bitcoin Core - Nucli de Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Sol·licita pagaments (genera codis QR i bitcoin: URI) - - &About Bitcoin Core - &Quant al Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifica les opcions de configuració del Bitcoin Core - Show the list of used sending addresses and labels Mostra la llista d'adreces d'enviament i etiquetes utilitzades @@ -429,10 +246,6 @@ &Command-line options Opcions de la &línia d'ordres - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostra el missatge d'ajuda del Bitcoin Core per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin - %n active connection(s) to Bitcoin network %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin @@ -544,13 +357,6 @@ El moneder està <b>encriptat</b> i actualment <b>bloquejat</b> - - ClientModel - - Network Alert - Alerta de xarxa - - CoinControlDialog @@ -629,150 +435,6 @@ Priority Prioritat - - Copy address - Copiar adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Lock unspent - Bloqueja sense gastar - - - Unlock unspent - Desbloqueja sense gastar - - - Copy quantity - Copia la quantitat - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy dust - Copia el polsim - - - Copy change - Copia el canvi - - - highest - El més alt - - - higher - Més alt - - - high - Alt - - - medium-high - mig-alt - - - medium - mig - - - low-medium - baix-mig - - - low - baix - - - lower - més baix - - - lowest - el més baix - - - (%1 locked) - (%1 bloquejada) - - - none - cap - - - This label turns red if the transaction size is greater than 1000 bytes. - Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». - - - This label turns red if any recipient receives an amount smaller than %1. - Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1. - - - Can vary +/- %1 satoshi(s) per input. - Pot variar +/- %1 satoshi(s) per entrada. - - - yes - - - - no - no - - - This means a fee of at least %1 per kB is required. - Això comporta una comissió d'almenys %1 per kB. - - - Can vary +/- 1 byte per input. - Pot variar +/- 1 byte per entrada. - - - Transactions with higher priority are more likely to get included into a block. - Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. - - - (no label) - (sense etiqueta) - - - change from %1 (%2) - canvia de %1 (%2) - - - (change) - (canvia) - EditAddressDialog @@ -796,38 +458,6 @@ &Address &Adreça - - New receiving address - Nova adreça de recepció. - - - New sending address - Nova adreça d'enviament - - - Edit receiving address - Edita les adreces de recepció - - - Edit sending address - Edita les adreces d'enviament - - - The entered address "%1" is already in the address book. - L'adreça introduïda «%1» ja és present a la llibreta d'adreces. - - - The entered address "%1" is not a valid Bitcoin address. - L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. - - - Could not unlock wallet. - No s'ha pogut desbloquejar el moneder. - - - New key generation failed. - Ha fallat la generació d'una nova clau. - FreespaceChecker @@ -854,10 +484,6 @@ HelpMessageDialog - - Bitcoin Core - Nucli de Bitcoin - version versió @@ -866,10 +492,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Quant al Bitcoin Core - Command-line options Opcions de línia d'ordres @@ -906,29 +528,13 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - - Reset all settings changes made over the GUI - Reinicialitza tots els canvis de configuració fets des de la interfície gràfica - - + Intro Welcome Us donem la benviguda - - Welcome to Bitcoin Core. - Us donem la benvinguda al Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en aquest directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder. - Use the default data directory Utilitza el directori de dades per defecte @@ -937,10 +543,6 @@ Use a custom data directory: Utilitza un directori de dades personalitzat: - - Bitcoin Core - Nucli de Bitcoin - Error: Specified data directory "%1" cannot be created. Error: el directori de dades «%1» especificat no pot ser creat. @@ -976,10 +578,6 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - - Select payment request file to open - Selecciona el fitxer de sol·licitud de pagament per obrir - OptionsDialog @@ -1019,10 +617,6 @@ 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. Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core. - 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 |. URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |. @@ -1047,14 +641,6 @@ &Network &Xarxa - - Automatically start Bitcoin Core after logging in to the system. - Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema. - - - &Start Bitcoin Core on system login - &Inicia el Bitcoin Core en inciar el sistema - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = deixa tants nuclis lliures) @@ -1283,97 +869,6 @@ Balanç total actual en adreces de només lectura - - PaymentServer - - URI handling - Gestió d'URI - - - Invalid payment address %1 - Adreça de pagament no vàlida %1 - - - Payment request rejected - La sol·licitud de pagament s'ha rebutjat - - - Payment request network doesn't match client network. - La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client. - - - Payment request is not initialized. - La sol·licitud de pagament no està inicialitzada. - - - Requested payment amount of %1 is too small (considered dust). - L'import de pagament sol·licitat %1 és massa petit (es considera polsim). - - - Payment request error - Error en la sol·licitud de pagament - - - Cannot start bitcoin: click-to-pay handler - No es pot iniciar bitcoin: gestor clica-per-pagar - - - Payment request fetch URL is invalid: %1 - L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format. - - - Payment request file handling - Gestió de fitxers de les sol·licituds de pagament - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Unverified payment requests to custom payment scripts are unsupported. - No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats. - - - Invalid payment request. - Sol·licitud de pagament no vàlida. - - - Refund from %1 - Reemborsament de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes). - - - Error communicating with %1: %2 - Error en comunicar amb %1: %2 - - - Payment request cannot be parsed! - No es pot analitzar la sol·licitud de pagament! - - - Bad response from server %1 - Mala resposta del servidor %1 - - - Payment acknowledged - Pagament reconegut - - - Network request error - Error en la sol·licitud de xarxa - - PeerTableModel @@ -1428,25 +923,6 @@ %1 ms - - QRImageWidget - - &Save Image... - De&sa la imatge... - - - &Copy Image - &Copia la imatge - - - Save QR Code - Desa el codi QR - - - PNG Image (*.png) - Imatge PNG (*.png) - - RPCConsole @@ -1513,10 +989,6 @@ Memory usage Us de memoria - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans. - Received Rebut @@ -1633,10 +1105,6 @@ Out: Fora: - - Build date - Data de compilació - Debug log file Fitxer de registre de depuració @@ -1673,10 +1141,6 @@ &Unban Node &Desbandeja el node - - Welcome to the Bitcoin Core RPC console. - Us donem la benviguda a la consola RPC del Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla. @@ -1804,18 +1268,6 @@ Remove Esborra - - Copy label - Copia l'etiqueta - - - Copy message - Copia el missatge - - - Copy amount - Copia l'import - ReceiveRequestDialog @@ -1835,73 +1287,6 @@ &Save Image... De&sa la imatge... - - Request payment to %1 - Sol·licita un pagament a %1 - - - Payment information - Informació de pagament - - - URI - URI - - - Address - Adreça - - - Amount - Import - - - Label - Etiqueta - - - Message - Missatge - - - Resulting URI too long, try to reduce the text for label / message. - URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge - - - Error encoding URI into QR Code. - Error en codificar l'URI en un codi QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiqueta - - - Message - Missatge - - - Amount - Import - - - (no label) - (sense etiqueta) - - - (no message) - (sense missatge) - - - (no amount) - (sense import) - SendCoinsDialog @@ -2021,14 +1406,6 @@ fast ràpid - - Send as zero-fee transaction if possible - Envia com a transacció de comissió zero si és possible - - - (confirmation may take longer) - (la confirmació pot trigar més temps) - Send to multiple recipients at once Envia a múltiples destinataris al mateix temps @@ -2061,118 +1438,6 @@ S&end E&nvia - - Confirm send coins - Confirma l'enviament de monedes - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copia la quantitat - - - Copy amount - Copia l'import - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy change - Copia el canvi - - - Total Amount %1 - Import total %1 - - - or - o - - - The amount to pay must be larger than 0. - L'import a pagar ha de ser major que 0. - - - The amount exceeds your balance. - L'import supera el vostre balanç. - - - The total exceeds your balance when the %1 transaction fee is included. - El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1. - - - Transaction creation failed! - Ha fallat la creació de la transacció! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades. - - - A fee higher than %1 is considered an absurdly high fee. - Una comissió superior a %1 es considera una comissió absurdament alta. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Pay only the required fee of %1 - Paga només la comissió necessària de %1 - - - Estimated to begin confirmation within %n block(s). - Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. - - - The recipient address is not valid. Please recheck. - L'adreça de destinatari no és vàlida. Torneu-la a comprovar. - - - Duplicate address found: addresses should only be used once each. - S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada. - - - Warning: Invalid Bitcoin address - Avís: adreça Bitcoin no vàlida - - - (no label) - (sense etiqueta) - - - Warning: Unknown change address - Avís: adreça de canvi desconeguda - - - Copy dust - Copia el polsim - - - Are you sure you want to send? - Esteu segur que ho voleu enviar? - - - added as transaction fee - S'ha afegit una taxa de transacció - SendCoinsEntry @@ -2184,10 +1449,6 @@ Pay &To: Paga &a: - - Enter a label for this address to add it to your address book - Introduïu una etiqueta per a aquesta adreça per afegir-la a la llibreta d'adreces - &Label: &Etiqueta: @@ -2259,10 +1520,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - S'està aturant el Bitcoin Core... - Do not shut down the computer until this window disappears. No apagueu l'ordinador fins que no desaparegui aquesta finestra. @@ -2354,69 +1611,9 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - - Click "Sign Message" to generate signature - Feu clic a «Signa el missatge» per a generar una signatura - - - The entered address is invalid. - L'adreça introduïda no és vàlida. - - - Please check the address and try again. - Comproveu l'adreça i torneu-ho a provar. - - - The entered address does not refer to a key. - L'adreça introduïda no referencia a cap clau. - - - Wallet unlock was cancelled. - El desbloqueig del moneder ha estat cancelat. - - - Private key for the entered address is not available. - La clau privada per a la adreça introduïda no està disponible. - - - Message signing failed. - La signatura del missatge ha fallat. - - - Message signed. - Missatge signat. - - - The signature could not be decoded. - La signatura no s'ha pogut descodificar. - - - Please check the signature and try again. - Comproveu la signatura i torneu-ho a provar. - - - The signature did not match the message digest. - La signatura no coincideix amb el resum del missatge. - - - Message verification failed. - Ha fallat la verificació del missatge. - - - Message verified. - Missatge verificat. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Els desenvolupadors del Bitcoin Core - [testnet] [testnet] @@ -2429,422 +1626,13 @@ KB/s - - TransactionDesc - - Open until %1 - Obert fins %1 - - - conflicted - en conflicte - - - %1/offline - %1/fora de línia - - - %1/unconfirmed - %1/sense confirmar - - - %1 confirmations - %1 confirmacions - - - Status - Estat - - - , broadcast through %n node(s) - , difusió a través de %n node, difusió a través de %n nodes - - - Date - Data - - - Source - Font - - - Generated - Generat - - - From - Des de - - - To - A - - - own address - Adreça pròpia - - - watch-only - només lectura - - - label - etiqueta - - - Credit - Crèdit - - - matures in %n more block(s) - disponible en %n bloc mésdisponibles en %n blocs més - - - not accepted - no acceptat - - - Debit - Dèbit - - - Total debit - Dèbit total - - - Total credit - Crèdit total - - - Transaction fee - Comissió de transacció - - - Net amount - Import net - - - Message - Missatge - - - Comment - Comentar - - - Transaction ID - ID de transacció - - - Merchant - Mercader - - - 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. - Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu aquest bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre. - - - Debug information - Informació de depuració - - - Transaction - Transacció - - - Inputs - Entrades - - - Amount - Import - - - true - cert - - - false - fals - - - , has not been successfully broadcast yet - , encara no ha estat emès correctement - - - Open for %n more block(s) - Obre per %n bloc mésObre per %n blocs més - - - unknown - desconegut - - TransactionDescDialog - - Transaction details - Detall de la transacció - This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - - TransactionTableModel - - Date - Data - - - Type - Tipus - - - Immature (%1 confirmations, will be available after %2) - Immadur (%1 confirmacions, serà disponible després de %2) - - - Open for %n more block(s) - Obre per %n bloc mésObre per %n blocs més - - - Open until %1 - Obert fins %1 - - - Confirmed (%1 confirmations) - Confirmat (%1 confirmacions) - - - This block was not received by any other nodes and will probably not be accepted! - Aquest bloc no ha estat rebut per cap altre node i probablement no serà acceptat! - - - Generated but not accepted - Generat però no acceptat - - - Offline - Fora de línia - - - Label - Etiqueta - - - Unconfirmed - Sense confirmar - - - Confirming (%1 of %2 recommended confirmations) - Confirmant (%1 de %2 confirmacions recomanades) - - - Conflicted - En conflicte - - - Received with - Rebut amb - - - Received from - Rebut de - - - Sent to - Enviat a - - - Payment to yourself - Pagament a un mateix - - - Mined - Minat - - - watch-only - només lectura - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Estat de la transacció. Desplaceu-vos sobre aquest camp per mostrar el nombre de confirmacions. - - - Date and time that the transaction was received. - Data i hora en que la transacció va ser rebuda. - - - Type of transaction. - Tipus de transacció. - - - Whether or not a watch-only address is involved in this transaction. - Si està implicada o no una adreça només de lectura en la transacció. - - - User-defined intent/purpose of the transaction. - Intenció/propòsit de la transacció definida per l'usuari. - - - Amount removed from or added to balance. - Import extret o afegit del balanç. - - - - TransactionView - - All - Tot - - - Today - Avui - - - This week - Aquesta setmana - - - This month - Aquest mes - - - Last month - El mes passat - - - This year - Enguany - - - Range... - Rang... - - - Received with - Rebut amb - - - Sent to - Enviat a - - - To yourself - A un mateix - - - Mined - Minat - - - Other - Altres - - - Enter address or label to search - Introduïu una adreça o una etiqueta per cercar - - - Min amount - Import mínim - - - Copy address - Copia l'adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Copy raw transaction - Copia la transacció crua - - - Edit label - Editar etiqueta - - - Show transaction details - Mostra detalls de la transacció - - - Export Transaction History - Exporta l'historial de transacció - - - Watch-only - Només de lectura - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the transaction history to %1. - S'ha produït un error en provar de desar l'historial de transacció a %1. - - - Exporting Successful - Exportació amb èxit - - - The transaction history was successfully saved to %1. - L'historial de transaccions s'ha desat correctament a %1. - - - Comma separated file (*.csv) - Fitxer separat per comes (*.csv) - - - Confirmed - Confirmat - - - Date - Data - - - Type - Tipus - - - Label - Etiqueta - - - Address - Adreça - - - ID - ID - - - Range: - Rang: - - - to - a - - UnitDisplayStatusBarControl @@ -2852,55 +1640,6 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. - - WalletFrame - - No wallet has been loaded. - No s'ha carregat cap moneder. - - - - WalletModel - - Send Coins - Envia monedes - - - - WalletView - - &Export - &Exporta - - - Export the data in the current tab to a file - Exporta les dades de la pestanya actual a un fitxer - - - Backup Wallet - Còpia de seguretat del moneder - - - Wallet Data (*.dat) - Dades del moneder (*.dat) - - - Backup Failed - Ha fallat la còpia de seguretat - - - There was an error trying to save the wallet data to %1. - S'ha produït un error en provar de desar les dades del moneder a %1. - - - The wallet data was successfully saved to %1. - S'han desat les dades del moneder correctament a %1. - - - Backup Successful - La còpia de seguretat s'ha realitzat correctament - - bitcoin-core @@ -2927,14 +1666,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Si no es proporciona <category> o si <category> = 1, treu a la sortida tota la informació de depuració. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Comproveu que la data i hora de l'ordinador són correctes! Si el vostre rellotge no té l'hora correcta, el Bitcoin Core no funcionarà adequadament. - Prune configured below the minimum of %d MiB. Please use a higher number. Poda configurada per sota el mínim de %d MiB. Utilitzeu un nombre superior. @@ -2975,6 +1706,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepta connexions de fora (per defecte: 1 si no -proxy o -connect) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee és molt elevat. Aquesta és la comissió de transacció que podeu pagar quan les estimacions de comissions no estan disponibles. @@ -3003,10 +1738,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi. - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) @@ -3023,10 +1754,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. @@ -3147,10 +1874,6 @@ Wallet options: Opcions de moneder: - - You need to rebuild the database using -reindex to change -txindex - Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades @@ -3163,10 +1886,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Aquesta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada) @@ -3207,10 +1926,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d) - The transaction amount is too small to send after the fee has been deducted L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió @@ -3235,26 +1950,10 @@ Accept public REST requests (default: %u) Accepta sol·licituds REST públiques (per defecte: %u) - - Activating best chain... - S'està activant la millor cadena... - - - Cannot resolve -whitebind address: '%s' - No es pot resoldre l'adreça -whitebind: «%s» - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core - Error reading from database, shutting down. Error en llegir la base de dades, tancant. @@ -3263,22 +1962,6 @@ Information &Informació - - Initialization sanity check failed. Bitcoin Core is shutting down. - Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Import no vàlid per a -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Import no vàlid per a -minrelaytxfee=<amount>: «%s» - - - Invalid amount for -mintxfee=<amount>: '%s' - Import no vàlid per a -mintxfee=<amount>: «%s» - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s) @@ -3303,14 +1986,6 @@ RPC server options: Opcions del servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici. - - - Receive and display P2P network alerts (default: %u) - Rep i mostra avisos de la xarxa P2P (per defecte: %u) - Send trace/debug info to console instead of debug.log file Envia informació de traça/depuració a la consola en comptes del fitxer debug.log @@ -3363,10 +2038,6 @@ Username for JSON-RPC connections Nom d'usuari per a connexions JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho. - Warning Avís @@ -3375,10 +2046,6 @@ Zapping all transactions from wallet... Se suprimeixen totes les transaccions del moneder... - - wallet.dat corrupt, salvage failed - El fitxer wallet.data és corrupte. El rescat de les dades ha fallat - Password for JSON-RPC connections Contrasenya per a connexions JSON-RPC @@ -3387,10 +2054,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc) - - This help message - Aquest misatge d'ajuda - Allow DNS lookups for -addnode, -seednode and -connect Permet consultes DNS per a -addnode, -seednode i -connect @@ -3399,10 +2062,6 @@ Loading addresses... S'estan carregant les adreces... - - Error loading wallet.dat: Wallet corrupted - Error en carregar wallet.dat: Moneder corrupte - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx) @@ -3435,14 +2094,6 @@ Always query for peer addresses via DNS lookup (default: %u) Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u) - - Error loading wallet.dat - Error en carregar wallet.dat - - - Generate coins (default: %u) - Genera monedes (per defecte: %u) - How many blocks to check at startup (default: %u, 0 = all) Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots) @@ -3527,18 +2178,6 @@ Unknown network specified in -onlynet: '%s' Xarxa desconeguda especificada a -onlynet: '%s' - - Cannot resolve -bind address: '%s' - No es pot resoldre l'adreça -bind: '%s' - - - Cannot resolve -externalip address: '%s' - No es pot resoldre l'adreça -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Import no vàlid per a -paytxfee=<amount>: «%s» - Insufficient funds Balanç insuficient diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index e5744fcbb..1fdf0249a 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -25,10 +25,6 @@ C&lose &Tanca - - &Copy Address - &Copia l'adreça - Delete the currently selected address from the list Elimina l'adreça sel·leccionada actualment de la llista @@ -45,73 +41,6 @@ &Delete &Elimina - - Choose the address to send coins to - Trieu una adreça on voleu enviar monedes - - - Choose the address to receive coins with - Trieu l'adreça on voleu rebre monedes - - - C&hoose - T&ria - - - Sending addresses - S'estan enviant les adreces - - - Receiving addresses - S'estan rebent les adreces - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. - - - Copy &Label - Copia l'&etiqueta - - - &Edit - &Edita - - - Export Address List - Exporta la llista d'adreces - - - Comma separated file (*.csv) - Fitxer de separació amb comes (*.csv) - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the address list to %1. Please try again. - S'ha produït un error en guardar la llista d'adreces a %1. Torneu-ho a provar. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Adreça - - - (no label) - (sense etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repetiu la nova contrasenya - - Encrypt wallet - Encripta el moneder - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operació requereix la contrasenya del moneder per a desbloquejar-lo. - - - Unlock wallet - Desbloqueja el moneder - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operació requereix la contrasenya del moneder per desencriptar-lo. - - - Decrypt wallet - Desencripta el moneder - - - Change passphrase - Canvia la contrasenya - - - Confirm wallet encryption - Confirma l'encriptació del moneder - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Esteu segur que voleu encriptar el vostre moneder? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguen ser robades per programari maliciós que infecti l'ordinador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Tota copia de seguretat que hàgeu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. - - - Warning: The Caps Lock key is on! - Avís: Les lletres majúscules estan activades! - - - Wallet encrypted - Moneder encriptat - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduïu la contrasenya antiga i la contrasenya nova al moneder. - - - Wallet encryption failed - L'encriptació del moneder ha fallat - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. - - - The supplied passphrases do not match. - La contrasenya introduïda no coincideix. - - - Wallet unlock failed - El desbloqueig del moneder ha fallat - - - The passphrase entered for the wallet decryption was incorrect. - La contrasenya introduïda per a desencriptar el moneder és incorrecta. - - - Wallet decryption failed - La desencriptació del moneder ha fallat - - - Wallet passphrase was successfully changed. - La contrasenya del moneder ha estat modificada correctament. - BanTableModel @@ -297,14 +138,6 @@ Open &URI... Obri un &URI... - - Bitcoin Core client - Client del Bitcoin Core - - - Importing blocks from disk... - S'estan important els blocs del disc... - Reindexing blocks on disk... S'estan reindexant els blocs al disc... @@ -349,10 +182,6 @@ &Receive &Rep - - Show information about Bitcoin Core - Mostra informació del Bitcoin Core - &Show / Hide &Mostra / Amaga @@ -389,22 +218,10 @@ Tabs toolbar Barra d'eines de les pestanyes - - Bitcoin Core - Nucli de Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Sol·licita pagaments (genera codis QR i bitcoin: URI) - - &About Bitcoin Core - &Quant al Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifica les opcions de configuració del Bitcoin Core - Show the list of used sending addresses and labels Mostra la llista d'adreces d'enviament i etiquetes utilitzades @@ -421,10 +238,6 @@ &Command-line options Opcions de la &línia d'ordes - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostra el missatge d'ajuda del Bitcoin Core per obtindre una llista amb les possibles opcions de línia d'ordes de Bitcoin - %n active connection(s) to Bitcoin network %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin @@ -536,13 +349,6 @@ El moneder està <b>encriptat</b> i actualment <b>bloquejat</b> - - ClientModel - - Network Alert - Alerta de xarxa - - CoinControlDialog @@ -621,150 +427,6 @@ Priority Prioritat - - Copy address - Copiar adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Lock unspent - Bloqueja sense gastar - - - Unlock unspent - Desbloqueja sense gastar - - - Copy quantity - Copia la quantitat - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy dust - Copia el polsim - - - Copy change - Copia el canvi - - - highest - El més alt - - - higher - Més alt - - - high - Alt - - - medium-high - mig-alt - - - medium - mig - - - low-medium - baix-mig - - - low - baix - - - lower - més baix - - - lowest - el més baix - - - (%1 locked) - (%1 bloquejada) - - - none - cap - - - This label turns red if the transaction size is greater than 1000 bytes. - Esta etiqueta es torna en roig si la transacció és superior a 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Esta etiqueta es torna en roig si la propietat és inferior que la «mitjana». - - - This label turns red if any recipient receives an amount smaller than %1. - Esta etiqueta es torna roja si el destinatari rep un import inferior de %1. - - - Can vary +/- %1 satoshi(s) per input. - Pot variar +/- %1 satoshi(s) per entrada. - - - yes - - - - no - no - - - This means a fee of at least %1 per kB is required. - Això comporta una comissió d'almenys %1 per kB. - - - Can vary +/- 1 byte per input. - Pot variar +/- 1 byte per entrada. - - - Transactions with higher priority are more likely to get included into a block. - Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. - - - (no label) - (sense etiqueta) - - - change from %1 (%2) - canvia de %1 (%2) - - - (change) - (canvia) - EditAddressDialog @@ -788,38 +450,6 @@ &Address &Adreça - - New receiving address - Nova adreça de recepció. - - - New sending address - Nova adreça d'enviament - - - Edit receiving address - Edita les adreces de recepció - - - Edit sending address - Edita les adreces d'enviament - - - The entered address "%1" is already in the address book. - L'adreça introduïda «%1» ja és present a la llibreta d'adreces. - - - The entered address "%1" is not a valid Bitcoin address. - L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. - - - Could not unlock wallet. - No s'ha pogut desbloquejar el moneder. - - - New key generation failed. - Ha fallat la generació d'una nova clau. - FreespaceChecker @@ -846,10 +476,6 @@ HelpMessageDialog - - Bitcoin Core - Nucli de Bitcoin - version versió @@ -858,10 +484,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Quant al Bitcoin Core - Command-line options Opcions de línia d'ordes @@ -881,18 +503,6 @@ Welcome Vos donem la benviguda - - Welcome to Bitcoin Core. - Vos donem la benvinguda al Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en este directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder. - Use the default data directory Utilitza el directori de dades per defecte @@ -901,10 +511,6 @@ Use a custom data directory: Utilitza un directori de dades personalitzat: - - Bitcoin Core - Nucli de Bitcoin - Error: Specified data directory "%1" cannot be created. Error: el directori de dades «%1» especificat no pot ser creat. @@ -940,10 +546,6 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - - Select payment request file to open - Selecciona el fitxer de sol·licitud de pagament per obrir - OptionsDialog @@ -983,10 +585,6 @@ 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. Minimitza en comptes d'eixir de l'aplicació quan la finestra es tanca. Quan s'habilita esta opció l'aplicació es tancara només quan se selecciona Ix del menú. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - La interfície d'usuari pot definir-se des d'ací. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core. - 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 |. URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |. @@ -1011,14 +609,6 @@ &Network &Xarxa - - Automatically start Bitcoin Core after logging in to the system. - Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema. - - - &Start Bitcoin Core on system login - &Inicia el Bitcoin Core en inciar el sistema - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = deixa tants nuclis lliures) @@ -1223,97 +813,6 @@ Balanç total actual en adreces de només lectura - - PaymentServer - - URI handling - Gestió d'URI - - - Invalid payment address %1 - Adreça de pagament no vàlida %1 - - - Payment request rejected - La sol·licitud de pagament s'ha rebutjat - - - Payment request network doesn't match client network. - La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client. - - - Payment request is not initialized. - La sol·licitud de pagament no està inicialitzada. - - - Requested payment amount of %1 is too small (considered dust). - L'import de pagament sol·licitat %1 és massa petit (es considera polsim). - - - Payment request error - Error en la sol·licitud de pagament - - - Cannot start bitcoin: click-to-pay handler - No es pot iniciar bitcoin: gestor clica-per-pagar - - - Payment request fetch URL is invalid: %1 - L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format. - - - Payment request file handling - Gestió de fitxers de les sol·licituds de pagament - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Unverified payment requests to custom payment scripts are unsupported. - No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats. - - - Invalid payment request. - Sol·licitud de pagament no vàlida. - - - Refund from %1 - Reemborsament de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes). - - - Error communicating with %1: %2 - Error en comunicar amb %1: %2 - - - Payment request cannot be parsed! - No es pot analitzar la sol·licitud de pagament! - - - Bad response from server %1 - Mala resposta del servidor %1 - - - Payment acknowledged - Pagament reconegut - - - Network request error - Error en la sol·licitud de xarxa - - PeerTableModel @@ -1368,25 +867,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Guarda la imatge... - - - &Copy Image - &Copia la imatge - - - Save QR Code - Guarda el codi QR - - - PNG Image (*.png) - Imatge PNG (*.png) - - RPCConsole @@ -1441,10 +921,6 @@ Current number of blocks Nombre de blocs actuals - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Obri el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans. - Received Rebut @@ -1533,10 +1009,6 @@ Out: Fora: - - Build date - Data de compilació - Debug log file Fitxer de registre de depuració @@ -1545,10 +1017,6 @@ Clear console Neteja la consola - - Welcome to the Bitcoin Core RPC console. - Vos donem la benviguda a la consola RPC del Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla. @@ -1672,18 +1140,6 @@ Remove Esborra - - Copy label - Copia l'etiqueta - - - Copy message - Copia el missatge - - - Copy amount - Copia l'import - ReceiveRequestDialog @@ -1703,73 +1159,6 @@ &Save Image... &Guarda la imatge... - - Request payment to %1 - Sol·licita un pagament a %1 - - - Payment information - Informació de pagament - - - URI - URI - - - Address - Adreça - - - Amount - Import - - - Label - Etiqueta - - - Message - Missatge - - - Resulting URI too long, try to reduce the text for label / message. - URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge - - - Error encoding URI into QR Code. - Error en codificar l'URI en un codi QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiqueta - - - Message - Missatge - - - Amount - Import - - - (no label) - (sense etiqueta) - - - (no message) - (sense missatge) - - - (no amount) - (sense import) - SendCoinsDialog @@ -1889,14 +1278,6 @@ fast ràpid - - Send as zero-fee transaction if possible - Envia com a transacció de comissió zero si és possible - - - (confirmation may take longer) - (la confirmació pot trigar més temps) - Send to multiple recipients at once Envia a múltiples destinataris al mateix temps @@ -1929,110 +1310,6 @@ S&end E&nvia - - Confirm send coins - Confirma l'enviament de monedes - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copia la quantitat - - - Copy amount - Copia l'import - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy change - Copia el canvi - - - or - o - - - The amount to pay must be larger than 0. - L'import a pagar ha de ser major que 0. - - - The amount exceeds your balance. - L'import supera el vostre balanç. - - - The total exceeds your balance when the %1 transaction fee is included. - El total excedeix el teu balanç quan s'afig la comissió a la transacció %1. - - - Transaction creation failed! - Ha fallat la creació de la transacció! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'hagueren gastat monedes de la còpia però sense marcar-les-hi com a gastades. - - - A fee higher than %1 is considered an absurdly high fee. - Una comissió superior a %1 es considera una comissió absurdament alta. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Estimated to begin confirmation within %n block(s). - Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. - - - The recipient address is not valid. Please recheck. - L'adreça de destinatari no és vàlida. Torneu-la a comprovar. - - - Duplicate address found: addresses should only be used once each. - S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada. - - - Warning: Invalid Bitcoin address - Avís: adreça Bitcoin no vàlida - - - (no label) - (sense etiqueta) - - - Warning: Unknown change address - Avís: adreça de canvi desconeguda - - - Copy dust - Copia el polsim - - - Are you sure you want to send? - Esteu segur que ho voleu enviar? - - - added as transaction fee - S'ha afegit una taxa de transacció - SendCoinsEntry @@ -2044,10 +1321,6 @@ Pay &To: Paga &a: - - Enter a label for this address to add it to your address book - Introduïu una etiqueta per a esta adreça per afegir-la a la llibreta d'adreces - &Label: &Etiqueta: @@ -2119,10 +1392,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - S'està parant el Bitcoin Core... - Do not shut down the computer until this window disappears. No apagueu l'ordinador fins que no desaparegui esta finestra. @@ -2214,69 +1483,9 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - - Click "Sign Message" to generate signature - Feu clic a «Signa el missatge» per a generar una signatura - - - The entered address is invalid. - L'adreça introduïda no és vàlida. - - - Please check the address and try again. - Comproveu l'adreça i torneu-ho a provar. - - - The entered address does not refer to a key. - L'adreça introduïda no referencia a cap clau. - - - Wallet unlock was cancelled. - El desbloqueig del moneder ha estat cancelat. - - - Private key for the entered address is not available. - La clau privada per a la adreça introduïda no està disponible. - - - Message signing failed. - La signatura del missatge ha fallat. - - - Message signed. - Missatge signat. - - - The signature could not be decoded. - La signatura no s'ha pogut descodificar. - - - Please check the signature and try again. - Comproveu la signatura i torneu-ho a provar. - - - The signature did not match the message digest. - La signatura no coincideix amb el resum del missatge. - - - Message verification failed. - Ha fallat la verificació del missatge. - - - Message verified. - Missatge verificat. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Els desenvolupadors del Bitcoin Core - [testnet] [testnet] @@ -2289,418 +1498,13 @@ KB/s - - TransactionDesc - - Open until %1 - Obert fins %1 - - - conflicted - en conflicte - - - %1/offline - %1/fora de línia - - - %1/unconfirmed - %1/sense confirmar - - - %1 confirmations - %1 confirmacions - - - Status - Estat - - - , broadcast through %n node(s) - , difusió a través de %n node, difusió a través de %n nodes - - - Date - Data - - - Source - Font - - - Generated - Generat - - - From - Des de - - - To - A - - - own address - Adreça pròpia - - - watch-only - només lectura - - - label - etiqueta - - - Credit - Crèdit - - - matures in %n more block(s) - madura en %n bloc mésmadura en %n blocs més - - - not accepted - no acceptat - - - Debit - Dèbit - - - Total debit - Dèbit total - - - Total credit - Crèdit total - - - Transaction fee - Comissió de transacció - - - Net amount - Import net - - - Message - Missatge - - - Comment - Comentar - - - Transaction ID - ID de transacció - - - Merchant - Mercader - - - 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. - Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu este bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre. - - - Debug information - Informació de depuració - - - Transaction - Transacció - - - Inputs - Entrades - - - Amount - Import - - - true - cert - - - false - fals - - - , has not been successfully broadcast yet - , encara no ha estat emés correctement - - - Open for %n more block(s) - Obri per %n bloc mésObri per %n blocs més - - - unknown - desconegut - - TransactionDescDialog - - Transaction details - Detall de la transacció - This pane shows a detailed description of the transaction Este panell mostra una descripció detallada de la transacció - - TransactionTableModel - - Date - Data - - - Type - Tipus - - - Immature (%1 confirmations, will be available after %2) - Immadur (%1 confirmacions, serà disponible després de %2) - - - Open for %n more block(s) - Obri per %n bloc mésObri per %n blocs més - - - Open until %1 - Obert fins %1 - - - Confirmed (%1 confirmations) - Confirmat (%1 confirmacions) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloc no ha estat rebut per cap altre node i probablement no serà acceptat! - - - Generated but not accepted - Generat però no acceptat - - - Offline - Fora de línia - - - Label - Etiqueta - - - Unconfirmed - Sense confirmar - - - Confirming (%1 of %2 recommended confirmations) - Confirmant (%1 de %2 confirmacions recomanades) - - - Conflicted - En conflicte - - - Received with - Rebut amb - - - Received from - Rebut de - - - Sent to - Enviat a - - - Payment to yourself - Pagament a un mateix - - - Mined - Minat - - - watch-only - només lectura - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Estat de la transacció. Desplaceu-vos sobre este camp per mostrar el nombre de confirmacions. - - - Date and time that the transaction was received. - Data i hora en que la transacció va ser rebuda. - - - Type of transaction. - Tipus de transacció. - - - Whether or not a watch-only address is involved in this transaction. - Si està implicada o no una adreça només de lectura en la transacció. - - - User-defined intent/purpose of the transaction. - Intenció/propòsit de la transacció definida per l'usuari. - - - Amount removed from or added to balance. - Import extret o afegit del balanç. - - - - TransactionView - - All - Tot - - - Today - Hui - - - This week - Esta setmana - - - This month - Este mes - - - Last month - El mes passat - - - This year - Enguany - - - Range... - Rang... - - - Received with - Rebut amb - - - Sent to - Enviat a - - - To yourself - A un mateix - - - Mined - Minat - - - Other - Altres - - - Enter address or label to search - Introduïu una adreça o una etiqueta per cercar - - - Min amount - Import mínim - - - Copy address - Copia l'adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Edit label - Editar etiqueta - - - Show transaction details - Mostra detalls de la transacció - - - Export Transaction History - Exporta l'historial de transacció - - - Watch-only - Només de lectura - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the transaction history to %1. - S'ha produït un error en provar de guardar l'historial de transacció a %1. - - - Exporting Successful - Exportació amb èxit - - - The transaction history was successfully saved to %1. - L'historial de transaccions s'ha guardat correctament a %1. - - - Comma separated file (*.csv) - Fitxer separat per comes (*.csv) - - - Confirmed - Confirmat - - - Date - Data - - - Type - Tipus - - - Label - Etiqueta - - - Address - Adreça - - - ID - ID - - - Range: - Rang: - - - to - a - - UnitDisplayStatusBarControl @@ -2708,55 +1512,6 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. - - WalletFrame - - No wallet has been loaded. - No s'ha carregat cap moneder. - - - - WalletModel - - Send Coins - Envia monedes - - - - WalletView - - &Export - &Exporta - - - Export the data in the current tab to a file - Exporta les dades de la pestanya actual a un fitxer - - - Backup Wallet - Còpia de seguretat del moneder - - - Wallet Data (*.dat) - Dades del moneder (*.dat) - - - Backup Failed - Ha fallat la còpia de seguretat - - - There was an error trying to save the wallet data to %1. - S'ha produït un error en provar de guardar les dades del moneder a %1. - - - The wallet data was successfully saved to %1. - S'han guardat les dades del moneder correctament a %1. - - - Backup Successful - La còpia de seguretat s'ha realitzat correctament - - bitcoin-core @@ -2787,6 +1542,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepta connexions de fora (per defecte: 1 si no -proxy o -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6 @@ -2811,10 +1570,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi. - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) @@ -2831,10 +1586,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Avís: pareix que no estem plenament d'acord amb els nostres iguals! Podria caldre que actualitzar l'aplicació, o potser que ho facen altres nodes. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat guardat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. @@ -2955,10 +1706,6 @@ Wallet options: Opcions de moneder: - - You need to rebuild the database using -reindex to change -txindex - Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar esta opció moltes vegades @@ -2971,10 +1718,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Esta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - No es pot obtindre un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estiga executant. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada) @@ -3015,10 +1758,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d) - The transaction amount is too small to send after the fee has been deducted L'import de la transacció és massa petit per enviar-la després que se'n deduïsca la comissió @@ -3043,26 +1782,10 @@ Accept public REST requests (default: %u) Accepta sol·licituds REST públiques (per defecte: %u) - - Activating best chain... - S'està activant la millor cadena... - - - Cannot resolve -whitebind address: '%s' - No es pot resoldre l'adreça -whitebind: «%s» - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core - Error reading from database, shutting down. Error en llegir la base de dades, tancant. @@ -3071,22 +1794,6 @@ Information &Informació - - Initialization sanity check failed. Bitcoin Core is shutting down. - Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Import no vàlid per a -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Import no vàlid per a -minrelaytxfee=<amount>: «%s» - - - Invalid amount for -mintxfee=<amount>: '%s' - Import no vàlid per a -mintxfee=<amount>: «%s» - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s) @@ -3111,14 +1818,6 @@ RPC server options: Opcions del servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici. - - - Receive and display P2P network alerts (default: %u) - Rep i mostra avisos de la xarxa P2P (per defecte: %u) - Send trace/debug info to console instead of debug.log file Envia informació de traça/depuració a la consola en comptes del fitxer debug.log @@ -3171,10 +1870,6 @@ Username for JSON-RPC connections Nom d'usuari per a connexions JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho. - Warning Avís @@ -3183,10 +1878,6 @@ Zapping all transactions from wallet... Se suprimeixen totes les transaccions del moneder... - - wallet.dat corrupt, salvage failed - El fitxer wallet.data és corrupte. El rescat de les dades ha fallat - Password for JSON-RPC connections Contrasenya per a connexions JSON-RPC @@ -3195,10 +1886,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executa l'orde quan el millor bloc canvie (%s en cmd es reemplaça per un resum de bloc) - - This help message - Este misatge d'ajuda - Allow DNS lookups for -addnode, -seednode and -connect Permet consultes DNS per a -addnode, -seednode i -connect @@ -3207,10 +1894,6 @@ Loading addresses... S'estan carregant les adreces... - - Error loading wallet.dat: Wallet corrupted - Error en carregar wallet.dat: Moneder corrupte - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx) @@ -3243,14 +1926,6 @@ Always query for peer addresses via DNS lookup (default: %u) Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u) - - Error loading wallet.dat - Error en carregar wallet.dat - - - Generate coins (default: %u) - Genera monedes (per defecte: %u) - How many blocks to check at startup (default: %u, 0 = all) Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots) @@ -3335,18 +2010,6 @@ Unknown network specified in -onlynet: '%s' Xarxa desconeguda especificada a -onlynet: '%s' - - Cannot resolve -bind address: '%s' - No es pot resoldre l'adreça -bind: '%s' - - - Cannot resolve -externalip address: '%s' - No es pot resoldre l'adreça -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Import no vàlid per a -paytxfee=<amount>: «%s» - Insufficient funds Balanç insuficient diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 2c238bb44..30004e10e 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -25,10 +25,6 @@ C&lose &Tanca - - &Copy Address - &Copia l'adreça - Delete the currently selected address from the list Elimina l'adreça sel·leccionada actualment de la llista @@ -45,73 +41,6 @@ &Delete &Elimina - - Choose the address to send coins to - Trieu una adreça on voleu enviar monedes - - - Choose the address to receive coins with - Trieu l'adreça on voleu rebre monedes - - - C&hoose - T&ria - - - Sending addresses - S'estan enviant les adreces - - - Receiving addresses - S'estan rebent les adreces - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. - - - Copy &Label - Copia l'&etiqueta - - - &Edit - &Edita - - - Export Address List - Exporta la llista d'adreces - - - Comma separated file (*.csv) - Fitxer de separació amb comes (*.csv) - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the address list to %1. Please try again. - S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Adreça - - - (no label) - (sense etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repetiu la nova contrasenya - - Encrypt wallet - Encripta el moneder - - - This operation needs your wallet passphrase to unlock the wallet. - Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. - - - Unlock wallet - Desbloqueja el moneder - - - This operation needs your wallet passphrase to decrypt the wallet. - Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. - - - Decrypt wallet - Desencripta el moneder - - - Change passphrase - Canvia la contrasenya - - - Confirm wallet encryption - Confirma l'encriptació del moneder - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Esteu segur que voleu encriptar el vostre moneder? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. - - - Warning: The Caps Lock key is on! - Avís: Les lletres majúscules estan activades! - - - Wallet encrypted - Moneder encriptat - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduïu la contrasenya antiga i la contrasenya nova al moneder. - - - Wallet encryption failed - L'encriptació del moneder ha fallat - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. - - - The supplied passphrases do not match. - La contrasenya introduïda no coincideix. - - - Wallet unlock failed - El desbloqueig del moneder ha fallat - - - The passphrase entered for the wallet decryption was incorrect. - La contrasenya introduïda per a desencriptar el moneder és incorrecta. - - - Wallet decryption failed - La desencriptació del moneder ha fallat - - - Wallet passphrase was successfully changed. - La contrasenya del moneder ha estat modificada correctament. - BanTableModel @@ -305,14 +146,6 @@ Open &URI... Obre un &URI... - - Bitcoin Core client - Client del Bitcoin Core - - - Importing blocks from disk... - S'estan important els blocs del disc... - Reindexing blocks on disk... S'estan reindexant els blocs al disc... @@ -357,10 +190,6 @@ &Receive &Rep - - Show information about Bitcoin Core - Mostra informació del Bitcoin Core - &Show / Hide &Mostra / Amaga @@ -397,22 +226,10 @@ Tabs toolbar Barra d'eines de les pestanyes - - Bitcoin Core - Nucli de Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Sol·licita pagaments (genera codis QR i bitcoin: URI) - - &About Bitcoin Core - &Quant al Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifica les opcions de configuració del Bitcoin Core - Show the list of used sending addresses and labels Mostra la llista d'adreces d'enviament i etiquetes utilitzades @@ -429,10 +246,6 @@ &Command-line options Opcions de la &línia d'ordres - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostra el missatge d'ajuda del Bitcoin Core per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin - %n active connection(s) to Bitcoin network %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin @@ -544,13 +357,6 @@ El moneder està <b>encriptat</b> i actualment <b>bloquejat</b> - - ClientModel - - Network Alert - Alerta de xarxa - - CoinControlDialog @@ -629,150 +435,6 @@ Priority Prioritat - - Copy address - Copiar adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Lock unspent - Bloqueja sense gastar - - - Unlock unspent - Desbloqueja sense gastar - - - Copy quantity - Copia la quantitat - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy dust - Copia el polsim - - - Copy change - Copia el canvi - - - highest - El més alt - - - higher - Més alt - - - high - Alt - - - medium-high - mig-alt - - - medium - mig - - - low-medium - baix-mig - - - low - baix - - - lower - més baix - - - lowest - el més baix - - - (%1 locked) - (%1 bloquejada) - - - none - cap - - - This label turns red if the transaction size is greater than 1000 bytes. - Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». - - - This label turns red if any recipient receives an amount smaller than %1. - Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1. - - - Can vary +/- %1 satoshi(s) per input. - Pot variar +/- %1 satoshi(s) per entrada. - - - yes - - - - no - no - - - This means a fee of at least %1 per kB is required. - Això comporta una comissió d'almenys %1 per kB. - - - Can vary +/- 1 byte per input. - Pot variar +/- 1 byte per entrada. - - - Transactions with higher priority are more likely to get included into a block. - Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. - - - (no label) - (sense etiqueta) - - - change from %1 (%2) - canvia de %1 (%2) - - - (change) - (canvia) - EditAddressDialog @@ -796,38 +458,6 @@ &Address &Adreça - - New receiving address - Nova adreça de recepció. - - - New sending address - Nova adreça d'enviament - - - Edit receiving address - Edita les adreces de recepció - - - Edit sending address - Edita les adreces d'enviament - - - The entered address "%1" is already in the address book. - L'adreça introduïda «%1» ja és present a la llibreta d'adreces. - - - The entered address "%1" is not a valid Bitcoin address. - L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. - - - Could not unlock wallet. - No s'ha pogut desbloquejar el moneder. - - - New key generation failed. - Ha fallat la generació d'una nova clau. - FreespaceChecker @@ -854,10 +484,6 @@ HelpMessageDialog - - Bitcoin Core - Nucli de Bitcoin - version versió @@ -866,10 +492,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Quant al Bitcoin Core - Command-line options Opcions de línia d'ordres @@ -906,29 +528,13 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - - Reset all settings changes made over the GUI - Reinicialitza tots els canvis de configuració fets des de la interfície gràfica - - + Intro Welcome Us donem la benviguda - - Welcome to Bitcoin Core. - Us donem la benvinguda al Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en aquest directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder. - Use the default data directory Utilitza el directori de dades per defecte @@ -937,10 +543,6 @@ Use a custom data directory: Utilitza un directori de dades personalitzat: - - Bitcoin Core - Nucli de Bitcoin - Error: Specified data directory "%1" cannot be created. Error: el directori de dades «%1» especificat no pot ser creat. @@ -976,10 +578,6 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - - Select payment request file to open - Selecciona el fitxer de sol·licitud de pagament per obrir - OptionsDialog @@ -1019,10 +617,6 @@ 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. Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core. - 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 |. URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |. @@ -1047,14 +641,6 @@ &Network &Xarxa - - Automatically start Bitcoin Core after logging in to the system. - Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema. - - - &Start Bitcoin Core on system login - &Inicia el Bitcoin Core en inciar el sistema - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = deixa tants nuclis lliures) @@ -1283,97 +869,6 @@ Balanç total actual en adreces de només lectura - - PaymentServer - - URI handling - Gestió d'URI - - - Invalid payment address %1 - Adreça de pagament no vàlida %1 - - - Payment request rejected - La sol·licitud de pagament s'ha rebutjat - - - Payment request network doesn't match client network. - La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client. - - - Payment request is not initialized. - La sol·licitud de pagament no està inicialitzada. - - - Requested payment amount of %1 is too small (considered dust). - L'import de pagament sol·licitat %1 és massa petit (es considera polsim). - - - Payment request error - Error en la sol·licitud de pagament - - - Cannot start bitcoin: click-to-pay handler - No es pot iniciar bitcoin: gestor clica-per-pagar - - - Payment request fetch URL is invalid: %1 - L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format. - - - Payment request file handling - Gestió de fitxers de les sol·licituds de pagament - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Unverified payment requests to custom payment scripts are unsupported. - No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats. - - - Invalid payment request. - Sol·licitud de pagament no vàlida. - - - Refund from %1 - Reemborsament de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes). - - - Error communicating with %1: %2 - Error en comunicar amb %1: %2 - - - Payment request cannot be parsed! - No es pot analitzar la sol·licitud de pagament! - - - Bad response from server %1 - Mala resposta del servidor %1 - - - Payment acknowledged - Pagament reconegut - - - Network request error - Error en la sol·licitud de xarxa - - PeerTableModel @@ -1428,25 +923,6 @@ %1 ms - - QRImageWidget - - &Save Image... - De&sa la imatge... - - - &Copy Image - &Copia la imatge - - - Save QR Code - Desa el codi QR - - - PNG Image (*.png) - Imatge PNG (*.png) - - RPCConsole @@ -1513,10 +989,6 @@ Memory usage Us de memoria - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans. - Received Rebut @@ -1633,10 +1105,6 @@ Out: Fora: - - Build date - Data de compilació - Debug log file Fitxer de registre de depuració @@ -1673,10 +1141,6 @@ &Unban Node &Desbandeja el node - - Welcome to the Bitcoin Core RPC console. - Us donem la benviguda a la consola RPC del Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla. @@ -1804,18 +1268,6 @@ Remove Esborra - - Copy label - Copia l'etiqueta - - - Copy message - Copia el missatge - - - Copy amount - Copia l'import - ReceiveRequestDialog @@ -1835,73 +1287,6 @@ &Save Image... De&sa la imatge... - - Request payment to %1 - Sol·licita un pagament a %1 - - - Payment information - Informació de pagament - - - URI - URI - - - Address - Adreça - - - Amount - Import - - - Label - Etiqueta - - - Message - Missatge - - - Resulting URI too long, try to reduce the text for label / message. - URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge - - - Error encoding URI into QR Code. - Error en codificar l'URI en un codi QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiqueta - - - Message - Missatge - - - Amount - Import - - - (no label) - (sense etiqueta) - - - (no message) - (sense missatge) - - - (no amount) - (sense import) - SendCoinsDialog @@ -2021,14 +1406,6 @@ fast ràpid - - Send as zero-fee transaction if possible - Envia com a transacció de comissió zero si és possible - - - (confirmation may take longer) - (la confirmació pot trigar més temps) - Send to multiple recipients at once Envia a múltiples destinataris al mateix temps @@ -2061,118 +1438,6 @@ S&end E&nvia - - Confirm send coins - Confirma l'enviament de monedes - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copia la quantitat - - - Copy amount - Copia l'import - - - Copy fee - Copia la comissió - - - Copy after fee - Copia la comissió posterior - - - Copy bytes - Copia els bytes - - - Copy priority - Copia la prioritat - - - Copy change - Copia el canvi - - - Total Amount %1 - Import total %1 - - - or - o - - - The amount to pay must be larger than 0. - L'import a pagar ha de ser major que 0. - - - The amount exceeds your balance. - L'import supera el vostre balanç. - - - The total exceeds your balance when the %1 transaction fee is included. - El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1. - - - Transaction creation failed! - Ha fallat la creació de la transacció! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades. - - - A fee higher than %1 is considered an absurdly high fee. - Una comissió superior a %1 es considera una comissió absurdament alta. - - - Payment request expired. - La sol·licitud de pagament ha vençut. - - - Pay only the required fee of %1 - Paga només la comissió necessària de %1 - - - Estimated to begin confirmation within %n block(s). - Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. - - - The recipient address is not valid. Please recheck. - L'adreça de destinatari no és vàlida. Torneu-la a comprovar. - - - Duplicate address found: addresses should only be used once each. - S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada. - - - Warning: Invalid Bitcoin address - Avís: adreça Bitcoin no vàlida - - - (no label) - (sense etiqueta) - - - Warning: Unknown change address - Avís: adreça de canvi desconeguda - - - Copy dust - Copia el polsim - - - Are you sure you want to send? - Esteu segur que ho voleu enviar? - - - added as transaction fee - S'ha afegit una taxa de transacció - SendCoinsEntry @@ -2184,10 +1449,6 @@ Pay &To: Paga &a: - - Enter a label for this address to add it to your address book - Introduïu una etiqueta per a aquesta adreça per afegir-la a la llibreta d'adreces - &Label: &Etiqueta: @@ -2259,10 +1520,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - S'està aturant el Bitcoin Core... - Do not shut down the computer until this window disappears. No apagueu l'ordinador fins que no desaparegui aquesta finestra. @@ -2354,69 +1611,9 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - - Click "Sign Message" to generate signature - Feu clic a «Signa el missatge» per a generar una signatura - - - The entered address is invalid. - L'adreça introduïda no és vàlida. - - - Please check the address and try again. - Comproveu l'adreça i torneu-ho a provar. - - - The entered address does not refer to a key. - L'adreça introduïda no referencia a cap clau. - - - Wallet unlock was cancelled. - El desbloqueig del moneder ha estat cancelat. - - - Private key for the entered address is not available. - La clau privada per a la adreça introduïda no està disponible. - - - Message signing failed. - La signatura del missatge ha fallat. - - - Message signed. - Missatge signat. - - - The signature could not be decoded. - La signatura no s'ha pogut descodificar. - - - Please check the signature and try again. - Comproveu la signatura i torneu-ho a provar. - - - The signature did not match the message digest. - La signatura no coincideix amb el resum del missatge. - - - Message verification failed. - Ha fallat la verificació del missatge. - - - Message verified. - Missatge verificat. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Els desenvolupadors del Bitcoin Core - [testnet] [testnet] @@ -2429,422 +1626,13 @@ KB/s - - TransactionDesc - - Open until %1 - Obert fins %1 - - - conflicted - en conflicte - - - %1/offline - %1/fora de línia - - - %1/unconfirmed - %1/sense confirmar - - - %1 confirmations - %1 confirmacions - - - Status - Estat - - - , broadcast through %n node(s) - , difusió a través de %n node, difusió a través de %n nodes - - - Date - Data - - - Source - Font - - - Generated - Generat - - - From - Des de - - - To - A - - - own address - Adreça pròpia - - - watch-only - només lectura - - - label - etiqueta - - - Credit - Crèdit - - - matures in %n more block(s) - disponible en %n bloc mésdisponibles en %n blocs més - - - not accepted - no acceptat - - - Debit - Dèbit - - - Total debit - Dèbit total - - - Total credit - Crèdit total - - - Transaction fee - Comissió de transacció - - - Net amount - Import net - - - Message - Missatge - - - Comment - Comentar - - - Transaction ID - ID de transacció - - - Merchant - Mercader - - - 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. - Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu aquest bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre. - - - Debug information - Informació de depuració - - - Transaction - Transacció - - - Inputs - Entrades - - - Amount - Import - - - true - cert - - - false - fals - - - , has not been successfully broadcast yet - , encara no ha estat emès correctement - - - Open for %n more block(s) - Obre per %n bloc mésObre per %n blocs més - - - unknown - desconegut - - TransactionDescDialog - - Transaction details - Detall de la transacció - This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - - TransactionTableModel - - Date - Data - - - Type - Tipus - - - Immature (%1 confirmations, will be available after %2) - Immadur (%1 confirmacions, serà disponible després de %2) - - - Open for %n more block(s) - Obre per %n bloc mésObre per %n blocs més - - - Open until %1 - Obert fins %1 - - - Confirmed (%1 confirmations) - Confirmat (%1 confirmacions) - - - This block was not received by any other nodes and will probably not be accepted! - Aquest bloc no ha estat rebut per cap altre node i probablement no serà acceptat! - - - Generated but not accepted - Generat però no acceptat - - - Offline - Fora de línia - - - Label - Etiqueta - - - Unconfirmed - Sense confirmar - - - Confirming (%1 of %2 recommended confirmations) - Confirmant (%1 de %2 confirmacions recomanades) - - - Conflicted - En conflicte - - - Received with - Rebut amb - - - Received from - Rebut de - - - Sent to - Enviat a - - - Payment to yourself - Pagament a un mateix - - - Mined - Minat - - - watch-only - només lectura - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Estat de la transacció. Desplaceu-vos sobre aquest camp per mostrar el nombre de confirmacions. - - - Date and time that the transaction was received. - Data i hora en que la transacció va ser rebuda. - - - Type of transaction. - Tipus de transacció. - - - Whether or not a watch-only address is involved in this transaction. - Si està implicada o no una adreça només de lectura en la transacció. - - - User-defined intent/purpose of the transaction. - Intenció/propòsit de la transacció definida per l'usuari. - - - Amount removed from or added to balance. - Import extret o afegit del balanç. - - - - TransactionView - - All - Tot - - - Today - Avui - - - This week - Aquesta setmana - - - This month - Aquest mes - - - Last month - El mes passat - - - This year - Enguany - - - Range... - Rang... - - - Received with - Rebut amb - - - Sent to - Enviat a - - - To yourself - A un mateix - - - Mined - Minat - - - Other - Altres - - - Enter address or label to search - Introduïu una adreça o una etiqueta per cercar - - - Min amount - Import mínim - - - Copy address - Copia l'adreça - - - Copy label - Copiar etiqueta - - - Copy amount - Copia l'import - - - Copy transaction ID - Copiar ID de transacció - - - Copy raw transaction - Copia la transacció crua - - - Edit label - Editar etiqueta - - - Show transaction details - Mostra detalls de la transacció - - - Export Transaction History - Exporta l'historial de transacció - - - Watch-only - Només de lectura - - - Exporting Failed - L'exportació ha fallat - - - There was an error trying to save the transaction history to %1. - S'ha produït un error en provar de desar l'historial de transacció a %1. - - - Exporting Successful - Exportació amb èxit - - - The transaction history was successfully saved to %1. - L'historial de transaccions s'ha desat correctament a %1. - - - Comma separated file (*.csv) - Fitxer separat per comes (*.csv) - - - Confirmed - Confirmat - - - Date - Data - - - Type - Tipus - - - Label - Etiqueta - - - Address - Adreça - - - ID - ID - - - Range: - Rang: - - - to - a - - UnitDisplayStatusBarControl @@ -2852,55 +1640,6 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. - - WalletFrame - - No wallet has been loaded. - No s'ha carregat cap moneder. - - - - WalletModel - - Send Coins - Envia monedes - - - - WalletView - - &Export - &Exporta - - - Export the data in the current tab to a file - Exporta les dades de la pestanya actual a un fitxer - - - Backup Wallet - Còpia de seguretat del moneder - - - Wallet Data (*.dat) - Dades del moneder (*.dat) - - - Backup Failed - Ha fallat la còpia de seguretat - - - There was an error trying to save the wallet data to %1. - S'ha produït un error en provar de desar les dades del moneder a %1. - - - The wallet data was successfully saved to %1. - S'han desat les dades del moneder correctament a %1. - - - Backup Successful - La còpia de seguretat s'ha realitzat correctament - - bitcoin-core @@ -2927,14 +1666,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Si no es proporciona <category> o si <category> = 1, treu a la sortida tota la informació de depuració. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Comproveu que la data i hora de l'ordinador són correctes! Si el vostre rellotge no té l'hora correcta, el Bitcoin Core no funcionarà adequadament. - Prune configured below the minimum of %d MiB. Please use a higher number. Poda configurada per sota el mínim de %d MiB. Utilitzeu un nombre superior. @@ -2975,6 +1706,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepta connexions de fora (per defecte: 1 si no -proxy o -connect) + + Bitcoin Core + Nucli de Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6 @@ -2999,10 +1734,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi. - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) @@ -3019,10 +1750,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. @@ -3143,10 +1870,6 @@ Wallet options: Opcions de moneder: - - You need to rebuild the database using -reindex to change -txindex - Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades @@ -3159,10 +1882,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Aquesta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada) @@ -3203,10 +1922,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d) - The transaction amount is too small to send after the fee has been deducted L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió @@ -3231,26 +1946,10 @@ Accept public REST requests (default: %u) Accepta sol·licituds REST públiques (per defecte: %u) - - Activating best chain... - S'està activant la millor cadena... - - - Cannot resolve -whitebind address: '%s' - No es pot resoldre l'adreça -whitebind: «%s» - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core - Error reading from database, shutting down. Error en llegir la base de dades, tancant. @@ -3259,22 +1958,6 @@ Information &Informació - - Initialization sanity check failed. Bitcoin Core is shutting down. - Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Import no vàlid per a -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Import no vàlid per a -minrelaytxfee=<amount>: «%s» - - - Invalid amount for -mintxfee=<amount>: '%s' - Import no vàlid per a -mintxfee=<amount>: «%s» - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s) @@ -3299,14 +1982,6 @@ RPC server options: Opcions del servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici. - - - Receive and display P2P network alerts (default: %u) - Rep i mostra avisos de la xarxa P2P (per defecte: %u) - Send trace/debug info to console instead of debug.log file Envia informació de traça/depuració a la consola en comptes del fitxer debug.log @@ -3359,10 +2034,6 @@ Username for JSON-RPC connections Nom d'usuari per a connexions JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho. - Warning Avís @@ -3371,10 +2042,6 @@ Zapping all transactions from wallet... Se suprimeixen totes les transaccions del moneder... - - wallet.dat corrupt, salvage failed - El fitxer wallet.data és corrupte. El rescat de les dades ha fallat - Password for JSON-RPC connections Contrasenya per a connexions JSON-RPC @@ -3383,10 +2050,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc) - - This help message - Aquest misatge d'ajuda - Allow DNS lookups for -addnode, -seednode and -connect Permet consultes DNS per a -addnode, -seednode i -connect @@ -3395,10 +2058,6 @@ Loading addresses... S'estan carregant les adreces... - - Error loading wallet.dat: Wallet corrupted - Error en carregar wallet.dat: Moneder corrupte - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx) @@ -3431,14 +2090,6 @@ Always query for peer addresses via DNS lookup (default: %u) Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u) - - Error loading wallet.dat - Error en carregar wallet.dat - - - Generate coins (default: %u) - Genera monedes (per defecte: %u) - How many blocks to check at startup (default: %u, 0 = all) Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots) @@ -3523,18 +2174,6 @@ Unknown network specified in -onlynet: '%s' Xarxa desconeguda especificada a -onlynet: '%s' - - Cannot resolve -bind address: '%s' - No es pot resoldre l'adreça -bind: '%s' - - - Cannot resolve -externalip address: '%s' - No es pot resoldre l'adreça -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Import no vàlid per a -paytxfee=<amount>: «%s» - Insufficient funds Balanç insuficient diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index d3ff5c1f5..d76839723 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -25,10 +25,6 @@ C&lose &Zavřít - - &Copy Address - &Kopíruj adresu - Delete the currently selected address from the list Smaž zvolenou adresu ze seznamu @@ -45,73 +41,6 @@ &Delete S&maž - - Choose the address to send coins to - Zvol adresu, na kterou pošleš mince - - - Choose the address to receive coins with - Zvol adres na příjem mincí - - - C&hoose - &Zvol - - - Sending addresses - Odesílací adresy - - - Receiving addresses - Přijímací adresy - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Tohle jsou tvé Bitcoinové adresy pro posílání plateb. Před odesláním mincí si vždy zkontroluj částku a cílovou adresu. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Nezapomeň si pro každou transakci vždy vygenerovat novou adresu. - - - Copy &Label - Kopíruj &označení - - - &Edit - &Uprav - - - Export Address List - Export seznamu adres - - - Comma separated file (*.csv) - Formát CSV (*.csv) - - - Exporting Failed - Exportování selhalo - - - There was an error trying to save the address list to %1. Please try again. - Při ukládání seznamu adres do %1 se přihodila nějaká chyba. Zkus to prosím znovu. - - - - AddressTableModel - - Label - Označení - - - Address - Adresa - - - (no label) - (bez označení) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Totéž heslo ještě jednou - - Encrypt wallet - Zašifruj peněženku - - - This operation needs your wallet passphrase to unlock the wallet. - K provedení této operace musíš zadat heslo k peněžence, aby se mohla odemknout. - - - Unlock wallet - Odemkni peněženku - - - This operation needs your wallet passphrase to decrypt the wallet. - K provedení této operace musíš zadat heslo k peněžence, aby se mohla dešifrovat. - - - Decrypt wallet - Dešifruj peněženku - - - Change passphrase - Změň heslo - - - Confirm wallet encryption - Potvrď zašifrování peněženky - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Upozornění: Pokud si zašifruješ peněženku a ztratíš či zapomeneš heslo, <b>PŘIJDEŠ O VŠECHNY BITCOINY</b>! - - - Are you sure you wish to encrypt your wallet? - Jsi si jistý, že chceš peněženku zašifrovat? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky nemůže zabránit krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - DŮLEŽITÉ: Všechny předchozí zálohy peněženky by měly být nahrazeny nově vygenerovanou, zašifrovanou peněženkou. Z bezpečnostních důvodů budou předchozí zálohy nešifrované peněženky nepoužitelné, jakmile začneš používat novou zašifrovanou peněženku. - - - Warning: The Caps Lock key is on! - Upozornění: Caps Lock je zapnutý! - - - Wallet encrypted - Peněženka je zašifrována - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Zadej nové heslo k peněžence.<br/>Použij <b>alespoň deset náhodných znaků</b> nebo <b>alespoň osm slov</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Zadej staré a nové heslo k peněžence. - - - Wallet encryption failed - Zašifrování peněženky selhalo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Zašifrování peněženky selhalo kvůli vnitřní chybě. Tvá peněženka tedy nebyla zašifrována. - - - The supplied passphrases do not match. - Zadaná hesla nejsou shodná. - - - Wallet unlock failed - Nepodařilo se odemknout peněženku - - - The passphrase entered for the wallet decryption was incorrect. - Nezadal jsi správné heslo pro dešifrování peněženky. - - - Wallet decryption failed - Nepodařilo se dešifrovat peněženku - - - Wallet passphrase was successfully changed. - Heslo k peněžence bylo v pořádku změněno. - BanTableModel @@ -297,14 +138,6 @@ Open &URI... Načíst &URI... - - Bitcoin Core client - Bitcoin Core klient - - - Importing blocks from disk... - Importuji bloky z disku... - Reindexing blocks on disk... Vytvářím nový index bloků na disku... @@ -349,10 +182,6 @@ &Receive Při&jmi - - Show information about Bitcoin Core - Zobraz informace o Bitcoin Core - &Show / Hide &Zobraz/Skryj @@ -389,22 +218,10 @@ Tabs toolbar Panel s listy - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Požaduj platby (generuje QR kódy a bitcoin: URI) - - &About Bitcoin Core - O &Bitcoin Core - - - Modify configuration options for Bitcoin Core - Uprav nastavení Bitcoin Core - Show the list of used sending addresses and labels Ukaž seznam použitých odesílacích adres a jejich označení @@ -421,10 +238,6 @@ &Command-line options Ar&gumenty příkazové řádky - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Seznam argumentů Bitcoinu pro příkazovou řádku získáš v nápovědě Bitcoinu Core - %n active connection(s) to Bitcoin network %n aktivní spojení do Bitcoinové sítě%n aktivní spojení do Bitcoinové sítě%n aktivních spojení do Bitcoinové sítě @@ -536,13 +349,6 @@ Peněženka je <b>zašifrovaná</b> a momentálně <b>zamčená</b> - - ClientModel - - Network Alert - Upozornění sítě - - CoinControlDialog @@ -621,150 +427,6 @@ Priority Priorita - - Copy address - Kopíruj adresu - - - Copy label - Kopíruj její označení - - - Copy amount - Kopíruj částku - - - Copy transaction ID - Kopíruj ID transakce - - - Lock unspent - Zamkni neutracené - - - Unlock unspent - Odemkni k utracení - - - Copy quantity - Kopíruj počet - - - Copy fee - Kopíruj poplatek - - - Copy after fee - Kopíruj čistou částku - - - Copy bytes - Kopíruj bajty - - - Copy priority - Kopíruj prioritu - - - Copy dust - Kopíruj prach - - - Copy change - Kopíruj drobné - - - highest - nejvyšší - - - higher - vyšší - - - high - vysoká - - - medium-high - vyšší střední - - - medium - střední - - - low-medium - nižší střední - - - low - nízká - - - lower - nižší - - - lowest - nejnižší - - - (%1 locked) - (%1 zamčeno) - - - none - žádná - - - This label turns red if the transaction size is greater than 1000 bytes. - Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů. - - - This label turns red if the priority is smaller than "medium". - Popisek zčervená, pokud je priorita menší než „střední“. - - - This label turns red if any recipient receives an amount smaller than %1. - Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1. - - - Can vary +/- %1 satoshi(s) per input. - Může se lišit o +/– %1 satoshi na každý vstup. - - - yes - ano - - - no - ne - - - This means a fee of at least %1 per kB is required. - To znamená, že je vyžadován poplatek alespoň %1 za kB. - - - Can vary +/- 1 byte per input. - Může se lišit o +/– 1 bajt na každý vstup. - - - Transactions with higher priority are more likely to get included into a block. - Transakce s vyšší prioritou mají větší šanci na zařazení do bloku. - - - (no label) - (bez označení) - - - change from %1 (%2) - drobné z %1 (%2) - - - (change) - (drobné) - EditAddressDialog @@ -788,38 +450,6 @@ &Address &Adresa - - New receiving address - Nová přijímací adresa - - - New sending address - Nová odesílací adresa - - - Edit receiving address - Uprav přijímací adresu - - - Edit sending address - Uprav odesílací adresu - - - The entered address "%1" is already in the address book. - Zadaná adresa „%1“ už v adresáři je. - - - The entered address "%1" is not a valid Bitcoin address. - Zadaná adresa „%1“ není platná Bitcoinová adresa. - - - Could not unlock wallet. - Nemohu odemknout peněženku. - - - New key generation failed. - Nepodařilo se mi vygenerovat nový klíč. - FreespaceChecker @@ -846,10 +476,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version verze @@ -858,10 +484,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - O Bitcoin Core - Command-line options Argumenty příkazové řádky @@ -898,29 +520,13 @@ Show splash screen on startup (default: %u) Zobrazit startovací obrazovku (výchozí: %u) - - Reset all settings changes made over the GUI - Resetovat všechna nastavení provedené v GUI - - + Intro Welcome Vítej - - Welcome to Bitcoin Core. - Vítej v Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Tohle je poprvé, co spouštíš Bitcoin Core, takže si můžeš zvolit, kam bude ukládat svá data. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core bude stahovat kopii řetězce bloků. Proto bude potřeba do tohoto adresáře uložit nejméně %1 GB dat – toto číslo bude navíc v průběhu času pomalu růst. Tvá peněženka bude rovněž uložena v tomto adresáři. - Use the default data directory Použij výchozí adresář pro data @@ -929,10 +535,6 @@ Use a custom data directory: Použij tento adresář pro data: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Chyba: Nejde vytvořit požadovaný adresář pro data „%1“. @@ -968,10 +570,6 @@ Select payment request file Vyber soubor platebního požadavku - - Select payment request file to open - Vyber soubor platebního požadavku k načtení - OptionsDialog @@ -1011,10 +609,6 @@ 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. Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoin Core. - 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 |. URL třetích stran (např. block exploreru), která se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |. @@ -1039,14 +633,6 @@ &Network &Síť - - Automatically start Bitcoin Core after logging in to the system. - Automaticky spustí Bitcoin Core po přihlášení do systému. - - - &Start Bitcoin Core on system login - S&pustit Bitcoin Core po přihlášení do systému - (0 = auto, <0 = leave that many cores free) (0 = automaticky, <0 = nechat daný počet jader volný, výchozí: 0) @@ -1275,97 +861,6 @@ Aktuální stav účtu sledovaných adres - - PaymentServer - - URI handling - Zpracování URI - - - Invalid payment address %1 - Neplatná platební adresa %1 - - - Payment request rejected - Platební požadavek byl odmítnut - - - Payment request network doesn't match client network. - Síť platebního požadavku neodpovídá síti klienta. - - - Payment request is not initialized. - Platební požadavek není zahájený. - - - Requested payment amount of %1 is too small (considered dust). - Požadovaná platební částka %1 je příliš malá (je považována za prach). - - - Payment request error - Chyba platebního požadavku - - - Cannot start bitcoin: click-to-pay handler - Nemůžu spustit bitcoin: obsluha click-to-pay - - - Payment request fetch URL is invalid: %1 - Zdrojová URL platebního požadavku není platná: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - Nepodařilo se analyzovat URI! Důvodem může být neplatná Bitcoinová adresa nebo poškozené parametry URI. - - - Payment request file handling - Zpracování souboru platebního požadavku - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku. - - - Payment request expired. - Platební požadavek vypršel. - - - Unverified payment requests to custom payment scripts are unsupported. - Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované. - - - Invalid payment request. - Neplatný platební požadavek. - - - Refund from %1 - Vrácení peněz od %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů). - - - Error communicating with %1: %2 - Chyba při komunikaci s %1: %2 - - - Payment request cannot be parsed! - Platební požadavek je nečitelný! - - - Bad response from server %1 - Chybná odpověď ze serveru %1 - - - Payment acknowledged - Platba potvrzena - - - Network request error - Chyba síťového požadavku - - PeerTableModel @@ -1420,25 +915,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Ulož obrázek... - - - &Copy Image - &Kopíruj obrázek - - - Save QR Code - Ulož QR kód - - - PNG Image (*.png) - PNG obrázek (*.png) - - RPCConsole @@ -1497,10 +973,6 @@ Memory usage Využití paměti - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Otevři soubor s ladicími záznamy Bitcoin Core z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat. - Received Přijato @@ -1589,10 +1061,6 @@ Out: Ven: - - Build date - Datum kompilace - Debug log file Soubor s ladicími záznamy @@ -1629,10 +1097,6 @@ &Unban Node &Zbavit uzel klatby - - Welcome to the Bitcoin Core RPC console. - Vítej v RPC konzoli Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. V historii se pohybuješ šipkami nahoru a dolů a pomocí <b>Ctrl-L</b> čistíš obrazovku. @@ -1760,18 +1224,6 @@ Remove Smazat - - Copy label - Kopíruj její označení - - - Copy message - Kopíruj zprávu - - - Copy amount - Kopíruj částku - ReceiveRequestDialog @@ -1791,73 +1243,6 @@ &Save Image... &Ulož obrázek... - - Request payment to %1 - Platební požadavek: %1 - - - Payment information - Informace o platbě - - - URI - URI - - - Address - Adresa - - - Amount - Částka - - - Label - Označení - - - Message - Zpráva - - - Resulting URI too long, try to reduce the text for label / message. - Výsledná URI je příliš dlouhá, zkus zkrátit text označení/zprávy. - - - Error encoding URI into QR Code. - Chyba při kódování URI do QR kódu. - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Označení - - - Message - Zpráva - - - Amount - Částka - - - (no label) - (bez označení) - - - (no message) - (bez zprávy) - - - (no amount) - (bez částky) - SendCoinsDialog @@ -1977,14 +1362,6 @@ fast rychlá - - Send as zero-fee transaction if possible - Pošli transakci pokud možno bez poplatku - - - (confirmation may take longer) - (potvrzení může trvat déle) - Send to multiple recipients at once Pošli více příjemcům naráz @@ -2017,118 +1394,6 @@ S&end Pošl&i - - Confirm send coins - Potvrď odeslání mincí - - - %1 to %2 - %1 pro %2 - - - Copy quantity - Kopíruj počet - - - Copy amount - Kopíruj částku - - - Copy fee - Kopíruj poplatek - - - Copy after fee - Kopíruj čistou částku - - - Copy bytes - Kopíruj bajty - - - Copy priority - Kopíruj prioritu - - - Copy change - Kopíruj drobné - - - Total Amount %1 - Celková částka %1 - - - or - nebo - - - The amount to pay must be larger than 0. - Odesílaná částka musí být větší než 0. - - - The amount exceeds your balance. - Částka překračuje stav účtu. - - - The total exceeds your balance when the %1 transaction fee is included. - Celková částka při připočítání poplatku %1 překročí stav účtu. - - - Transaction creation failed! - Vytvoření transakce selhalo! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transakce byla odmítnuta! Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této. - - - A fee higher than %1 is considered an absurdly high fee. - Poplatek vyšší než %1 je považován za absurdně vysoký. - - - Payment request expired. - Platební požadavek vypršel. - - - Pay only the required fee of %1 - Zaplatit pouze vyžadovaný poplatek %1 - - - Estimated to begin confirmation within %n block(s). - Potvrzování by podle odhadu mělo začít během %n bloku.Potvrzování by podle odhadu mělo začít během %n bloků.Potvrzování by podle odhadu mělo začít během %n bloků. - - - The recipient address is not valid. Please recheck. - Adresa příjemce je neplatná – překontroluj ji prosím. - - - Duplicate address found: addresses should only be used once each. - Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou. - - - Warning: Invalid Bitcoin address - Upozornění: Neplatná Bitcoinová adresa - - - (no label) - (bez označení) - - - Warning: Unknown change address - Upozornění: Neznámá adresa pro drobné - - - Copy dust - Kopíruj prach - - - Are you sure you want to send? - Jsi si jistý, že to chceš poslat? - - - added as transaction fee - přidán jako transakční poplatek - SendCoinsEntry @@ -2140,10 +1405,6 @@ Pay &To: &Komu: - - Enter a label for this address to add it to your address book - Zadej označení této adresy; obojí se ti pak uloží do adresáře - &Label: O&značení: @@ -2215,10 +1476,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core se ukončuje... - Do not shut down the computer until this window disappears. Nevypínej počítač, dokud toto okno nezmizí. @@ -2310,69 +1567,9 @@ Reset all verify message fields Vymaž všechna pole formuláře pro ověření zrávy - - Click "Sign Message" to generate signature - Kliknutím na „Podepiš zprávu“ vygeneruješ podpis - - - The entered address is invalid. - Zadaná adresa je neplatná. - - - Please check the address and try again. - Zkontroluj ji prosím a zkus to pak znovu. - - - The entered address does not refer to a key. - Zadaná adresa nepasuje ke klíči. - - - Wallet unlock was cancelled. - Odemčení peněženky bylo zrušeno. - - - Private key for the entered address is not available. - Soukromý klíč pro zadanou adresu není dostupný. - - - Message signing failed. - Nepodařilo se podepsat zprávu. - - - Message signed. - Zpráva podepsána. - - - The signature could not be decoded. - Podpis nejde dekódovat. - - - Please check the signature and try again. - Zkontroluj ho prosím a zkus to pak znovu. - - - The signature did not match the message digest. - Podpis se neshoduje s hašem zprávy. - - - Message verification failed. - Nepodařilo se ověřit zprávu. - - - Message verified. - Zpráva ověřena. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Vývojáři Bitcoin Core - [testnet] [testnet] @@ -2385,422 +1582,13 @@ kB/s - - TransactionDesc - - Open until %1 - Otřevřeno dokud %1 - - - conflicted - kolidující - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/nepotvrzeno - - - %1 confirmations - %1 potvrzení - - - Status - Stav - - - , broadcast through %n node(s) - , rozesláno přes %n uzel, rozesláno přes %n uzly, rozesláno přes %n uzlů - - - Date - Datum - - - Source - Zdroj - - - Generated - Vygenerováno - - - From - Od - - - To - Pro - - - own address - vlastní adresa - - - watch-only - sledovaná - - - label - označení - - - Credit - Příjem - - - matures in %n more block(s) - dozraje po %n blokudozraje po %n blocíchdozraje po %n blocích - - - not accepted - neakceptováno - - - Debit - Výdaj - - - Total debit - Celkové výdaje - - - Total credit - Celkové příjmy - - - Transaction fee - Transakční poplatek - - - Net amount - Čistá částka - - - Message - Zpráva - - - Comment - Komentář - - - Transaction ID - ID transakce - - - Merchant - Obchodník - - - 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. - Vygenerované mince musí čekat %1 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na „neakceptovaný“ a nepůjde utratit. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. - - - Debug information - Ladicí informace - - - Transaction - Transakce - - - Inputs - Vstupy - - - Amount - Částka - - - true - true - - - false - false - - - , has not been successfully broadcast yet - , ještě nebylo rozesláno - - - Open for %n more block(s) - Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků - - - unknown - neznámo - - TransactionDescDialog - - Transaction details - Detaily transakce - This pane shows a detailed description of the transaction Toto okno zobrazuje detailní popis transakce - - TransactionTableModel - - Date - Datum - - - Type - Typ - - - Immature (%1 confirmations, will be available after %2) - Nedozráno (%1 potvrzení, dozraje při %2 potvrzeních) - - - Open for %n more block(s) - Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků - - - Open until %1 - Otřevřeno dokud %1 - - - Confirmed (%1 confirmations) - Potvrzeno (%1 potvrzení) - - - This block was not received by any other nodes and will probably not be accepted! - Tento blok nedostal žádný jiný uzel a pravděpodobně nebude akceptován! - - - Generated but not accepted - Vygenerováno, ale neakceptováno - - - Offline - Offline - - - Label - Označení - - - Unconfirmed - Nepotvrzeno - - - Confirming (%1 of %2 recommended confirmations) - Potvrzuje se (%1 z %2 doporučených potvrzení) - - - Conflicted - V kolizi - - - Received with - Přijato do - - - Received from - Přijato od - - - Sent to - Posláno na - - - Payment to yourself - Platba sama sobě - - - Mined - Vytěženo - - - watch-only - sledovací - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Stav transakce. Najetím myši na toto políčko si zobrazíš počet potvrzení. - - - Date and time that the transaction was received. - Datum a čas přijetí transakce. - - - Type of transaction. - Druh transakce. - - - Whether or not a watch-only address is involved in this transaction. - Zda tato transakce zahrnuje i některou sledovanou adresu. - - - User-defined intent/purpose of the transaction. - Uživatelsky určený účel transakce. - - - Amount removed from or added to balance. - Částka odečtená z nebo přičtená k účtu. - - - - TransactionView - - All - Vše - - - Today - Dnes - - - This week - Tento týden - - - This month - Tento měsíc - - - Last month - Minulý měsíc - - - This year - Letos - - - Range... - Rozsah... - - - Received with - Přijato - - - Sent to - Posláno - - - To yourself - Sám sobě - - - Mined - Vytěženo - - - Other - Ostatní - - - Enter address or label to search - Zadej adresu nebo označení pro její vyhledání - - - Min amount - Minimální částka - - - Copy address - Kopíruj adresu - - - Copy label - Kopíruj její označení - - - Copy amount - Kopíruj částku - - - Copy transaction ID - Kopíruj ID transakce - - - Copy raw transaction - Kopíruj surovou transakci - - - Edit label - Uprav označení - - - Show transaction details - Zobraz detaily transakce - - - Export Transaction History - Exportuj transakční historii - - - Watch-only - Sledovaná - - - Exporting Failed - Exportování selhalo - - - There was an error trying to save the transaction history to %1. - Při ukládání transakční historie do %1 se přihodila nějaká chyba. - - - Exporting Successful - Úspěšně vyexportováno - - - The transaction history was successfully saved to %1. - Transakční historie byla v pořádku uložena do %1. - - - Comma separated file (*.csv) - Formát CSV (*.csv) - - - Confirmed - Potvrzeno - - - Date - Datum - - - Type - Typ - - - Label - Označení - - - Address - Adresa - - - ID - ID - - - Range: - Rozsah: - - - to - - - UnitDisplayStatusBarControl @@ -2808,55 +1596,6 @@ Jednotka pro částky. Klikni pro výběr nějaké jiné. - - WalletFrame - - No wallet has been loaded. - Žádná peněženka se nenačetla. - - - - WalletModel - - Send Coins - Pošli mince - - - - WalletView - - &Export - &Export - - - Export the data in the current tab to a file - Exportuj data z tohoto panelu do souboru - - - Backup Wallet - Záloha peněženky - - - Wallet Data (*.dat) - Data peněženky (*.dat) - - - Backup Failed - Zálohování selhalo - - - There was an error trying to save the wallet data to %1. - Při ukládání peněženky do %1 se přihodila nějaká chyba. - - - The wallet data was successfully saved to %1. - Data z peněženky byla v pořádku uložena do %1. - - - Backup Successful - Úspěšně zazálohováno - - bitcoin-core @@ -2883,10 +1622,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Pokud není <category> zadána nebo je <category> = 1, bude tisknout veškeré ladicí informace. - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Prosím zkontrolujte nastavení času na svém počítači. Pokud čas a datum není nastaven správně, Bitcoin Core nebude fungovat! - Prune configured below the minimum of %d MiB. Please use a higher number. Prořezávání je nastaveno pod minimum %d MiB. Použij, prosím, nějaké vyšší číslo. @@ -2927,6 +1662,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Přijímat spojení zvenčí (výchozí: 1, pokud není zadáno -proxy nebo -connect) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee je nastaveno velmi vysoko! Toto je transakční poplatek, který bys platil, pokud nebude k dispozici odhad poplatků. @@ -2971,14 +1710,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Tohle je testovací verze – používej ji jen na vlastní riziko, ale rozhodně ji nepoužívej k těžbě nebo pro obchodní aplikace - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Nepodporovaný argument -whitelistalwaysrelay se ignoruje, použij -whitelistrelay a/nebo -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá a nepoužívá -proxy) @@ -2999,10 +1730,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Upozornění: Nesouhlasím zcela se svými protějšky! Možná potřebuji aktualizovat nebo ostatní uzly potřebují aktualizovat. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud jsou stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Vždy vítat protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. @@ -3167,10 +1894,6 @@ Wallet options: Možnosti peněženky: - - You need to rebuild the database using -reindex to change -txindex - Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Povolit JSON-RPC spojení ze specifikovaného zdroje. Platnou hodnotou <ip> je jednotlivá IP adresa (např. 1.2.3.4), síť/maska (např. 1.2.3.4/255.255.255.0) nebo síť/CIDR (např. 1.2.3.4/24). Tuto volbu lze použít i vícekrát @@ -3183,10 +1906,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Čekat na zadané adrese na JSON-RPC spojení. Pro zápis IPv6 adresy použij notaci [adresa]:port. Tuto volbu lze použít i vícekrát (výchozí: poslouchat na všech rozhraních) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Nedaří se mi získat zámek na datový adresář %s. Bitcoin Core pravděpodobně už jednou běží. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky) @@ -3231,10 +1950,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d) - The transaction amount is too small to send after the fee has been deducted Částka v transakci po odečtení poplatku je příliš malá na odeslání @@ -3259,34 +1974,14 @@ Accept public REST requests (default: %u) Přijímat veřejné REST požadavky (výchozí: %u) - - Activating best chain... - Aktivuji nejlepší řetězec... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Pokusit se při startu zachránit soukromé klíče z poškozeného souboru wallet.dat - Automatically create Tor hidden service (default: %d) Automaticky v Toru vytvářet skryté služby (výchozí: %d) - - Cannot resolve -whitebind address: '%s' - Nemohu přeložit -whitebind adresu: '%s' - Connect through SOCKS5 proxy Připojit se přes SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Vývojáři Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoin Core - Error reading from database, shutting down. Chyba při čtení z databáze, ukončuji se. @@ -3299,22 +1994,6 @@ Information Informace - - Initialization sanity check failed. Bitcoin Core is shutting down. - Selhala úvodní zevrubná prověrka. Bitcoin Core se ukončuje. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Neplatná částka pro -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Neplatná částka pro -minrelaytxfee=<částka>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Neplatná částka pro -mintxfee=<částka>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Neplatná částka pro -paytxfee=<částka>: '%s' (musí být alespoň %s) @@ -3339,14 +2018,6 @@ RPC server options: Možnosti RPC serveru: - - Rebuild block chain index from current blk000??.dat files on startup - Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů - - - Receive and display P2P network alerts (default: %u) - Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Omezuji -maxconnections z %d na %d kvůli systémovým omezením. @@ -3419,10 +2090,6 @@ Username for JSON-RPC connections Uživatelské jméno pro JSON-RPC spojení - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Soubor s peněženkou potřeboval přepsat: restartuj Bitcoin Core, aby se operace dokončila - Warning Upozornění @@ -3439,10 +2106,6 @@ ZeroMQ notification options: Možnosti ZeroMQ oznámení: - - wallet.dat corrupt, salvage failed - Soubor wallet.dat je poškozen, jeho záchrana se nezdařila - Password for JSON-RPC connections Heslo pro JSON-RPC spojení @@ -3451,10 +2114,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Spustit příkaz, když se změní nejlepší blok (%s se v příkazu nahradí hashem bloku) - - This help message - Tato nápověda - Allow DNS lookups for -addnode, -seednode and -connect Povolit DNS dotazy pro -addnode (přidání uzlu), -seednode a -connect (připojení) @@ -3463,10 +2122,6 @@ Loading addresses... Načítám adresy... - - Error loading wallet.dat: Wallet corrupted - Chyba při načítání wallet.dat: peněženka je poškozená - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata) @@ -3483,10 +2138,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Nedržet transakce v zásobníku déle než <n> hodin (výchozí: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Nastala chyba při čtení souboru wallet.dat! Všechny klíče se přečetly správně, ale data o transakcích nebo záznamy v adresáři mohou chybět či být nesprávné. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Poplatky (v %s/kB) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s) @@ -3523,6 +2174,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Byl použit nepodporovaný argument -socks. Nastavení verze SOCKS už není možné, podporovány jsou pouze SOCKS5 proxy. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Nepodporovaný argument -whitelistalwaysrelay se ignoruje, použij -whitelistrelay a/nebo -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru (výchozí: %s) @@ -3539,14 +2194,6 @@ Always query for peer addresses via DNS lookup (default: %u) Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u) - - Error loading wallet.dat - Chyba při načítání wallet.dat - - - Generate coins (default: %u) - Těžit (výchozí: %u) - How many blocks to check at startup (default: %u, 0 = all) Kolik bloků při startu zkontrolovat (výchozí: %u, 0 = všechny) @@ -3627,18 +2274,6 @@ Unknown network specified in -onlynet: '%s' V -onlynet byla uvedena neznámá síť: '%s' - - Cannot resolve -bind address: '%s' - Nemohu přeložit -bind adresu: '%s' - - - Cannot resolve -externalip address: '%s' - Nemohu přeložit -externalip adresu: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Neplatná částka pro -paytxfee=<částka>: '%s' - Insufficient funds Nedostatek prostředků diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts index 34d7b4b4a..70aa981f5 100644 --- a/src/qt/locale/bitcoin_cs_CZ.ts +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -29,25 +29,6 @@ &Delete &Odstranit - - Comma separated file (*.csv) - Textový soubor oddělený středníkem (*.csv) - - - - AddressTableModel - - Label - Popis - - - Address - Adresa - - - (no label) - (bez popisu) - AskPassphraseDialog @@ -63,63 +44,7 @@ Repeat new passphrase Zopakujte nové heslo - - Encrypt wallet - Zašifrovat peněženku - - - This operation needs your wallet passphrase to unlock the wallet. - Tato operace vyžaduje heslo k odemknutí peněženky. - - - Unlock wallet - Odemknout peněženku - - - This operation needs your wallet passphrase to decrypt the wallet. - Tato operace vyžaduje heslo k dešifrování peněženky. - - - Decrypt wallet - Dešifrovat peněženku - - - Change passphrase - Změnit heslo - - - Confirm wallet encryption - Potvrďte zašifrování peněženky - - - Wallet encrypted - Peněženka zašifrována - - - Wallet encryption failed - Zašifrování peněženky selhalo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Šifrování peněženky selhalo vinou vnitřní chyby. Vaše peněženka nebyla zašifrována. - - - The supplied passphrases do not match. - Zadaná hesla nejsou shodná. - - - Wallet unlock failed - Odemčení peněženky selhalo - - - The passphrase entered for the wallet decryption was incorrect. - Heslo zadané k dešifrování peněženky nebylo správné - - - Wallet decryption failed - Deěifrování peněženky selhalo - - + BanTableModel @@ -202,9 +127,6 @@ Peněženka je <b>zašifrována</b> a momentálně <b>uzamčená</b> - - ClientModel - CoinControlDialog @@ -223,18 +145,6 @@ Confirmed Potvrzeno - - Copy address - Kopírovat sdresu - - - Copy label - Kopírovat popis - - - (no label) - (bez popisu) - EditAddressDialog @@ -250,34 +160,6 @@ &Address &Adresa - - New receiving address - Nová adresa pro příjem - - - New sending address - Nová adresa k odeslání - - - Edit receiving address - Upravit adresu pro příjem - - - Edit sending address - Upravit adresu k odeslání - - - The entered address "%1" is already in the address book. - Zadaná adresa "%1" se již v seznamu adres nachází. - - - Could not unlock wallet. - Nemohu odemknout peněženku - - - New key generation failed. - Generování nového klíče selhalo. - FreespaceChecker @@ -317,9 +199,6 @@ OverviewPage - - PaymentServer - PeerTableModel @@ -330,9 +209,6 @@ Množství - - QRImageWidget - RPCConsole @@ -350,52 +226,9 @@ &Message: Zpráva: - - Copy label - Kopírovat popis - ReceiveRequestDialog - - Address - Adresa - - - Amount - Množství - - - Label - Popis - - - Message - Zpráva - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Popis - - - Message - Zpráva - - - Amount - Množství - - - (no label) - (bez popisu) - SendCoinsDialog @@ -407,14 +240,6 @@ Balance: Zůstatek: - - The amount to pay must be larger than 0. - Částka k zaplacení musí být větší než 0. - - - (no label) - (bez popisu) - SendCoinsEntry @@ -443,210 +268,16 @@ TrafficGraphWidget - - TransactionDesc - - %1/unconfirmed - %1 potvrzeno - - - %1 confirmations - %1 potvrzení - - - Status - Stav - - - Date - Datum - - - Message - Zpráva - - - Transaction - Transakce - - - Amount - Množství - - TransactionDescDialog - - Transaction details - Detaily transakce - This pane shows a detailed description of the transaction Toto podokno zobrazuje detailní popis transakce - - TransactionTableModel - - Date - Datum - - - Type - Typ - - - Confirmed (%1 confirmations) - Potvrzeno (%1 potvrzení) - - - This block was not received by any other nodes and will probably not be accepted! - Tento blok nebyl přijat žádným dalším uzlem a pravděpodobně nebude akceptován! - - - Label - Popis - - - Received with - Přijato s - - - Sent to - Odesláno na - - - Payment to yourself - Platba sobě samému - - - Mined - Vytěženo - - - Type of transaction. - Typ transakce. - - - - TransactionView - - All - Vše - - - Today - Dnes - - - This week - Tento týden - - - This month - Tento měsíc - - - Last month - Minulý měsíc - - - This year - Tento rok - - - Range... - Rozsah... - - - Received with - Přijato s - - - Sent to - Odesláno na - - - To yourself - Sobě samému - - - Mined - Vytěženo - - - Other - Ostatní - - - Min amount - Min. množství - - - Copy address - Kopírovat sdresu - - - Copy label - Kopírovat popis - - - Edit label - Upravit popis - - - Comma separated file (*.csv) - Textový soubor oddělený středníkem (*.csv) - - - Confirmed - Potvrzeno - - - Date - Datum - - - Type - Typ - - - Label - Popis - - - Address - Adresa - - - ID - ID - - - Range: - Rozsah: - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportovat - - - Export the data in the current tab to a file - Exportovat aktuální pohled do souboru - - bitcoin-core diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index c32d236a9..38bc45775 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -21,10 +21,6 @@ C&lose C&au - - &Copy Address - &Cyfeiriad Copi - &Export &Allforio @@ -33,49 +29,6 @@ &Delete &Dileu - - C&hoose - &Dewis - - - Sending addresses - Cyfeiriadau anfon - - - Receiving addresses - Cyfeiriadau derbyn - - - Copy &Label - Copïo &Label - - - &Edit - &Golygu - - - Export Address List - Allforio Rhestr Cyfeiriad - - - Exporting Failed - Methodd Allfor - - - - AddressTableModel - - Label - Label - - - Address - Cyfeiriad - - - (no label) - (heb label) - AskPassphraseDialog @@ -91,63 +44,7 @@ Repeat new passphrase Ailadroddwch gyfrinymadrodd newydd - - Encrypt wallet - Amgryptio'r waled - - - This operation needs your wallet passphrase to unlock the wallet. - Mae angen i'r gweithred hon ddefnyddio'ch cyfrinymadrodd er mwyn datgloi'r waled. - - - Unlock wallet - Datgloi'r waled - - - This operation needs your wallet passphrase to decrypt the wallet. - Mae angen i'r gweithred hon ddefnyddio'ch cyfrinymadrodd er mwyn dadgryptio'r waled. - - - Decrypt wallet - Dadgryptio'r waled - - - Change passphrase - Newid cyfrinymadrodd - - - Confirm wallet encryption - Cadarnau amgryptiad y waled - - - Are you sure you wish to encrypt your wallet? - Ydych chi'n siwr eich bod chi eisiau amgryptio dy waled di? - - - Wallet encrypted - Waled wedi'i amgryptio - - - Wallet encryption failed - Amgryptiad waled wedi methu - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Methodd amgryptiad y waled oherwydd gwall mewnol. Ni amgryptwyd eich waled. - - - The supplied passphrases do not match. - Dydy'r cyfrinymadroddion a ddarparwyd ddim yn cyd-fynd â'u gilydd. - - - Wallet unlock failed - Methodd ddatgloi'r waled - - - Wallet decryption failed - Methodd dadgryptiad y waled - - + BanTableModel @@ -229,10 +126,6 @@ &Receive &Derbyn - - Show information about Bitcoin Core - Dangos gwybodaeth am Graidd Bitcoin - &Show / Hide &Dangos / Cuddio @@ -253,14 +146,6 @@ Tabs toolbar Bar offer tabiau - - Bitcoin Core - Craidd Bitcoin - - - &About Bitcoin Core - &Ynghylch Craidd Bitcoin - %n hour(s) %n awr%n awr%n awr%n awr @@ -342,9 +227,6 @@ Mae'r waled <b>wedi'i amgryptio</b> ac <b>ar glo</b> ar hyn o bryd - - ClientModel - CoinControlDialog @@ -355,23 +237,7 @@ Date Dyddiad - - Copy address - Cyfeiriad copi - - - Copy label - Copïo label - - - (no label) - (heb label) - - - (change) - (newid) - - + EditAddressDialog @@ -386,34 +252,6 @@ &Address &Cyfeiriad - - New receiving address - Cyfeiriad derbyn newydd - - - New sending address - Cyfeiriad anfon newydd - - - Edit receiving address - Golygu'r cyfeiriad derbyn - - - Edit sending address - Golygu'r cyfeiriad anfon - - - The entered address "%1" is already in the address book. - Mae'r cyfeiriad "%1" sydd newydd gael ei geisio gennych yn y llyfr cyfeiriad yn barod. - - - Could not unlock wallet. - Methodd ddatgloi'r waled. - - - New key generation failed. - Methodd gynhyrchu allwedd newydd. - FreespaceChecker @@ -424,14 +262,6 @@ HelpMessageDialog - - Bitcoin Core - Craidd Bitcoin - - - About Bitcoin Core - Ynghylch Craidd Bitcoin - Usage: Cynefod: @@ -443,14 +273,6 @@ Welcome Croeso - - Welcome to Bitcoin Core. - Croeso i Graidd Bitcoin - - - Bitcoin Core - Craidd Bitcoin - Error Gwall @@ -509,18 +331,12 @@ Ffurflen - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -542,10 +358,6 @@ &Label: &Label: - - Copy label - Copïo label - ReceiveRequestDialog @@ -553,37 +365,6 @@ Copy &Address &Cyfeiriad Copi - - Address - Cyfeiriad - - - Label - Label - - - Message - Neges - - - - RecentRequestsTableModel - - Date - Dyddiad - - - Label - Label - - - Message - Neges - - - (no label) - (heb label) - SendCoinsDialog @@ -607,14 +388,6 @@ Confirm the send action Cadarnhau'r gweithrediad anfon - - %1 to %2 - %1 i %2 - - - (no label) - (heb label) - SendCoinsEntry @@ -663,14 +436,6 @@ SplashScreen - - Bitcoin Core - Craidd Bitcoin - - - The Bitcoin Core developers - Datblygwyr Graidd Bitcoin - [testnet] [testnet] @@ -679,108 +444,22 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Agor tan %1 - - - Date - Dyddiad - - - Message - Neges - - TransactionDescDialog - - TransactionTableModel - - Date - Dyddiad - - - Type - Math - - - Open until %1 - Agor tan %1 - - - Label - Label - - - - TransactionView - - Today - Heddiw - - - This year - Eleni - - - Copy address - Cyfeiriad copi - - - Copy label - Copïo label - - - Exporting Failed - Methodd Allfor - - - Date - Dyddiad - - - Type - Math - - - Label - Label - - - Address - Cyfeiriad - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Anfon arian - - - - WalletView - - &Export - &Allforio - - bitcoin-core Options: Opsiynau: + + Bitcoin Core + Craidd Bitcoin + Information Gwybodaeth diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 7d11825a6..91903088c 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -25,10 +25,6 @@ C&lose &Luk - - &Copy Address - &Kopiér adresse - Delete the currently selected address from the list Slet den markerede adresse fra listen @@ -45,73 +41,6 @@ &Delete &Slet - - Choose the address to send coins to - Vælg adresse at sende bitcoins til - - - Choose the address to receive coins with - Vælg adresse at modtage bitcoins med - - - C&hoose - &Vælg - - - Sending addresses - Afsendelsesadresser - - - Receiving addresses - Modtagelsesadresser - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Disse er dine Bitcoin-adresser for at sende betalinger. Tjek altid beløb og modtageradresse, inden du sender bitcoins. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dette er dine Bitcoin-adresser til at modtage betalinger med. Det anbefales are bruge en ny modtagelsesadresse for hver transaktion. - - - Copy &Label - Kopiér &mærkat - - - &Edit - &Redigér - - - Export Address List - Eksportér adresseliste - - - Comma separated file (*.csv) - Kommasepareret fil (*.csv) - - - Exporting Failed - Eksport mislykkedes - - - There was an error trying to save the address list to %1. Please try again. - Der opstod en fejl under gemning af adresselisten til %1. Prøv venligst igen. - - - - AddressTableModel - - Label - Mærkat - - - Address - Adresse - - - (no label) - (ingen mærkat) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Gentag ny adgangskode - - Encrypt wallet - Kryptér tegnebog - - - This operation needs your wallet passphrase to unlock the wallet. - Denne funktion har brug for din tegnebogs adgangskode for at låse tegnebogen op. - - - Unlock wallet - Lås tegnebog op - - - This operation needs your wallet passphrase to decrypt the wallet. - Denne funktion har brug for din tegnebogs adgangskode for at dekryptere tegnebogen. - - - Decrypt wallet - Dekryptér tegnebog - - - Change passphrase - Skift adgangskode - - - Confirm wallet encryption - Bekræft tegnebogskryptering - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Advarsel: Hvis du krypterer din tegnebog og mister din adgangskode, vil du <b>MISTE ALLE DINE BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Er du sikker på, at du ønsker at kryptere din tegnebog? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core vil nu lukke for at færdiggøre krypteringsprocessen. Husk at kryptering af din tegnebog kan ikke beskytte dine bitcoin fuldt ud mod at blive stjålet af eventuel malware, der måtte have inficeret din computer. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - VIGTIGT: Enhver tidligere sikkerhedskopi, som du har lavet af tegnebogsfilen, bør blive erstattet af den nyligt genererede, krypterede tegnebogsfil. Af sikkerhedsmæssige årsager vil tidligere sikkerhedskopier af den ikke-krypterede tegnebogsfil blive ubrugelige i det øjeblik, du starter med at anvende den nye, krypterede tegnebog. - - - Warning: The Caps Lock key is on! - Advarsel: Caps Lock-tasten er aktiveret! - - - Wallet encrypted - Tegnebog krypteret - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Indtast det nye kodeord til tegnebogen.<br/>Brug venligst et kodeord på <b>ti eller flere tilfældige tegn</b> eller <b>otte eller flere ord</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Indtast den gamle adgangskode og en ny adgangskode til tegnebogen. - - - Wallet encryption failed - Tegnebogskryptering mislykkedes - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Tegnebogskryptering mislykkedes på grund af en intern fejl. Din tegnebog blev ikke krypteret. - - - The supplied passphrases do not match. - De angivne adgangskoder stemmer ikke overens. - - - Wallet unlock failed - Tegnebogsoplåsning mislykkedes - - - The passphrase entered for the wallet decryption was incorrect. - Den angivne adgangskode for tegnebogsdekrypteringen er forkert. - - - Wallet decryption failed - Tegnebogsdekryptering mislykkedes - - - Wallet passphrase was successfully changed. - Tegnebogens adgangskode blev ændret. - BanTableModel @@ -269,6 +110,14 @@ Quit application Afslut program + + &About %1 + &Om %1 + + + Show information about %1 + Vis informationer om %1 + About &Qt Om &Qt @@ -281,6 +130,10 @@ &Options... &Indstillinger… + + Modify configuration options for %1 + Redigér konfigurationsindstillinger for %1 + &Encrypt Wallet... &Kryptér tegnebog… @@ -305,14 +158,6 @@ Open &URI... &Åbn URI… - - Bitcoin Core client - Bitcoin Core-klient - - - Importing blocks from disk... - Importerer blokke fra disken… - Reindexing blocks on disk... Genindekserer blokke på disken… @@ -357,10 +202,6 @@ &Receive &Modtag - - Show information about Bitcoin Core - Vis oplysninger om Bitcoin Core - &Show / Hide &Vis / skjul @@ -397,22 +238,10 @@ Tabs toolbar Faneværktøjslinje - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Anmod om betalinger (genererer QR-koder og "bitcoin:"-URI'er) - - &About Bitcoin Core - &Om Bitcoin Core - - - Modify configuration options for Bitcoin Core - Ændr opsætning af Bitcoin Core - Show the list of used sending addresses and labels Vis listen over brugte afsendelsesadresser og -mærkater @@ -429,14 +258,18 @@ &Command-line options Tilvalg for &kommandolinje - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Vis Bitcoin Core hjælpebesked for at få en liste over mulige tilvalg for Bitcoin kommandolinje - %n active connection(s) to Bitcoin network %n aktiv forbindelse til Bitcoin-netværket%n aktive forbindelser til Bitcoin-netværket + + Indexing blocks on disk... + Genindekserer blokke på disken… + + + Processing blocks on disk... + Bearbejder blokke på disken… + No block source available... Ingen blokkilde tilgængelig… @@ -493,6 +326,14 @@ Up to date Opdateret + + Show the %1 help message to get a list with possible Bitcoin command-line options + Vis %1 hjælpebesked for at få en liste over mulige tilvalg for Bitcoin kommandolinje + + + %1 client + %1-klient + Catching up... Indhenter… @@ -544,13 +385,6 @@ Tegnebog er <b>krypteret</b> og i øjeblikket <b>låst</b> - - ClientModel - - Network Alert - Netværksadvarsel - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Prioritet - - Copy address - Kopiér adresse - - - Copy label - Kopiér mærkat - - - Copy amount - Kopiér beløb - - - Copy transaction ID - Kopiér transaktions-ID - - - Lock unspent - Fastlås ubrugte - - - Unlock unspent - Lås ubrugte op - - - Copy quantity - Kopiér mængde - - - Copy fee - Kopiér gebyr - - - Copy after fee - Kopiér efter-gebyr - - - Copy bytes - Kopiér byte - - - Copy priority - Kopiér prioritet - - - Copy dust - Kopiér støv - - - Copy change - Kopiér byttepenge - - - highest - højest - - - higher - højere - - - high - højt - - - medium-high - mellemhøj - - - medium - medium - - - low-medium - mellemlav - - - low - lav - - - lower - lavere - - - lowest - lavest - - - (%1 locked) - (%1 fastlåst) - - - none - ingen - - - This label turns red if the transaction size is greater than 1000 bytes. - Denne mærkat bliver rød, hvis transaktionsstørrelsen er større end 1000 byte. - - - This label turns red if the priority is smaller than "medium". - Denne mærkat bliver rød, hvis prioriteten er mindre end "medium". - - - This label turns red if any recipient receives an amount smaller than %1. - Denne mærkat bliver rød, hvis en eller flere modtagere modtager et beløb, der er mindre end %1. - - - Can vary +/- %1 satoshi(s) per input. - Kan variere med +/- %1 satoshi per input. - - - yes - ja - - - no - nej - - - This means a fee of at least %1 per kB is required. - Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt. - - - Can vary +/- 1 byte per input. - Kan variere ±1 byte pr. input. - - - Transactions with higher priority are more likely to get included into a block. - Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok. - - - (no label) - (ingen mærkat) - - - change from %1 (%2) - byttepenge fra %1 (%2) - - - (change) - (byttepange) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adresse - - New receiving address - Ny modtagelsesadresse - - - New sending address - Ny afsendelsesadresse - - - Edit receiving address - Redigér modtagelsesadresse - - - Edit sending address - Redigér afsendelsesadresse - - - The entered address "%1" is already in the address book. - Den indtastede adresse "%1" er allerede i adressebogen. - - - The entered address "%1" is not a valid Bitcoin address. - Den indtastede adresse "%1" er ikke en gyldig Bitcoin-adresse. - - - Could not unlock wallet. - Kunne ikke låse tegnebog op. - - - New key generation failed. - Ny nøglegenerering mislykkedes. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - Om Bitcoin Core + About %1 + Om %1 Command-line options @@ -907,7 +561,7 @@ Vis startskærm under opstart (standard: %u) - Reset all settings changes made over the GUI + Reset all settings changed in the GUI Nulstil alle indstillinger, der er foretaget i den grafiske brugerflade @@ -918,16 +572,16 @@ Velkommen - Welcome to Bitcoin Core. - Velkommen til Bitcoin Core. + Welcome to %1. + Velkommen til %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Siden dette er første gang, programmet startes, kan du vælge, hvor Bitcoin Core skal gemme sin data. + As this is the first time the program is launched, you can choose where %1 will store its data. + Siden dette er første gang, programmet startes, kan du vælge, hvor %1 skal gemme sin data. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core vil downloade og gemme et kopi af Bitcoin-blokkæden. Mindst %1 GB data vil blive gemt i denne mappe, og den vil vokse over tid. Tegnebogen vil også blive gemt i denne mappe. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 vil downloade og gemme et kopi af Bitcoin-blokkæden. Mindst %2 GB data vil blive gemt i denne mappe, og den vil vokse over tid. Tegnebogen vil også blive gemt i denne mappe. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Brug tilpasset mappe for data: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Fejl: Angivet datamappe "%1" kan ikke oprettes. @@ -976,10 +626,6 @@ Select payment request file Vælg fil for betalingsanmodning - - Select payment request file to open - Vælg fil for betalingsanmodning til åbning - OptionsDialog @@ -991,6 +637,14 @@ &Main &Generelt + + Automatically start %1 after logging in to the system. + Start %1 automatisk, når der logges ind på systemet. + + + &Start %1 on system login + &Start %1 ved systemlogin + Size of &database cache Størrelsen på &databasens cache @@ -1019,10 +673,6 @@ 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. Minimér i stedet for at lukke applikationen, når vinduet lukkes. Når denne indstilling er aktiveret, vil applikationen først blive lukket, når Afslut vælges i menuen. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Sproget for brugerfladen kan vælges her. Denne indstilling vil træde i kraft efter genstart af Bitcoin Core. - 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 |. Tredjeparts-URL'er (fx et blokhåndteringsværktøj), der vises i transaktionsfanen som genvejsmenupunkter. %s i URL'en erstattes med transaktionens hash. Flere URL'er separeres med en lodret streg |. @@ -1047,14 +697,6 @@ &Network &Netværk - - Automatically start Bitcoin Core after logging in to the system. - Start Bitcoin Core automatisk efter der logges ind på systemet. - - - &Start Bitcoin Core on system login - &Start Bitcoin Core ved system-login - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = efterlad så mange kerner fri) @@ -1139,6 +781,14 @@ &Window &Vindue + + &Hide the icon from the system tray. + &Skjul ikonet fra statusbaren. + + + Hide tray icon + Skjul statusikon + Show only a tray icon after minimizing the window. Vis kun et statusikon efter minimering af vinduet. @@ -1159,6 +809,10 @@ User Interface &language: &Sprog for brugergrænseflade: + + The user interface language can be set here. This setting will take effect after restarting %1. + Sproget for brugerfladen kan vælges her. Denne indstilling vil træde i kraft efter genstart af %1. + &Unit to show amounts in: &Enhed, som beløb vises i: @@ -1283,97 +937,6 @@ Nuværende totalsaldo på kigge-adresser - - PaymentServer - - URI handling - URI-håndtering - - - Invalid payment address %1 - Ugyldig betalingsadresse %1 - - - Payment request rejected - Betalingsanmodning afvist - - - Payment request network doesn't match client network. - Netværk for betalingsanmodning stemmer ikke overens med klientens netværk. - - - Payment request is not initialized. - Betalingsanmodning er ikke klargjort. - - - Requested payment amount of %1 is too small (considered dust). - Anmodet betalingsbeløb på %1 er for lille (regnes som støv). - - - Payment request error - Fejl i betalingsanmodning - - - Cannot start bitcoin: click-to-pay handler - Kan ikke starte bitcoin: click-to-pay-håndtering - - - Payment request fetch URL is invalid: %1 - Hentnings-URL for betalingsanmodning er ugyldig: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kan ikke tolkes! Dette kan skyldes en ugyldig Bitcoin-adresse eller forkert udformede URL-parametre. - - - Payment request file handling - Filhåndtering for betalingsanmodninger - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Fil for betalingsanmodning kan ikke læses! Dette kan skyldes en ugyldig fil for betalingsanmodning. - - - Payment request expired. - Betalingsanmodning er udløbet. - - - Unverified payment requests to custom payment scripts are unsupported. - Ikke-verificerede betalingsanmodninger for tilpassede betalings-scripts understøttes ikke. - - - Invalid payment request. - Ugyldig betalingsanmodning. - - - Refund from %1 - Tilbagebetaling fra %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Betalingsanmodning %1 er for stor (%2 byte, %3 byte tilladt). - - - Error communicating with %1: %2 - Fejl under kommunikation med %1: %2 - - - Payment request cannot be parsed! - Betalingsanmodning kan ikke tolkes! - - - Bad response from server %1 - Fejlagtigt svar fra server %1 - - - Payment acknowledged - Betaling anerkendt - - - Network request error - Fejl i netværksforespørgsel - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Gem billede… - - - &Copy Image - &Kopiér foto - - - Save QR Code - Gem QR-kode - - - PNG Image (*.png) - PNG-billede (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Bruger BerkeleyDB version + + Datadir + Datamappe + Startup time Opstartstidspunkt @@ -1513,10 +1061,6 @@ Memory usage Hukommelsesforbrug - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler. - Received Modtaget @@ -1565,6 +1109,18 @@ User Agent Brugeragent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Åbn %1s fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler. + + + Decrease font size + Formindsk skrifttypestørrelse + + + Increase font size + Forstør skrifttypestørrelse + Services Tjenester @@ -1633,10 +1189,6 @@ Out: Udgående: - - Build date - Byggedato - Debug log file Fejlsøgningslogfil @@ -1674,8 +1226,8 @@ &Fjern bandlysning af knude - Welcome to the Bitcoin Core RPC console. - Velkommen til Bitcoin Cores RPC-konsol. + Welcome to the %1 RPC console. + Velkommen til %1s RPC-konsol. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove Fjern - - Copy label - Kopiér mærkat - - - Copy message - Kopiér besked - - - Copy amount - Kopier beløb - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... &Gem billede… - - Request payment to %1 - Anmod om betaling til %1 - - - Payment information - Betalingsinformation - - - URI - URI - - - Address - Adresse - - - Amount - Beløb - - - Label - Mærkat - - - Message - Besked - - - Resulting URI too long, try to reduce the text for label / message. - Resulterende URI var for lang; prøv at forkorte teksten til mærkaten/beskeden. - - - Error encoding URI into QR Code. - Fejl ved kodning fra URI til QR-kode. - - - - RecentRequestsTableModel - - Date - Dato - - - Label - Mærkat - - - Message - Besked - - - Amount - Beløb - - - (no label) - (ingen mærkat) - - - (no message) - (ingen besked) - - - (no amount) - (intet beløb) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast hurtig - - Send as zero-fee transaction if possible - Send som nul-gebyr-transaktion hvis muligt - - - (confirmation may take longer) - (bekræftelse kan tage længere) - Send to multiple recipients at once Send til flere modtagere på en gang @@ -2061,118 +1526,6 @@ S&end &Afsend - - Confirm send coins - Bekræft afsendelse af bitcoins - - - %1 to %2 - %1 til %2 - - - Copy quantity - Kopiér mængde - - - Copy amount - Kopier beløb - - - Copy fee - Kopiér gebyr - - - Copy after fee - Kopiér efter-gebyr - - - Copy bytes - Kopiér byte - - - Copy priority - Kopiér prioritet - - - Copy change - Kopiér byttepenge - - - Total Amount %1 - Totalbeløb %1 - - - or - eller - - - The amount to pay must be larger than 0. - Beløbet til betaling skal være større end 0. - - - The amount exceeds your balance. - Beløbet overstiger din saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - Totalen overstiger din saldo, når transaktionsgebyret på %1 er inkluderet. - - - Transaction creation failed! - Oprettelse af transaktion mislykkedes! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her. - - - A fee higher than %1 is considered an absurdly high fee. - Et gebyr højere end %1 opfattes som et absurd højt gebyr. - - - Payment request expired. - Betalingsanmodning er udløbet. - - - Pay only the required fee of %1 - Betal kun det påkrævede gebyr på %1 - - - Estimated to begin confirmation within %n block(s). - Bekræftelse estimeres til at begynde inden for %n blok.Bekræftelse estimeres til at begynde inden for %n blokke. - - - The recipient address is not valid. Please recheck. - Modtageradressen er ikke gyldig. Tjek venligst igen. - - - Duplicate address found: addresses should only be used once each. - Adressegenganger fundet. Adresser bør kun bruges én gang hver. - - - Warning: Invalid Bitcoin address - Advarsel: Ugyldig Bitcoin-adresse - - - (no label) - (ingen mærkat) - - - Warning: Unknown change address - Advarsel: Ukendt byttepengeadresse - - - Copy dust - Kopiér støv - - - Are you sure you want to send? - Er du sikker på, at du vil sende? - - - added as transaction fee - tilføjet som transaktionsgebyr - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: Betal &til: - - Enter a label for this address to add it to your address book - Indtast en mærkat for denne adresse for at føje den til din adressebog - &Label: &Mærkat: @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core lukker ned… + %1 is shutting down... + %1 lukker ned… Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields Nulstil alle "verificér besked"-felter - - Click "Sign Message" to generate signature - Klik "Underskriv besked" for at generere underskriften - - - The entered address is invalid. - Den indtastede adresse er ugyldig. - - - Please check the address and try again. - Tjek venligst adressen og forsøg igen. - - - The entered address does not refer to a key. - Den indtastede adresse henviser ikke til en nøgle. - - - Wallet unlock was cancelled. - Tegnebogsoplåsning annulleret. - - - Private key for the entered address is not available. - Den private nøgle for den indtastede adresse er ikke tilgængelig. - - - Message signing failed. - Underskrivning af besked mislykkedes. - - - Message signed. - Besked underskrevet. - - - The signature could not be decoded. - Underskriften kunne ikke afkodes. - - - Please check the signature and try again. - Tjek venligst underskriften, og forsøg igen. - - - The signature did not match the message digest. - Underskriften matcher ikke beskedens indhold. - - - Message verification failed. - Verificering af besked mislykkedes. - - - Message verified. - Besked verificeret. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Udviklerne af Bitcoin Core - [testnet] [testnetværk] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - Åben indtil %1 - - - conflicted - konflikt - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/ubekræftet - - - %1 confirmations - %1 bekræftelser - - - Status - Status - - - , broadcast through %n node(s) - , transmitteret igennem %n knude, transmitteret igennem %n knuder - - - Date - Dato - - - Source - Kilde - - - Generated - Genereret - - - From - Fra - - - To - Til - - - own address - egen adresse - - - watch-only - kigge - - - label - mærkat - - - Credit - Kredit - - - matures in %n more block(s) - modner efter yderligere %n blokmodner efter yderligere %n blokke - - - not accepted - ikke accepteret - - - Debit - Debet - - - Total debit - Total debet - - - Total credit - Total kredit - - - Transaction fee - Transaktionsgebyr - - - Net amount - Nettobeløb - - - Message - Besked - - - Comment - Kommentar - - - Transaction ID - Transaktions-ID - - - Merchant - Forretningsdrivende - - - 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. - Minede bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den transmitteret til netværket for at blive føjet til blokkæden. Hvis det ikke lykkes at få den i kæden, vil dens tilstand ændres til "ikke accepteret", og den vil ikke kunne bruges. Dette kan ske nu og da, hvis en anden knude udvinder en blok inden for nogle få sekunder fra din. - - - Debug information - Fejlsøgningsinformation - - - Transaction - Transaktion - - - Inputs - Input - - - Amount - Beløb - - - true - sand - - - false - falsk - - - , has not been successfully broadcast yet - , er ikke blevet transmitteret endnu - - - Open for %n more block(s) - Åbn yderligere %n blokÅbn yderligere %n blokke - - - unknown - ukendt - - TransactionDescDialog - - Transaction details - Transaktionsdetaljer - This pane shows a detailed description of the transaction Denne rude viser en detaljeret beskrivelse af transaktionen - - TransactionTableModel - - Date - Dato - - - Type - Type - - - Immature (%1 confirmations, will be available after %2) - Umoden (%1 bekræftelser; vil være tilgængelig efter %2) - - - Open for %n more block(s) - Åbn yderligere %n blokÅbn yderligere %n blokke - - - Open until %1 - Åben indtil %1 - - - Confirmed (%1 confirmations) - Bekræftet (%1 bekræftelser) - - - This block was not received by any other nodes and will probably not be accepted! - Denne blok blev ikke modtaget af nogen andre knuder og vil formentlig ikke blive accepteret! - - - Generated but not accepted - Genereret, men ikke accepteret - - - Offline - Offline - - - Label - Mærkat - - - Unconfirmed - Ubekræftet - - - Confirming (%1 of %2 recommended confirmations) - Bekræfter (%1 af %2 anbefalede bekræftelser) - - - Conflicted - Konflikt - - - Received with - Modtaget med - - - Received from - Modtaget fra - - - Sent to - Sendt til - - - Payment to yourself - Betaling til dig selv - - - Mined - Minet - - - watch-only - kigge - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Transaktionsstatus. Hold musen over dette felt for at vise antallet af bekræftelser. - - - Date and time that the transaction was received. - Dato og klokkeslæt for modtagelse af transaktionen. - - - Type of transaction. - Transaktionstype. - - - Whether or not a watch-only address is involved in this transaction. - Afgør hvorvidt en kigge-adresse er involveret i denne transaktion. - - - User-defined intent/purpose of the transaction. - Brugerdefineret hensigt/formål med transaktionen. - - - Amount removed from or added to balance. - Beløb trukket fra eller tilføjet balance. - - - - TransactionView - - All - Alle - - - Today - I dag - - - This week - Denne uge - - - This month - Denne måned - - - Last month - Sidste måned - - - This year - Dette år - - - Range... - Interval… - - - Received with - Modtaget med - - - Sent to - Sendt til - - - To yourself - Til dig selv - - - Mined - Minet - - - Other - Andet - - - Enter address or label to search - Indtast adresse eller mærkat for at søge - - - Min amount - Minimumsbeløb - - - Copy address - Kopiér adresse - - - Copy label - Kopiér mærkat - - - Copy amount - Kopiér beløb - - - Copy transaction ID - Kopiér transaktions-ID - - - Copy raw transaction - Kopiér rå transaktion - - - Edit label - Redigér mærkat - - - Show transaction details - Vis transaktionsdetaljer - - - Export Transaction History - Historik for eksport af transaktioner - - - Watch-only - Kigge - - - Exporting Failed - Eksport mislykkedes - - - There was an error trying to save the transaction history to %1. - En fejl opstod under gemning af transaktionshistorik til %1. - - - Exporting Successful - Eksport problemfri - - - The transaction history was successfully saved to %1. - Transaktionshistorikken blev gemt til %1 med succes. - - - Comma separated file (*.csv) - Kommasepareret fil (*.csv) - - - Confirmed - Bekræftet - - - Date - Dato - - - Type - Type - - - Label - Mærkat - - - Address - Adresse - - - ID - ID - - - Range: - Interval: - - - to - til - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ Enhed, som beløb vises i. Klik for at vælge en anden enhed. - - WalletFrame - - No wallet has been loaded. - Ingen tegnebog er indlæst. - - - - WalletModel - - Send Coins - Send bitcoins - - - - WalletView - - &Export - &Eksportér - - - Export the data in the current tab to a file - Eksportér den aktuelle visning til en fil - - - Backup Wallet - Sikkerhedskopiér tegnebog - - - Wallet Data (*.dat) - Tegnebogsdata (*.dat) - - - Backup Failed - Sikkerhedskopiering mislykkedes - - - There was an error trying to save the wallet data to %1. - Der skete en fejl under gemning af tegnebogsdata til %1. - - - The wallet data was successfully saved to %1. - Tegnebogsdata blev gemt til %1 med succes. - - - Backup Successful - Sikkerhedskopiering problemfri - - bitcoin-core @@ -2927,14 +1758,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Hvis <category> ikke angives eller hvis <category> = 1, udskriv al fejlretningsinformation. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maksimalt totalgebyr (i %s) for brug i en enkelt tegnebogstransaktion; ved at sætte dette for lavt, kan store transaktioner afbrydes (standard: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Kontrollér venligst, at din computers dato og tid er korrekt! Hvis uret ikke passer, vil Bitcoin Core ikke fungere korrekt. - Prune configured below the minimum of %d MiB. Please use a higher number. Beskæring er sat under minimumsgrænsen på %d MiB. Brug venligst et større tal. @@ -2975,6 +1798,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Acceptér forbindelser udefra (standard: 1 hvis hverken -proxy eller -connect) + + Bitcoin Core + Bitcoin Core + + + The %s developers + Udviklerne af %s + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee er sat meget højt! Dette er transaktionsgebyret, du eventuelt betaler, hvis gebyrestimater ikke er tilgængelige. @@ -2991,6 +1822,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Kan ikke opnå en lås på datamappe %s. %s kører sansynligvis allerede. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart @@ -2999,6 +1834,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Fejl under indlæsning af %s: Du kan ikke aktivere HD på en allerede eksisterende ikke-HD-tegnebog + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Fejl under læsning af %s! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID) @@ -3007,6 +1850,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Justering af maksimalt tilladt gennemsnitlig afvigelse fra peer-tid. Den lokale opfattelse af tid kan blive påvirket frem eller tilbage af peers med denne mængde tid. (standard: %u sekunder) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maksimalt totalgebyr (i %s) der må bruges i en enkelt tegnebogstransaktion eller rå transaktion; en for lav en værdi kan afbryde store transaktioner (standard: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse, vil %s ikke fungere korrekt. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Overvej venligst at bidrage til udviklingen, hvis du finder %s brugbar. Besøg %s for yderligere information om softwaren. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d) @@ -3019,14 +1878,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dette er en foreløbig testudgivelse - brug på eget ansvar - brug ikke til udvinding eller handelsprogrammer - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Argument -whitelistalwaysrelay understøttes ikke og ignoreres; brug -whitelistrelay og/eller -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Brug UPnP for at konfigurere den lyttende port (standard: 1 under lytning og ingen -proxy) @@ -3043,22 +1894,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Advarsel: Netværket ser ikke ud til at være fuldt ud enige! Enkelte minere ser ud til at opleve problemer. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Advarsel: Ukendte blokversioner bliver minet! Det er muligt, at ukendte regler er i brug - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Advarsel: Vi ser ikke ud til at være fuldt ud enige med andre knuder! Du kan være nødt til at opgradere, eller andre knuder kan være nødt til at opgradere. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Advarsel: wallet.dat ødelagt, data reddet! Oprindelig wallet.dat gemt som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaktioner er forkert, bør du genskabe fra en sikkerhedskopi. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Sæt andre knuder, der forbinder fra den angivne netmaske eller IP, på hvidliste. Kan angives flere gange. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Du er nødt til at genopbygge databasen ved hjælp af -reindex-chainstate for at ændre -txindex + + + %s corrupt, salvage failed + %s ødelagt, redning af data mislykkedes + -maxmempool must be at least %d MB -maxmempool skal være mindst %d MB @@ -3071,10 +1922,22 @@ Append comment to the user agent string Føj kommentar til brugeragentstrengen + + Attempt to recover private keys from a corrupt wallet on startup + Forsøg at genskabe private nøgler fra en ødelagt tegnebog under opstart + Block creation options: Blokoprettelsestilvalg: + + Cannot resolve -%s address: '%s' + Kan ikke finde -%s-adressen: "%s" + + + Change index out of range + Ændr indeks uden for interval + Connect only to the specified node(s) Tilslut kun til de(n) angivne knude(r) @@ -3083,6 +1946,10 @@ Connection options: Tilvalg for forbindelser: + + Copyright (C) %i-%i + Ophavsret © %i-%i + Corrupted block database detected Ødelagt blokdatabase opdaget @@ -3127,6 +1994,22 @@ Error initializing wallet database environment %s! Klargøring af tegnebogsdatabasemiljøet %s mislykkedes! + + Error loading %s + Fejl under indlæsning af %s + + + Error loading %s: Wallet corrupted + Fejl under indlæsning af %s: Tegnebog ødelagt + + + Error loading %s: Wallet requires newer version of %s + Fejl under indlæsning af %s: Tegnebog kræver nyere version af %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Fejl under indlæsning af %s: Du kan ikke deaktivere HD på en allerede eksisterende HD-tegnebog + Error loading block database Indlæsning af blokdatabase mislykkedes @@ -3151,10 +2034,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Ukorrekt eller ingen tilblivelsesblok fundet. Forkert datamappe for netværk? + + Initialization sanity check failed. %s is shutting down. + Klargøring af sundhedstjek mislykkedes. %s lukker ned. + Invalid -onion address: '%s' Ugyldig -onion adresse: "%s" + + Invalid amount for -%s=<amount>: '%s' + Ugyldigt beløb for -%s=<beløb>: "%s" + Invalid amount for -fallbackfee=<amount>: '%s' Ugyldigt beløb for -fallbackfee=<beløb>: "%s" @@ -3163,6 +2054,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Hold hukommelsespuljen med transaktioner under <n> megabyte (standard: %u) + + Loading banlist... + Indlæser bandlysningsliste… + Location of the auth cookie (default: data dir) Placering for autentificerings-cookie (standard: datamappe) @@ -3179,6 +2074,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Tilslut kun til knuder i netværk <net> (IPv4, IPv6 eller Onion) + + Print this help message and exit + Udskriv denne hjælpetekst og afslut + Print version and exit Udskriv version og afslut @@ -3191,6 +2090,14 @@ Prune mode is incompatible with -txindex. Beskæringstilstand er ikke kompatibel med -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Genopbyg kædetilstand og blokindeks fra blk*.dat-filerne på disken + + + Rebuild chain state from the currently indexed blocks + Genopbyg kædetilstand ud fra de aktuelt indekserede blokke + Set database cache size in megabytes (%d to %d, default: %d) Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d) @@ -3203,6 +2110,14 @@ Specify wallet file (within data directory) Angiv tegnebogsfil (inden for datamappe) + + The source code is available from %s. + Kildekoden er tilgængelig fra %s. + + + Unable to bind to %s on this computer. %s is probably already running. + Ikke i stand til at tildele til %s på denne computer. %s kører formodentlig allerede. + Unsupported argument -benchmark ignored, use -debug=bench. Argument -benchmark understøttes ikke og ignoreres; brug -debug=bench. @@ -3236,12 +2151,16 @@ Tegnebog %s findes uden for datamappe %s - Wallet options: - Tilvalg for tegnebog: + Wallet debugging/testing options: + Tilvalg for fejlfinding/test af tegnebog: - You need to rebuild the database using -reindex to change -txindex - Du er nødt til at genopbygge databasen ved hjælp af -reindex for at ændre -txindex + Wallet needed to be rewritten: restart %s to complete + Det var nødvendigt at genskrive tegnebogen: Genstart %s for at gennemføre + + + Wallet options: + Tilvalg for tegnebog: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3255,10 +2174,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Tildel til den givne adresse for at lytte efter JSON-RPC-forbindelser. Brug [vært]:port-notation for IPv6. Denne valgmulighed kan angives flere gange (standard: tildel til alle grænseflader) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Kan ikke opnå en lås på datamappe %s. Bitcoin Core kører sansynligvis allerede. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Opret nye filer med systemstandard for rettigheder i stedet for umask 077 (kun virksomt med tegnebogsfunktionalitet slået fra) @@ -3303,10 +2218,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Sæt antaller af tråde for coin-generering, hvis aktiveret (-1 = alle kerner, standard: %d) - The transaction amount is too small to send after the fee has been deducted Transaktionsbeløbet er for lille til at sende, når gebyret er trukket fra @@ -3315,6 +2226,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Dette produkt indeholder software, der er udviklet af OpenSSL-projektet for brug i OpenSSL-værktøjskassen <https://www.openssl.org/>, samt kryptografisk software, der er skrevet af Eric Young, samt UPnP-software, der er skrevet af Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Brug hierarkisk deterministisk nøglegenerering (HD) efter BIP32. Har kun effekt ved generering af ny tegnebog og under første opstart + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Andre knuder på hvidliste kan ikke DoS-bandlyses, og deres transaktioner videresendes altid, selv hvis de allerede er i hukommelsespuljen. Brugbart til fx et adgangspunkt @@ -3331,34 +2246,14 @@ Accept public REST requests (default: %u) Acceptér offentlige REST-anmodninger (standard: %u) - - Activating best chain... - Aktiverer bedste kæde… - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Forsøg at genskabe private nøgler fra en ødelagt wallet.dat under opstart - Automatically create Tor hidden service (default: %d) Opret automatisk skjult Tor-tjeneste (standard: %d) - - Cannot resolve -whitebind address: '%s' - Kan ikke løse -whitebind adresse: "%s" - Connect through SOCKS5 proxy Forbind gennem SOCKS5-proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Ophavsret © 2009-%i Udviklerne af Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Fejl ved indlæsning af wallet.dat: Tegnebog kræver en nyere version af Bitcoin Core - Error reading from database, shutting down. Fejl under læsning fra database; lukker ned. @@ -3371,22 +2266,6 @@ Information Information - - Initialization sanity check failed. Bitcoin Core is shutting down. - Sundhedstjek under klargøring mislykkedes. Bitcoin Core lukker ned. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Ugyldigt beløb for -maxtxfee=<beløb>: "%s" - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Ugyldigt beløb til -minrelaytxfee=<beløb>: "%s" - - - Invalid amount for -mintxfee=<amount>: '%s' - Ugyldigt beløb til -mintxfee=<beløb>: "%s" - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Ugyldigt beløb for -paytxfee=<beløb>: "%s" (skal være mindst %s) @@ -3411,14 +2290,6 @@ RPC server options: Tilvalg for RPC-server: - - Rebuild block chain index from current blk000??.dat files on startup - Genopbyg blokkædeindeks fra nuværende blk000??.dat-filer ved opstart - - - Receive and display P2P network alerts (default: %u) - Modtag og vis P2P-netværksadvarsler (standard: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reducerer -maxconnections fra %d til %d på grund af systembegrænsninger. @@ -3491,10 +2362,6 @@ Username for JSON-RPC connections Brugernavn til JSON-RPC-forbindelser - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Det var nødvendigt at genskrive tegnebogen: genstart Bitcoin Core for at gennemføre - Warning Advarsel @@ -3515,10 +2382,6 @@ ZeroMQ notification options: ZeroMQ-notifikationsindstillinger: - - wallet.dat corrupt, salvage failed - wallet.dat ødelagt, redning af data mislykkedes - Password for JSON-RPC connections Adgangskode til JSON-RPC-forbindelser @@ -3527,10 +2390,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Udfør kommando, når den bedste blok ændres (%s i kommandoen erstattes med blokhash) - - This help message - Denne hjælpebesked - Allow DNS lookups for -addnode, -seednode and -connect Tillad DNS-opslag for -addnode, -seednode og -connect @@ -3539,10 +2398,6 @@ Loading addresses... Indlæser adresser… - - Error loading wallet.dat: Wallet corrupted - Fejl ved indlæsning af wallet.dat: Tegnebog ødelagt - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion) @@ -3559,10 +2414,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Behold ikke transaktioner i hukommelsespuljen i mere end <n> timer (default: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr under oprettelse af transaktioner (standard: %s) @@ -3599,6 +2450,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Argument -socks understøttes ikke. Det er ikke længere muligt at sætte SOCKS-version; kun SOCKS5-proxier understøttes. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argument -whitelistalwaysrelay understøttes ikke og ignoreres; brug -whitelistrelay og/eller -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Brug separat SOCS5-proxy for at nå knuder via skjulte Tor-tjenester (standard: %s) @@ -3607,6 +2462,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Brugernavn og hashet adgangskode for JSON-RPC-forbindelser. Feltet <userpw> er i formatet: <BRUGERNAVN>:<SALT>$<HASH>. Et kanonisk Python-skript inkluderes i share/rpcuser. Dette tilvalg kan angives flere gange + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advarsel: Ukendte blokversioner bliver minet! Det er muligt, at ukendte regler er i brug + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Advarsel: Tegnebogsfil ødelagt, data reddet! Oprindelig %s gemt som %s i %s; hvis din saldo eller dine transaktioner er forkert, bør du genskabe fra en sikkerhedskopi. + (default: %s) (standard: %s) @@ -3615,14 +2478,6 @@ Always query for peer addresses via DNS lookup (default: %u) Forespørg altid adresser på andre knuder via DNS-opslag (default: %u) - - Error loading wallet.dat - Fejl ved indlæsning af wallet.dat - - - Generate coins (default: %u) - Generér bitcoins (standard: %u) - How many blocks to check at startup (default: %u, 0 = all) Antal blokke som tjekkes ved opstart (standard: %u, 0 = alle) @@ -3708,18 +2563,6 @@ Unknown network specified in -onlynet: '%s' Ukendt netværk anført i -onlynet: "%s" - - Cannot resolve -bind address: '%s' - Kan ikke finde -bind adressen: "%s" - - - Cannot resolve -externalip address: '%s' - Kan ikke finde -externalip adressen: "%s" - - - Invalid amount for -paytxfee=<amount>: '%s' - Ugyldigt beløb for -paytxfee=<beløb>: "%s" - Insufficient funds Manglende dækning diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 947a471ac..639bc3cf2 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -25,10 +25,6 @@ C&lose &Schließen - - &Copy Address - Adresse &kopieren - Delete the currently selected address from the list Ausgewählte Adresse aus der Liste entfernen @@ -45,73 +41,6 @@ &Delete &Löschen - - Choose the address to send coins to - Wählen Sie die Adresse aus, an die Sie Bitcoins überweisen möchten - - - Choose the address to receive coins with - Wählen Sie die Adresse aus, über die Sie Bitcoins empfangen wollen - - - C&hoose - &Auswählen - - - Sending addresses - Zahlungsadressen - - - Receiving addresses - Empfangsadressen - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Dies sind Ihre Bitcoin-Adressen zum Tätigen von Überweisungen. Bitte prüfen Sie den Betrag und die Empfangsadresse, bevor Sie Bitcoins überweisen. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dies sind Ihre Bitcoin-Adressen zum Empfangen von Zahlungen. Es wird empfohlen für jede Transaktion eine neue Empfangsadresse zu verwenden. - - - Copy &Label - &Bezeichnung kopieren - - - &Edit - &Editieren - - - Export Address List - Addressliste exportieren - - - Comma separated file (*.csv) - Kommagetrennte-Datei (*.csv) - - - Exporting Failed - Exportieren fehlgeschlagen - - - There was an error trying to save the address list to %1. Please try again. - Beim Speichern der Adressliste nach %1 ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut. - - - - AddressTableModel - - Label - Bezeichnung - - - Address - Adresse - - - (no label) - (keine Bezeichnung) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Neue Passphrase bestätigen - - Encrypt wallet - Wallet verschlüsseln - - - This operation needs your wallet passphrase to unlock the wallet. - Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entsperren. - - - Unlock wallet - Wallet entsperren - - - This operation needs your wallet passphrase to decrypt the wallet. - Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entschlüsseln. - - - Decrypt wallet - Wallet entschlüsseln - - - Change passphrase - Passphrase ändern - - - Confirm wallet encryption - Wallet-Verschlüsselung bestätigen - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Warnung: Wenn Sie Ihre Wallet verschlüsseln und Ihre Passphrase verlieren, werden Sie <b>alle Ihre Bitcoins verlieren</b>! - - - Are you sure you wish to encrypt your wallet? - Sind Sie sich sicher, dass Sie Ihre Wallet verschlüsseln möchten? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Vergessen Sie nicht, dass eine Wallet-Verschlüsselung nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadsoftware schützen kann, die Ihren Computer infiziert. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - WICHTIG: Alle vorherigen Wallet-Sicherungen sollten durch die neu erzeugte, verschlüsselte Wallet ersetzt werden. Aus Sicherheitsgründen werden vorherige Sicherungen der unverschlüsselten Wallet nutzlos, sobald Sie die neue, verschlüsselte Wallet verwenden. - - - Warning: The Caps Lock key is on! - Warnung: Die Feststelltaste ist aktiviert! - - - Wallet encrypted - Wallet verschlüsselt - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Geben Sie die neue Passphrase für die Wallet ein.<br>Bitte benutzen Sie eine Passphrase bestehend aus <b>zehn oder mehr zufälligen Zeichen</b> oder <b>acht oder mehr Wörtern</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Geben Sie die alte und neue Wallet-Passphrase ein. - - - Wallet encryption failed - Wallet-Verschlüsselung fehlgeschlagen - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Die Wallet-Verschlüsselung ist aufgrund eines internen Fehlers fehlgeschlagen. Ihre Wallet wurde nicht verschlüsselt. - - - The supplied passphrases do not match. - Die eingegebenen Passphrasen stimmen nicht überein. - - - Wallet unlock failed - Wallet-Entsperrung fehlgeschlagen - - - The passphrase entered for the wallet decryption was incorrect. - Die eingegebene Passphrase zur Wallet-Entschlüsselung war nicht korrekt. - - - Wallet decryption failed - Wallet-Entschlüsselung fehlgeschlagen - - - Wallet passphrase was successfully changed. - Die Wallet-Passphrase wurde erfolgreich geändert. - BanTableModel @@ -269,6 +110,14 @@ Quit application Anwendung beenden + + &About %1 + &Über %1 + + + Show information about %1 + Informationen über %1 anzeigen + About &Qt Über &Qt @@ -281,6 +130,10 @@ &Options... &Konfiguration... + + Modify configuration options for %1 + Konfiguration von %1 bearbeiten + &Encrypt Wallet... Wallet &verschlüsseln... @@ -305,14 +158,6 @@ Open &URI... &URI öffnen... - - Bitcoin Core client - "Bitcoin Core"-Client - - - Importing blocks from disk... - Importiere Blöcke von Datenträger... - Reindexing blocks on disk... Reindiziere Blöcke auf Datenträger... @@ -357,10 +202,6 @@ &Receive &Empfangen - - Show information about Bitcoin Core - Informationen über Bitcoin Core anzeigen - &Show / Hide &Anzeigen / Verstecken @@ -397,22 +238,10 @@ Tabs toolbar Registerkartenleiste - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Zahlungen anfordern (erzeugt QR-Codes und "bitcoin:"-URIs) - - &About Bitcoin Core - &Über Bitcoin Core - - - Modify configuration options for Bitcoin Core - Konfiguration von Bitcoin Core bearbeiten - Show the list of used sending addresses and labels Liste verwendeter Zahlungsadressen und Bezeichnungen anzeigen @@ -429,14 +258,18 @@ &Command-line options &Kommandozeilenoptionen - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Zeige den "Bitcoin Core"-Hilfetext, um eine Liste mit möglichen Kommandozeilenoptionen zu erhalten - %n active connection(s) to Bitcoin network %n aktive Verbindung zum Bitcoin-Netzwerk%n aktive Verbindungen zum Bitcoin-Netzwerk + + Indexing blocks on disk... + Reindiziere Blöcke auf Datenträger... + + + Processing blocks on disk... + Verarbeite Blöcke auf Datenträger... + No block source available... Keine Blockquelle verfügbar... @@ -493,6 +326,14 @@ Up to date Auf aktuellem Stand + + Show the %1 help message to get a list with possible Bitcoin command-line options + Zeige den "%1"-Hilfetext, um eine Liste mit möglichen Kommandozeilenoptionen zu erhalten + + + %1 client + %1 Client + Catching up... Hole auf... @@ -544,13 +385,6 @@ Wallet ist <b>verschlüsselt</b> und aktuell <b>gesperrt</b> - - ClientModel - - Network Alert - Netzwerkalarm - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Priorität - - Copy address - Adresse kopieren - - - Copy label - Bezeichnung kopieren - - - Copy amount - Betrag kopieren - - - Copy transaction ID - Transaktions-ID kopieren - - - Lock unspent - Nicht ausgegebenen Betrag sperren - - - Unlock unspent - Nicht ausgegebenen Betrag entsperren - - - Copy quantity - Anzahl kopieren - - - Copy fee - Gebühr kopieren - - - Copy after fee - Abzüglich Gebühr kopieren - - - Copy bytes - Byte kopieren - - - Copy priority - Priorität kopieren - - - Copy dust - "Dust" kopieren - - - Copy change - Wechselgeld kopieren - - - highest - am höchsten - - - higher - höher - - - high - hoch - - - medium-high - mittel-hoch - - - medium - mittel - - - low-medium - niedrig-mittel - - - low - niedrig - - - lower - niedriger - - - lowest - am niedrigsten - - - (%1 locked) - (%1 gesperrt) - - - none - keine - - - This label turns red if the transaction size is greater than 1000 bytes. - Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist. - - - This label turns red if the priority is smaller than "medium". - Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist. - - - This label turns red if any recipient receives an amount smaller than %1. - Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als %1 erhält. - - - Can vary +/- %1 satoshi(s) per input. - Kann pro Eingabe um +/- %1 Satoshi(s) abweichen. - - - yes - ja - - - no - nein - - - This means a fee of at least %1 per kB is required. - Das bedeutet, dass eine Gebühr von mindestens %1 pro kB erforderlich ist. - - - Can vary +/- 1 byte per input. - Kann um +/- 1 Byte pro Eingabe variieren. - - - Transactions with higher priority are more likely to get included into a block. - Transaktionen mit höherer Priorität haben eine größere Chance in einen Block aufgenommen zu werden. - - - (no label) - (keine Bezeichnung) - - - change from %1 (%2) - Wechselgeld von %1 (%2) - - - (change) - (Wechselgeld) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adresse - - New receiving address - Neue Empfangsadresse - - - New sending address - Neue Zahlungsadresse - - - Edit receiving address - Empfangsadresse bearbeiten - - - Edit sending address - Zahlungsadresse bearbeiten - - - The entered address "%1" is already in the address book. - Die eingegebene Adresse "%1" befindet sich bereits im Adressbuch. - - - The entered address "%1" is not a valid Bitcoin address. - Die eingegebene Adresse "%1" ist keine gültige Bitcoin-Adresse. - - - Could not unlock wallet. - Wallet konnte nicht entsperrt werden. - - - New key generation failed. - Erzeugung eines neuen Schlüssels fehlgeschlagen. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version Version @@ -867,8 +521,8 @@ (%1-Bit) - About Bitcoin Core - Über Bitcoin Core + About %1 + Über %1 Command-line options @@ -892,7 +546,7 @@ Set language, for example "de_DE" (default: system locale) - Sprache einstellen, zum Beispiel "de_DE" (Standard: Systemgebietsschema) + Sprache einstellen, zum Beispiel "de_DE" (default: system locale) Start minimized @@ -907,7 +561,7 @@ Startbildschirm beim Starten anzeigen (Standard: %u) - Reset all settings changes made over the GUI + Reset all settings changed in the GUI Setze alle Einstellungen zurück, die über die grafische Oberfläche geändert wurden. @@ -918,16 +572,16 @@ Willkommen - Welcome to Bitcoin Core. - Willkommen zu Bitcoin Core. + Welcome to %1. + Willkommen zu %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Da Sie das Programm gerade zum ersten Mal starten, können Sie nun auswählen wo Bitcoin Core seine Daten ablegen soll. + As this is the first time the program is launched, you can choose where %1 will store its data. + Da Sie das Programm gerade zum ersten Mal starten, können Sie nun auswählen wo %1 seine Daten ablegen wird. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core wird eine Kopie der Blockkette herunterladen und speichern. Mindestens %1GB Daten werden in diesem Verzeichnis abgelegt und die Datenmenge wächst über die Zeit an. Auch die Wallet wird in diesem Verzeichnis abgelegt. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 wird eine Kopie der Blockkette herunterladen und speichern. Mindestens %2GB Daten werden in diesem Verzeichnis abgelegt und die Datenmenge wächst über die Zeit an. Auch die Wallet wird in diesem Verzeichnis abgelegt. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Ein benutzerdefiniertes Datenverzeichnis verwenden: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Fehler: Angegebenes Datenverzeichnis "%1" kann nicht angelegt werden. @@ -976,10 +626,6 @@ Select payment request file Zahlungsanforderungsdatei auswählen - - Select payment request file to open - Zu öffnende Zahlungsanforderungsdatei auswählen - OptionsDialog @@ -991,6 +637,14 @@ &Main &Allgemein + + Automatically start %1 after logging in to the system. + %1 nach der Anmeldung am System automatisch ausführen. + + + &Start %1 on system login + &Starte %1 nach Systemanmeldung + Size of &database cache Größe des &Datenbankcaches @@ -1019,10 +673,6 @@ 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. Minimiert die Anwendung anstatt sie zu beenden wenn das Fenster geschlossen wird. Wenn dies aktiviert ist, müssen Sie die Anwendung über "Beenden" im Menü schließen. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Legt die Sprache der Benutzeroberfläche fest. Diese Einstellung wird erst nach einem Neustart von Bitcoin Core aktiv. - 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 |. Externe URLs (z.B. ein Block-Explorer), die im Kontextmenü des Transaktionsverlaufs eingefügt werden. In der URL wird %s durch den Transaktionshash ersetzt. Bei Angabe mehrerer URLs müssen diese durch "|" voneinander getrennt werden. @@ -1047,14 +697,6 @@ &Network &Netzwerk - - Automatically start Bitcoin Core after logging in to the system. - Bitcoin Core nach der Anmeldung am System automatisch starten. - - - &Start Bitcoin Core on system login - &Bitcoin Core nach Systemanmeldung starten - (0 = auto, <0 = leave that many cores free) (0 = automatisch, <0 = so viele Kerne frei lassen) @@ -1283,97 +925,6 @@ Aktueller Gesamtbetrag in beobachteten Adressen aus obigen Kategorien - - PaymentServer - - URI handling - URI-Verarbeitung - - - Invalid payment address %1 - Ungültige Zahlungsadresse %1 - - - Payment request rejected - Zahlungsanforderung abgelehnt - - - Payment request network doesn't match client network. - Netzwerk der Zahlungsanforderung stimmt nicht mit dem Client-Netzwerk überein. - - - Payment request is not initialized. - Zahlungsanforderung ist nicht initialisiert. - - - Requested payment amount of %1 is too small (considered dust). - Angeforderter Zahlungsbetrag in Höhe von %1 ist zu niedrig und wurde als "Dust" eingestuft. - - - Payment request error - fehlerhafte Zahlungsanforderung - - - Cannot start bitcoin: click-to-pay handler - "bitcoin: Klicken-zum-Bezahlen"-Handler konnte nicht gestartet werden - - - Payment request fetch URL is invalid: %1 - Abruf-URL der Zahlungsanforderung ist ungültig: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kann nicht analysiert werden! Dies kann durch eine ungültige Bitcoin-Adresse oder fehlerhafte URI-Parameter verursacht werden. - - - Payment request file handling - Zahlungsanforderungsdatei-Verarbeitung - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Zahlungsanforderungsdatei kann nicht gelesen werden! Dies kann durch eine ungültige Zahlungsanforderungsdatei verursacht werden. - - - Payment request expired. - Zahlungsanforderung abgelaufen. - - - Unverified payment requests to custom payment scripts are unsupported. - Unverifizierte Zahlungsanforderungen an benutzerdefinierte Zahlungsskripte werden nicht unterstützt. - - - Invalid payment request. - Ungültige Zahlungsanforderung. - - - Refund from %1 - Rücküberweisung von %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte). - - - Error communicating with %1: %2 - Kommunikationsfehler mit %1: %2 - - - Payment request cannot be parsed! - Zahlungsanforderung kann nicht verarbeitet werden! - - - Bad response from server %1 - Fehlerhafte Antwort vom Server: %1 - - - Payment acknowledged - Zahlung bestätigt - - - Network request error - fehlerhafte Netzwerkanfrage - - PeerTableModel @@ -1428,25 +979,6 @@ %1 ms - - QRImageWidget - - &Save Image... - Grafik &speichern... - - - &Copy Image - Grafik &kopieren - - - Save QR Code - QR-Code speichern - - - PNG Image (*.png) - PNG-Grafik (*.png) - - RPCConsole @@ -1513,10 +1045,6 @@ Memory usage Speichernutzung - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern. - Received Empfangen @@ -1565,6 +1093,14 @@ User Agent User-Agent + + Decrease font size + Schrift verkleinern + + + Increase font size + Schrift vergrößern + Services Dienste @@ -1633,10 +1169,6 @@ Out: ausgehend: - - Build date - Erstellungsdatum - Debug log file Debugprotokolldatei @@ -1674,8 +1206,8 @@ &Node entsperren - Welcome to the Bitcoin Core RPC console. - Willkommen in der "Bitcoin Core"-RPC-Konsole. + Welcome to the %1 RPC console. + Willkommen in der %1 RPC Konsole. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1336,6 @@ Remove Entfernen - - Copy label - Bezeichnung kopieren - - - Copy message - Nachricht kopieren - - - Copy amount - Betrag kopieren - ReceiveRequestDialog @@ -1835,73 +1355,6 @@ &Save Image... Grafik &speichern... - - Request payment to %1 - Zahlung anfordern an %1 - - - Payment information - Zahlungsinformationen - - - URI - URI - - - Address - Adresse - - - Amount - Betrag - - - Label - Bezeichnung - - - Message - Nachricht - - - Resulting URI too long, try to reduce the text for label / message. - Resultierende URI ist zu lang, bitte den Text für Bezeichnung/Nachricht kürzen. - - - Error encoding URI into QR Code. - Beim Enkodieren der URI in den QR-Code ist ein Fehler aufgetreten. - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Bezeichnung - - - Message - Nachricht - - - Amount - Betrag - - - (no label) - (keine Bezeichnung) - - - (no message) - (keine Nachricht) - - - (no amount) - (kein Betrag) - SendCoinsDialog @@ -2021,14 +1474,6 @@ fast schnell - - Send as zero-fee transaction if possible - Wenn möglich als gebührenfreie Transaktion senden - - - (confirmation may take longer) - (Bestätigung kann länger dauern) - Send to multiple recipients at once An mehrere Empfänger auf einmal überweisen @@ -2061,118 +1506,6 @@ S&end &Überweisen - - Confirm send coins - Überweisung bestätigen - - - %1 to %2 - %1 an %2 - - - Copy quantity - Anzahl kopieren - - - Copy amount - Betrag kopieren - - - Copy fee - Gebühr kopieren - - - Copy after fee - Abzüglich Gebühr kopieren - - - Copy bytes - Byte kopieren - - - Copy priority - Priorität kopieren - - - Copy change - Wechselgeld kopieren - - - Total Amount %1 - Gesamtbetrag %1 - - - or - oder - - - The amount to pay must be larger than 0. - Der zu zahlende Betrag muss größer als 0 sein. - - - The amount exceeds your balance. - Der angegebene Betrag übersteigt Ihren Kontostand. - - - The total exceeds your balance when the %1 transaction fee is included. - Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand. - - - Transaction creation failed! - Transaktionserstellung fehlgeschlagen! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist. - - - A fee higher than %1 is considered an absurdly high fee. - Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen. - - - Payment request expired. - Zahlungsanforderung abgelaufen. - - - Pay only the required fee of %1 - Nur die notwendige Gebühr in Höhe von %1 zahlen - - - Estimated to begin confirmation within %n block(s). - Voraussichtlicher Beginn der Bestätigung innerhalb von %n Block.Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken. - - - The recipient address is not valid. Please recheck. - Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen. - - - Duplicate address found: addresses should only be used once each. - Doppelte Adresse entdeckt: Adressen dürfen jeweils nur einmal vorkommen. - - - Warning: Invalid Bitcoin address - Warnung: Ungültige Bitcoin-Adresse - - - (no label) - (keine Bezeichnung) - - - Warning: Unknown change address - Warnung: Unbekannte Wechselgeld-Adresse - - - Copy dust - "Dust" kopieren - - - Are you sure you want to send? - Wollen Sie die Überweisung ausführen? - - - added as transaction fee - als Transaktionsgebühr hinzugefügt - SendCoinsEntry @@ -2184,10 +1517,6 @@ Pay &To: E&mpfänger: - - Enter a label for this address to add it to your address book - Adressbezeichnung eingeben (diese wird zusammen mit der Adresse dem Adressbuch hinzugefügt) - &Label: &Bezeichnung: @@ -2260,8 +1589,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core wird beendet... + %1 is shutting down... + %1 wird beendet... Do not shut down the computer until this window disappears. @@ -2354,69 +1683,9 @@ Reset all verify message fields Alle "Nachricht verifizieren"-Felder zurücksetzen - - Click "Sign Message" to generate signature - Auf "Nachricht signieren" klicken, um die Signatur zu erzeugen - - - The entered address is invalid. - Die eingegebene Adresse ist ungültig. - - - Please check the address and try again. - Bitte überprüfen Sie die Adresse und versuchen Sie es erneut. - - - The entered address does not refer to a key. - Die eingegebene Adresse verweist nicht auf einen Schlüssel. - - - Wallet unlock was cancelled. - Wallet-Entsperrung wurde abgebrochen. - - - Private key for the entered address is not available. - Privater Schlüssel zur eingegebenen Adresse ist nicht verfügbar. - - - Message signing failed. - Signierung der Nachricht fehlgeschlagen. - - - Message signed. - Nachricht signiert. - - - The signature could not be decoded. - Die Signatur konnte nicht dekodiert werden. - - - Please check the signature and try again. - Bitte überprüfen Sie die Signatur und versuchen Sie es erneut. - - - The signature did not match the message digest. - Die Signatur entspricht nicht dem "Message Digest". - - - Message verification failed. - Verifikation der Nachricht fehlgeschlagen. - - - Message verified. - Nachricht verifiziert. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Die "Bitcoin Core"-Entwickler - [testnet] [Testnetz] @@ -2429,422 +1698,13 @@ KB/s - - TransactionDesc - - Open until %1 - Offen bis %1 - - - conflicted - in Konflikt stehend - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/unbestätigt - - - %1 confirmations - %1 Bestätigungen - - - Status - Status - - - , broadcast through %n node(s) - , über %n Knoten übertragen, über %n Knoten übertragen - - - Date - Datum - - - Source - Quelle - - - Generated - Erzeugt - - - From - Von - - - To - An - - - own address - eigene Adresse - - - watch-only - beobachtet - - - label - Bezeichnung - - - Credit - Gutschrift - - - matures in %n more block(s) - reift noch %n weiteren Blockreift noch %n weitere Blöcke - - - not accepted - nicht angenommen - - - Debit - Belastung - - - Total debit - Gesamtbelastung - - - Total credit - Gesamtgutschrift - - - Transaction fee - Transaktionsgebühr - - - Net amount - Nettobetrag - - - Message - Nachricht - - - Comment - Kommentar - - - Transaction ID - Transaktions-ID - - - Merchant - Händler - - - 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. - Erzeugte Bitcoins müssen %1 Blöcke lang reifen, bevor sie ausgegeben werden können. Als Sie diesen Block erzeugten, wurde er an das Netzwerk übertragen, um ihn der Blockkette hinzuzufügen. Falls dies fehlschlägt wird der Status in "nicht angenommen" geändert und Sie werden keine Bitcoins gutgeschrieben bekommen. Das kann gelegentlich passieren, wenn ein anderer Knoten einen Block fast zeitgleich erzeugt. - - - Debug information - Debuginformationen - - - Transaction - Transaktion - - - Inputs - Eingaben - - - Amount - Betrag - - - true - wahr - - - false - falsch - - - , has not been successfully broadcast yet - , wurde noch nicht erfolgreich übertragen - - - Open for %n more block(s) - Offen für %n weiteren BlockOffen für %n weitere Blöcke - - - unknown - unbekannt - - TransactionDescDialog - - Transaction details - Transaktionsdetails - This pane shows a detailed description of the transaction Dieser Bereich zeigt eine detaillierte Beschreibung der Transaktion an - - TransactionTableModel - - Date - Datum - - - Type - Typ - - - Immature (%1 confirmations, will be available after %2) - Unreif (%1 Bestätigungen, wird verfügbar sein nach %2) - - - Open for %n more block(s) - Offen für %n weiteren BlockOffen für %n weitere Blöcke - - - Open until %1 - Offen bis %1 - - - Confirmed (%1 confirmations) - Bestätigt (%1 Bestätigungen) - - - This block was not received by any other nodes and will probably not be accepted! - Dieser Block wurde von keinem anderen Knoten empfangen und wird wahrscheinlich nicht angenommen werden! - - - Generated but not accepted - Erzeugt, jedoch nicht angenommen - - - Offline - Offline - - - Label - Bezeichnung - - - Unconfirmed - Unbestätigt - - - Confirming (%1 of %2 recommended confirmations) - Wird bestätigt (%1 von %2 empfohlenen Bestätigungen) - - - Conflicted - in Konflikt stehend - - - Received with - Empfangen über - - - Received from - Empfangen von - - - Sent to - Überwiesen an - - - Payment to yourself - Eigenüberweisung - - - Mined - Erarbeitet - - - watch-only - beobachtet - - - (n/a) - (k.A.) - - - Transaction status. Hover over this field to show number of confirmations. - Transaktionsstatus, fahren Sie mit der Maus über dieses Feld, um die Anzahl der Bestätigungen zu sehen. - - - Date and time that the transaction was received. - Datum und Uhrzeit zu der die Transaktion empfangen wurde. - - - Type of transaction. - Art der Transaktion - - - Whether or not a watch-only address is involved in this transaction. - Zeigt an, ob eine beobachtete Adresse in diese Transaktion involviert ist. - - - User-defined intent/purpose of the transaction. - Benutzerdefinierte Absicht bzw. Verwendungszweck der Transaktion - - - Amount removed from or added to balance. - Der Betrag, der dem Kontostand abgezogen oder hinzugefügt wurde. - - - - TransactionView - - All - Alle - - - Today - Heute - - - This week - Diese Woche - - - This month - Diesen Monat - - - Last month - Letzten Monat - - - This year - Dieses Jahr - - - Range... - Zeitraum - - - Received with - Empfangen über - - - Sent to - Überwiesen an - - - To yourself - Eigenüberweisung - - - Mined - Erarbeitet - - - Other - Andere - - - Enter address or label to search - Zu suchende Adresse oder Bezeichnung eingeben - - - Min amount - Minimaler Betrag - - - Copy address - Adresse kopieren - - - Copy label - Bezeichnung kopieren - - - Copy amount - Betrag kopieren - - - Copy transaction ID - Transaktions-ID kopieren - - - Copy raw transaction - Kopiere rohe Transaktion - - - Edit label - Bezeichnung bearbeiten - - - Show transaction details - Transaktionsdetails anzeigen - - - Export Transaction History - Transaktionsverlauf exportieren - - - Watch-only - Beobachtet - - - Exporting Failed - Exportieren fehlgeschlagen - - - There was an error trying to save the transaction history to %1. - Beim Speichern des Transaktionsverlaufs nach %1 ist ein Fehler aufgetreten. - - - Exporting Successful - Exportieren erfolgreich - - - The transaction history was successfully saved to %1. - Speichern des Transaktionsverlaufs nach %1 war erfolgreich. - - - Comma separated file (*.csv) - Kommagetrennte-Datei (*.csv) - - - Confirmed - Bestätigt - - - Date - Datum - - - Type - Typ - - - Label - Bezeichnung - - - Address - Adresse - - - ID - ID - - - Range: - Zeitraum: - - - to - bis - - UnitDisplayStatusBarControl @@ -2852,55 +1712,6 @@ Die Einheit in der Beträge angezeigt werden. Klicken, um eine andere Einheit auszuwählen. - - WalletFrame - - No wallet has been loaded. - Es wurde keine Wallet geladen. - - - - WalletModel - - Send Coins - Bitcoins überweisen - - - - WalletView - - &Export - E&xportieren - - - Export the data in the current tab to a file - Daten der aktuellen Ansicht in eine Datei exportieren - - - Backup Wallet - Wallet sichern - - - Wallet Data (*.dat) - Wallet-Daten (*.dat) - - - Backup Failed - Sicherung fehlgeschlagen - - - There was an error trying to save the wallet data to %1. - Beim Speichern der Wallet-Daten nach %1 ist ein Fehler aufgetreten. - - - The wallet data was successfully saved to %1. - Speichern der Wallet-Daten nach %1 war erfolgreich. - - - Backup Successful - Sicherung erfolgreich - - bitcoin-core @@ -2927,14 +1738,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Wenn <category> nicht angegeben wird oder <category>=1, jegliche Debugginginformationen ausgeben. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird. - Prune configured below the minimum of %d MiB. Please use a higher number. Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert. @@ -2967,6 +1770,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee ist sehr hoch eingestellt! Das ist die Transaktionsgebühr, welche du zahlen müsstest, wenn die Gebührenschätzungen nicht verfügbar sind. @@ -3007,14 +1814,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen! - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Das Argument -whitelistalwaysrelay wird nicht unterstützt und deswegen ignoriert. Benutze -whitelistrelay und/oder -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist) @@ -3031,18 +1830,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Warnung: Unbekannte Blockversion wird durch Mining erzeugt! Es ist möglich, dass unbekannte Regeln in Kraft sind. - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Warnung: Wir scheinen nicht vollständig mit unseren Gegenstellen übereinzustimmen! Sie oder die anderen Knoten müssen unter Umständen Ihre Client-Software aktualisieren. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Warnung: wallet.dat beschädigt, Datenrettung erfolgreich! Original wallet.dat wurde als wallet.{Zeitstempel}.dat in %s gespeichert. Falls Ihr Kontostand oder Transaktionen nicht korrekt sind, sollten Sie von einer Datensicherung wiederherstellen. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden. @@ -3063,6 +1854,10 @@ Block creation options: Blockerzeugungsoptionen: + + Cannot resolve -%s address: '%s' + Kann Adresse in -%s nicht auflösen: '%s' + Connect only to the specified node(s) Mit nur dem oder den angegebenen Knoten verbinden @@ -3071,6 +1866,10 @@ Connection options: Verbindungsoptionen: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Beschädigte Blockdatenbank erkannt @@ -3111,6 +1910,10 @@ Error initializing wallet database environment %s! Fehler beim Initialisieren der Wallet-Datenbankumgebung %s! + + Error loading %s + Fehler beim Laden von %s + Error loading block database Fehler beim Laden der Blockdatenbank @@ -3139,6 +1942,10 @@ Invalid -onion address: '%s' Ungültige "-onion"-Adresse: '%s' + + Invalid amount for -%s=<amount>: '%s' + Ungültiger Betrag für -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Ungültiger Betrag für -fallbackfee=<amount>: '%s' @@ -3147,6 +1954,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Halten Sie den Transaktionsspeicherpool unter <n> Megabytes (Voreinstellung: %u) + + Loading banlist... + Lade Sperrliste... + Location of the auth cookie (default: data dir) Dateiort für das Auth-Cookie (Standard: Datenverzeichnis) @@ -3183,6 +1994,14 @@ Specify wallet file (within data directory) Wallet-Datei angeben (innerhalb des Datenverzeichnisses) + + The source code is available from %s. + Der Quellcode ist von %s verfügbar. + + + Unable to bind to %s on this computer. %s is probably already running. + Kann auf diesem Computer nicht an %s binden. Evtl. wurde %s bereits gestartet. + Unsupported argument -benchmark ignored, use -debug=bench. Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden. @@ -3219,10 +2038,6 @@ Wallet options: Wallet-Optionen: - - You need to rebuild the database using -reindex to change -txindex - Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um -txindex zu verändern - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times JSON-RPC-Verbindungen von der angegeben Quelle erlauben. Gültig für <ip> ist eine einzelne IP-Adresse (z.B. 1.2.3.4), ein Netzwerk bzw. eine Netzmaske (z.B. 1.2.3.4/255.255.255.0), oder die CIDR-Notation (z.B. 1.2.3.4/24). Kann mehrmals angegeben werden. @@ -3235,10 +2050,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) An die angegebene Adresse binden und nach eingehenden JSON-RPC-Verbindungen abhören. Für IPv6 "[Host]:Port"-Notation verwenden. Kann mehrmals angegeben werden. (Standard: an alle Schnittstellen binden) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Datenverzeichnis %s kann nicht gesperrt werden, da Bitcoin Core wahrscheinlich bereits gestartet wurde. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Neue Dateien mit Standard-Systemrechten erzeugen, anstatt mit umask 077 (nur mit deaktivierter Walletfunktion nutzbar) @@ -3283,10 +2094,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Maximale Anzahl an Threads zur Bitcoinerzeugung, wenn aktiviert, festlegen (-1 = alle Kerne, Standard: %d) - The transaction amount is too small to send after the fee has been deducted Der Transaktionsbetrag ist zum senden zu niedrig, nachdem die Gebühr abgezogen wurde. @@ -3311,34 +2118,14 @@ Accept public REST requests (default: %u) Öffentliche REST-Anfragen annehmen (Standard: %u) - - Activating best chain... - Aktiviere beste Blockkette... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Versuchen, private Schlüssel beim Starten aus einer beschädigten wallet.dat wiederherzustellen - Automatically create Tor hidden service (default: %d) Automatisch versteckten Tor-Dienst erstellen (Standard: %d) - - Cannot resolve -whitebind address: '%s' - Kann Adresse in -whitebind nicht auflösen: '%s' - Connect through SOCKS5 proxy Über einen SOCKS5-Proxy &verbinden - - Copyright (C) 2009-%i The Bitcoin Core Developers - Urheberrecht (C) 2009-%i Die "Bitcoin Core"-Entwickler - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Fehler beim Laden von wallet.dat: Wallet benötigt neuere Version von Bitcoin Core - Error reading from database, shutting down. Fehler beim lesen der Datenbank, Ausführung wird beendet. @@ -3351,22 +2138,6 @@ Information Hinweis - - Initialization sanity check failed. Bitcoin Core is shutting down. - Initialisierungsplausibilitätsprüfung fehlgeschlagen. Bitcoin Core wird beendet. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Ungültiger Betrag für -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Ungültiger Betrag für -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Ungültiger Betrag für -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Ungültiger Betrag für -paytxfee=<amount>: '%s' (muss mindestens %s sein) @@ -3391,14 +2162,6 @@ RPC server options: RPC-Serveroptionen: - - Rebuild block chain index from current blk000??.dat files on startup - Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen - - - Receive and display P2P network alerts (default: %u) - P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reduziere -maxconnections von %d zu %d, aufgrund von Systemlimitierungen. @@ -3471,10 +2234,6 @@ Username for JSON-RPC connections Benutzername für JSON-RPC-Verbindungen - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Wallet musste neu geschrieben werden: starten Sie Bitcoin Core zur Fertigstellung neu - Warning Warnung @@ -3495,10 +2254,6 @@ ZeroMQ notification options: ZeroMQ-Benachrichtigungsoptionen: - - wallet.dat corrupt, salvage failed - wallet.dat beschädigt, Datenrettung fehlgeschlagen - Password for JSON-RPC connections Passwort für JSON-RPC-Verbindungen @@ -3507,10 +2262,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Befehl ausführen wenn der beste Block wechselt (%s im Befehl wird durch den Hash des Blocks ersetzt) - - This help message - Dieser Hilfetext - Allow DNS lookups for -addnode, -seednode and -connect Erlaube DNS-Abfragen für -addnode, -seednode und -connect @@ -3519,10 +2270,6 @@ Loading addresses... Lade Adressen... - - Error loading wallet.dat: Wallet corrupted - Fehler beim Laden von wallet.dat: Wallet beschädigt - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen) @@ -3539,10 +2286,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Die Transaktion nicht länger im Speicherpool behalten als <n> Stunden (Standard: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Niedrigere Gebühren (in %s/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s) @@ -3575,6 +2318,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Das Argument -whitelistalwaysrelay wird nicht unterstützt und deswegen ignoriert. Benutze -whitelistrelay und/oder -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s) @@ -3583,6 +2330,10 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Benutzername und gehashtes Passwort für JSON-RPC Verbindungen. Das Feld <userpw> kommt im Format: <USERNAME>:<SALT>$<HASH>. Ein kanonisches Pythonskript ist in share/rpcuser inbegriffen. Diese Option kann mehrere Male spezifiziert werden + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Warnung: Unbekannte Blockversion wird durch Mining erzeugt! Es ist möglich, dass unbekannte Regeln in Kraft sind. + (default: %s) (Standard: %s) @@ -3591,14 +2342,6 @@ Always query for peer addresses via DNS lookup (default: %u) Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u) - - Error loading wallet.dat - Fehler beim Laden von wallet.dat - - - Generate coins (default: %u) - Bitcoins erzeugen (Standard: %u) - How many blocks to check at startup (default: %u, 0 = all) Wieviele Blöcke beim Starten geprüft werden sollen (Standard: %u, 0 = alle) @@ -3683,18 +2426,6 @@ Unknown network specified in -onlynet: '%s' Unbekannter Netztyp in -onlynet angegeben: '%s' - - Cannot resolve -bind address: '%s' - Kann Adresse in -bind nicht auflösen: '%s' - - - Cannot resolve -externalip address: '%s' - Kann Adresse in -externalip nicht auflösen: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Ungültiger Betrag für -paytxfee=<amount>: '%s' - Insufficient funds Unzureichender Kontostand diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts index 6777961cb..de76a110c 100644 --- a/src/qt/locale/bitcoin_el.ts +++ b/src/qt/locale/bitcoin_el.ts @@ -6,17 +6,6 @@ Δημιουργία νέου λογαριασμού - - AddressTableModel - - Label - Ετικέτα - - - Address - Διεύθυνση - - AskPassphraseDialog @@ -31,11 +20,7 @@ Repeat new passphrase Επαναλάβετε νέο συνθηματικό - - Change passphrase - Αλλαγή συνθηματικού - - + BanTableModel @@ -54,31 +39,12 @@ Σφάλμα - - ClientModel - CoinControlDialog Date Ημερομηνία - - Copy address - Αντιγραφή διεύθυνσης - - - Copy amount - Αντιγραφή ποσού - - - Copy quantity - Αντιγραφή ποσότητας - - - Copy change - Αντιγραφή αλλαγής - EditAddressDialog @@ -90,7 +56,7 @@ &Address Διεύθυνση - + FreespaceChecker @@ -125,18 +91,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -150,48 +110,9 @@ Remove Αφαίρεση - - Copy message - Αντιγραφή μηνύματος - - - Copy amount - Αντιγραφή ποσού - ReceiveRequestDialog - - Address - Διεύθυνση - - - Label - Ετικέτα - - - Message - Μήνυμα - - - - RecentRequestsTableModel - - Date - Ημερομηνία - - - Label - Ετικέτα - - - Message - Μήνυμα - - - (no message) - (κανένα μήνυμα) - SendCoinsDialog @@ -203,18 +124,6 @@ Recommended: Συνίσταται: - - Copy quantity - Αντιγραφή ποσότητας - - - Copy amount - Αντιγραφή ποσού - - - Copy change - Αντιγραφή αλλαγής - SendCoinsEntry @@ -235,66 +144,12 @@ TrafficGraphWidget - - TransactionDesc - - Date - Ημερομηνία - - - Message - Μήνυμα - - TransactionDescDialog - - TransactionTableModel - - Date - Ημερομηνία - - - Label - Ετικέτα - - - - TransactionView - - Copy address - Αντιγραφή διεύθυνσης - - - Copy amount - Αντιγραφή ποσού - - - Date - Ημερομηνία - - - Label - Ετικέτα - - - Address - Διεύθυνση - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - bitcoin-core diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index b5fb22f97..59779692d 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -25,10 +25,6 @@ C&lose Κ&λείσιμο - - &Copy Address - &Αντιγραφή διεύθυνσης - Delete the currently selected address from the list Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος @@ -45,73 +41,6 @@ &Delete &Διαγραφή - - Choose the address to send coins to - Επιλογή διεύθυνσης όπου θα σταλθούν νομίσματα - - - Choose the address to receive coins with - Επιλογή διεύθυνσης απ' όπου θα ληφθούν νομίσματα - - - C&hoose - Ε&πιλογή - - - Sending addresses - Διευθύνσεις αποστολής - - - Receiving addresses - Διευθύνσεις λήψης - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει. - - - Copy &Label - Αντιγραφή &επιγραφής - - - &Edit - &Επεξεργασία - - - Export Address List - Εξαγωγή της λίστας διευθύνσεων - - - Comma separated file (*.csv) - Αρχείο οριοθετημένο με κόμματα (*.csv) - - - Exporting Failed - Η Εξαγωγή Απέτυχε - - - There was an error trying to save the address list to %1. Please try again. - Παρουσιάστηκε σφάλμα κατά την αποθήκευση της λίστας πορτοφολιών στο %1. Παρακαλώ δοκιμάστε ξανά - - - - AddressTableModel - - Label - Επιγραφή - - - Address - Διεύθυνση - - - (no label) - (χωρίς ετικέτα) - AskPassphraseDialog @@ -131,96 +60,6 @@ Repeat new passphrase Επανέλαβε τον νέο κωδικό πρόσβασης - - Encrypt wallet - &Κρυπτογράφηση πορτοφολιού - - - This operation needs your wallet passphrase to unlock the wallet. - Αυτη η ενεργεία χρειάζεται τον κωδικό του πορτοφολιού για να ξεκλειδώσει το πορτοφόλι. - - - Unlock wallet - Ξεκλειδωσε το πορτοφολι - - - This operation needs your wallet passphrase to decrypt the wallet. - Αυτη η ενεργεια χρειάζεται τον κωδικο του πορτοφολιου για να αποκρυπτογραφησειι το πορτοφολι. - - - Decrypt wallet - Αποκρυπτογράφησε το πορτοφολι - - - Change passphrase - Άλλαξε κωδικο πρόσβασης - - - Confirm wallet encryption - Επιβεβαίωσε την κρυπτογραφηση του πορτοφολιού - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Προσοχη: Εαν κρυπτογραφησεις το πορτοφολι σου και χάσεις τον κωδικο σου θα χάσεις <b> ΟΛΑ ΣΟΥ ΤΑ BITCOINS</b>! -Είσαι σίγουρος ότι θέλεις να κρυπτογραφησεις το πορτοφολι; - - - Are you sure you wish to encrypt your wallet? - Είστε σίγουροι ότι θέλετε να κρυπτογραφήσετε το πορτοφόλι σας; - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Το Bitcoin Core θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογράφησης. Θυμήσου ότι κρυπτογραφώντας το πορτοφόλι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση που μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικό. - - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ΣΗΜΑΝΤΙΚΟ: Τα προηγούμενα αντίγραφα ασφαλείας που έχετε κάνει από το αρχείο του πορτοφόλιου σας θα πρέπει να αντικατασταθουν με το νέο που δημιουργείται, κρυπτογραφημένο αρχείο πορτοφόλιου. Για λόγους ασφαλείας, τα προηγούμενα αντίγραφα ασφαλείας του μη κρυπτογραφημένου αρχείου πορτοφόλιου θα καταστουν άχρηστα μόλις αρχίσετε να χρησιμοποιείτε το νέο κρυπτογραφημένο πορτοφόλι. - - - Warning: The Caps Lock key is on! - Προσοχη: το πλήκτρο Caps Lock είναι ενεργο. - - - Wallet encrypted - Κρυπτογραφημενο πορτοφολι - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι <br/> Παρακαλώ χρησιμοποιείστε ένα κωδικό με <b> 10 ή περισσότερους τυχαίους χαρακτήρες</b> ή <b> οχτώ ή παραπάνω λέξεις</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Πληκτρολόγησε τον παλιό και τον νέο κωδικό στο πορτοφολι. - - - Wallet encryption failed - Η κρυπτογραφηση του πορτοφολιού απέτυχε - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Η κρυπτογράφηση του πορτοφολιού απέτυχε λογω εσωτερικού σφάλματος. Το πορτοφολι δεν κρυπτογραφηθηκε. - - - The supplied passphrases do not match. - Οι εισαχθέντες κωδικοί δεν ταιριάζουν. - - - Wallet unlock failed - το ξεκλείδωμα του πορτοφολιού απέτυχε - - - The passphrase entered for the wallet decryption was incorrect. - Ο κωδικος που εισήχθη για την αποκρυπτογραφηση του πορτοφολιού ήταν λαθος. - - - Wallet decryption failed - Η αποκρυπτογραφηση του πορτοφολιού απέτυχε - - - Wallet passphrase was successfully changed. - Ο κωδικος του πορτοφολιού άλλαξε με επιτυχία. - BanTableModel @@ -263,6 +102,10 @@ Quit application Εξοδος από την εφαρμογή + + &About %1 + &Περί %1 + About &Qt Σχετικά με &Qt @@ -299,14 +142,6 @@ Open &URI... 'Ανοιγμα &URI - - Bitcoin Core client - Εφαρμογή Bitcoin Core - - - Importing blocks from disk... - Εισαγωγή μπλοκ από τον σκληρο δίσκο ... - Reindexing blocks on disk... Φόρτωση ευρετηρίου μπλοκ στον σκληρο δισκο... @@ -351,10 +186,6 @@ &Receive &Παραλαβή - - Show information about Bitcoin Core - Σχετικά με το Bitcoin Core - &Show / Hide &Εμφάνισε/Κρύψε @@ -391,18 +222,10 @@ Tabs toolbar Εργαλειοθήκη καρτελών - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Αίτηση πληρωμών (δημιουργεί QR codes και διευθύνσεις bitcoin: ) - - &About Bitcoin Core - &Σχετικά με το Bitcoin Core - Show the list of used sending addresses and labels Προβολή της λίστας των χρησιμοποιημένων διευθύνσεων και ετικετών αποστολής @@ -419,10 +242,6 @@ &Command-line options &Επιλογές γραμμής εντολών - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Εμφανιση του Bitcoin-Qt μήνυματος βοήθειας για να πάρετε μια λίστα με τις πιθανές επιλογές Bitcoin γραμμής εντολών. - No block source available... Η πηγή του μπλοκ δεν ειναι διαθέσιμη... @@ -510,13 +329,6 @@ Το πορτοφόλι είναι <b>κρυπτογραφημένο</b> και <b>κλειδωμένο</b> - - ClientModel - - Network Alert - Ειδοποίηση Δικτύου - - CoinControlDialog @@ -595,151 +407,6 @@ Priority Προτεραιότητα - - Copy address - Αντιγραφή διεύθυνσης - - - Copy label - Αντιγραφή επιγραφής - - - Copy amount - Αντιγραφή ποσού - - - Copy transaction ID - Αντιγραφη του ID Συναλλαγής - - - Lock unspent - Κλείδωμα αξόδευτων - - - Unlock unspent - Ξεκλείδωμα αξόδευτων - - - Copy quantity - Αντιγραφή ποσότητας - - - Copy fee - Αντιγραφή ταρίφας - - - Copy after fee - Αντιγραφή μετα-ταρίφας - - - Copy bytes - Αντιγραφή των byte - - - Copy priority - Αντιγραφή προτεραιότητας - - - Copy dust - Αντιγραφή 'σκόνης' - - - Copy change - Αντιγραφή των ρέστων - - - highest - ύψιστη - - - higher - υψηλότερη - - - high - ψηλή - - - medium-high - μεσαία-ψηλή - - - medium - μεσαία - - - low-medium - μεσαία-χαμηλή - - - low - χαμηλή - - - lower - χαμηλότερη - - - lowest - χαμηλότατη - - - (%1 locked) - (%1 κλειδωμένο) - - - none - κανένα - - - This label turns red if the transaction size is greater than 1000 bytes. - Αυτή η ετικέτα γίνεται κόκκινη αν το μέγεθος της συναλλαγής είναι μεγαλύτερο από 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Αυτή η ετικέτα γίνεται κόκκινη αν η προτεραιότητα είναι μικρότερη από "μεσαία". - - - This label turns red if any recipient receives an amount smaller than %1. - Αυτή η ετικέτα γίνεται κόκκινη αν οποιοσδήποτε παραλήπτης λάβει ποσό μικρότερο από %1. - - - Can vary +/- %1 satoshi(s) per input. - Μπορεί να διαφέρει +/- %1 Satoshi (ες) ανά εγγραφή. - - - yes - ναι - - - no - όχι - - - This means a fee of at least %1 per kB is required. - Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB - - - Can vary +/- 1 byte per input. - Μπορεί να διαφέρει +/- 1 byte ανά εγγραφή. - - - Transactions with higher priority are more likely to get included into a block. - Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ. - - - (no label) - (χωρίς ετικέτα) - - - change from %1 (%2) - ρέστα από %1 (%2) - - - (change) - (ρέστα) - - EditAddressDialog @@ -763,38 +430,6 @@ &Address &Διεύθυνση - - New receiving address - Νέα διεύθυνση λήψης - - - New sending address - Νέα διεύθυνση αποστολής - - - Edit receiving address - Επεξεργασία διεύθυνσης λήψης - - - Edit sending address - Επεξεργασία διεύθυνσης αποστολής - - - The entered address "%1" is already in the address book. - Η διεύθυνση "%1" βρίσκεται ήδη στο βιβλίο διευθύνσεων. - - - The entered address "%1" is not a valid Bitcoin address. - Η διεύθυνση "%1" δεν είναι έγκυρη Bitcoin διεύθυνση. - - - Could not unlock wallet. - Δεν είναι δυνατό το ξεκλείδωμα του πορτοφολιού. - - - New key generation failed. - Η δημιουργία νέου κλειδιού απέτυχε. - FreespaceChecker @@ -821,10 +456,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version έκδοση @@ -833,10 +464,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Σχετικά με το Bitcoin Core - Command-line options επιλογής γραμμής εντολών @@ -856,18 +483,6 @@ Welcome Καλώς ήρθατε - - Welcome to Bitcoin Core. - Καλώς ήρθατε στο Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Καθώς αυτή είναι η πρώτη φορά που εκκινείται το πρόγραμμα, μπορείτε να διαλέξετε πού θα αποθηκεύει το Bitcoin Core τα δεδομένα του. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - O πυρήνας Bitcoin θα κατεβάσει και να αποθηκεύσει ένα αντίγραφο της αλυσίδας μπλοκ Bitcoin. Τουλάχιστον %1GB δεδομένων θα αποθηκευτούν σε αυτόν τον κατάλογο, και θα αυξηθεί με την πάροδο του χρόνου. Το πορτοφόλι θα αποθηκευτεί σε αυτόν τον κατάλογο. - Use the default data directory Χρήση του προεπιλεγμένου φακέλου δεδομένων @@ -876,10 +491,6 @@ Use a custom data directory: Προσαρμογή του φακέλου δεδομένων: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Σφάλμα: Ο καθορισμένος φάκελος δεδομένων "%1" δεν μπορεί να δημιουργηθεί. @@ -915,10 +526,6 @@ Select payment request file Επιλέξτε πληρωμή αρχείου αίτησης - - Select payment request file to open - Επιλέξτε αρχείο πληρωμής για άνοιγμα. - OptionsDialog @@ -1179,69 +786,6 @@ Το τρέχον συνολικό υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο - - PaymentServer - - URI handling - Χειρισμός URI - - - Invalid payment address %1 - Μη έγκυρη διεύθυνση πληρωμής %1 - - - Payment request rejected - Η αίτηση πληρωμής έχει αρνηθεί. - - - Payment request is not initialized. - Η αίτηση πληρωμής δεν έχει αρχίζει ακόμα. - - - Requested payment amount of %1 is too small (considered dust). - Το ζητούμενο ποσό πληρωμής του %1 είναι πολύ μικρό (θεωρείται σκόνη) - - - Payment request error - Σφάλμα αιτήματος πληρωμής - - - Cannot start bitcoin: click-to-pay handler - Δεν είναι δυνατή η εκκίνηση του Bitcoin: click-to-pay handler - - - Payment request fetch URL is invalid: %1 - Η διεύθυνση πληρωμής (URL) δεν είναι έγκυρη: %1 - - - Payment request file handling - Επιλέξτε αρχείο πληρωμής για άνοιγμα. - - - Refund from %1 - Επιστροφή ποσού από %1 - - - Error communicating with %1: %2 - Σφάλμα επικοινωνίας με %1: %2 - - - Payment request cannot be parsed! - Η αίτηση πληρωμής δεν μπορεί να αναλυθεί! - - - Bad response from server %1 - Κακή απάντηση από διακομιστή %1 - - - Payment acknowledged - Πληρωμή αναγνωρίστηκε - - - Network request error - Σφάλμα αιτήματος δικτύου - - PeerTableModel @@ -1288,25 +832,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Αποθήκευση εικόνας... - - - &Copy Image - &Αντιγραφή εικόνας - - - Save QR Code - Αποθήκευση κώδικα QR - - - PNG Image (*.png) - Εικόνες PNG (*.png) - - RPCConsole @@ -1437,10 +962,6 @@ Out: Εξερχόμενα: - - Build date - Ημερομηνία κατασκευής - Debug log file Αρχείο καταγραφής εντοπισμού σφαλμάτων @@ -1536,18 +1057,6 @@ Remove Αφαίρεση - - Copy label - Αντιγραφή επιγραφής - - - Copy message - Αντιγραφή μηνύματος - - - Copy amount - Αντιγραφή ποσού - ReceiveRequestDialog @@ -1567,73 +1076,6 @@ &Save Image... &Αποθήκευση εικόνας... - - Request payment to %1 - Αίτηση πληρωμής για %1 - - - Payment information - Πληροφορίες πληρωμής - - - URI - URI: - - - Address - Διεύθυνση - - - Amount - Ποσό - - - Label - Επιγραφή - - - Message - Μήνυμα - - - Resulting URI too long, try to reduce the text for label / message. - Το αποτέλεσμα της διεύθυνσης είναι πολύ μεγάλο. Μειώστε το μέγεθος για το κείμενο της ετικέτας/ μηνύματος. - - - Error encoding URI into QR Code. - Σφάλμα κατά την κωδικοποίηση του URI σε κώδικα QR - - - - RecentRequestsTableModel - - Date - Ημερομηνία - - - Label - Επιγραφή - - - Message - Μήνυμα - - - Amount - Ποσό - - - (no label) - (χωρίς ετικέτα) - - - (no message) - (κανένα μήνυμα) - - - (no amount) - (κανένα ποσό) - SendCoinsDialog @@ -1733,10 +1175,6 @@ fast Γρήγορο - - (confirmation may take longer) - (η επικύρωση ίσως χρειαστεί περισσότερο χρόνο) - Send to multiple recipients at once Αποστολή σε πολλούς αποδέκτες ταυτόχρονα @@ -1769,82 +1207,6 @@ S&end Αποστολη - - Confirm send coins - Επιβεβαίωση αποστολής νομισμάτων - - - %1 to %2 - %1 σε %2 - - - Copy quantity - Αντιγραφή ποσότητας - - - Copy amount - Αντιγραφή ποσού - - - Copy fee - Αντιγραφή ταρίφας - - - Copy after fee - Αντιγραφή μετα-ταρίφας - - - Copy bytes - Αντιγραφή των byte - - - Copy priority - Αντιγραφή προτεραιότητας - - - Copy change - Αντιγραφή των ρέστων - - - or - ή - - - The amount to pay must be larger than 0. - Το ποσό πληρωμής πρέπει να είναι μεγαλύτερο από 0. - - - The amount exceeds your balance. - Το ποσό ξεπερνάει το διαθέσιμο υπόλοιπο - - - The total exceeds your balance when the %1 transaction fee is included. - Το σύνολο υπερβαίνει το υπόλοιπό σας όταν συμπεριληφθεί και η αμοιβή %1 - - - Transaction creation failed! - Η δημιουργία της συναλλαγής απέτυχε! - - - Warning: Invalid Bitcoin address - Προειδοποίηση: Μη έγκυρη διεύθυνση Bitcoin - - - (no label) - (χωρίς ετικέτα) - - - Copy dust - Αντιγραφή 'σκόνης' - - - Are you sure you want to send? - Είστε βέβαιοι για την αποστολή; - - - added as transaction fee - προστέθηκαν ως αμοιβή συναλλαγής - SendCoinsEntry @@ -1856,10 +1218,6 @@ Pay &To: Πληρωμή &σε: - - Enter a label for this address to add it to your address book - Εισάγετε μια επιγραφή για αυτή τη διεύθυνση ώστε να καταχωρηθεί στο βιβλίο διευθύνσεων - &Label: &Επιγραφή @@ -1911,10 +1269,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Το Bitcoin Core τερματίζεται... - Do not shut down the computer until this window disappears. Μην απενεργοποιήσετε τον υπολογιστή μέχρι να κλείσει αυτό το παράθυρο. @@ -1998,69 +1352,9 @@ Reset all verify message fields Επαναφορά όλων επαλήθευμενων πεδίων μήνυματος - - Click "Sign Message" to generate signature - Κάντε κλικ στο "Υπογραφή Μηνύματος" για να λάβετε την υπογραφή - - - The entered address is invalid. - Η διεύθυνση που εισήχθη είναι λάθος. - - - Please check the address and try again. - Παρακαλούμε ελέγξτε την διεύθυνση και δοκιμάστε ξανά. - - - The entered address does not refer to a key. - Η διεύθυνση που έχει εισαχθεί δεν αναφέρεται σε ένα πλήκτρο. - - - Wallet unlock was cancelled. - το ξεκλείδωμα του πορτοφολιού απέτυχε - - - Private key for the entered address is not available. - Το προσωπικό κλειδί εισαγμενης διευθυνσης δεν είναι διαθέσιμο. - - - Message signing failed. - Η υπογραφή του μηνύματος απέτυχε. - - - Message signed. - Μήνυμα υπεγράφη. - - - The signature could not be decoded. - Η υπογραφή δεν μπόρεσε να αποκρυπτογραφηθεί. - - - Please check the signature and try again. - Παρακαλούμε ελέγξτε την υπογραφή και δοκιμάστε ξανά. - - - The signature did not match the message digest. - Η υπογραφή δεν ταιριάζει με το μήνυμα. - - - Message verification failed. - Η επιβεβαίωση του μηνύματος απέτυχε - - - Message verified. - Μήνυμα επιβεβαιώθηκε. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Οι προγραμματιστές του Bitcoin Core - [testnet] [testnet] @@ -2073,386 +1367,13 @@ KB/s - - TransactionDesc - - Open until %1 - Ανοιχτό μέχρι %1 - - - conflicted - σύγκρουση - - - %1/offline - %1/χωρίς σύνδεση; - - - %1/unconfirmed - %1/χωρίς επιβεβαίωση - - - %1 confirmations - %1 επιβεβαιώσεις - - - Status - Κατάσταση - - - Date - Ημερομηνία - - - Source - Πηγή - - - Generated - Δημιουργία - - - From - Από - - - To - Προς - - - own address - δική σας διεύθυνση - - - watch-only - Επίβλεψη μόνο: - - - label - eπιγραφή - - - Credit - Πίστωση - - - not accepted - μη αποδεκτό - - - Debit - Debit - - - Total debit - Σύνολο χρέωσης - - - Total credit - Συνολική πίστωση - - - Transaction fee - Τέλος συναλλαγής - - - Net amount - Καθαρό ποσό - - - Message - Μήνυμα - - - Comment - Σχόλιο: - - - Transaction ID - ID Συναλλαγής: - - - Merchant - Έμπορος - - - 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. - Πρέπει να περιμένετε %1 μπλοκ πριν μπορέσετε να χρησιμοποιήσετε τα νομίσματα που έχετε δημιουργήσει. Το μπλοκ που δημιουργήσατε μεταδόθηκε στο δίκτυο για να συμπεριληφθεί στην αλυσίδα των μπλοκ. Αν δεν μπει σε αυτή θα μετατραπεί σε "μη αποδεκτό" και δε θα μπορεί να καταναλωθεί. Αυτό συμβαίνει σπάνια όταν κάποιος άλλος κόμβος δημιουργήσει ένα μπλοκ λίγα δευτερόλεπτα πριν από εσάς. - - - Debug information - Πληροφορίες αποσφαλμάτωσης - - - Transaction - Συναλλαγή - - - Inputs - εισροές - - - Amount - Ποσό - - - true - αληθής - - - false - αναληθής - - - , has not been successfully broadcast yet - , δεν έχει ακόμα μεταδοθεί μ' επιτυχία - - - unknown - άγνωστο - - TransactionDescDialog - - Transaction details - Λεπτομέρειες συναλλαγής - This pane shows a detailed description of the transaction Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής - - TransactionTableModel - - Date - Ημερομηνία - - - Type - Τύπος - - - Open until %1 - Ανοιχτό μέχρι %1 - - - Confirmed (%1 confirmations) - Επικυρωμένη (%1 επικυρώσεις) - - - This block was not received by any other nodes and will probably not be accepted! - Αυτό το μπλοκ δεν έχει παραληφθεί από κανέναν άλλο κόμβο και κατά πάσα πιθανότητα θα απορριφθεί! - - - Generated but not accepted - Δημιουργήθηκε αλλά απορρίφθηκε - - - Offline - Offline - - - Label - Επιγραφή - - - Unconfirmed - Ανεπιβεβαίωτες - - - Conflicted - Σύγκρουση - - - Received with - Ελήφθη με - - - Received from - Ελήφθη από - - - Sent to - Απεστάλη προς - - - Payment to yourself - Πληρωμή προς εσάς - - - Mined - Εξόρυξη - - - watch-only - Επίβλεψη μόνο: - - - (n/a) - (δ/α) - - - Transaction status. Hover over this field to show number of confirmations. - Κατάσταση συναλλαγής. Πηγαίνετε το ποντίκι πάνω από αυτό το πεδίο για να δείτε τον αριθμό των επικυρώσεων - - - Date and time that the transaction was received. - Ημερομηνία κι ώρα λήψης της συναλλαγής. - - - Type of transaction. - Είδος συναλλαγής. - - - Amount removed from or added to balance. - Ποσό που αφαιρέθηκε ή προστέθηκε στο υπόλοιπο. - - - - TransactionView - - All - Όλα - - - Today - Σήμερα - - - This week - Αυτή την εβδομάδα - - - This month - Αυτόν τον μήνα - - - Last month - Τον προηγούμενο μήνα - - - This year - Αυτό το έτος - - - Range... - Έκταση... - - - Received with - Ελήφθη με - - - Sent to - Απεστάλη προς - - - To yourself - Προς εσάς - - - Mined - Εξόρυξη - - - Other - Άλλο - - - Enter address or label to search - Αναζήτηση με βάση τη διεύθυνση ή την επιγραφή - - - Min amount - Ελάχιστο ποσό - - - Copy address - Αντιγραφή διεύθυνσης - - - Copy label - Αντιγραφή επιγραφής - - - Copy amount - Αντιγραφή ποσού - - - Copy transaction ID - Αντιγραφη του ID Συναλλαγής - - - Edit label - Επεξεργασία επιγραφής - - - Show transaction details - Εμφάνιση λεπτομερειών συναλλαγής - - - Export Transaction History - Εξαγωγή Ιστορικού Συναλλαγών - - - Watch-only - Επίβλεψη μόνο: - - - Exporting Failed - Η Εξαγωγή Απέτυχε - - - There was an error trying to save the transaction history to %1. - Yπήρξε σφάλμα κατά την προσπάθεια αποθήκευσης του ιστορικού συναλλαγών στο %1. - - - Exporting Successful - Επιτυχής εξαγωγή - - - The transaction history was successfully saved to %1. - Το ιστορικό συναλλαγών αποθηκεύτηκε επιτυχώς στο %1. - - - Comma separated file (*.csv) - Αρχείο οριοθετημένο με κόμματα (*.csv) - - - Confirmed - Επικυρωμένες - - - Date - Ημερομηνία - - - Type - Τύπος - - - Label - Επιγραφή - - - Address - Διεύθυνση - - - ID - ID - - - Range: - Έκταση: - - - to - έως - - UnitDisplayStatusBarControl @@ -2460,55 +1381,6 @@ Μονάδα μέτρησης προβολής ποσών. Κάντε κλικ για επιλογή άλλης μονάδας. - - WalletFrame - - No wallet has been loaded. - Δεν έχει φορτωθεί πορτοφόλι - - - - WalletModel - - Send Coins - Αποστολή νομισμάτων - - - - WalletView - - &Export - &Εξαγωγή - - - Export the data in the current tab to a file - Εξαγωγή δεδομένων καρτέλας σε αρχείο - - - Backup Wallet - Αντίγραφο ασφαλείας του πορτοφολιού - - - Wallet Data (*.dat) - Αρχεία δεδομένων πορτοφολιού (*.dat) - - - Backup Failed - Αποτυχία κατά τη δημιουργία αντιγράφου - - - There was an error trying to save the wallet data to %1. - Παρουσιάστηκε σφάλμα κατά την αποθήκευση των δεδομένων πορτοφολιού στο %1. - - - The wallet data was successfully saved to %1. - Τα δεδομένα πορτοφολιού αποθηκεύτηκαν με επιτυχία στο %1. - - - Backup Successful - Η δημιουργια αντιγραφου ασφαλειας πετυχε - - bitcoin-core @@ -2539,6 +1411,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Αποθηκευση σε συγκεκριμένη διεύθυνση. Χρησιμοποιήστε τα πλήκτρα [Host] : συμβολισμός θύρα για IPv6 @@ -2551,10 +1427,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Αυτό είναι ένα προ-τεστ κυκλοφορίας - χρησιμοποιήστε το με δική σας ευθύνη - δεν χρησιμοποιείτε για εξόρυξη ή για αλλες εφαρμογές - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Προειδοποίηση : το αρχειο wallet.dat ειναι διεφθαρμένο, τα δεδομένα σώζονται ! Original wallet.dat αποθηκεύονται ως wallet.{timestamp}.bak στο %s . Αν το υπόλοιπο του ή τις συναλλαγές σας, είναι λάθος θα πρέπει να επαναφέρετε από ένα αντίγραφο ασφαλείας - Block creation options: Αποκλεισμός επιλογων δημιουργίας: @@ -2639,22 +1511,10 @@ Wallet options: Επιλογές πορτοφολιού: - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό. - Connect through SOCKS5 proxy Σύνδεση μέσω διαμεσολαβητή SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Πνευματικά δικαιώματα 2009-%i Οι προγραμματιστές του Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin - Error reading from database, shutting down. Σφάλμα ανάγνωσης από τη βάση δεδομένων, γίνεται τερματισμός. @@ -2663,22 +1523,6 @@ Information Πληροφορία - - Initialization sanity check failed. Bitcoin Core is shutting down. - Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Μη έγκυρο ποσό για την παράμετρο -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s' - Node relay options: Επιλογές αναμετάδοσης κόμβου: @@ -2731,10 +1575,6 @@ Zapping all transactions from wallet... Μεταφορά όλων των συναλλαγών απο το πορτοφόλι - - wallet.dat corrupt, salvage failed - Το αρχειο wallet.dat ειναι διεφθαρμένο, η διάσωση απέτυχε - Password for JSON-RPC connections Κωδικός για τις συνδέσεις JSON-RPC @@ -2743,10 +1583,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ) - - This help message - Αυτό το κείμενο βοήθειας - Allow DNS lookups for -addnode, -seednode and -connect Να επιτρέπονται οι έλεγχοι DNS για προσθήκη και σύνδεση κόμβων @@ -2755,10 +1591,6 @@ Loading addresses... Φόρτωση διευθύνσεων... - - Error loading wallet.dat: Wallet corrupted - Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι - How thorough the block verification of -checkblocks is (0-4, default: %u) Πόσο εξονυχιστική να είναι η επιβεβαίωση του μπλοκ (0-4, προεπιλογή: %u) @@ -2771,14 +1603,6 @@ Number of seconds to keep misbehaving peers from reconnecting (default: %u) Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: %u) - - Error loading wallet.dat - Σφάλμα φόρτωσης αρχείου wallet.dat - - - Generate coins (default: %u) - Δημιουργία νομισμάτων (προκαθορισμος: %u) - How many blocks to check at startup (default: %u, 0 = all) Πόσα μπλοκ να ελέγχθουν κατά την εκκίνηση (προεπιλογή: %u, 0 = όλα) @@ -2815,18 +1639,6 @@ Unknown network specified in -onlynet: '%s' Άγνωστo δίκτυο ορίζεται σε onlynet: '%s' - - Cannot resolve -bind address: '%s' - Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση: '%s' - - - Cannot resolve -externalip address: '%s' - Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s' - Insufficient funds Ανεπαρκές κεφάλαιο diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 4e4c9f45e..9723ffa39 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1239,7 +1239,7 @@ - + %1 s @@ -2224,7 +2224,7 @@ UnitDisplayStatusBarControl - + Unit to show amounts in. Click to select another unit. @@ -2232,32 +2232,32 @@ bitcoin-core - + Options: Options: - + Specify data directory Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -2282,7 +2282,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -2297,22 +2297,22 @@ - + Run in the background as a daemon and accept commands Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -2412,7 +2412,12 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -2687,12 +2692,22 @@ - + + Rewinding blocks... + + + + Set database cache size in megabytes (%d to %d, default: %d) + Set maximum block cost (default: %d) + + + + Set maximum block size in bytes (default: %d) @@ -2767,7 +2782,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -2847,7 +2862,7 @@ - + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start @@ -2937,7 +2952,7 @@ - + Send trace/debug info to console instead of debug.log file Send trace/debug info to console instead of debug.log file @@ -2947,7 +2962,7 @@ - + Show all debugging options (usage: --help -help-debug) @@ -3042,17 +3057,17 @@ - + Password for JSON-RPC connections Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect @@ -3062,7 +3077,7 @@ Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3122,7 +3137,7 @@ - + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. @@ -3222,12 +3237,12 @@ - + Set key pool size to <n> (default: %u) - + Set minimum block size in bytes (default: %u) @@ -3267,7 +3282,7 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index b9c0c8281..89653e7aa 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -25,10 +25,6 @@ C&lose C&lose - - &Copy Address - &Copy Address - Delete the currently selected address from the list Delete the currently selected address from the list @@ -45,73 +41,6 @@ &Delete &Delete - - Choose the address to send coins to - Choose the address to send coins to - - - Choose the address to receive coins with - Choose the address to receive coins with - - - C&hoose - C&hoose - - - Sending addresses - Sending addresses - - - Receiving addresses - Receiving addresses - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - - - Copy &Label - Copy &Label - - - &Edit - &Edit - - - Export Address List - Export Address List - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Exporting Failed - Exporting Failed - - - There was an error trying to save the address list to %1. Please try again. - There was an error trying to save the address list to %1. Please try again. - - - - AddressTableModel - - Label - Label - - - Address - Address - - - (no label) - (no label) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repeat new passphrase - - Encrypt wallet - Encrypt wallet - - - This operation needs your wallet passphrase to unlock the wallet. - This operation needs your wallet passphrase to unlock the wallet. - - - Unlock wallet - Unlock wallet - - - This operation needs your wallet passphrase to decrypt the wallet. - This operation needs your wallet passphrase to decrypt the wallet. - - - Decrypt wallet - Decrypt wallet - - - Change passphrase - Change passphrase - - - Confirm wallet encryption - Confirm wallet encryption - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Are you sure you wish to encrypt your wallet? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - - - Warning: The Caps Lock key is on! - Warning: The Caps Lock key is on! - - - Wallet encrypted - Wallet encrypted - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Enter the old passphrase and new passphrase to the wallet. - - - Wallet encryption failed - Wallet encryption failed - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - - - The supplied passphrases do not match. - The supplied passphrases do not match. - - - Wallet unlock failed - Wallet unlock failed - - - The passphrase entered for the wallet decryption was incorrect. - The passphrase entered for the wallet decryption was incorrect. - - - Wallet decryption failed - Wallet decryption failed - - - Wallet passphrase was successfully changed. - Wallet passphrase was successfully changed. - BanTableModel @@ -269,6 +110,14 @@ Quit application Quit application + + &About %1 + &About %1 + + + Show information about %1 + Show information about %1 + About &Qt About &Qt @@ -281,6 +130,10 @@ &Options... &Options... + + Modify configuration options for %1 + Modify configuration options for %1 + &Encrypt Wallet... &Encrypt Wallet... @@ -305,14 +158,6 @@ Open &URI... Open &URI... - - Bitcoin Core client - Bitcoin Core client - - - Importing blocks from disk... - Importing blocks from disk... - Reindexing blocks on disk... Reindexing blocks on disk... @@ -357,10 +202,6 @@ &Receive &Receive - - Show information about Bitcoin Core - Show information about Bitcoin Core - &Show / Hide &Show / Hide @@ -397,22 +238,10 @@ Tabs toolbar Tabs toolbar - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Request payments (generates QR codes and bitcoin: URIs) - - &About Bitcoin Core - &About Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modify configuration options for Bitcoin Core - Show the list of used sending addresses and labels Show the list of used sending addresses and labels @@ -429,14 +258,18 @@ &Command-line options &Command-line options - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - %n active connection(s) to Bitcoin network %n active connection to Bitcoin network%n active connections to Bitcoin network + + Indexing blocks on disk... + Indexing blocks on disk... + + + Processing blocks on disk... + Processing blocks on disk... + No block source available... No block source available... @@ -493,6 +326,14 @@ Up to date Up to date + + Show the %1 help message to get a list with possible Bitcoin command-line options + Show the %1 help message to get a list with possible Bitcoin command-line options + + + %1 client + %1 client + Catching up... Catching up... @@ -544,13 +385,6 @@ Wallet is <b>encrypted</b> and currently <b>locked</b> - - ClientModel - - Network Alert - Network Alert - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Priority - - Copy address - Copy address - - - Copy label - Copy label - - - Copy amount - Copy amount - - - Copy transaction ID - Copy transaction ID - - - Lock unspent - Lock unspent - - - Unlock unspent - Unlock unspent - - - Copy quantity - Copy quantity - - - Copy fee - Copy fee - - - Copy after fee - Copy after fee - - - Copy bytes - Copy bytes - - - Copy priority - Copy priority - - - Copy dust - Copy dust - - - Copy change - Copy change - - - highest - highest - - - higher - higher - - - high - high - - - medium-high - medium-high - - - medium - medium - - - low-medium - low-medium - - - low - low - - - lower - lower - - - lowest - lowest - - - (%1 locked) - (%1 locked) - - - none - none - - - This label turns red if the transaction size is greater than 1000 bytes. - This label turns red if the transaction size is greater than 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - This label turns red if the priority is smaller than "medium". - - - This label turns red if any recipient receives an amount smaller than %1. - This label turns red if any recipient receives an amount smaller than %1. - - - Can vary +/- %1 satoshi(s) per input. - Can vary +/- %1 satoshi(s) per input. - - - yes - yes - - - no - no - - - This means a fee of at least %1 per kB is required. - This means a fee of at least %1 per kB is required. - - - Can vary +/- 1 byte per input. - Can vary +/- 1 byte per input. - - - Transactions with higher priority are more likely to get included into a block. - Transactions with higher priority are more likely to get included into a block. - - - (no label) - (no label) - - - change from %1 (%2) - change from %1 (%2) - - - (change) - (change) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Address - - New receiving address - New receiving address - - - New sending address - New sending address - - - Edit receiving address - Edit receiving address - - - Edit sending address - Edit sending address - - - The entered address "%1" is already in the address book. - The entered address "%1" is already in the address book. - - - The entered address "%1" is not a valid Bitcoin address. - The entered address "%1" is not a valid Bitcoin address. - - - Could not unlock wallet. - Could not unlock wallet. - - - New key generation failed. - New key generation failed. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - About Bitcoin Core + About %1 + About %1 Command-line options @@ -907,8 +561,8 @@ Show splash screen on startup (default: %u) - Reset all settings changes made over the GUI - Reset all setting changes made via the GUI + Reset all settings changed in the GUI + Reset all settings changed in the GUI @@ -918,16 +572,16 @@ Welcome - Welcome to Bitcoin Core. - Welcome to Bitcoin Core. + Welcome to %1. + Welcome to %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + As this is the first time the program is launched, you can choose where %1 will store its data. + As this is the first time the program is launched, you can choose where %1 will store its data. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Use a custom data directory: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Error: Specified data directory "%1" cannot be created. @@ -976,10 +626,6 @@ Select payment request file Select payment request file - - Select payment request file to open - Select payment request file to open - OptionsDialog @@ -991,6 +637,14 @@ &Main &Main + + Automatically start %1 after logging in to the system. + Automatically start %1 after logging in to the system. + + + &Start %1 on system login + &Start %1 on system login + Size of &database cache Size of &database cache @@ -1019,10 +673,6 @@ 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. Minimise 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. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - 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 |. 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 |. @@ -1047,14 +697,6 @@ &Network &Network - - Automatically start Bitcoin Core after logging in to the system. - Automatically start Bitcoin Core after logging in to the system. - - - &Start Bitcoin Core on system login - &Start Bitcoin Core on system login - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = leave that many cores free) @@ -1139,6 +781,14 @@ &Window &Window + + &Hide the icon from the system tray. + &Hide the icon from the system tray. + + + Hide tray icon + Hide tray icon + Show only a tray icon after minimizing the window. Show on a tray icon after minimising the window. @@ -1159,6 +809,10 @@ User Interface &language: User Interface &language: + + The user interface language can be set here. This setting will take effect after restarting %1. + The user interface language can be set here. This setting will take effect after restarting %1. + &Unit to show amounts in: &Unit to show amounts in: @@ -1283,97 +937,6 @@ Current total balance in watch-only addresses - - PaymentServer - - URI handling - URI handling - - - Invalid payment address %1 - Invalid payment address %1 - - - Payment request rejected - Payment request rejected - - - Payment request network doesn't match client network. - Payment request network doesn't match client network. - - - Payment request is not initialized. - Payment request is not initialised. - - - Requested payment amount of %1 is too small (considered dust). - Requested payment amount of %1 is too small (considered dust). - - - Payment request error - Payment request error - - - Cannot start bitcoin: click-to-pay handler - Cannot start bitcoin: click-to-pay handler - - - Payment request fetch URL is invalid: %1 - Payment request fetch URL is invalid: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - - - Payment request file handling - Payment request file handling - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Payment request file cannot be read! This can be caused by an invalid payment request file. - - - Payment request expired. - Payment request expired. - - - Unverified payment requests to custom payment scripts are unsupported. - Unverified payment requests to custom payment scripts are unsupported. - - - Invalid payment request. - Invalid payment request. - - - Refund from %1 - Refund from %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - - - Error communicating with %1: %2 - Error communicating with %1: %2 - - - Payment request cannot be parsed! - Payment request cannot be parsed! - - - Bad response from server %1 - Bad response from server %1 - - - Payment acknowledged - Payment acknowledged - - - Network request error - Network request error - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Save Image... - - - &Copy Image - &Copy Image - - - Save QR Code - Save QR Code - - - PNG Image (*.png) - PNG Image (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Using BerkeleyDB version + + Datadir + Datadir + Startup time Startup time @@ -1513,10 +1061,6 @@ Memory usage Memory usage - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Received Received @@ -1565,6 +1109,18 @@ User Agent User Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + + + Decrease font size + Decrease font size + + + Increase font size + Increase font size + Services Services @@ -1633,10 +1189,6 @@ Out: Out: - - Build date - Build date - Debug log file Debug log file @@ -1674,8 +1226,8 @@ &Unban Node - Welcome to the Bitcoin Core RPC console. - Welcome to the Bitcoin Core RPC console. + Welcome to the %1 RPC console. + Welcome to the %1 RPC console. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove Remove - - Copy label - Copy label - - - Copy message - Copy message - - - Copy amount - Copy amount - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... &Save Image... - - Request payment to %1 - Request payment to %1 - - - Payment information - Payment information - - - URI - URI - - - Address - Address - - - Amount - Amount - - - Label - Label - - - Message - Message - - - Resulting URI too long, try to reduce the text for label / message. - Resulting URI too long, try to reduce the text for label / message. - - - Error encoding URI into QR Code. - Error encoding URI into QR Code. - - - - RecentRequestsTableModel - - Date - Date - - - Label - Label - - - Message - Message - - - Amount - Amount - - - (no label) - (no label) - - - (no message) - (no message) - - - (no amount) - (no amount) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast fast - - Send as zero-fee transaction if possible - Send as zero-fee transaction if possible - - - (confirmation may take longer) - (confirmation may take longer) - Send to multiple recipients at once Send to multiple recipients at once @@ -2061,118 +1526,6 @@ S&end S&end - - Confirm send coins - Confirm send coins - - - %1 to %2 - %1 to %2 - - - Copy quantity - Copy quantity - - - Copy amount - Copy amount - - - Copy fee - Copy fee - - - Copy after fee - Copy after fee - - - Copy bytes - Copy bytes - - - Copy priority - Copy priority - - - Copy change - Copy change - - - Total Amount %1 - Total Amount %1 - - - or - or - - - The amount to pay must be larger than 0. - The amount to pay must be larger than 0. - - - The amount exceeds your balance. - The amount exceeds your balance. - - - The total exceeds your balance when the %1 transaction fee is included. - The total exceeds your balance when the %1 transaction fee is included. - - - Transaction creation failed! - Transaction creation failed! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - - - A fee higher than %1 is considered an absurdly high fee. - A fee higher than %1 is considered an absurdly high fee. - - - Payment request expired. - Payment request expired. - - - Pay only the required fee of %1 - Pay only the required fee of %1 - - - Estimated to begin confirmation within %n block(s). - Estimated to begin confirmation within %n block.Estimated to begin confirmation within %n blocks. - - - The recipient address is not valid. Please recheck. - The recipient address is not valid. Please recheck. - - - Duplicate address found: addresses should only be used once each. - Duplicate address found: addresses should only be used once each. - - - Warning: Invalid Bitcoin address - Warning: Invalid Bitcoin address - - - (no label) - (no label) - - - Warning: Unknown change address - Warning: Unknown change address - - - Copy dust - Copy dust - - - Are you sure you want to send? - Are you sure you want to send? - - - added as transaction fee - added as transaction fee - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: Pay &To: - - Enter a label for this address to add it to your address book - Enter a label for this address to add it to your address book - &Label: &Label: @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core is shutting down... + %1 is shutting down... + %1 is shutting down... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields Reset all verify message fields - - Click "Sign Message" to generate signature - Click "Sign Message" to generate signature - - - The entered address is invalid. - The entered address is invalid. - - - Please check the address and try again. - Please check the address and try again. - - - The entered address does not refer to a key. - The entered address does not refer to a key. - - - Wallet unlock was cancelled. - Wallet unlock was cancelled. - - - Private key for the entered address is not available. - Private key for the entered address is not available. - - - Message signing failed. - Message signing failed. - - - Message signed. - Message signed. - - - The signature could not be decoded. - The signature could not be decoded. - - - Please check the signature and try again. - Please check the signature and try again. - - - The signature did not match the message digest. - The signature did not match the message digest. - - - Message verification failed. - Message verification failed. - - - Message verified. - Message verified. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - The Bitcoin Core developers - [testnet] [testnet] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - Open until %1 - - - conflicted - conflicted - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/unconfirmed - - - %1 confirmations - %1 confirmations - - - Status - Status - - - , broadcast through %n node(s) - , broadcast through %n node, broadcast through %n nodes - - - Date - Date - - - Source - Source - - - Generated - Generated - - - From - From - - - To - To - - - own address - own address - - - watch-only - watch-only - - - label - label - - - Credit - Credit - - - matures in %n more block(s) - matures in %n more blockmatures in %n more blocks - - - not accepted - not accepted - - - Debit - Debit - - - Total debit - Total debit - - - Total credit - Total credit - - - Transaction fee - Transaction fee - - - Net amount - Net amount - - - Message - Message - - - Comment - Comment - - - Transaction ID - Transaction ID - - - Merchant - Merchant - - - 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. - 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. - - - Debug information - Debug information - - - Transaction - Transaction - - - Inputs - Inputs - - - Amount - Amount - - - true - true - - - false - false - - - , has not been successfully broadcast yet - , has not been successfully broadcast yet - - - Open for %n more block(s) - Open for %n more blockOpen for %n more blocks - - - unknown - unknown - - TransactionDescDialog - - Transaction details - Transaction details - This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction - - TransactionTableModel - - Date - Date - - - Type - Type - - - Immature (%1 confirmations, will be available after %2) - Immature (%1 confirmations, will be available after %2) - - - Open for %n more block(s) - Open for %n more blockOpen for %n more blocks - - - Open until %1 - Open until %1 - - - Confirmed (%1 confirmations) - Confirmed (%1 confirmations) - - - This block was not received by any other nodes and will probably not be accepted! - This block was not received by any other nodes and will probably not be accepted! - - - Generated but not accepted - Generated but not accepted - - - Offline - Offline - - - Label - Label - - - Unconfirmed - Unconfirmed - - - Confirming (%1 of %2 recommended confirmations) - Confirming (%1 of %2 recommended confirmations) - - - Conflicted - Conflicted - - - Received with - Received with - - - Received from - Received from - - - Sent to - Sent to - - - Payment to yourself - Payment to yourself - - - Mined - Mined - - - watch-only - watch-only - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Transaction status. Hover over this field to show number of confirmations. - - - Date and time that the transaction was received. - Date and time that the transaction was received. - - - Type of transaction. - Type of transaction. - - - Whether or not a watch-only address is involved in this transaction. - Whether or not a watch-only address is involved in this transaction. - - - User-defined intent/purpose of the transaction. - User-defined intent/purpose of the transaction. - - - Amount removed from or added to balance. - Amount removed from or added to balance. - - - - TransactionView - - All - All - - - Today - Today - - - This week - This week - - - This month - This month - - - Last month - Last month - - - This year - This year - - - Range... - Range... - - - Received with - Received with - - - Sent to - Sent to - - - To yourself - To yourself - - - Mined - Mined - - - Other - Other - - - Enter address or label to search - Enter address or label to search - - - Min amount - Min amount - - - Copy address - Copy address - - - Copy label - Copy label - - - Copy amount - Copy amount - - - Copy transaction ID - Copy transaction ID - - - Copy raw transaction - Copy raw transaction - - - Edit label - Edit label - - - Show transaction details - Show transaction details - - - Export Transaction History - Export Transaction History - - - Watch-only - Watch-only - - - Exporting Failed - Exporting Failed - - - There was an error trying to save the transaction history to %1. - There was an error trying to save the transaction history to %1. - - - Exporting Successful - Exporting Successful - - - The transaction history was successfully saved to %1. - The transaction history was successfully saved to %1. - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Confirmed - Confirmed - - - Date - Date - - - Type - Type - - - Label - Label - - - Address - Address - - - ID - ID - - - Range: - Range: - - - to - to - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ Unit to show amounts in. Click to select another unit. - - WalletFrame - - No wallet has been loaded. - No wallet has been loaded. - - - - WalletModel - - Send Coins - Send Coins - - - - WalletView - - &Export - &Export - - - Export the data in the current tab to a file - Export the data in the current tab to a file - - - Backup Wallet - Backup Wallet - - - Wallet Data (*.dat) - Wallet Data (*.dat) - - - Backup Failed - Backup Failed - - - There was an error trying to save the wallet data to %1. - There was an error trying to save the wallet data to %1. - - - The wallet data was successfully saved to %1. - The wallet data was successfully saved to %1. - - - Backup Successful - Backup Successful - - bitcoin-core @@ -2927,14 +1758,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. If <category> is not supplied or if <category> = 1, output all debugging information. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Prune configured below the minimum of %d MiB. Please use a higher number. Prune configured below the minimum of %d MiB. Please use a higher number. @@ -2975,6 +1798,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) + + Bitcoin Core + Bitcoin Core + + + The %s developers + The %s developers + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. @@ -2991,6 +1822,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind to given address and always listen on it. Use [host]:port notation for IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Cannot obtain a lock on data directory %s. %s is probably already running. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup @@ -2999,6 +1834,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Error loading %s: You can't enable HD on a already existing non-HD wallet + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) @@ -3007,6 +1850,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Please contribute if you find %s useful. Visit %s for further information about the software. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -3019,14 +1878,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -3043,22 +1894,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + + You need to rebuild the database using -reindex-chainstate to change -txindex + You need to rebuild the database using -reindex-chainstate to change -txindex + + + %s corrupt, salvage failed + %s corrupt, salvage failed + -maxmempool must be at least %d MB -maxmempool must be at least %d MB @@ -3071,10 +1922,22 @@ Append comment to the user agent string Append comment to the user agent string + + Attempt to recover private keys from a corrupt wallet on startup + Attempt to recover private keys from a corrupt wallet on startup + Block creation options: Block creation options: + + Cannot resolve -%s address: '%s' + Cannot resolve -%s address: '%s' + + + Change index out of range + Change index out of range + Connect only to the specified node(s) Connect only to the specified node(s) @@ -3083,6 +1946,10 @@ Connection options: Connection options: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Corrupted block database detected @@ -3127,6 +1994,22 @@ Error initializing wallet database environment %s! Error initialising wallet database environment %s! + + Error loading %s + Error loading %s + + + Error loading %s: Wallet corrupted + Error loading %s: Wallet corrupted + + + Error loading %s: Wallet requires newer version of %s + Error loading %s: Wallet requires newer version of %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Error loading %s: You can't disable HD on a already existing HD wallet + Error loading block database Error loading block database @@ -3151,10 +2034,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Incorrect or no genesis block found. Wrong datadir for network? + + Initialization sanity check failed. %s is shutting down. + Initialisation sanity check failed. %s is shutting down. + Invalid -onion address: '%s' Invalid -onion address: '%s' + + Invalid amount for -%s=<amount>: '%s' + Invalid amount for -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Invalid amount for -fallbackfee=<amount>: '%s' @@ -3163,6 +2054,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Keep the transaction memory pool below <n> megabytes (default: %u) + + Loading banlist... + Loading banlist... + Location of the auth cookie (default: data dir) Location of the auth cookie (default: data dir) @@ -3179,6 +2074,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Only connect to nodes in network <net> (ipv4, ipv6 or onion) + + Print this help message and exit + Print this help message and exit + Print version and exit Print version and exit @@ -3191,6 +2090,14 @@ Prune mode is incompatible with -txindex. Prune mode is incompatible with -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Rebuild chain state and block index from the blk*.dat files on disk + + + Rebuild chain state from the currently indexed blocks + Rebuild chain state from the currently indexed blocks + Set database cache size in megabytes (%d to %d, default: %d) Set database cache size in megabytes (%d to %d, default: %d) @@ -3203,6 +2110,14 @@ Specify wallet file (within data directory) Specify wallet file (within data directory) + + The source code is available from %s. + The source code is available from %s. + + + Unable to bind to %s on this computer. %s is probably already running. + Unable to bind to %s on this computer. %s is probably already running. + Unsupported argument -benchmark ignored, use -debug=bench. Unsupported argument -benchmark ignored, use -debug=bench. @@ -3236,12 +2151,16 @@ Wallet %s resides outside data directory %s - Wallet options: - Wallet options: + Wallet debugging/testing options: + Wallet debugging/testing options: - You need to rebuild the database using -reindex to change -txindex - You need to rebuild the database using -reindex to change -txindex + Wallet needed to be rewritten: restart %s to complete + Wallet needed to be rewritten: restart %s to complete + + + Wallet options: + Wallet options: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3255,10 +2174,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) @@ -3303,10 +2218,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - The transaction amount is too small to send after the fee has been deducted The transaction amount is too small to send after the fee has been deducted @@ -3315,6 +2226,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -3331,34 +2246,14 @@ Accept public REST requests (default: %u) Accept public REST requests (default: %u) - - Activating best chain... - Activating best chain... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Attempt to recover private keys from a corrupt wallet.dat on startup - Automatically create Tor hidden service (default: %d) Automatically create Tor hidden service (default: %d) - - Cannot resolve -whitebind address: '%s' - Cannot resolve -whitebind address: '%s' - Connect through SOCKS5 proxy Connect through SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i The Bitcoin Core Developers - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error reading from database, shutting down. Error reading from database, shutting down. @@ -3371,22 +2266,6 @@ Information Information - - Initialization sanity check failed. Bitcoin Core is shutting down. - Initialisation sanity check failed. Bitcoin Core is shutting down. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Invalid amount for -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Invalid amount for -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Invalid amount for -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) @@ -3411,14 +2290,6 @@ RPC server options: RPC server options: - - Rebuild block chain index from current blk000??.dat files on startup - Rebuild block chain index from current blk000??.dat files on startup - - - Receive and display P2P network alerts (default: %u) - Receive and display P2P network alerts (default: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reducing -maxconnections from %d to %d, because of system limitations. @@ -3491,10 +2362,6 @@ Username for JSON-RPC connections Username for JSON-RPC connections - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Wallet needed to be rewritten: restart Bitcoin Core to complete - Warning Warning @@ -3515,10 +2382,6 @@ ZeroMQ notification options: ZeroMQ notification options: - - wallet.dat corrupt, salvage failed - wallet.dat corrupt, salvage failed - Password for JSON-RPC connections Password for JSON-RPC connections @@ -3527,10 +2390,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - - This help message - This help message - Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect @@ -3539,10 +2398,6 @@ Loading addresses... Loading addresses... - - Error loading wallet.dat: Wallet corrupted - Error loading wallet.dat: Wallet corrupted - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3559,10 +2414,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Do not keep transactions in the mempool longer than <n> hours (default: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) @@ -3599,6 +2450,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) @@ -3607,6 +2462,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + (default: %s) (default: %s) @@ -3615,14 +2478,6 @@ Always query for peer addresses via DNS lookup (default: %u) Always query for peer addresses via DNS lookup (default: %u) - - Error loading wallet.dat - Error loading wallet.dat - - - Generate coins (default: %u) - Generate coins (default: %u) - How many blocks to check at startup (default: %u, 0 = all) How many blocks to check at startup (default: %u, 0 = all) @@ -3707,18 +2562,6 @@ Unknown network specified in -onlynet: '%s' Unknown network specified in -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Cannot resolve -bind address: '%s' - - - Cannot resolve -externalip address: '%s' - Cannot resolve -externalip address: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' - Insufficient funds Insufficient funds diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 2095db34b..043b28abc 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -25,10 +25,6 @@ C&lose &Fermi - - &Copy Address - &Kopii Adreson - Delete the currently selected address from the list Forigi la elektitan adreson el la listo @@ -45,73 +41,6 @@ &Delete &Forigi - - Choose the address to send coins to - Elektu la alsendotan adreson - - - Choose the address to receive coins with - Elektu la ricevontan adreson - - - C&hoose - &Elekti - - - Sending addresses - Sendaj adresoj - - - Receiving addresses - Ricevaj adresoj - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Jen viaj Bitmon-adresoj por sendi pagojn. Zorge kontrolu la sumon kaj la alsendan adreson antaŭ ol sendi. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Jen viaj bitmonaj adresoj por ricevi pagojn. Estas konsilinde uzi apartan ricevan adreson por ĉiu transakcio. - - - Copy &Label - Kopii &Etikedon - - - &Edit - &Redakti - - - Export Address List - Eksporti Adresliston - - - Comma separated file (*.csv) - Perkome disigita dosiero (*.csv) - - - Exporting Failed - ekspotado malsukcesinta - - - There was an error trying to save the address list to %1. Please try again. - Okazis eraron dum konservo de adreslisto al %1. Bonvolu provi denove. - - - - AddressTableModel - - Label - Etikedo - - - Address - Adreso - - - (no label) - (neniu etikedo) - AskPassphraseDialog @@ -131,86 +60,6 @@ Repeat new passphrase Ripetu la novan pasfrazon - - Encrypt wallet - Ĉifri la monujon - - - This operation needs your wallet passphrase to unlock the wallet. - Ĉi tiu operacio bezonas vian monujan pasfrazon, por malŝlosi la monujon. - - - Unlock wallet - Malŝlosi la monujon - - - This operation needs your wallet passphrase to decrypt the wallet. - Ĉi tiu operacio bezonas vian monujan pasfrazon, por malĉifri la monujon. - - - Decrypt wallet - Malĉifri la monujon - - - Change passphrase - Ŝanĝi la pasfrazon - - - Confirm wallet encryption - Konfirmo de ĉifrado de la monujo - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atentu! Se vi ĉifras vian monujon kaj perdas la pasfrazon, vi <b>PERDOS LA TUTON DE VIA BITMONO<b>! - - - Are you sure you wish to encrypt your wallet? - Ĉu vi certas, ke vi volas ĉifri la monujon? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - GRAVE: antaŭaj sekur-kopioj de via monujo-dosiero estas forigindaj kiam vi havas nove kreitan ĉifritan monujo-dosieron. Pro sekureco, antaŭaj kopioj de la neĉifrita dosiero ne plu funkcios tuj kiam vi ekuzos la novan ĉifritan dosieron. - - - Warning: The Caps Lock key is on! - Atentu: la majuskla baskulo estas ŝaltita! - - - Wallet encrypted - La monujo estas ĉifrita - - - Enter the old passphrase and new passphrase to the wallet. - Tajpu la malnovan pasvorton kaj la novan pasvorton por la monujo. - - - Wallet encryption failed - Ĉifrado de la monujo fiaskis - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Ĉifrado de monujo fiaskis pro interna eraro. Via monujo ne estas ĉifrita. - - - The supplied passphrases do not match. - La pasfrazoj entajpitaj ne samas. - - - Wallet unlock failed - Malŝloso de la monujo fiaskis - - - The passphrase entered for the wallet decryption was incorrect. - La pasfrazo enigita por ĉifrado de monujo ne ĝustas. - - - Wallet decryption failed - Malĉifrado de la monujo fiaskis - - - Wallet passphrase was successfully changed. - Vi sukcese ŝanĝis la pasfrazon de la monujo. - BanTableModel @@ -289,14 +138,6 @@ Open &URI... Malfermi &URI-on... - - Bitcoin Core client - kliento de bitmon-kerno - - - Importing blocks from disk... - Importado de blokoj el disko... - Reindexing blocks on disk... Reindeksado de blokoj sur disko... @@ -341,10 +182,6 @@ &Receive &Ricevi - - Show information about Bitcoin Core - Vidigi informon pri Bitmona Kerno - &Show / Hide &Montri / Kaŝi @@ -381,18 +218,10 @@ Tabs toolbar Langeto-breto - - Bitcoin Core - Kerno de Bitmono - Request payments (generates QR codes and bitcoin: URIs) Peti pagon (kreas QR-kodojn kaj URI-ojn kun prefikso bitcoin:) - - &About Bitcoin Core - &Pri la Bitmona Kerno - Show the list of used sending addresses and labels Vidigi la liston de uzitaj sendaj adresoj kaj etikedoj @@ -512,13 +341,6 @@ Monujo estas <b>ĉifrita</b> kaj aktuale <b>ŝlosita</b> - - ClientModel - - Network Alert - Reta Averto - - CoinControlDialog @@ -593,134 +415,6 @@ Priority Prioritato - - Copy address - Kopii adreson - - - Copy label - Kopii etikedon - - - Copy amount - Kopii sumon - - - Copy transaction ID - Kopii transakcian ID-on - - - Lock unspent - Ŝlosi la neelspezitajn - - - Unlock unspent - Malŝlosi la neelspezitajn - - - Copy quantity - Kopii kvanton - - - Copy fee - Kopii krompagon - - - Copy after fee - Kopii post krompago - - - Copy bytes - Kopii bajtojn - - - Copy priority - Kopii prioritaton - - - Copy dust - Kopii polvon - - - Copy change - Kopii restmonon - - - highest - plej alta - - - higher - pli alta - - - high - alta - - - medium-high - mezalta - - - medium - meza - - - low-medium - mezmalalta - - - low - malalta - - - lower - pli malalta - - - lowest - plej malalta - - - (%1 locked) - (%1 ŝlosita) - - - none - neniu - - - yes - jes - - - no - ne - - - This means a fee of at least %1 per kB is required. - Tio signifas, ke krompago de almenaŭ po %1 por ĉiu kB estas deviga. - - - Can vary +/- 1 byte per input. - Povas varii po +/- 1 bajton por ĉiu enigo. - - - Transactions with higher priority are more likely to get included into a block. - Transakcioj kun pli alta prioritato havas pli altan ŝancon inkluziviĝi en bloko. - - - (no label) - (neniu etikedo) - - - change from %1 (%2) - restmono de %1 (%2) - - - (change) - (restmono) - EditAddressDialog @@ -744,38 +438,6 @@ &Address &Adreso - - New receiving address - Nova adreso por ricevi - - - New sending address - Nova adreso por sendi - - - Edit receiving address - Redakti adreson por ricevi - - - Edit sending address - Redakti adreson por sendi - - - The entered address "%1" is already in the address book. - La adreso enigita "%1" jam ekzistas en la adresaro. - - - The entered address "%1" is not a valid Bitcoin address. - La adreso enigita "%1" ne estas valida Bitmon-adreso. - - - Could not unlock wallet. - Ne eblis malŝlosi monujon. - - - New key generation failed. - Fiaskis kreo de nova ŝlosilo. - FreespaceChecker @@ -802,18 +464,10 @@ HelpMessageDialog - - Bitcoin Core - Kerno de Bitmono - version versio - - About Bitcoin Core - Pri la Bitmona Kerno - Command-line options Komandliniaj agordaĵoj @@ -837,18 +491,6 @@ Welcome Bonvenon - - Welcome to Bitcoin Core. - Bonvenon al la bitmona kerno, Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Dum tiu ĉi unua uzo de la programo, vi povas elekti lokon, kie Bitcoin Core stokos siajn datumojn. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core elŝutos kaj konservos kopion de la bitmona blokĉeno. Almenaŭ %1GB da datumoj konserviĝos en tiu loko, kaj tio poiome kreskos. Ankaŭ via monujo konserviĝos en tiu dosierujo. - Use the default data directory Uzi la defaŭltan dosierujon por datumoj @@ -857,10 +499,6 @@ Use a custom data directory: Uzi alian dosierujon por datumoj: - - Bitcoin Core - Kerno de Bitmono - Error Eraro @@ -888,10 +526,6 @@ Select payment request file Elektu la dosieron de la pagpeto - - Select payment request file to open - Elektu la malfermotan dosieron de la pagpeto - OptionsDialog @@ -1075,49 +709,6 @@ Lastaj transakcioj - - PaymentServer - - URI handling - Traktado de URI-oj - - - Invalid payment address %1 - Nevalida pagadreso %1 - - - Requested payment amount of %1 is too small (considered dust). - La petita pagosumo de %1 estas tro malgranda (konsiderata kiel polvo). - - - Payment request error - Eraro dum pagopeto - - - Cannot start bitcoin: click-to-pay handler - Ne eblas lanĉi la ilon 'klaki-por-pagi' - - - Refund from %1 - Repago de %1 - - - Error communicating with %1: %2 - Eraro dum komunikado kun %1: %2 - - - Bad response from server %1 - Malbona respondo de la servilo %1 - - - Payment acknowledged - Pago agnoskita - - - Network request error - Eraro dum ret-peto - - PeerTableModel @@ -1148,25 +739,6 @@ neaplikebla - - QRImageWidget - - &Save Image... - &Konservi Bildon... - - - &Copy Image - &Kopii Bildon - - - Save QR Code - Konservi QR-kodon - - - PNG Image (*.png) - PNG-bildo (*.png) - - RPCConsole @@ -1277,10 +849,6 @@ Out: El: - - Build date - Dato de kompilado - Debug log file Sencimiga protokoldosiero @@ -1356,18 +924,6 @@ Remove Forigi - - Copy label - Kopii etikedon - - - Copy message - Kopiu mesaĝon - - - Copy amount - Kopii sumon - ReceiveRequestDialog @@ -1387,70 +943,7 @@ &Save Image... &Konservi Bildon... - - Request payment to %1 - Peti pagon al %1 - - - Payment information - Paginformoj - - - URI - URI - - - Address - Adreso - - - Amount - Sumo - - - Label - Etikedo - - - Message - Mesaĝo - - - Resulting URI too long, try to reduce the text for label / message. - La rezultanta URI estas tro longa. Provu malplilongigi la tekston de la etikedo / mesaĝo. - - - Error encoding URI into QR Code. - Eraro de kodigo de URI en la QR-kodon. - - - RecentRequestsTableModel - - Date - Dato - - - Label - Etikedo - - - Message - Mesaĝo - - - Amount - Sumo - - - (no label) - (neniu etikedo) - - - (no message) - (neniu mesaĝo) - - SendCoinsDialog @@ -1533,82 +1026,6 @@ S&end Ŝendi - - Confirm send coins - Konfirmi sendon de bitmono - - - %1 to %2 - %1 al %2 - - - Copy quantity - Kopii kvanton - - - Copy amount - Kopii sumon - - - Copy fee - Kopii krompagon - - - Copy after fee - Kopii post krompago - - - Copy bytes - Kopii bajtojn - - - Copy priority - Kopii prioritaton - - - Copy change - Kopii restmonon - - - or - - - - The amount to pay must be larger than 0. - La pagenda sumo devas esti pli ol 0. - - - The amount exceeds your balance. - La sumo estas pli granda ol via saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - La sumo kun la %1 krompago estas pli granda ol via saldo. - - - Transaction creation failed! - Kreo de transakcio fiaskis! - - - Warning: Invalid Bitcoin address - Averto: Nevalida Bitmon-adreso - - - (no label) - (neniu etikedo) - - - Copy dust - Kopii polvon - - - Are you sure you want to send? - Ĉu vi certas, ke vi volas sendi? - - - added as transaction fee - aldonita kiel krompago - SendCoinsEntry @@ -1620,10 +1037,6 @@ Pay &To: &Ricevonto: - - Enter a label for this address to add it to your address book - Tajpu etikedon por tiu ĉi adreso kaj aldonu ĝin al via adresaro - &Label: &Etikedo: @@ -1746,69 +1159,9 @@ Reset all verify message fields Reagordigi ĉiujn prikontrolajn kampojn - - Click "Sign Message" to generate signature - Klaku "Subskribi Mesaĝon" por krei subskribon - - - The entered address is invalid. - La adreso, kiun vi enmetis, estas nevalida. - - - Please check the address and try again. - Bonvolu kontroli la adreson kaj reprovi. - - - The entered address does not refer to a key. - La adreso, kiun vi enmetis, referencas neniun ŝlosilon. - - - Wallet unlock was cancelled. - Malŝloso de monujo estas nuligita. - - - Private key for the entered address is not available. - La privata ŝlosilo por la enigita adreso ne disponeblas. - - - Message signing failed. - Subskribo de mesaĝo fiaskis. - - - Message signed. - Mesaĝo estas subskribita. - - - The signature could not be decoded. - Ne eblis malĉifri la subskribon. - - - Please check the signature and try again. - Bonvolu kontroli la subskribon kaj reprovu. - - - The signature did not match the message digest. - La subskribo ne kongruis kun la mesaĝ-kompilaĵo. - - - Message verification failed. - Kontrolo de mesaĝo malsukcesis. - - - Message verified. - Mesaĝo sukcese kontrolita. - SplashScreen - - Bitcoin Core - Kerno de Bitmono - - - The Bitcoin Core developers - La programistoj de Bitmona Kerno - [testnet] [testnet] @@ -1821,382 +1174,16 @@ KB/s - - TransactionDesc - - Open until %1 - Malferma ĝis %1 - - - %1/offline - %1/senkonekte - - - %1/unconfirmed - %1/nekonfirmite - - - %1 confirmations - %1 konfirmoj - - - Status - Stato - - - Date - Dato - - - Source - Fonto - - - Generated - Kreita - - - From - De - - - To - Al - - - own address - propra adreso - - - label - etikedo - - - Credit - Kredito - - - not accepted - ne akceptita - - - Debit - Debeto - - - Transaction fee - Krompago - - - Net amount - Neta sumo - - - Message - Mesaĝo - - - Comment - Komento - - - Transaction ID - Transakcia ID - - - Merchant - Vendisto - - - 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. - Kreitaj moneroj devas esti maturaj je %1 blokoj antaŭ ol eblas elspezi ilin. Kiam vi generis tiun ĉi blokon, ĝi estis elsendita al la reto por aldono al la blokĉeno. Se tiu aldono malsukcesas, ĝia stato ŝanĝiĝos al "neakceptita" kaj ne eblos elspezi ĝin. Tio estas malofta, sed povas okazi se alia bloko estas kreita je preskaŭ la sama momento kiel la via. - - - Debug information - Sencimigaj informoj - - - Transaction - Transakcio - - - Inputs - Enigoj - - - Amount - Sumo - - - true - vera - - - false - malvera - - - , has not been successfully broadcast yet - , ankoraŭ ne elsendita sukcese - - - unknown - nekonata - - TransactionDescDialog - - Transaction details - Transakciaj detaloj - This pane shows a detailed description of the transaction Tiu ĉi panelo montras detalan priskribon de la transakcio - - TransactionTableModel - - Date - Dato - - - Type - Tipo - - - Open until %1 - Malferma ĝis %1 - - - Confirmed (%1 confirmations) - Konfirmita (%1 konfirmoj) - - - This block was not received by any other nodes and will probably not be accepted! - Tiun ĉi blokon ne ricevis ajna alia nodo, kaj ĝi verŝajne ne akceptiĝos! - - - Generated but not accepted - Kreita sed ne akceptita - - - Offline - Senkonekte - - - Label - Etikedo - - - Unconfirmed - Nekonfirmita - - - Received with - Ricevita kun - - - Received from - Ricevita de - - - Sent to - Sendita al - - - Payment to yourself - Pago al vi mem - - - Mined - Minita - - - (n/a) - neaplikebla - - - Transaction status. Hover over this field to show number of confirmations. - Transakcia stato. Ŝvebi super tiu ĉi kampo por montri la nombron de konfirmoj. - - - Date and time that the transaction was received. - Dato kaj horo kiam la transakcio alvenis. - - - Type of transaction. - Tipo de transakcio. - - - Amount removed from or added to balance. - Sumo elprenita de aŭ aldonita al la saldo. - - - - TransactionView - - All - Ĉiuj - - - Today - Hodiaŭ - - - This week - Ĉi-semajne - - - This month - Ĉi-monate - - - Last month - Pasintmonate - - - This year - Ĉi-jare - - - Range... - Intervalo... - - - Received with - Ricevita kun - - - Sent to - Sendita al - - - To yourself - Al vi mem - - - Mined - Minita - - - Other - Aliaj - - - Enter address or label to search - Tajpu adreson aŭ etikedon por serĉi - - - Min amount - Minimuma sumo - - - Copy address - Kopii adreson - - - Copy label - Kopii etikedon - - - Copy amount - Kopii sumon - - - Copy transaction ID - Kopii transakcian ID-on - - - Edit label - Redakti etikedon - - - Show transaction details - Montri detalojn de transakcio - - - Exporting Failed - ekspotado malsukcesinta - - - Comma separated file (*.csv) - Perkome disigita dosiero (*.csv) - - - Confirmed - Konfirmita - - - Date - Dato - - - Type - Tipo - - - Label - Etikedo - - - Address - Adreso - - - ID - ID - - - Range: - Intervalo: - - - to - al - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Sendi Bitmonon - - - - WalletView - - &Export - &Eksporti - - - Export the data in the current tab to a file - Eksporti la datumojn el la aktuala langeto al dosiero - - - Backup Wallet - Krei sekurkopion de monujo - - - Wallet Data (*.dat) - Monuj-datumoj (*.dat) - - - Backup Failed - Malsukcesis sekurkopio - - - Backup Successful - Sukcesis krei sekurkopion - - bitcoin-core @@ -2227,6 +1214,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Akcepti konektojn el ekstere (defaŭlte: 1 se ne estas -proxy nek -connect) + + Bitcoin Core + Kerno de Bitmono + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bindi al donita adreso kaj ĉiam aŭskulti per ĝi. Uzu la formaton [gastigo]:pordo por IPv6 @@ -2247,10 +1238,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Averto: ŝajne ni ne tute konsentas kun niaj samtavolanoj! Eble vi devas ĝisdatigi vian klienton, aŭ eble aliaj nodoj faru same. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Averto: via wallet.dat estas difektita, sed la datumoj sukcese saviĝis! La originala wallet.dat estas nun konservita kiel wallet.{timestamp}.bak en %s; se via saldo aŭ transakcioj estas malĝustaj vi devus restaŭri per alia sekurkopio. - <category> can be: <category> povas esti: @@ -2327,34 +1314,14 @@ Wallet options: Monujaj opcioj: - - You need to rebuild the database using -reindex to change -txindex - Vi devas rekontrui la datumbazon kun -reindex por ŝanĝi -txindex - Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo) - - Cannot resolve -whitebind address: '%s' - Ne eblas trovi la adreson -whitebind: '%s' - Information Informoj - - Invalid amount for -maxtxfee=<amount>: '%s' - Nevalida sumo por -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Nevalida sumo por -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Nevalida sumo por -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log @@ -2391,10 +1358,6 @@ Warning Averto - - wallet.dat corrupt, salvage failed - wallet.dat estas difektita, riparo malsukcesis - Password for JSON-RPC connections Pasvorto por konektoj JSON-RPC @@ -2403,10 +1366,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Plenumi komandon kiam plej bona bloko ŝanĝiĝas (%s en cmd anstataŭiĝas per bloka haketaĵo) - - This help message - Tiu ĉi helpmesaĝo - Allow DNS lookups for -addnode, -seednode and -connect Permesi DNS-elserĉojn por -addnote, -seednote kaj -connect @@ -2415,14 +1374,6 @@ Loading addresses... Ŝarĝante adresojn... - - Error loading wallet.dat: Wallet corrupted - Eraro dum ŝargado de wallet.dat: monujo difektita - - - Error loading wallet.dat - Eraro dum ŝargado de wallet.dat - Invalid -proxy address: '%s' Nevalid adreso -proxy: '%s' @@ -2431,18 +1382,6 @@ Unknown network specified in -onlynet: '%s' Nekonata reto specifita en -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Ne eblas trovi la adreson -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Ne eblas trovi la adreson -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Nevalida sumo por -paytxfee=<amount>: '%s' - Insufficient funds Nesufiĉa mono diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 5322634c5..fc430e86b 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -25,10 +25,6 @@ C&lose C&errar - - &Copy Address - &Copiar dirección - Delete the currently selected address from the list Eliminar la dirección seleccionada de la lista @@ -45,73 +41,6 @@ &Delete &Eliminar - - Choose the address to send coins to - Elija la dirección para enviar monedas a - - - Choose the address to receive coins with - Elija la dirección para recibir monedas con - - - C&hoose - E&scoger - - - Sending addresses - Direcciones de envío - - - Receiving addresses - Direcciones de recepción - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son tus direcciones Bitcoin para enviar los pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar las monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son tus direcciones de Bitcoin para recibir los pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar la lista de direcciones - - - Comma separated file (*.csv) - Archivos separados por coma (*.csv) - - - Exporting Failed - Fallo al exportar - - - There was an error trying to save the address list to %1. Please try again. - Hubo un error al tratar de guardar en la lista de direcciones a %1 . Por favor, vuelve a intentarlo . - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repita la nueva contraseña - - Encrypt wallet - Cifrar el monedero - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación requiere su contraseña para desbloquear el monedero. - - - Unlock wallet - Desbloquear monedero - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación requiere su contraseña para descifrar el monedero. - - - Decrypt wallet - Descifrar el monedero - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirmar cifrado del monedero - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atencion: ¡Si cifra su monedero y pierde la contraseña perderá <b>TODOS SUS BITCOINS</b>!" - - - Are you sure you wish to encrypt your wallet? - ¿Estás seguro que deseas cifrar tu monedero ? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core se cerrará ahora para completar el procedo de encriptación. Recuerda que encriptar tu cartera no te protegerá completamente de la pérdida de bitcoins por infección de malware en tu computadora. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Cualquier copia de seguridad que haya realizado previamente de su archivo de monedero debe reemplazarse con el nuevo archivo de monedero cifrado. Por razones de seguridad, las copias de seguridad previas del archivo de monedero no cifradas serán inservibles en cuanto comience a usar el nuevo monedero cifrado. - - - Warning: The Caps Lock key is on! - Aviso: ¡La tecla de Mayúsculas está activada! - - - Wallet encrypted - Monedero cifrado - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduzca la nueva contraseña para el monedero.<br/>Utilice por favor una contraseña con <b>diez o más caracteres aleatorios</b> o con <b>ocho o más palabras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduce la antigua y la nueva contraseña de la cartera. - - - Wallet encryption failed - Ha fallado el cifrado del monedero - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Ha fallado el cifrado del monedero debido a un error interno. El monedero no ha sido cifrado. - - - The supplied passphrases do not match. - Las contraseñas no coinciden. - - - Wallet unlock failed - Ha fallado el desbloqueo del monedero - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña introducida para descifrar el monedero es incorrecta. - - - Wallet decryption failed - Ha fallado el descifrado del monedero - - - Wallet passphrase was successfully changed. - Se ha cambiado correctamente la contraseña del monedero. - BanTableModel @@ -269,6 +110,14 @@ Quit application Salir de la aplicación + + &About %1 + &Acerca de %1 + + + Show information about %1 + Mostrar información acerca de %1 + About &Qt Acerca de &Qt @@ -281,6 +130,10 @@ &Options... &Opciones... + + Modify configuration options for %1 + Modificar las opciones de configuración para %1 + &Encrypt Wallet... &Cifrar monedero… @@ -305,14 +158,6 @@ Open &URI... Abrir &URI... - - Bitcoin Core client - Cliente Bitcoin Core - - - Importing blocks from disk... - Importando bloques de disco... - Reindexing blocks on disk... Reindexando bloques en disco... @@ -357,10 +202,6 @@ &Receive &Recibir - - Show information about Bitcoin Core - Mostrar información acerca de Bitcoin Core - &Show / Hide &Mostrar / Ocultar @@ -397,22 +238,10 @@ Tabs toolbar Barra de pestañas - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Solicitar pagos (generando códigos QR e identificadores URI "bitcoin:") - - &About Bitcoin Core - &Acerca de Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modificar las opciones de configuración de Bitcoin - Show the list of used sending addresses and labels Mostrar la lista de direcciones de envío y etiquetas @@ -429,14 +258,18 @@ &Command-line options &Opciones de consola de comandos - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostrar el mensaje de ayuda de Bitcoin Core con una lista de las posibles opciones de la consola de comandos de Bitcoin - %n active connection(s) to Bitcoin network %n conexión activa hacia la red Bitcoin%n conexiones activas hacia la red Bitcoin + + Indexing blocks on disk... + Indexando bloques en disco... + + + Processing blocks on disk... + Procesando bloques en disco... + No block source available... Ninguna fuente de bloques disponible ... @@ -493,6 +326,14 @@ Up to date Actualizado + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostrar el mensaje de ayuda %1 para obtener una lista de los posibles comandos de linea de comandos de Bitcoin + + + %1 client + %1 cliente + Catching up... Actualizando... @@ -544,13 +385,6 @@ El monedero está <b>cifrado</b> y actualmente <b>bloqueado</b> - - ClientModel - - Network Alert - Alerta de red - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Prioridad - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cuantía - - - Copy transaction ID - Copiar identificador de transacción - - - Lock unspent - Bloquear lo no gastado - - - Unlock unspent - Desbloquear lo no gastado - - - Copy quantity - Copiar cantidad - - - Copy fee - Copiar comisión - - - Copy after fee - Copiar después de aplicar comisión - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy dust - Copiar polvo - - - Copy change - Copiar cambio - - - highest - lo más alto - - - higher - más alto - - - high - alto - - - medium-high - medio-alto - - - medium - medio - - - low-medium - bajo-medio - - - low - bajo - - - lower - más bajo - - - lowest - lo más bajo - - - (%1 locked) - (%1 bloqueado) - - - none - ninguna - - - This label turns red if the transaction size is greater than 1000 bytes. - Esta etiqueta se mostrará en rojo si el tamaño de la transacción es mayor de 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Esta etiqueta se mostrará en rojo si la prioridad es menor a "media" - - - This label turns red if any recipient receives an amount smaller than %1. - Esta etiqueta se vuelve roja si el cambio es menor que %1 - - - Can vary +/- %1 satoshi(s) per input. - Puede variar en +/- %1 satoshi(s) por entrada. - - - yes - si - - - no - no - - - This means a fee of at least %1 per kB is required. - Esto implica que se requiere una comisión de al menos %1 por kB - - - Can vary +/- 1 byte per input. - Puede variar en +/- 1 byte por entrada. - - - Transactions with higher priority are more likely to get included into a block. - Las transacciones con mayor prioridad tienen mayor probabilidad de ser incluidas en un bloque. - - - (no label) - (sin etiqueta) - - - change from %1 (%2) - Cambio desde %1 (%2) - - - (change) - (cambio) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Dirección - - New receiving address - Nueva dirección de recepción - - - New sending address - Nueva dirección de envío - - - Edit receiving address - Editar dirección de recepción - - - Edit sending address - Editar dirección de envío - - - The entered address "%1" is already in the address book. - La dirección introducida "%1" ya está presente en la libreta de direcciones. - - - The entered address "%1" is not a valid Bitcoin address. - La dirección introducida "%1" no es una dirección Bitcoin válida. - - - Could not unlock wallet. - No se pudo desbloquear el monedero. - - - New key generation failed. - Ha fallado la generación de la nueva clave. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versión @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - Acerca de Bitcoin Core + About %1 + Acerda de %1 Command-line options @@ -903,8 +557,8 @@ Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) - Reset all settings changes made over the GUI - Resetear los cambios de configuracion hechos por el GUI + Reset all settings changed in the GUI + Reiniciar todos los ajustes modificados en el GUI @@ -914,16 +568,16 @@ Bienvenido - Welcome to Bitcoin Core. - Bienvenido a Bitcoin Core + Welcome to %1. + Bienvenido a %1 - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Al ser la primera vez que se ejecuta el programa, puede elegir dónde almacenará sus datos Bitcoin Core. + As this is the first time the program is launched, you can choose where %1 will store its data. + Al ser la primera vez que se ejecuta el programa, puede elegir donde %1 almacenara sus datos - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core va a descargar y guardar una copia de la cadena de bloques de Bitcoin. Se almacenará al menos %1GB de datos en este directorio, que irá creciendo con el tiempo. El monedero se guardará también en este directorio. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 va a descargar y almacenar una copia de la cadena de bloques de Bitcoin. Al menos %2GB de datos seran almacenados en este directorio, que ira creciendo con el tiempo. El monedero se guardara tambien en ese directorio. Use the default data directory @@ -933,10 +587,6 @@ Use a custom data directory: Utilizar un directorio de datos personalizado: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Error: no ha podido crearse el directorio de datos especificado "%1". @@ -972,10 +622,6 @@ Select payment request file Seleccionar archivo de sulicitud de pago - - Select payment request file to open - Seleccionar el archivo de solicitud de pago para abrir - OptionsDialog @@ -987,6 +633,14 @@ &Main &Principal + + Automatically start %1 after logging in to the system. + Iniciar automaticamente %1 al encender el sistema. + + + &Start %1 on system login + &Iniciar %1 al iniciar el sistema + Size of &database cache Tamaño de cache de la &base de datos @@ -1015,10 +669,6 @@ 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. Minimizar en lugar de salir de la aplicación cuando la ventana está cerrada. Cuando se activa esta opción, la aplicación sólo se cerrará después de seleccionar Salir en el menú. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin. - 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 |. Identificadores URL de terceros (por ejemplo, un explorador de bloques) que aparecen en la pestaña de transacciones como elementos del menú contextual. El %s en la URL es reemplazado por el valor hash de la transacción. Se pueden separar URL múltiples por una barra vertical |. @@ -1043,14 +693,6 @@ &Network &Red - - Automatically start Bitcoin Core after logging in to the system. - Iniciar automáticamente Bitcoin Core al iniciar el sistema. - - - &Start Bitcoin Core on system login - &Iniciar Bitcoin Core al inicio del sistema - (0 = auto, <0 = leave that many cores free) (0 = automático, <0 = dejar libres ese número de núcleos) @@ -1135,6 +777,14 @@ &Window &Ventana + + &Hide the icon from the system tray. + &Ocultar el icono de la barra de tareas + + + Hide tray icon + Ocultar barra de tareas + Show only a tray icon after minimizing the window. Minimizar la ventana a la bandeja de iconos del sistema. @@ -1155,6 +805,10 @@ User Interface &language: I&dioma de la interfaz de usuario + + The user interface language can be set here. This setting will take effect after restarting %1. + El idioma de la interfaz de usuario puede establecerse aquí. Esta configuración tendrá efecto tras reiniciar %1. + &Unit to show amounts in: Mostrar las cantidades en la &unidad: @@ -1279,97 +933,6 @@ Saldo total en las direcciones watch-only - - PaymentServer - - URI handling - Gestión de URI - - - Invalid payment address %1 - Dirección de pago no válida %1 - - - Payment request rejected - Solicitud de pago rechazada - - - Payment request network doesn't match client network. - La red de solicitud de pago no coincide con la red cliente - - - Payment request is not initialized. - La solicitud de pago no está inicializada - - - Requested payment amount of %1 is too small (considered dust). - La cantidad del pago solicitado (%1) es demasiado pequeña (considerada polvo). - - - Payment request error - Error en solicitud de pago - - - Cannot start bitcoin: click-to-pay handler - No se puede iniciar el gestor de identificadores "bitcoin:" de clic-para-pagar - - - Payment request fetch URL is invalid: %1 - La URL de obtención de la solicitud de pago es inválida: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - ¡No se puede leer el identificador URI! Esto puede deberse a una dirección Bitcoin inválida o a parámetros de la URI mal formados - - - Payment request file handling - Procesado del archivo de solicitud de pago - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - ¡No puede leerse el archivo de solicitud de pago! Esto puede deberse a un archivo inválido de solicitud de pago. - - - Payment request expired. - Solicitud de pago caducada. - - - Unverified payment requests to custom payment scripts are unsupported. - No están soportadas las peticiones inseguras a scripts de pago personalizados - - - Invalid payment request. - Petición de pago no válida. - - - Refund from %1 - Devolución desde %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La petición de pago %1 es demasiado grande (%2 bytes, permitidos %3 bytes). - - - Error communicating with %1: %2 - Error en la comunicación con %1: %2 - - - Payment request cannot be parsed! - ¡No puede leerse la solicitud de pago! - - - Bad response from server %1 - Respuesta errónea del servidor %1 - - - Payment acknowledged - Pago aceptado - - - Network request error - Error en petición de red - - PeerTableModel @@ -1424,25 +987,6 @@ %1 ms - - QRImageWidget - - &Save Image... - Guardar Imagen... - - - &Copy Image - Copiar imagen - - - Save QR Code - Guardar código QR - - - PNG Image (*.png) - Imágenes PNG (*.png) - - RPCConsole @@ -1473,6 +1017,10 @@ Using BerkeleyDB version Utilizando la versión de BerkeleyDB + + Datadir + Datadir + Startup time Hora de inicio @@ -1509,10 +1057,6 @@ Memory usage Uso de memoria - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Abre el archivo de registro de depuración de Bitcoin desde el directorio de datos actual. Esto puede tardar unos segundos para ficheros de registro de gran tamaño. - Received Recibido @@ -1561,6 +1105,18 @@ User Agent User Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Abrir el archivo de depuración %1 desde el directorio de datos actual. Puede tardar unos segundos para ficheros de gran tamaño. + + + Decrease font size + Disminuir tamaño de letra + + + Increase font size + Aumentar tamaño de letra + Services Servicios @@ -1629,10 +1185,6 @@ Out: Saliente: - - Build date - Fecha de compilación - Debug log file Archivo de registro de depuración @@ -1670,8 +1222,8 @@ &Desbanear Nodo - Welcome to the Bitcoin Core RPC console. - Bienvenido a la consola RPC de Bitcoin Core. + Welcome to the %1 RPC console. + Bienvenido a la consola RPC %1. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1800,18 +1352,6 @@ Remove Eliminar - - Copy label - Copiar etiqueta - - - Copy message - Mensaje - - - Copy amount - Copiar cuantía - ReceiveRequestDialog @@ -1831,73 +1371,6 @@ &Save Image... Guardar Imagen... - - Request payment to %1 - Solicitar pago a %1 - - - Payment information - Información de pago - - - URI - URI - - - Address - Dirección - - - Amount - Cantidad - - - Label - Etiqueta - - - Message - Mensaje - - - Resulting URI too long, try to reduce the text for label / message. - URI resultante demasiado larga. Intente reducir el texto de la etiqueta / mensaje. - - - Error encoding URI into QR Code. - Error al codificar la URI en el código QR. - - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - Message - Mensaje - - - Amount - Cantidad - - - (no label) - (sin etiqueta) - - - (no message) - (Ningun mensaje) - - - (no amount) - (sin cantidad) - SendCoinsDialog @@ -2017,14 +1490,6 @@ fast rápido - - Send as zero-fee transaction if possible - Enviar transacción, si es posible, sin comisión - - - (confirmation may take longer) - (confirmación puede tardar más tiempo) - Send to multiple recipients at once Enviar a múltiples destinatarios de una vez @@ -2057,118 +1522,6 @@ S&end &Enviar - - Confirm send coins - Confirmar el envío de bitcoins - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copiar cantidad - - - Copy amount - Copiar cuantía - - - Copy fee - Copiar donación - - - Copy after fee - Copiar después de aplicar donación - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar Cambio - - - Total Amount %1 - Monto Total %1 - - - or - o - - - The amount to pay must be larger than 0. - La cantidad por pagar tiene que ser mayor de 0. - - - The amount exceeds your balance. - La cantidad sobrepasa su saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - El total sobrepasa su saldo cuando se incluye la tasa de envío de %1 - - - Transaction creation failed! - ¡Ha fallado la creación de la transacción! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - ¡La transacción fue rechazada! Esto puede haber ocurrido si alguno de los bitcoins de su monedero ya estaba gastado o si ha usado una copia de wallet.dat y los bitcoins estaban gastados en la copia pero no se habían marcado como gastados aqui. - - - A fee higher than %1 is considered an absurdly high fee. - Una comisión mayor al %1 se considera demasiado alta. - - - Payment request expired. - Solicitud de pago caducada. - - - Pay only the required fee of %1 - Paga sólo la cuota mínima de %1 - - - Estimated to begin confirmation within %n block(s). - Estimado para empezar la confirmación dentro de %n bloque.Estimado para empezar la confirmación dentro de %n bloques. - - - The recipient address is not valid. Please recheck. - La dirección del destinatario no es válida. Por favor, compruébela de nuevo. - - - Duplicate address found: addresses should only be used once each. - Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío. - - - Warning: Invalid Bitcoin address - Alerta: Dirección de Bitcoin inválida - - - (no label) - (sin etiqueta) - - - Warning: Unknown change address - Alerta: Dirección de Bitcoin inválida - - - Copy dust - Copiar polvo - - - Are you sure you want to send? - ¿Está seguro que desea enviar? - - - added as transaction fee - añadido como comisión de transacción - SendCoinsEntry @@ -2180,10 +1533,6 @@ Pay &To: &Pagar a: - - Enter a label for this address to add it to your address book - Etiquete esta dirección para añadirla a la libreta - &Label: &Etiqueta: @@ -2256,8 +1605,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core se está cerrando... + %1 is shutting down... + %1 se esta cerrando... Do not shut down the computer until this window disappears. @@ -2350,69 +1699,9 @@ Reset all verify message fields Vaciar todos los campos de la verificación de mensaje - - Click "Sign Message" to generate signature - Haga clic en "Firmar mensaje" para generar la firma - - - The entered address is invalid. - La dirección introducida es inválida. - - - Please check the address and try again. - Verifique la dirección e inténtelo de nuevo. - - - The entered address does not refer to a key. - La dirección introducida no corresponde a una clave. - - - Wallet unlock was cancelled. - Se ha cancelado el desbloqueo del monedero. - - - Private key for the entered address is not available. - No se dispone de la clave privada para la dirección introducida. - - - Message signing failed. - Ha fallado la firma del mensaje. - - - Message signed. - Mensaje firmado. - - - The signature could not be decoded. - No se puede decodificar la firma. - - - Please check the signature and try again. - Compruebe la firma e inténtelo de nuevo. - - - The signature did not match the message digest. - La firma no coincide con el resumen del mensaje. - - - Message verification failed. - La verificación del mensaje ha fallado. - - - Message verified. - Mensaje verificado. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Los desarrolladores de Bitcoin Core - [testnet] [testnet] @@ -2425,422 +1714,13 @@ KB/s - - TransactionDesc - - Open until %1 - Abierto hasta %1 - - - conflicted - en conflicto - - - %1/offline - %1/fuera de línea - - - %1/unconfirmed - %1/no confirmado - - - %1 confirmations - %1 confirmaciones - - - Status - Estado - - - , broadcast through %n node(s) - , transmitir a través de %n nodo, transmitir a través de %n nodos - - - Date - Fecha - - - Source - Fuente - - - Generated - Generado - - - From - De - - - To - Para - - - own address - dirección propia - - - watch-only - de observación - - - label - etiqueta - - - Credit - Crédito - - - matures in %n more block(s) - disponible en %n bloque másdisponible en %n bloques más - - - not accepted - no aceptada - - - Debit - Débito - - - Total debit - Débito total - - - Total credit - Crédito total - - - Transaction fee - Comisión de transacción - - - Net amount - Cantidad neta - - - Message - Mensaje - - - Comment - Comentario - - - Transaction ID - Identificador de transacción - - - Merchant - Vendedor - - - 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. - Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo. - - - Debug information - Información de depuración - - - Transaction - Transacción - - - Inputs - entradas - - - Amount - Cantidad - - - true - verdadero - - - false - falso - - - , has not been successfully broadcast yet - , todavía no se ha sido difundido satisfactoriamente - - - Open for %n more block(s) - Abrir para %n bloque másAbrir para %n bloques más - - - unknown - desconocido - - TransactionDescDialog - - Transaction details - Detalles de transacción - This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - - TransactionTableModel - - Date - Fecha - - - Type - Tipo - - - Immature (%1 confirmations, will be available after %2) - No vencidos (%1 confirmaciones. Estarán disponibles al cabo de %2) - - - Open for %n more block(s) - Abrir para %n bloque másAbrir para %n bloques más - - - Open until %1 - Abierto hasta %1 - - - Confirmed (%1 confirmations) - Confirmado (%1 confirmaciones) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! - - - Generated but not accepted - Generado pero no aceptado - - - Offline - Sin conexión - - - Label - Etiqueta - - - Unconfirmed - Sin confirmar - - - Confirming (%1 of %2 recommended confirmations) - Confirmando (%1 de %2 confirmaciones recomendadas) - - - Conflicted - En conflicto - - - Received with - Recibido con - - - Received from - Recibidos de - - - Sent to - Enviado a - - - Payment to yourself - Pago propio - - - Mined - Minado - - - watch-only - de observación - - - (n/a) - (nd) - - - Transaction status. Hover over this field to show number of confirmations. - Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. - - - Date and time that the transaction was received. - Fecha y hora en que se recibió la transacción. - - - Type of transaction. - Tipo de transacción. - - - Whether or not a watch-only address is involved in this transaction. - Sea o no una dirección sólo está involucrada en esta transacción. - - - User-defined intent/purpose of the transaction. - intento/propósito de la transacción definido por el usuario. - - - Amount removed from or added to balance. - Cantidad retirada o añadida al saldo. - - - - TransactionView - - All - Todo - - - Today - Hoy - - - This week - Esta semana - - - This month - Este mes - - - Last month - Mes pasado - - - This year - Este año - - - Range... - Rango... - - - Received with - Recibido con - - - Sent to - Enviado a - - - To yourself - A usted mismo - - - Mined - Minado - - - Other - Otra - - - Enter address or label to search - Introduzca una dirección o etiqueta que buscar - - - Min amount - Cantidad mínima - - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cuantía - - - Copy transaction ID - Copiar identificador de transacción - - - Copy raw transaction - Copiar traducción en crudo - - - Edit label - Editar etiqueta - - - Show transaction details - Mostrar detalles de la transacción - - - Export Transaction History - Exportar historial de transacciones - - - Watch-only - De observación - - - Exporting Failed - Error exportando - - - There was an error trying to save the transaction history to %1. - Ha habido un error al intentar guardar la transacción con %1. - - - Exporting Successful - Exportación finalizada - - - The transaction history was successfully saved to %1. - La transacción ha sido guardada en %1. - - - Comma separated file (*.csv) - Archivos de columnas separadas por coma (*.csv) - - - Confirmed - Confirmado - - - Date - Fecha - - - Type - Tipo - - - Label - Etiqueta - - - Address - Dirección - - - ID - ID - - - Range: - Rango: - - - to - para - - UnitDisplayStatusBarControl @@ -2848,55 +1728,6 @@ Unidad en la que se muestran las cantidades. Haga clic para seleccionar otra unidad. - - WalletFrame - - No wallet has been loaded. - No se ha cargado ningún monedero - - - - WalletModel - - Send Coins - Enviar bitcoins - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar a un archivo los datos de esta pestaña - - - Backup Wallet - Copia de seguridad del monedero - - - Wallet Data (*.dat) - Datos de monedero (*.dat) - - - Backup Failed - Ha fallado el respaldo - - - There was an error trying to save the wallet data to %1. - Ha habido un error al intentar guardar los datos del monedero en %1. - - - The wallet data was successfully saved to %1. - Los datos del monedero se han guardado con éxito en %1. - - - Backup Successful - Se ha completado la copia de seguridad del monedero - - bitcoin-core @@ -2925,14 +1756,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Si <category> no es proporcionado o si <category> =1, muestra toda la información de depuración. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Máximas comisiones totales (en %s) para utilizar en una sola transacción de la cartera; establecer esto demasiado bajo puede abortar grandes transacciones (predeterminado: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Por favor, mira si la fecha y la hora en tu computador son correctas! Si tu hara es errónea Bitcoin Core no funcionará correctamente. - Prune configured below the minimum of %d MiB. Please use a higher number. La Poda se ha configurado por debajo del minimo de %d MiB. Por favor utiliza un valor mas alto. @@ -2974,6 +1797,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) + + Bitcoin Core + Bitcoin Core + + + The %s developers + Los %s desarrolladores + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee tiene un ajuste muy alto! Esta es la comisión de transacción que pagarás cuando las estimaciones de comisiones no estén disponibles. @@ -2990,6 +1821,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + No se puede bloquear el directorio %s. %s ya se está ejecutando. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup. @@ -2998,6 +1833,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Error cargando %s: No puede habilitar HD en un monedero existente que no es HD + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error leyendo %s!. Todas las claves se han leido correctamente, pero los datos de transacciones o la libreta de direcciones pueden faltar o ser incorrectos. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) @@ -3006,6 +1849,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Ajuste máximo permitido del tiempo offset medio de pares. La perspectiva local de tiempo se verá influenciada por los pares anteriores y posteriores a esta cantidad. (Por defecto: %u segundos) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Máximas comisiones totales (en %s) para utilizar en una sola transacción de la cartera; establecer esto demasiado bajo puede abortar grandes transacciones (predeterminado: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Por favor, compruebe si la fecha y hora en su computadora son correctas! Si su reloj esta mal, %s no trabajara correctamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Contribuya si encuentra %s de utilidad. Visite %s para mas información acerca del programa. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, <0 = dejar libres ese número de núcleos; predeterminado: %d) @@ -3018,14 +1877,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - El argumento no soportado -whitelistalwaysrelay ha sido ignorado, utiliza -whitelistrelay y/o -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) @@ -3042,22 +1893,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Advertencia: Se están minando versiones de bloques desconocidas! Es posible que normas desconocidas estén activas - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Aviso: ¡Recuperados datos de wallet.dat corrupto! El wallet.dat original se ha guardado como wallet.{timestamp}.bak en %s; si hubiera errores en su saldo o transacciones, deberá restaurar una copia de seguridad. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Necesita reconstruir la base de datos usando -reindex-chainstate para cambiar -txindex + + + %s corrupt, salvage failed + %s corrupto. Fracasó la recuperacion + -maxmempool must be at least %d MB -maxmempool debe ser por lo menos de %d MB @@ -3070,10 +1921,22 @@ Append comment to the user agent string Adjunta un comentario a la linea de agente de usuario + + Attempt to recover private keys from a corrupt wallet on startup + Intento de recuperar claves privadas de un monedero corrupto en arranque + Block creation options: Opciones de creación de bloques: + + Cannot resolve -%s address: '%s' + No se puede resolver -%s direccion: '%s' + + + Change index out of range + Cambio de indice fuera de rango + Connect only to the specified node(s) Conectar sólo a los nodos (o nodo) especificados @@ -3082,6 +1945,10 @@ Connection options: Opciones de conexión: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Corrupción de base de datos de bloques detectada. @@ -3126,6 +1993,22 @@ Error initializing wallet database environment %s! Error al inicializar el entorno de la base de datos del monedero %s + + Error loading %s + Error cargando %s + + + Error loading %s: Wallet corrupted + Error cargando %s: Monedero dañado + + + Error loading %s: Wallet requires newer version of %s + Error cargando %s: Monedero requiere un versión mas reciente de %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Error cargando %s: No puede deshabilitar HD en un monedero existente que ya es HD + Error loading block database Error cargando base de datos de bloques @@ -3150,10 +2033,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red? + + Initialization sanity check failed. %s is shutting down. + La inicialización de la verificación de validez falló. Se está apagando %s. + Invalid -onion address: '%s' Dirección -onion inválida: '%s' + + Invalid amount for -%s=<amount>: '%s' + Cantidad no valida para -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Cantidad inválida para -fallbackfee=<amount>: '%s' @@ -3162,6 +2053,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Mantener la memoria de transacciones por debajo de <n> megabytes (predeterminado: %u) + + Loading banlist... + Cargando banlist... + Location of the auth cookie (default: data dir) Ubicación de la cookie de autenticación (default: data dir) @@ -3178,6 +2073,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion) + + Print this help message and exit + Imprimir este mensaje de ayuda y salir + Print version and exit Imprimir versión y salir @@ -3190,6 +2089,14 @@ Prune mode is incompatible with -txindex. El modo recorte es incompatible con -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruir el estado de la cadena e indice de bloques a partir de los ficheros blk*.dat en disco + + + Rebuild chain state from the currently indexed blocks + Reconstruir el estado de la cadena a partir de los bloques indexados + Set database cache size in megabytes (%d to %d, default: %d) Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) @@ -3202,6 +2109,14 @@ Specify wallet file (within data directory) Especificar archivo de monedero (dentro del directorio de datos) + + The source code is available from %s. + El código fuente esta disponible desde %s. + + + Unable to bind to %s on this computer. %s is probably already running. + No se ha podido conectar con %s en este equipo. %s es posible que este todavia en ejecución. + Unsupported argument -benchmark ignored, use -debug=bench. El argumento -benchmark no es soportado y ha sido ignorado, utiliza -debug=bench @@ -3235,12 +2150,16 @@ El monedero %s se encuentra fuera del directorio de datos %s - Wallet options: - Opciones de monedero: + Wallet debugging/testing options: + Opciones de depuración/pruebas de monedero: - You need to rebuild the database using -reindex to change -txindex - Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex + Wallet needed to be rewritten: restart %s to complete + Es necesario reescribir el monedero: reiniciar %s para completar + + + Wallet options: + Opciones de monedero: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3254,10 +2173,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Ligar a las direcciones especificadas para escuchar por conexiones JSON-RPC. Usar la notación para IPv6 [host]:puerto. Esta opción se puede especificar múltiples veces (por defecto: ligar a todas las interfaces) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - No se ha podido bloquear el directorio de datos %s. Probablemente ya se está ejecutando Bitcoin Core. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada) @@ -3302,10 +2217,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d) - The transaction amount is too small to send after the fee has been deducted Monto de transacción muy pequeña luego de la deducción por comisión @@ -3314,6 +2225,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit <https://www.openssl.org/>, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usar tras BIP32 la generación de llave determinística jerárquica (HD) . Solo tiene efecto durante el primer inicio/generación del monedero + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway. @@ -3330,34 +2245,14 @@ Accept public REST requests (default: %u) Aceptar solicitudes públicas en FERIADOS (por defecto: %u) - - Activating best chain... - Activando la mejor cadena... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Intento de recuperar claves privadas de un wallet.dat corrupto - Automatically create Tor hidden service (default: %d) Automáticamente crea el servicio Tor oculto (por defecto: %d) - - Cannot resolve -whitebind address: '%s' - No se puede resolver -whitebind address: '%s' - Connect through SOCKS5 proxy Conectar usando SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i The Bitcoin Core Developers - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin Core - Error reading from database, shutting down. Error al leer la base de datos, cerrando. @@ -3370,22 +2265,6 @@ Information Información - - Initialization sanity check failed. Bitcoin Core is shutting down. - La inicialización de la verificación de validez falló. Se está apagando Bitcoin Core. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Monto inválido para -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Cantidad inválida para -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Cantidad inválida para -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Cantidad inválida para -paytxfee=<amount>: '%s' (debe ser por lo menos %s) @@ -3410,14 +2289,6 @@ RPC server options: Opciones de servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat - - - Receive and display P2P network alerts (default: %u) - Recibir y mostrar alertas de red P2P (default: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reduciendo -maxconnections de %d a %d, debido a limitaciones del sistema. @@ -3491,10 +2362,6 @@ Nombre de usuario para las conexiones JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Monedero es necesario volver a escribir: reiniciar Bitcoin Core para completar - Warning Aviso @@ -3515,10 +2382,6 @@ ZeroMQ notification options: Opciones de notificación ZeroQM: - - wallet.dat corrupt, salvage failed - wallet.dat corrupto. Ha fallado la recuperación. - Password for JSON-RPC connections Contraseña para las conexiones JSON-RPC @@ -3528,11 +2391,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque) - - This help message - Este mensaje de ayuda - - Allow DNS lookups for -addnode, -seednode and -connect Permitir búsquedas DNS para -addnode, -seednode y -connect @@ -3541,10 +2399,6 @@ Loading addresses... Cargando direcciones... - - Error loading wallet.dat: Wallet corrupted - Error al cargar wallet.dat: el monedero está dañado - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3561,10 +2415,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) No mantener transacciones en la memoria mas de <n> horas (predeterminado: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Error al leer wallet.dat! Todas las llaves se leyeron correctamente, pero los datos de transacciones o la libreta de direcciones pueden faltar o ser incorrectos. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Las comisiones (en %s/kB) menores que esto son consideradas de cero comision para la creacion de transacciones (predeterminado: %s) @@ -3589,6 +2439,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + El argumento no soportado -whitelistalwaysrelay ha sido ignorado, utiliza -whitelistrelay y/o -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s) @@ -3597,6 +2451,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Nombre de usuario y hash de la contraseña para las conexiones JSON-RPC. El campo <userpw> tiene el formato: <USERNAME>:<SALT>$<HASH>. Se incluye un script python convencional en share/rpcuser. Esta opción puede ser especificada multiples veces + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advertencia: Se están minando versiones de bloques desconocidas! Es posible que normas desconocidas estén activas + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Aviso: fichero de monedero corrupto, datos recuperados! Original %s guardado como %s en %s; si su balance de transacciones es incorrecto, debe restaurar desde una copia de seguridad. + (default: %s) (predeterminado: %s) @@ -3605,14 +2467,6 @@ Always query for peer addresses via DNS lookup (default: %u) Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u) - - Error loading wallet.dat - Error al cargar wallet.dat - - - Generate coins (default: %u) - Generar monedas (por defecto: %u) - How many blocks to check at startup (default: %u, 0 = all) Cuántos bloques comprobar al iniciar (predeterminado: %u, 0 = todos) @@ -3697,18 +2551,6 @@ Unknown network specified in -onlynet: '%s' La red especificada en -onlynet '%s' es desconocida - - Cannot resolve -bind address: '%s' - No se puede resolver la dirección de -bind: '%s' - - - Cannot resolve -externalip address: '%s' - No se puede resolver la dirección de -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Cantidad inválida para -paytxfee=<amount>: '%s' - Insufficient funds Fondos insuficientes diff --git a/src/qt/locale/bitcoin_es_419.ts b/src/qt/locale/bitcoin_es_419.ts deleted file mode 100644 index b76915662..000000000 --- a/src/qt/locale/bitcoin_es_419.ts +++ /dev/null @@ -1,173 +0,0 @@ - - - AddressBookPage - - Right-click to edit address or label - Haga clic para editar la dirección o etiqueta - - - Create a new address - Crear una nueva dirección - - - &New - &New - - - Copy the currently selected address to the system clipboard - Copia la dirección seleccionada al portapapeles del sistema - - - Choose the address to send coins to - Seleccione la Direccion a la que enviara dinero - - - Choose the address to receive coins with - Seleccione la direccion de la que recibira dinero - - - Export Address List - Exportar Lista de Direcciones - - - - AddressTableModel - - Address - Direccion - - - - AskPassphraseDialog - - Decrypt wallet - Desencriptar Monedero - - - Confirm wallet encryption - Confirmar Encriptacion de Monedero - - - Warning: The Caps Lock key is on! - Advertencia: La Tecla Caps Lock esta habilitada! - - - Wallet encrypted - Monedero ha sido encriptado - - - Wallet encryption failed - La encriptacion del monedero ha fallado - - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - Address - Direccion - - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - Address - Direccion - - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_AR.ts b/src/qt/locale/bitcoin_es_AR.ts index fb9ac895b..40ebaf885 100644 --- a/src/qt/locale/bitcoin_es_AR.ts +++ b/src/qt/locale/bitcoin_es_AR.ts @@ -25,10 +25,6 @@ C&lose C&lose - - &Copy Address - &Copiar Dirección - Delete the currently selected address from the list Borrar de la lista la dirección seleccionada @@ -45,73 +41,6 @@ &Delete &Borrar - - Choose the address to send coins to - Elegir la dirección a donde enviar las monedas (coins) - - - Choose the address to receive coins with - Elegí la dirección donde recibir las monedas - - - C&hoose - E&legir - - - Sending addresses - Direcciones de envío - - - Receiving addresses - Direcciones de recepción - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son tus direcciones Bitcoin para enviar pagos. Siempre chequeá el monto y la dirección de recepción antes de mandar monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son tus direcciones para recibir pagos. Te recomendamos que uses una dirección de recibir para cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar lista de direcciones - - - Comma separated file (*.csv) - Archivo separado por coma (*.csv) - - - Exporting Failed - Falló la exportación - - - There was an error trying to save the address list to %1. Please try again. - Hubo un error al tratar de guardar la lista de direcciones a %1. Por favor tratá de nuevo. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -131,106 +60,15 @@ Repeat new passphrase Repetí la nueva Frase de Contraseña - - Encrypt wallet - Encriptar la billetera - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación necesita tu frase de contraseña para desbloquear tu billetera. - - - Unlock wallet - Desbloquear la billetera - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación necesita tu Frase de Contraseña de billetera para desencriptar la billetera. - - - Decrypt wallet - Desencriptar la billetera - - - Change passphrase - Cambiar la Frase de Contraseña - - - Confirm wallet encryption - Confirmá la encriptación de la billetera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atención: Si encriptás tu billetera y perdés tu frase de contraseña, vas a <b>PERDER TODOS TUS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - ¿Estás seguro que querés encriptar tu billetera? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core ahora se va a cerrar para terminar el proceso de encriptación. Acordate que encriptar tu billetera no te protege completamente de que algún malware que pueda infectar tu computadora te robe tus bitcoins. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Todos los backups que hayas hecho de tu billetera tendrían que ser reemplazados por el archivo encriptado de billetera que generaste. Por razones de seguridad, los backups anteriores del archivo de billetera no encriptado se inutilizan en el momento en que empezás a usar la nueva billetera encriptada - - - Warning: The Caps Lock key is on! - Atención: Tenés puestas las mayúsculas! - - - Wallet encrypted - Billetera encriptada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Ingresá una nueva frase de contraseña para la billetera.<br/>Por favor, fijate de usar una frase de contraseña de <b>diez o más caracteres aleatorios</b>, o de <b>ocho o más palabras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Ingresá la frase de contraseña vieja y la nueva para la billetera. - - - Wallet encryption failed - Falló la encriptación de la billetera - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Falló la encriptación de la billetera por un error interno. Tu billetera no está encriptada. - - - The supplied passphrases do not match. - Las frases de contraseña no son iguales. - - - Wallet unlock failed - Falló el desbloqueo de la billetera - - - The passphrase entered for the wallet decryption was incorrect. - La frase de contraseña que ingresaste para desencriptar la billetera es incorrecta. - - - Wallet decryption failed - Falló la desencriptación de la billetera - - + BanTableModel BitcoinGUI - - ClientModel - CoinControlDialog - - (no label) - (sin etiqueta) - EditAddressDialog @@ -253,18 +91,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -273,32 +105,9 @@ ReceiveRequestDialog - - Address - Dirección - - - Label - Etiqueta - - - - RecentRequestsTableModel - - Label - Etiqueta - - - (no label) - (sin etiqueta) - SendCoinsDialog - - (no label) - (sin etiqueta) - SendCoinsEntry @@ -315,58 +124,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Etiqueta - - - - TransactionView - - Exporting Failed - Falló la exportación - - - Comma separated file (*.csv) - Archivo separado por coma (*.csv) - - - Label - Etiqueta - - - Address - Dirección - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar los datos de la pestaña actual a un archivo - - bitcoin-core diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index 742dee29d..ff0fce611 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -25,10 +25,6 @@ C&lose C y perder - - &Copy Address - &Copia dirección - Delete the currently selected address from the list Eliminar la dirección seleccionada de la lista @@ -45,57 +41,6 @@ &Delete &Borrar - - Choose the address to send coins to - Selecciona la direccion para enviar coins - - - Choose the address to receive coins with - Selecciona la dirección para recibir coins - - - Sending addresses - Dirección de envio - - - Receiving addresses - Dirección para recibir - - - Copy &Label - Copia &etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar lista de direcciones - - - Comma separated file (*.csv) - Archivos separados por coma (*.csv) - - - Exporting Failed - Exportado fallo - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -111,82 +56,6 @@ Repeat new passphrase Repite nueva contraseña - - Encrypt wallet - Codificar billetera - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación necesita la contraseña para desbloquear la billetera. - - - Unlock wallet - Desbloquea billetera - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación necesita la contraseña para decodificar la billetara. - - - Decrypt wallet - Decodificar cartera - - - Change passphrase - Cambia contraseña - - - Confirm wallet encryption - Confirma la codificación de cartera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atención: ¡Si codificas tu billetera y pierdes la contraseña perderás <b>TODOS TUS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - ¿Seguro que quieres seguir codificando la billetera? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Cualquier versión anterior que hayas realizado de tu archivo de billetera será reemplazada por el nuevo archivo de billetera encriptado. Por razones de seguridad, los respaldos anteriores de los archivos de billetera se volverán inútiles en tanto comiences a usar la nueva billetera encriptada. - - - Warning: The Caps Lock key is on! - Precaucion: Mayúsculas Activadas - - - Wallet encrypted - Billetera codificada - - - Wallet encryption failed - Falló la codificación de la billetera - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - La codificación de la billetera falló debido a un error interno. Tu billetera no ha sido codificada. - - - The supplied passphrases do not match. - Las contraseñas no coinciden. - - - Wallet unlock failed - Ha fallado el desbloqueo de la billetera - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña introducida para decodificar la billetera es incorrecta. - - - Wallet decryption failed - Ha fallado la decodificación de la billetera - - - Wallet passphrase was successfully changed. - La contraseña de billetera ha sido cambiada con éxito. - BanTableModel @@ -225,6 +94,10 @@ Quit application Salir del programa + + &About %1 + S&obre %1 + About &Qt Acerca de @@ -261,10 +134,6 @@ Open &URI... Abrir y url... - - Bitcoin Core client - cliente bitcoin core - Reindexing blocks on disk... Cargando el index de bloques... @@ -309,10 +178,6 @@ &Receive y recibir - - Show information about Bitcoin Core - Mostrar informacion sobre Bitcoin Core - &Show / Hide &Mostrar/Ocultar @@ -337,22 +202,10 @@ Tabs toolbar Barra de pestañas - - Bitcoin Core - bitcoin core - Request payments (generates QR codes and bitcoin: URIs) Pide pagos (genera codigos QR and bitcoin: URls) - - &About Bitcoin Core - &Sobre Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifica las opciones para BitCoin Core - %1 and %2 %1 y %2 @@ -394,13 +247,6 @@ La billetera esta <b>codificada</b> y actualmente <b>bloqueda</b> - - ClientModel - - Network Alert - Alerta de Red - - CoinControlDialog @@ -436,51 +282,7 @@ Priority prioridad - - Copy address - Copia dirección - - - Copy label - Copia etiqueta - - - Copy amount - Copiar Cantidad - - - Copy quantity - copiar cantidad - - - Copy fee - copiar comision - - - Copy bytes - copiar bytes - - - medium - medio - - - low - bajo - - - yes - si - - - no - no - - - (no label) - (sin etiqueta) - - + EditAddressDialog @@ -495,38 +297,6 @@ &Address &Dirección - - New receiving address - Nueva dirección para recibir - - - New sending address - Nueva dirección para enviar - - - Edit receiving address - Editar dirección de recepción - - - Edit sending address - Editar dirección de envio - - - The entered address "%1" is already in the address book. - La dirección introducida "%1" ya esta guardada en la libreta de direcciones. - - - The entered address "%1" is not a valid Bitcoin address. - La dirección introducida "%1" no es una dirección Bitcoin valida. - - - Could not unlock wallet. - No se pudo desbloquear la billetera. - - - New key generation failed. - La generación de nueva clave falló. - FreespaceChecker @@ -537,10 +307,6 @@ HelpMessageDialog - - Bitcoin Core - bitcoin core - version versión @@ -560,10 +326,6 @@ Welcome bienvenido - - Bitcoin Core - bitcoin core - Error Error @@ -679,13 +441,6 @@ Total: - - PaymentServer - - Payment acknowledged - Pago completado - - PeerTableModel @@ -700,17 +455,6 @@ N/A - - QRImageWidget - - &Save Image... - Guardar imagen... - - - &Copy Image - Copiar Imagen - - RPCConsole @@ -793,15 +537,7 @@ &Message: &mensaje - - Copy label - Copia etiqueta - - - Copy amount - Copiar Cantidad - - + ReceiveRequestDialog @@ -816,46 +552,7 @@ &Save Image... Guardar imagen... - - Address - Dirección - - - Amount - Cantidad - - - Label - Etiqueta - - - Message - Mensaje - - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - Message - Mensaje - - - Amount - Cantidad - - - (no label) - (sin etiqueta) - - + SendCoinsDialog @@ -915,43 +612,7 @@ S&end &Envía - - Confirm send coins - Confirmar el envio de monedas - - - Copy quantity - copiar cantidad - - - Copy amount - Copiar Cantidad - - - Copy fee - copiar comision - - - Copy bytes - copiar bytes - - - The amount to pay must be larger than 0. - La cantidad por pagar tiene que ser mayor 0. - - - The amount exceeds your balance. - La cantidad sobrepasa tu saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - El total sobrepasa tu saldo cuando se incluyen %1 como tasa de envio. - - - (no label) - (sin etiqueta) - - + SendCoinsEntry @@ -962,10 +623,6 @@ Pay &To: &Pagar a: - - Enter a label for this address to add it to your address book - Introduce una etiqueta a esta dirección para añadirla a tu guia - &Label: &Etiqueta: @@ -1040,41 +697,9 @@ Verify &Message &Firmar Mensaje - - Click "Sign Message" to generate signature - Click en "Firmar Mensage" para conseguir firma - - - The entered address is invalid. - La dirección introducida no es una valida. - - - Please check the address and try again. - Por favor, revise la dirección Bitcoin e inténtelo denuevo - - - Wallet unlock was cancelled. - Ha fallado el desbloqueo de la billetera - - - Message signing failed. - Firma fallida - - - Message signed. - Mensaje firmado - - - Message verified. - Mensaje comprobado - - + SplashScreen - - Bitcoin Core - bitcoin core - [testnet] [red-de-pruebas] @@ -1087,346 +712,16 @@ KB/s - - TransactionDesc - - Open until %1 - Abierto hasta %1 - - - %1/offline - %1/fuera de linea - - - %1/unconfirmed - %1/no confirmado - - - %1 confirmations - %1 confirmaciónes - - - Status - Estado - - - Date - Fecha - - - Generated - Generado - - - From - De - - - To - A - - - own address - propia dirección - - - label - etiqueta - - - Credit - Credito - - - not accepted - no aceptada - - - Debit - Debito - - - Transaction fee - Comisión transacción - - - Net amount - Cantidad total - - - Message - Mensaje - - - Comment - Comentario - - - Transaction ID - ID de Transacción - - - Transaction - Transacción - - - Amount - Cantidad - - - , has not been successfully broadcast yet - , no ha sido emitido satisfactoriamente todavía - - - unknown - desconocido - - TransactionDescDialog - - Transaction details - Detalles de transacción - This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - - TransactionTableModel - - Date - Fecha - - - Type - Tipo - - - Open until %1 - Abierto hasta %1 - - - Confirmed (%1 confirmations) - Confirmado (%1 confirmaciones) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado ! - - - Generated but not accepted - Generado pero no acceptado - - - Offline - fuera de linea - - - Label - Etiqueta - - - Unconfirmed - no confirmado - - - Received with - Recibido con - - - Received from - Recibido de - - - Sent to - Enviado a - - - Payment to yourself - Pagar a usted mismo - - - Mined - Minado - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Estado de transacción. Pasa el raton sobre este campo para ver el numero de confirmaciónes. - - - Date and time that the transaction was received. - Fecha y hora cuando se recibió la transaccion - - - Type of transaction. - Tipo de transacción. - - - Amount removed from or added to balance. - Cantidad restada o añadida al balance - - - - TransactionView - - All - Todo - - - Today - Hoy - - - This week - Esta semana - - - This month - Esta mes - - - Last month - Mes pasado - - - This year - Este año - - - Range... - Rango... - - - Received with - Recibido con - - - Sent to - Enviado a - - - To yourself - A ti mismo - - - Mined - Minado - - - Other - Otra - - - Enter address or label to search - Introduce una dirección o etiqueta para buscar - - - Min amount - Cantidad minima - - - Copy address - Copia dirección - - - Copy label - Copia etiqueta - - - Copy amount - Copiar Cantidad - - - Edit label - Edita etiqueta - - - Show transaction details - Mostrar detalles de la transacción - - - Exporting Failed - Exportado fallo - - - Comma separated file (*.csv) - Archivos separados por coma (*.csv) - - - Confirmed - Confirmado - - - Date - Fecha - - - Type - Tipo - - - Label - Etiqueta - - - Address - Dirección - - - ID - ID - - - Range: - Rango: - - - to - para - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Enviar monedas - - - - WalletView - - &Export - y exportar - - - Export the data in the current tab to a file - Exportar los datos de la pestaña actual a un archivo - - - Backup Wallet - Respaldar billetera - - - Wallet Data (*.dat) - Datos de billetera (*.dat) - - - Backup Failed - Ha fallado el respaldo - - bitcoin-core @@ -1449,6 +744,10 @@ Correr como demonio y acepta comandos + + Bitcoin Core + bitcoin core + Connect only to the specified node(s) Conecta solo al nodo especificado @@ -1466,18 +765,6 @@ Information Información - - Invalid amount for -maxtxfee=<amount>: '%s' - Cantidad inválida para -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Cantidad inválida para -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Cantidad inválida para -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Enviar informacion de seguimiento a la consola en vez del archivo debug.log @@ -1491,18 +778,9 @@ Warning Atención - - wallet.dat corrupt, salvage failed - wallet.dat corrompió, guardado fallido - Password for JSON-RPC connections Contraseña para las conexiones JSON-RPC - - - - This help message - Este mensaje de ayuda @@ -1514,30 +792,10 @@ Loading addresses... Cargando direcciónes... - - Error loading wallet.dat: Wallet corrupted - Error cargando wallet.dat: Billetera corrupta - - - Error loading wallet.dat - Error cargando wallet.dat - Invalid -proxy address: '%s' Dirección -proxy invalida: '%s' - - Cannot resolve -bind address: '%s' - No se pudo resolver la dirección fija: '%s' - - - Cannot resolve -externalip address: '%s' - No se pudo resolver la dirección ip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Cantidad inválida para -paytxfee=<amount>: '%s' - Insufficient funds Fondos insuficientes diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts index ea0664636..df189190f 100644 --- a/src/qt/locale/bitcoin_es_CO.ts +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -25,10 +25,6 @@ C&lose C&errar - - &Copy Address - &Copiar dirección - Delete the currently selected address from the list Borrar la dirección actualmente seleccionada de la lista @@ -41,74 +37,6 @@ &Delete &Borrar - - Choose the address to send coins to - Escoje la dirección para enviar monedas a - - - Choose the address to receive coins with - Escoje la dirección para recibir monedas con - - - C&hoose - E&scojer - - - Sending addresses - Enviando direcciones - - - Receiving addresses - Recibiendo direcciones - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - -Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la cantidad y la dirección de recepción antes de enviar monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son las direcciones de Bitcoin para recibir los pagos . Se recomienda el uso de una nueva dirección de recepción para cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar lista de direcciones - - - Comma separated file (*.csv) - Coma(,) archivo separado (*.csv) - - - Exporting Failed - Exportación Fallida - - - There was an error trying to save the address list to %1. Please try again. - Hubo un error intentando guardar la lista de direcciones a %1 Inténtelo otravez - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (ninguna dirección) - AskPassphraseDialog @@ -128,90 +56,6 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca Repeat new passphrase Repetir nueva contraseña - - Encrypt wallet - Billetera Encriptada - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación necesita tu contraseña de la billetera para desbloquear la billetera - - - Unlock wallet - Billetera Desbloqueada - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación necesita tu contraseña de la billetera para desencriptar la billetera. - - - Decrypt wallet - Billetera Desencriptada - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirmar encriptación de la billetera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Precaución: Si tú has encriptado tu billetera y has perdido tu contraseña, usted <b>PERDERÁ TODOS TUS BITCOINS</b> - - - Are you sure you wish to encrypt your wallet? - Estas seguro de que deseas encriptar tu billetera? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core se cerrará ahora para finalizar el proceso de encriptación. Recuerda que encriptando tu billetera no protegera por completo tus bitcoins desde robos por malware que infectan tu computadora. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE : Cualquier copias de seguridad anteriores que han hecho de su archivo cartera debe ser reemplazado por el archivo de la carpeta recién generado , encriptado . Por razones de seguridad , las copias de seguridad anteriores del archivo cartera sin cifrar se vuelven inútiles , tan pronto como empiece a utilizar el nuevo , carpeta cifrada . - - - Warning: The Caps Lock key is on! - Ojo: El bloqueo de MAYUSCULAS esta activado! - - - Wallet encrypted - Billetera encriptada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Poner la nueva contraseña a la billetera.<br/>Por favor usa una contraseña de <b>diez o más palabras aleatorias</b>, o <b>nueve o más letras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Poner la antigua contraseña y nueva contraseña a la billetera. - - - Wallet encryption failed - Encriptación de la billetera fallida - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Encriptación de la billetera fallida por un error interno. Tu billetera no ha sido encriptada. - - - Wallet unlock failed - Falló el desbloqueo de la billetera - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña tecleada de la desencriptación de la billetera ha sido incorrecta. - - - Wallet decryption failed - Encriptación de la billetera fallida - - - Wallet passphrase was successfully changed. - La contraseña de la billetera a sido cambiada exitosamente. - BanTableModel @@ -278,14 +122,6 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca Open &URI... Abrir &URL... - - Bitcoin Core client - Bitcoin Core cliente - - - Importing blocks from disk... - Importando bloques desde el disco... - Send coins to a Bitcoin address Enviando monedas a una dirección de Bitcoin @@ -322,10 +158,6 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca &Receive &Recibir - - Show information about Bitcoin Core - Mostrar información sobre Bitcoin Core - &Show / Hide &Mostrar / Ocultar @@ -346,24 +178,13 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca &Help &Ayuda - - Bitcoin Core - Bitcoin Core - Error Error - - ClientModel - CoinControlDialog - - (no label) - (ninguna dirección) - EditAddressDialog @@ -373,17 +194,9 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca HelpMessageDialog - - Bitcoin Core - Bitcoin Core - Intro - - Bitcoin Core - Bitcoin Core - Error Error @@ -398,18 +211,12 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -418,32 +225,9 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca ReceiveRequestDialog - - Address - Dirección - - - Label - Etiqueta - - - - RecentRequestsTableModel - - Label - Etiqueta - - - (no label) - (ninguna dirección) - SendCoinsDialog - - (no label) - (ninguna dirección) - SendCoinsEntry @@ -456,64 +240,22 @@ Estas son las direcciones de Bitcoin para enviar pagos . Siempre verifique la ca SplashScreen - - Bitcoin Core - Bitcoin Core - TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Etiqueta - - - - TransactionView - - Exporting Failed - Exportación Fallida - - - Comma separated file (*.csv) - Coma(,) archivo separado (*.csv) - - - Label - Etiqueta - - - Address - Dirección - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportar - - bitcoin-core + + Bitcoin Core + Bitcoin Core + Insufficient funds Fondos Insuficientes diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index b4841ca9b..3f4380840 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -21,10 +21,6 @@ C&lose &Cerrar - - &Copy Address - &Copiar dirección - Delete the currently selected address from the list Borrar de la lista la dirección seleccionada @@ -41,69 +37,6 @@ &Delete &Eliminar - - Choose the address to send coins to - Escoja la dirección para enviar monedas - - - Choose the address to receive coins with - Escoja la dirección para recibir monedas - - - C&hoose - &Escoger - - - Sending addresses - Enviando dirección - - - Receiving addresses - Recibiendo dirección - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son sus direcciones Bitcoin para enviar pagos. Compruebe siempre la cantidad y la dirección receptora antes de transferir monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son sus direcciones de Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción. - - - Copy &Label - Copiar &etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar la lista de direcciones - - - Comma separated file (*.csv) - Archivos de columnas separadas por coma (*.csv) - - - Exporting Failed - Error exportando - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -123,82 +56,6 @@ Repeat new passphrase Repita la nueva contraseña - - Encrypt wallet - Cifrar la cartera - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación requiere su contraseña para desbloquear la cartera - - - Unlock wallet - Desbloquear cartera - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación requiere su contraseña para descifrar la cartera. - - - Decrypt wallet - Descifrar la certare - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirmar cifrado de la cartera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atencion: ¡Si cifra su monedero y pierde la contraseña perderá <b>TODOS SUS BITCOINS</b>!" - - - Are you sure you wish to encrypt your wallet? - ¿Seguro que desea cifrar su monedero? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Cualquier copia de seguridad que haya realizado previamente de su archivo de monedero debe reemplazarse con el nuevo archivo de monedero cifrado. Por razones de seguridad, las copias de seguridad previas del archivo de monedero no cifradas serán inservibles en cuanto comience a usar el nuevo monedero cifrado. - - - Warning: The Caps Lock key is on! - Aviso: ¡La tecla de bloqueo de mayúsculas está activada! - - - Wallet encrypted - Monedero cifrado - - - Wallet encryption failed - Ha fallado el cifrado del monedero - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Ha fallado el cifrado del monedero debido a un error interno. El monedero no ha sido cifrado. - - - The supplied passphrases do not match. - Las contraseñas no coinciden. - - - Wallet unlock failed - Ha fallado el desbloqueo del monedero - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña introducida para descifrar el monedero es incorrecta. - - - Wallet decryption failed - Ha fallado el descifrado del monedero - - - Wallet passphrase was successfully changed. - Se ha cambiado correctamente la contraseña del monedero. - BanTableModel @@ -277,10 +134,6 @@ Open &URI... Abrir URI... - - Importing blocks from disk... - Importando bloques de disco... - Reindexing blocks on disk... Reindexando bloques en disco... @@ -361,18 +214,10 @@ Tabs toolbar Barra de pestañas - - Bitcoin Core - Núcleo de Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Solicitar pagos (genera codigo QR y URL's de Bitcoin) - - &About Bitcoin Core - &Acerca del Núcleo de Bitcoin - Show the list of used sending addresses and labels Mostrar la lista de direcciones de envío y etiquetas @@ -442,13 +287,6 @@ El monedero está <b>cifrado</b> y actualmente <b>bloqueado</b> - - ClientModel - - Network Alert - Alerta de red - - CoinControlDialog @@ -511,130 +349,6 @@ Priority Prioridad - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidad - - - Copy transaction ID - Copiar identificador de transacción - - - Lock unspent - Bloquear lo no gastado - - - Unlock unspent - Desbloquear lo no gastado - - - Copy quantity - Copiar cantidad - - - Copy fee - Copiar donación - - - Copy after fee - Copiar después de aplicar donación - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar Cambio - - - highest - lo más alto - - - higher - más alto - - - high - alto - - - medium-high - medio-alto - - - medium - medio - - - low-medium - bajo-medio - - - low - bajo - - - lower - más bajo - - - lowest - lo más bajo - - - (%1 locked) - (%1 bloqueado) - - - none - ninguno - - - yes - si - - - no - no - - - This means a fee of at least %1 per kB is required. - Esto implica que se requiere una tarifa de al menos %1 por kB - - - Can vary +/- 1 byte per input. - Puede variar +/- 1 byte por entrada. - - - Transactions with higher priority are more likely to get included into a block. - Las transacciones con alta prioridad son más propensas a ser incluidas dentro de un bloque. - - - (no label) - (sin etiqueta) - - - change from %1 (%2) - Enviar desde %1 (%2) - - - (change) - (cambio) - EditAddressDialog @@ -658,38 +372,6 @@ &Address &Dirección - - New receiving address - Nueva dirección de recepción - - - New sending address - Nueva dirección de envío - - - Edit receiving address - Editar dirección de recepción - - - Edit sending address - Editar dirección de envío - - - The entered address "%1" is already in the address book. - La dirección introducida "%1" ya está presente en la libreta de direcciones. - - - The entered address "%1" is not a valid Bitcoin address. - La dirección introducida "%1" no es una dirección Bitcoin válida. - - - Could not unlock wallet. - No se pudo desbloquear el monedero. - - - New key generation failed. - Ha fallado la generación de la nueva clave. - FreespaceChecker @@ -716,18 +398,10 @@ HelpMessageDialog - - Bitcoin Core - Núcleo de Bitcoin - version versión - - About Bitcoin Core - Acerca del Núcleo de Bitcoin - Command-line options Opciones de la línea de órdenes @@ -747,18 +421,6 @@ Welcome Bienvenido - - Welcome to Bitcoin Core. - Bienvenido al Núcleo de Bitcoin - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Al ser la primera vez que se ejecuta el programa, puede elegir dónde almacenará sus datos Bitcoin-Qt. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin-Qt va a descargar y guardar una copia de la cadena de bloques de Bitcoin. Se almacenará al menos %1GB de datos en este directorio, que irá creciendo con el tiempo. El monedero se guardará también en este directorio. - Use the default data directory Utilizar el directorio de datos predeterminado @@ -767,10 +429,6 @@ Use a custom data directory: Utilice un directorio de datos personalizado: - - Bitcoin Core - Núcleo de Bitcoin - Error Error @@ -794,10 +452,6 @@ Select payment request file Seleccione archivo de sulicitud de pago - - Select payment request file to open - Abrir archivo de solicitud de pago - OptionsDialog @@ -961,53 +615,6 @@ Su balance actual total - - PaymentServer - - URI handling - Gestión de URI - - - Invalid payment address %1 - Dirección de pago no válida %1 - - - Requested payment amount of %1 is too small (considered dust). - La cantidad del pago solicitado (%1) es demasiado pequeña (considerada polvo). - - - Payment request error - Error en petición de pago - - - Cannot start bitcoin: click-to-pay handler - No se pudo iniciar bitcoin: manejador de pago-al-clic - - - Unverified payment requests to custom payment scripts are unsupported. - No están soportadas las peticiones inseguras a scripts de pago personalizados - - - Refund from %1 - Devolución de %1 - - - Error communicating with %1: %2 - Error en la comunicación con %1: %2 - - - Bad response from server %1 - Respuesta errónea del servidor %1 - - - Payment acknowledged - Pago aceptado - - - Network request error - Error en petición de red - - PeerTableModel @@ -1030,25 +637,6 @@ N/D - - QRImageWidget - - &Save Image... - Guardar Imagen... - - - &Copy Image - Copiar imagen - - - Save QR Code - Guardar código QR - - - PNG Image (*.png) - Imágenes PNG (*.png) - - RPCConsole @@ -1131,10 +719,6 @@ Out: Fuera: - - Build date - Fecha de compilación - Debug log file Archivo de registro de depuración @@ -1218,14 +802,6 @@ Remove Eliminar - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidad - ReceiveRequestDialog @@ -1245,70 +821,7 @@ &Save Image... Guardar Imagen... - - Request payment to %1 - Solicitar pago a %1 - - - Payment information - Información de pago - - - URI - URI - - - Address - Dirección - - - Amount - Cantidad - - - Label - Etiqueta - - - Message - Mensaje - - - Resulting URI too long, try to reduce the text for label / message. - URI resultante demasiado larga. Intente reducir el texto de la etiqueta / mensaje. - - - Error encoding URI into QR Code. - Error al codificar la URI en el código QR. - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - Message - Mensaje - - - Amount - Cantidad - - - (no label) - (sin etiqueta) - - - (no message) - (Ningun mensaje) - - SendCoinsDialog @@ -1399,86 +912,6 @@ S&end &Enviar - - Confirm send coins - Confirmar el envío de monedas - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copiar cantidad - - - Copy amount - Copiar cantidad - - - Copy fee - Copiar donación - - - Copy after fee - Copiar después de aplicar donación - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar Cambio - - - or - o - - - The amount to pay must be larger than 0. - La cantidad por pagar tiene que ser mayor de 0. - - - The amount exceeds your balance. - La cantidad sobrepasa su saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - El total sobrepasa su saldo cuando se incluye la tasa de envío de %1 - - - Transaction creation failed! - ¡Ha fallado la creación de la transacción! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas ya estaba gastada o si ha usado una copia de wallet.dat y las monedas se gastaron en la copia pero no se han marcado como gastadas aqui. - - - Warning: Invalid Bitcoin address - Alerta: Dirección de Bitcoin inválida - - - (no label) - (sin etiqueta) - - - Warning: Unknown change address - Alerta: Dirección de Bitcoin inválida - - - Are you sure you want to send? - ¿Está seguro que desea enviar? - - - added as transaction fee - añadido como comisión de transacción - SendCoinsEntry @@ -1490,10 +923,6 @@ Pay &To: &Pagar a: - - Enter a label for this address to add it to your address book - Etiquete esta dirección para añadirla a la libreta - &Label: &Etiqueta: @@ -1612,69 +1041,9 @@ Reset all verify message fields Limpiar todos los campos de la verificación de mensaje - - Click "Sign Message" to generate signature - Haga clic en "Firmar mensaje" para generar la firma - - - The entered address is invalid. - La dirección introducida es inválida. - - - Please check the address and try again. - Verifique la dirección e inténtelo de nuevo. - - - The entered address does not refer to a key. - La dirección introducida no corresponde a una clave. - - - Wallet unlock was cancelled. - Se ha cancelado el desbloqueo del monedero. - - - Private key for the entered address is not available. - No se dispone de la clave privada para la dirección introducida. - - - Message signing failed. - Ha fallado la firma del mensaje. - - - Message signed. - Mensaje firmado. - - - The signature could not be decoded. - No se puede decodificar la firma. - - - Please check the signature and try again. - Compruebe la firma e inténtelo de nuevo. - - - The signature did not match the message digest. - La firma no coincide con el resumen del mensaje. - - - Message verification failed. - La verificación del mensaje ha fallado. - - - Message verified. - Mensaje verificado. - SplashScreen - - Bitcoin Core - Núcleo de Bitcoin - - - The Bitcoin Core developers - Los desarrolladores del Núcleo de Bitcoin - [testnet] [testnet] @@ -1687,402 +1056,16 @@ KB/s - - TransactionDesc - - Open until %1 - Abierto hasta %1 - - - %1/offline - %1/fuera de línea - - - %1/unconfirmed - %1/no confirmado - - - %1 confirmations - %1 confirmaciones - - - Status - Estado - - - Date - Fecha - - - Source - Fuente - - - Generated - Generado - - - From - De - - - To - Para - - - own address - dirección propia - - - label - etiqueta - - - Credit - Crédito - - - not accepted - no aceptada - - - Debit - Débito - - - Transaction fee - Comisión de transacción - - - Net amount - Cantidad neta - - - Message - Mensaje - - - Comment - Comentario - - - Transaction ID - ID - - - Merchant - Vendedor - - - 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. - Las monedas generadas deben madurar %1 bloques antes de que puedan ser gastadas. Una vez que generas este bloque, es propagado por la red para ser añadido a la cadena de bloques. Si falla el intento de meterse en la cadena, su estado cambiará a "no aceptado" y ya no se puede gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del tuyo. - - - Debug information - Información de depuración - - - Transaction - Transacción - - - Inputs - entradas - - - Amount - Cantidad - - - true - verdadero - - - false - falso - - - , has not been successfully broadcast yet - , todavía no se ha sido difundido satisfactoriamente - - - unknown - desconocido - - TransactionDescDialog - - Transaction details - Detalles de transacción - This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - - TransactionTableModel - - Date - Fecha - - - Type - Tipo - - - Open until %1 - Abierto hasta %1 - - - Confirmed (%1 confirmations) - Confirmado (%1 confirmaciones) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! - - - Generated but not accepted - Generado pero no aceptado - - - Label - Etiqueta - - - Received with - Recibido con - - - Received from - Recibidos de - - - Sent to - Enviado a - - - Payment to yourself - Pago propio - - - Mined - Minado - - - (n/a) - (nd) - - - Transaction status. Hover over this field to show number of confirmations. - Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. - - - Date and time that the transaction was received. - Fecha y hora en que se recibió la transacción. - - - Type of transaction. - Tipo de transacción. - - - Amount removed from or added to balance. - Cantidad retirada o añadida al saldo. - - - - TransactionView - - All - Todo - - - Today - Hoy - - - This week - Esta semana - - - This month - Este mes - - - Last month - Mes pasado - - - This year - Este año - - - Range... - Rango... - - - Received with - Recibido con - - - Sent to - Enviado a - - - To yourself - A usted mismo - - - Mined - Minado - - - Other - Otra - - - Enter address or label to search - Introduzca una dirección o etiqueta que buscar - - - Min amount - Cantidad mínima - - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidad - - - Copy transaction ID - Copiar identificador de transacción - - - Edit label - Editar etiqueta - - - Show transaction details - Mostrar detalles de la transacción - - - Export Transaction History - Exportar historial de transacciones - - - Exporting Failed - Error exportando - - - There was an error trying to save the transaction history to %1. - Ha habido un error al intentar guardar la transacción con %1. - - - Exporting Successful - Exportación finalizada - - - The transaction history was successfully saved to %1. - La transacción ha sido guardada en %1. - - - Comma separated file (*.csv) - Archivos de columnas separadas por coma (*.csv) - - - Confirmed - Confirmado - - - Date - Fecha - - - Type - Tipo - - - Label - Etiqueta - - - Address - Dirección - - - ID - ID - - - Range: - Rango: - - - to - para - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - No se ha cargado ningún monedero - - - - WalletModel - - Send Coins - Enviar monedas - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar a un archivo los datos de esta pestaña - - - Backup Wallet - Respaldo de monedero - - - Wallet Data (*.dat) - Datos de monedero (*.dat) - - - Backup Failed - Ha fallado el respaldo - - - There was an error trying to save the wallet data to %1. - Ha habido un error al intentar guardar los datos del monedero en %1. - - - The wallet data was successfully saved to %1. - Los datos del monedero se han guardado con éxito en %1. - - - Backup Successful - Se ha completado con éxito la copia de respaldo - - bitcoin-core @@ -2116,6 +1099,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) + + Bitcoin Core + Núcleo de Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6 @@ -2136,10 +1123,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Aviso: ¡Recuperados datos de wallet.dat corrupto! El wallet.dat original se ha guardado como wallet.{timestamp}.bak en %s; si hubiera errores en su saldo o transacciones, deberá restaurar una copia de seguridad. - <category> can be: <category> puede ser: @@ -2216,10 +1199,6 @@ Wallet %s resides outside data directory %s El monedero %s se encuentra fuera del directorio de datos %s - - You need to rebuild the database using -reindex to change -txindex - Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex - Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje) @@ -2228,26 +1207,10 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d) - - Cannot resolve -whitebind address: '%s' - No se puede resolver la dirección de -whitebind: '%s' - Information Información - - Invalid amount for -maxtxfee=<amount>: '%s' - Inválido por el monto -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Inválido por el monto -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Inválido por el monto -mintxfee=<amount>: '%s' - RPC server options: Opciones del sservidor RPC: @@ -2289,10 +1252,6 @@ Warning Aviso - - wallet.dat corrupt, salvage failed - wallet.dat corrupto. Ha fallado la recuperación. - Password for JSON-RPC connections Contraseña para las conexiones JSON-RPC @@ -2302,11 +1261,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque) - - This help message - Este mensaje de ayuda - - Allow DNS lookups for -addnode, -seednode and -connect Permitir búsquedas DNS para -addnode, -seednode y -connect @@ -2315,14 +1269,6 @@ Loading addresses... Cargando direcciones... - - Error loading wallet.dat: Wallet corrupted - Error al cargar wallet.dat: el monedero está dañado - - - Error loading wallet.dat - Error al cargar wallet.dat - Invalid -proxy address: '%s' Dirección -proxy inválida: '%s' @@ -2331,18 +1277,6 @@ Unknown network specified in -onlynet: '%s' La red especificada en -onlynet '%s' es desconocida - - Cannot resolve -bind address: '%s' - No se puede resolver la dirección de -bind: '%s' - - - Cannot resolve -externalip address: '%s' - No se puede resolver la dirección de -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Cantidad inválida para -paytxfee=<amount>: '%s' - Insufficient funds Fondos insuficientes diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index bdbfed4ec..c66a477cc 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -25,10 +25,6 @@ C&lose C&errar - - &Copy Address - &Copiar Direccón - Delete the currently selected address from the list Elimina la dirección seleccionada de la lista @@ -45,73 +41,6 @@ &Delete &Eliminar - - Choose the address to send coins to - Elige la dirección a la que enviar las monedas - - - Choose the address to receive coins with - Elige la direccón con la que recibir monedas - - - C&hoose - E&legir - - - Sending addresses - Enviando direcciones - - - Receiving addresses - Recibiendo direcciones - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son tus direcciones de Bitcoin para enviar pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son tus direcciones de Bitcoin para recibir pagos. Se recomienda usar una nueva dirección receptora para cada transacción - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar Lista de Direcciones - - - Comma separated file (*.csv) - Archivo separado por comas (*.csv) - - - Exporting Failed - Exportacón Fallida - - - There was an error trying to save the address list to %1. Please try again. - Ha ocurrido un error intentando guardar la lista de direcciones en %1. Por favor intentalo de nuevo. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repite la nueva contraseña - - Encrypt wallet - Encriptar cartera - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operacón necesita tu contraseña de la cartera para desbloquear la cartera. - - - Unlock wallet - Desbloquear cartera - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación requiere tu contraseña de la cartera para desencriptar la cartera. - - - Decrypt wallet - Desencriptar cartera - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirmar encriptación de la cartera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Advertencia: Si encriptas tu cartera y pierdes tu contraseña, <b>PERDERÁS TODOS TUS BITCOINS</B> - - - Are you sure you wish to encrypt your wallet? - Estás seguro ue deseas encriptar tu cartera? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core se cerrará ahora para finalizar el proceso de encriptación. Recuerda que encriptar tu cartera no protege completamente tus bitcoins de ser robados por malware infectando tu ordenador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Cualquier copia de seguridad anterior del archivo de tu cartera debería ser remplazado con el nuevo archivo encriptado. Por motivos de seguridad, las copias de seguridad anteriores de la cartera desencriptada quedaran inusables tan pronto como empieces a usar la nueva cartera encriptada. - - - Warning: The Caps Lock key is on! - Advertencia: La Tecla de Bloqueo de Mayusculas esta activada! - - - Wallet encrypted - Cartera encriptada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduzca la nueva contraseña de la cartera. <br/>Por favor utilice una contraseña de <b>diez o mas caracteres aleatorios</b>, o <b>ocho o mas palabras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduzca la antigua contraseña y la nueva contraseña en la cartera. - - - Wallet encryption failed - Encriptación de la cartera fallida - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - La encriptación de la cartera ha fallado debido a un error interno. Tu cartera no ha sido encriptada. - - - The supplied passphrases do not match. - Las contraseñas proporcianadas no se corresponden. - - - Wallet unlock failed - Desbloqueo de la cartera fallido - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña introducida para desencriptar la cartera es incorrecta. - - - Wallet decryption failed - Desencriptación de la cartera fallida - - - Wallet passphrase was successfully changed. - Contraseña de la cartera cambiada correctamente - BanTableModel @@ -297,14 +138,6 @@ Open &URI... Abrir &URI... - - Bitcoin Core client - Cliente Bitcoin Core - - - Importing blocks from disk... - Importando bloques desde disco... - Reindexing blocks on disk... Reindexando bloques en el disco... @@ -318,15 +151,8 @@ Crea una copia de seguridad de tu cartera en otra ubicación - - ClientModel - CoinControlDialog - - (no label) - (sin etiqueta) - EditAddressDialog @@ -338,7 +164,7 @@ &Address Dirección - + FreespaceChecker @@ -357,18 +183,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -381,32 +201,9 @@ Copy &Address &Copiar Direccón - - Address - Dirección - - - Label - Etiqueta - - - - RecentRequestsTableModel - - Label - Etiqueta - - - (no label) - (sin etiqueta) - SendCoinsDialog - - (no label) - (sin etiqueta) - SendCoinsEntry @@ -423,58 +220,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Etiqueta - - - - TransactionView - - Exporting Failed - Exportacón Fallida - - - Comma separated file (*.csv) - Archivo separado por comas (*.csv) - - - Label - Etiqueta - - - Address - Dirección - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exporta los datos de la pestaña actual a un archivo - - bitcoin-core diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index b0dfa4ab7..26432190a 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -25,10 +25,6 @@ C&lose Cerrar - - &Copy Address - &Copiar dirección - Delete the currently selected address from the list Eliminar la dirección actualmente seleccionada de la lista @@ -45,69 +41,6 @@ &Delete &Borrar - - Choose the address to send coins to - Elija una dirección a la cual enviar monedas - - - Choose the address to receive coins with - Elija la dirección con la cual recibir monedas - - - C&hoose - Elegir - - - Sending addresses - Enviando direcciones - - - Receiving addresses - Recibiendo direcciones - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son tus direcciones de Bitcoin para enviar pagos. Siempre revise la cantidad y la dirección receptora antes de enviar monedas - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son tus direcciones Bitcoin para recibir pagos. Es recomendado usar una nueva dirección receptora para cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar Lista de direcciones - - - Comma separated file (*.csv) - Archivo separado por comas (*.CSV) - - - Exporting Failed - Exportación fallida - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -123,78 +56,6 @@ Repeat new passphrase Repita la nueva contraseña - - Encrypt wallet - Encriptar cartera. - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación necesita la contraseña de su cartera para desbloquear su cartera. - - - Unlock wallet - Desbloquear cartera. - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación necesita la contraseña de su cartera para desencriptar su cartera. - - - Decrypt wallet - Desencriptar cartera - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirmar la encriptación de cartera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Advertencia: Si encripta su cartera y pierde su contraseña, <b>PERDERÁ TODOS SUS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - ¿Está seguro que desea encriptar su cartera? - - - Warning: The Caps Lock key is on! - Advertencia: ¡La tecla Bloq Mayus está activada! - - - Wallet encrypted - Cartera encriptada - - - Wallet encryption failed - La encriptación de la cartera fallo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - La encriptación de la cartera falló debido a un error interno. Su cartera no fue encriptada. - - - The supplied passphrases do not match. - Las contraseñas dadas no coinciden - - - Wallet unlock failed - El desbloqueo de la cartera falló - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña ingresada para la desencriptación de la cartera es incorrecta - - - Wallet decryption failed - La desencriptación de la cartera fallo - - - Wallet passphrase was successfully changed. - La contraseña de la cartera ha sido exitosamente cambiada. - BanTableModel @@ -273,14 +134,6 @@ Open &URI... Abrir &URL... - - Bitcoin Core client - cliente Bitcoin Core - - - Importing blocks from disk... - Importando bloques desde el disco... - Reindexing blocks on disk... Reindexando bloques en el disco... @@ -341,26 +194,10 @@ Tabs toolbar Pestañas - - Bitcoin Core - nucleo Bitcoin - - - &About Bitcoin Core - Acerca de Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modificar las opciones de configuración de Bitcoin Core - &Command-line options opciones de la &Linea de comandos - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostrar mensaje de ayuda del nucleo de Bitcoin para optener una lista con los posibles comandos de Bitcoin - Error Error @@ -398,9 +235,6 @@ La cartera esta <b>encriptada</b> y <b>bloqueada</b> actualmente - - ClientModel - CoinControlDialog @@ -447,70 +281,6 @@ Priority Prioridad - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar monto - - - Copy transaction ID - Copiar identificación de la transacción. - - - Copy quantity - Copiar cantidad - - - Copy fee - Copiar cuota - - - Copy after fee - Copiar después de cuota - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar cambio - - - low - Bajo - - - none - Ninguno - - - yes - si - - - no - no - - - (no label) - (sin etiqueta) - - - (change) - cambio - EditAddressDialog @@ -526,34 +296,6 @@ &Address &Dirección - - New receiving address - Nueva dirección de recepción - - - New sending address - Nueva dirección de envío - - - Edit receiving address - Editar dirección de recepción - - - Edit sending address - Editar dirección de envío - - - The entered address "%1" is already in the address book. - La dirección ingresada "%1" ya existe en la libreta de direcciones - - - Could not unlock wallet. - No se puede desbloquear la cartera - - - New key generation failed. - La generación de la nueva clave fallo - FreespaceChecker @@ -564,10 +306,6 @@ HelpMessageDialog - - Bitcoin Core - nucleo Bitcoin - version versión @@ -576,10 +314,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Acerca de Bitcoin Core - Command-line options opciones de la Linea de comandos @@ -595,10 +329,6 @@ Intro - - Bitcoin Core - nucleo Bitcoin - Error Error @@ -633,9 +363,6 @@ Formulario - - PaymentServer - PeerTableModel @@ -646,9 +373,6 @@ Monto - - QRImageWidget - RPCConsole @@ -682,60 +406,13 @@ An optional amount to request. Leave this empty or zero to not request a specific amount. Monto opcional a solicitar. Dejarlo vacion o en cero no solicita un monto especifico. - - Copy label - Copiar etiqueta - - - Copy amount - Copiar monto - - + ReceiveRequestDialog Copy &Address &Copiar dirección - - Address - Dirección - - - Amount - Monto - - - Label - Etiqueta - - - Message - Mensaje - - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - Message - Mensaje - - - Amount - Monto - - - (no label) - (sin etiqueta) - SendCoinsDialog @@ -787,66 +464,6 @@ Confirm the send action Confirme la acción de enviar - - Confirm send coins - Confirme para enviar monedas - - - Copy quantity - Copiar cantidad - - - Copy amount - Copiar monto - - - Copy fee - Copiar cuota - - - Copy after fee - Copiar después de cuota - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar cambio - - - or - o - - - The amount to pay must be larger than 0. - El monto a pagar debe ser mayor a 0 - - - Transaction creation failed! - ¡La creación de la transación falló! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - ¡La transación fue rechazada! Esto puede ocurrir si algunas de tus monedas en tu cartera han sido gastadas, al igual que si usas una cartera copiada y la monedas fueron gastadas en la copia pero no se marcaron como gastadas. - - - Warning: Invalid Bitcoin address - Advertencia: Dirección de Bitcoin invalida - - - (no label) - (sin etiqueta) - - - Warning: Unknown change address - Advertencia: Cambio de dirección desconocido - SendCoinsEntry @@ -858,10 +475,6 @@ Pay &To: Pagar &a: - - Enter a label for this address to add it to your address book - Ingrese una etiqueta para esta dirección para agregarlo en su libreta de direcciones. - &Label: &Etiqueta @@ -897,10 +510,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Apagando el nucleo de Bitcoin... - Do not shut down the computer until this window disappears. No apague su computadora hasta que esta ventana desaparesca. @@ -927,324 +536,30 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Los desarrolladores de Bitcoin Core - TrafficGraphWidget - - TransactionDesc - - Open until %1 - Abrir hasta %1 - - - %1/unconfirmed - %1/No confirmado - - - %1 confirmations - %1 confirmaciones - - - Status - Estado - - - Date - Fecha - - - From - De - - - To - Para - - - label - etiqueta - - - Message - Mensaje - - - Comment - Comentario - - - Transaction ID - ID - - - Transaction - Transacción - - - Amount - Monto - - - , has not been successfully broadcast yet - , no ha sido transmitido aun - - - unknown - desconocido - - TransactionDescDialog - - Transaction details - Detalles de la transacción - This pane shows a detailed description of the transaction Este panel muestras una descripción detallada de la transacción - - TransactionTableModel - - Date - Fecha - - - Type - Tipo - - - Open until %1 - Abrir hasta %1 - - - Confirmed (%1 confirmations) - Confimado (%1 confirmaciones) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloque no fue recibido por ningun nodo y probablemente no fue aceptado ! - - - Generated but not accepted - Generado pero no aprovado - - - Label - Etiqueta - - - Received with - Recibido con - - - Sent to - Enviar a - - - Payment to yourself - Pagar a si mismo - - - Mined - Minado - - - (n/a) - (n/a) - - - Date and time that the transaction was received. - Fecha y hora en que la transacción fue recibida - - - Type of transaction. - Escriba una transacción - - - Amount removed from or added to balance. - Cantidad removida del saldo o agregada - - - - TransactionView - - All - Todo - - - Today - Hoy - - - This week - Esta semana - - - This month - Este mes - - - Last month - El mes pasado - - - This year - Este año - - - Received with - Recibido con - - - Sent to - Enviar a - - - To yourself - Para ti mismo - - - Mined - Minado - - - Other - Otro - - - Enter address or label to search - Ingrese dirección o capa a buscar - - - Min amount - Monto minimo - - - Copy address - Copiar dirección - - - Copy label - Copiar capa - - - Copy amount - copiar monto - - - Copy transaction ID - Copiar identificación de la transacción. - - - Edit label - Editar capa - - - Export Transaction History - Exportar el historial de transacción - - - Exporting Failed - Exportación fallida - - - There was an error trying to save the transaction history to %1. - Ocurrio un error intentando guardar el historial de transaciones a %1 - - - Exporting Successful - Exportacion satisfactoria - - - The transaction history was successfully saved to %1. - el historial de transaciones ha sido guardado exitosamente en %1 - - - Comma separated file (*.csv) - Arhchivo separado por comas (*.CSV) - - - Confirmed - Confirmado - - - Date - Fecha - - - Type - Tipo - - - Label - Etiqueta - - - Address - Domicilio - - - ID - ID - - - to - Para - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - No se há cargado la cartera. - - - - WalletModel - - Send Coins - Mandar monedas - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar la información en la tabla actual a un archivo - - - There was an error trying to save the wallet data to %1. - Ocurrio un error tratando de guardar la información de la cartera %1 - - - The wallet data was successfully saved to %1. - La información de la cartera fué guardada exitosamente a %1 - - bitcoin-core Options: Opciones: + + Bitcoin Core + nucleo Bitcoin + <category> can be: <categoria> puede ser: diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 32d433d6e..8d361620d 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -25,10 +25,6 @@ C&lose Cerrar - - &Copy Address - Copiar Dirección - &Export Exportar @@ -37,50 +33,6 @@ &Delete &Borrar - - Choose the address to send coins to - Elige una dirección donde enviar monedas a - - - Sending addresses - Enviando direcciones - - - Receiving addresses - Recibiendo direcciones - - - - &Edit - Editar - - - Export Address List - Exportar Lista de Direcciones - - - Comma separated file (*.csv) - Archivos separados por coma (*.csv) - - - Exporting Failed - Exportación fallida - - - - AddressTableModel - - Label - Etiqueta - - - Address - Direccion - - - (no label) - (Sin etiqueta) - AskPassphraseDialog @@ -96,71 +48,7 @@ Repeat new passphrase Repetir nueva contraseña - - Encrypt wallet - Monedero cifrado - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operacion necesita la contraseña del monedero para desbloquear el mismo - - - Unlock wallet - Monedero destrabado - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operacion necesita la contraseña del monedero para descifrar el mismo - - - Decrypt wallet - Monedero descifrado - - - Change passphrase - Cambiar contraseña - - - Confirm wallet encryption - Confirme el cifrado del monedero - - - Are you sure you wish to encrypt your wallet? - Estas seguro que deseas encriptar tu billetera? - - - Warning: The Caps Lock key is on! - Atención: la tecla Mayusculas esta activa! - - - Wallet encrypted - Monedero cifrado - - - Wallet encryption failed - Fallo en el cifrado del monedero - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Fallo en el cifrado del monedero a causa de un error interno. Su monedero no esta cifrado - - - The supplied passphrases do not match. - Las contraseñas suministradas no coinciden. - - - Wallet unlock failed - Fallo en el desbloqueo del mondero - - - The passphrase entered for the wallet decryption was incorrect. - La contraseña introducida para el descifrado del monedero es incorrecta. - - - Wallet decryption failed - Fallo en el descifrado del monedero - - + BanTableModel @@ -302,9 +190,6 @@ El Monedero esta <b>cifrado</b> y actualmente <b>bloqueado</b> - - ClientModel - CoinControlDialog @@ -339,11 +224,7 @@ Priority Prioridad - - (no label) - (Sin etiqueta) - - + EditAddressDialog @@ -358,34 +239,6 @@ &Address &Direccion - - New receiving address - Nueva dirección de recepción - - - New sending address - Nueva dirección de envío - - - Edit receiving address - Editar dirección de recepcion - - - Edit sending address - Editar dirección de envío - - - The entered address "%1" is already in the address book. - La dirección introducida "%1" ya está en la libreta de direcciones. - - - Could not unlock wallet. - No se puede abrir el monedero. - - - New key generation failed. - Fallo en la nueva clave generada. - FreespaceChecker @@ -421,18 +274,12 @@ Formulario - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -453,29 +300,6 @@ Copy &Address Copiar Dirección - - Address - Direccion - - - Label - Etiqueta - - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - (no label) - (Sin etiqueta) - SendCoinsDialog @@ -515,18 +339,6 @@ Confirm the send action Confirmar el envío - - Confirm send coins - Confirmar el envio de monedas - - - The amount to pay must be larger than 0. - La cantidad a pagar debe ser mayor que 0. - - - (no label) - (Sin etiqueta) - SendCoinsEntry @@ -538,10 +350,6 @@ Pay &To: Pagar &A: - - Enter a label for this address to add it to your address book - Introduzca una etiqueta para esta dirección para añadirla a su libreta de direcciones - &Label: &Etiqueta: @@ -591,90 +399,12 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Abrir hasta %1 - - - Date - Fecha - - - Transaction - Transaccion - - - unknown - desconocido - - TransactionDescDialog - - TransactionTableModel - - Date - Fecha - - - Open until %1 - Abrir hasta %1 - - - Label - Etiqueta - - - - TransactionView - - Exporting Failed - Exportación fallida - - - Comma separated file (*.csv) - Archivos separados por coma (*.csv) - - - Confirmed - Confirmado - - - Date - Fecha - - - Label - Etiqueta - - - Address - Direccion - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Enviar monedas - - - - WalletView - - &Export - Exportar - - bitcoin-core diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts index 582e72884..432adc57e 100644 --- a/src/qt/locale/bitcoin_es_VE.ts +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -22,8 +22,8 @@ &Copiar - &Copy Address - &Copiar Dirección + C&lose + C&errar Delete the currently selected address from the list @@ -41,69 +41,6 @@ &Delete &Borrar - - Choose the address to send coins to - Elige la dirección para enviar monedas - - - Choose the address to receive coins with - Elige la dirección para recibir monedas - - - Sending addresses - Envío de direcciones - - - Receiving addresses - Recepción de direcciones - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son tus direcciones Bitcoin para realizar pagos. Siempre checa el monto y la dirección de recepción antes de enviar monedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son tus direcciones Bitcoin para recibir pagos. Es recomendable usar una nueva dirección para cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Editar - - - Export Address List - Exportar lista de direcciones - - - Comma separated file (*.csv) - Archivo separado por comas (*.csv) - - - Exporting Failed - Exportación fallida - - - There was an error trying to save the address list to %1. Please try again. - Hubo un error intentando guardar la lista de direcciones al %1. Por favor intente nuevamente. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sin etiqueta) - AskPassphraseDialog @@ -123,86 +60,6 @@ Repeat new passphrase Repetir nueva frase de contraseña - - Encrypt wallet - Encriptar billetera - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación necesita tu frase de contraseña de la billetera para desbloquearla. - - - Unlock wallet - Desbloquear billetera - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operacción necesita tu frase de contraseña para desepcriptar la billetera - - - Decrypt wallet - Desencriptar billetera - - - Change passphrase - Cambiar frase secreta - - - Confirm wallet encryption - Confirmar encriptación de billetera - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Aviso: Si encriptas tu billetera y pierdes tu frase secreta, ¡PERDERÁS TODOS TUS BITCOINS! - - - Are you sure you wish to encrypt your wallet? - ¿Está seguro que desea encriptar su billetera? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Algunas copias de seguridad que hayas hecho de tu archivo de billetera deberían ser reemplazadas con la billetera encriptada generada recientemente. Por razones de seguridad, las copias de seguridad previas del archivo de billetera sin cifrar serán inútiles tan pronto uses la nueva billetera encriptada. - - - Warning: The Caps Lock key is on! - Aviso: El bloqueo de mayúsculas está activado. - - - Wallet encrypted - Billetera encriptada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduce la nueva frase secreta a la billetera. Por favor use una frase secreta de diez o más caracteres aleatorios, u ocho o más palabras. - - - Wallet encryption failed - Encriptación de billetera fallida - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Encriptación de billetera fallida debido a un error interno. Tu billetera no fue encriptada. - - - The supplied passphrases do not match. - Las frases secretas introducidas no concuerdan. - - - Wallet unlock failed - Desbloqueo de billetera fallido - - - The passphrase entered for the wallet decryption was incorrect. - La frase secreta introducida para la desencriptación de la billetera fué incorrecta. - - - Wallet decryption failed - Desencriptación de billetera fallida - - - Wallet passphrase was successfully changed. - La frase secreta de la billetera fué cambiada exitosamente. - BanTableModel @@ -233,22 +90,22 @@ Browse transaction history Buscar historial de transacciones + + E&xit + S&alir + Quit application Quitar aplicación + + &Options... + &Opciones... + &Receiving addresses... Recepción de direcciones - - Bitcoin Core client - Cliente Bitcoin Core - - - Importing blocks from disk... - Importando bloques desde el disco... - Reindexing blocks on disk... Reindexando bloques en el disco... @@ -285,10 +142,6 @@ &Receive &Recibir - - Show information about Bitcoin Core - Mostrar información acerca de Bitcoin Core - &Show / Hide &Mostar / Ocultar @@ -317,14 +170,6 @@ &Settings &Configuración - - Bitcoin Core - Bitcoin Core - - - &About Bitcoin Core - Acerca de Bitcoin Core - &Command-line options Opciones de línea de comandos @@ -382,13 +227,6 @@ La billetera está encriptada y bloqueada recientemente - - ClientModel - - Network Alert - Alerta de red - - CoinControlDialog @@ -463,134 +301,6 @@ Priority Prioridad - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar monto - - - Copy transaction ID - Copiar ID de la transacción - - - Lock unspent - Bloqueo no gastado - - - Unlock unspent - Desbloqueo no gastado - - - Copy quantity - Copiar cantidad - - - Copy fee - Copiar comisión - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy dust - Copiar dust - - - Copy change - Copiar cambio - - - highest - Más alto - - - higher - superior - - - high - alto - - - medium-high - medio-alto - - - medium - medio - - - low-medium - bajo-medio - - - low - bajo - - - lower - inferior - - - lowest - más bajo - - - (%1 locked) - (%1 bloqueado) - - - none - ninguno - - - Can vary +/- %1 satoshi(s) per input. - Puede variar +/- %1 satoshi(s) por entrada. - - - yes - si - - - no - no - - - This means a fee of at least %1 per kB is required. - Esto significa que se requiere al menos de una comisión de %1 por kB - - - Can vary +/- 1 byte per input. - Puede variar +/- 1 byte por entrada. - - - Transactions with higher priority are more likely to get included into a block. - Transacciones con mayor prioridad son más probables de ser incluidas en un bloque. - - - (no label) - (sin etiqueta) - - - change from %1 (%2) - Cambio desde %1 (%2) - - - (change) - (cambio) - EditAddressDialog @@ -614,38 +324,6 @@ &Address &Dirección - - New receiving address - Nueva dirección de recibo - - - New sending address - Nueva dirección de envío - - - Edit receiving address - Editar dirección de envío - - - Edit sending address - Editar dirección de envío - - - The entered address "%1" is already in the address book. - La dirección introducida "%1" ya está en el libro de direcciones. - - - The entered address "%1" is not a valid Bitcoin address. - La dirección introducida "%1" no es una dirección Bitcoin válida. - - - Could not unlock wallet. - No se pudo desbloquear la billetera. - - - New key generation failed. - Creación de la nueva llave fallida - FreespaceChecker @@ -672,10 +350,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versión @@ -684,10 +358,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Acerca de Bitcoin Core - Command-line options Opciones de línea de comandos @@ -703,10 +373,6 @@ Intro - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core descargará y almacenará una copia de la cadena de bloques Bitcoin. Al menos %1GB de datos serán almacenados en este directorio, y crecerá con el tiempo. La billetera será también almacenada en este directorio. - Use the default data directory Usar el directorio de datos por defecto @@ -715,10 +381,6 @@ Use a custom data directory: Usa un directorio de datos personalizado: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Error: Directorio de datos especificado "%1" no puede ser creado. @@ -746,10 +408,6 @@ Select payment request file Seleccionar archivo de solicitud de pago - - Select payment request file to open - Seleccionar archivo de solicitud de pago para abrir - OptionsDialog @@ -761,10 +419,18 @@ &Main &Main + + &Network + &Red + W&allet Billetera + + Expert + Experto + none ninguno @@ -772,9 +438,14 @@ OverviewPage - - - PaymentServer + + Available: + Disponible: + + + Pending: + Pendiente: + PeerTableModel @@ -786,15 +457,20 @@ Monto - - QRImageWidget - RPCConsole &Information Información + + In: + Entrada: + + + Out: + Salida: + ReceiveCoinsDialog @@ -807,51 +483,16 @@ &Etiqueta: - Copy label - Copiar etiqueta + Show + Mostrar - - Copy amount - Copiar monto - - + ReceiveRequestDialog Copy &Address &Copiar Dirección - - Address - Dirección - - - Amount - Monto - - - Label - Etiqueta - - - - RecentRequestsTableModel - - Date - Fecha - - - Label - Etiqueta - - - Amount - Monto - - - (no label) - (sin etiqueta) - SendCoinsDialog @@ -883,38 +524,6 @@ Dust: Polvo: - - Copy quantity - Copiar cantidad - - - Copy amount - Copiar monto - - - Copy fee - Copiar comisión - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridad - - - Copy change - Copiar cambio - - - (no label) - (sin etiqueta) - - - Copy dust - Copiar dust - SendCoinsEntry @@ -935,122 +544,16 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - TrafficGraphWidget - - TransactionDesc - - Date - Fecha - - - Transaction - Transacción - - - Amount - Monto - - TransactionDescDialog - - TransactionTableModel - - Date - Fecha - - - Label - Etiqueta - - - - TransactionView - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar monto - - - Copy transaction ID - Copiar ID de la transacción - - - Exporting Failed - Exportación fallida - - - Comma separated file (*.csv) - Archivo separado por comas (*.csv) - - - Confirmed - Confirmado - - - Date - Fecha - - - Label - Etiqueta - - - Address - Dirección - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar los datos en la pestaña actual a un archivo - - - Backup Failed - Copia de seguridad fallida - - - There was an error trying to save the wallet data to %1. - Hubo un error intentando guardar los datos de la billetera al %1 - - - The wallet data was successfully saved to %1. - Los datos de la billetera fueron guardados exitosamente al %1 - - - Backup Successful - Copia de seguridad completada - - bitcoin-core @@ -1077,6 +580,10 @@ Run in the background as a daemon and accept commands Correr en segundo plano como daemon y aceptar comandos + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Enlazar dirección dada y siempre escuchar en ella. Usar [host]:port notación para IPv6 @@ -1101,10 +608,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta es una compilación de prueba pre-lanzamiento - use bajo su propio riesgo - no utilizar para aplicaciones de minería o mercantes - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Deshabilitar para enlezar a %s en esta computadora. Bitcoin Core probablemente ya está ejecutándose. - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Aviso: ¡La red no parece estar totalmente de acuerdo! Algunos mineros parecen estar teniendo inconvenientes. @@ -1113,10 +616,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Aviso: ¡No parecen estar totalmente de acuerdo con nuestros compañeros! Puede que tengas que actualizar, u otros nodos tengan que actualizarce. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Aviso: wallet.dat está corrupto, ¡datos salvados! wallet.dat original guardado como wallet.{timestamp}.bak en %s; si tus transacciones o balance está incorrecto deberías restaurarlo desde una copia de seguridad. - Information Información diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 089f01035..e861d4e47 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -21,10 +21,6 @@ C&lose S&ulge - - &Copy Address - &Kopeeri Aadress - Delete the currently selected address from the list Kustuta märgistatud aadress loetelust @@ -41,45 +37,6 @@ &Delete &Kustuta - - C&hoose - V&ali - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Need on sinu Bitcoini aadressid maksete saatmiseks. Müntide saatmisel kontrolli alati summat ning saaja aadressi. - - - Copy &Label - &Märgise kopeerimine - - - &Edit - &Muuda - - - Comma separated file (*.csv) - Komaeraldatud fail (*.csv) - - - Exporting Failed - Eksportimine Ebaõnnestus - - - - AddressTableModel - - Label - Silt - - - Address - Aadress - - - (no label) - (silti pole) - AskPassphraseDialog @@ -99,82 +56,6 @@ Repeat new passphrase Korda salafraasi - - Encrypt wallet - Krüpteeri rahakott - - - This operation needs your wallet passphrase to unlock the wallet. - See toiming nõuab sinu rahakoti salafraasi. - - - Unlock wallet - Tee rahakott lukust lahti. - - - This operation needs your wallet passphrase to decrypt the wallet. - See toiming nõuab sinu rahakoti salafraasi. - - - Decrypt wallet - Dekrüpteeri rahakott. - - - Change passphrase - Muuda salafraasi - - - Confirm wallet encryption - Kinnita rahakoti krüpteering - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Hoiatus: Kui sa kaotad oma, rahakoti krüpteerimisel kasutatud, salafraasi, siis <b>KAOTAD KA KÕIK OMA BITCOINID</b>! - - - Are you sure you wish to encrypt your wallet? - Kas soovid oma rahakoti krüpteerida? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - TÄHTIS: Kõik varasemad rahakoti varundfailid tuleks üle kirjutada äsja loodud krüpteeritud rahakoti failiga. Turvakaalutlustel tühistatakse krüpteerimata rahakoti failid alates uue, krüpteeritud rahakoti, kasutusele võtust. - - - Warning: The Caps Lock key is on! - Hoiatus: Caps Lock on sisse lülitatud! - - - Wallet encrypted - Rahakott krüpteeritud - - - Wallet encryption failed - Tõrge rahakoti krüpteerimisel - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Rahakoti krüpteering ebaõnnestus tõrke tõttu. Sinu rahakotti ei krüpteeritud. - - - The supplied passphrases do not match. - Salafraasid ei kattu. - - - Wallet unlock failed - Rahakoti avamine ebaõnnestus - - - The passphrase entered for the wallet decryption was incorrect. - Rahakoti salafraas ei ole õige. - - - Wallet decryption failed - Rahakoti dekrüpteerimine ei õnnestunud - - - Wallet passphrase was successfully changed. - Rahakoti salafraasi muutmine õnnestus. - BanTableModel @@ -241,10 +122,6 @@ Open &URI... Ava &URI... - - Importing blocks from disk... - Impordi blokid kettalt... - Reindexing blocks on disk... Kettal olevate blokkide re-indekseerimine... @@ -325,14 +202,6 @@ Tabs toolbar Vahelehe tööriistariba - - Bitcoin Core - Bitcoini tuumik - - - &About Bitcoin Core - Kirjeldus Bitcoini Tuumast - &Command-line options Käsurea valikud @@ -436,13 +305,6 @@ Rahakott on <b>krüpteeritud</b> ning hetkel <b>suletud</b> - - ClientModel - - Network Alert - Võrgu Häire - - CoinControlDialog @@ -469,70 +331,6 @@ Confirmed Kinnitatud - - Copy address - Aadressi kopeerimine - - - Copy label - Märgise kopeerimine - - - Copy amount - Kopeeri summa - - - Copy transaction ID - Kopeeri tehingu ID - - - Copy fee - Kopeeri tasu - - - highest - kõrgeim - - - higher - kõrgem - - - high - kõrge - - - medium - keskmine - - - low - madal - - - lower - madalam - - - lowest - madalaim - - - (%1 locked) - (%1 lukustatud) - - - yes - jah - - - no - ei - - - (no label) - (silti pole) - EditAddressDialog @@ -548,38 +346,6 @@ &Address &Aadress - - New receiving address - Uus sissetulev aadress - - - New sending address - Uus väljaminev aadress - - - Edit receiving address - Sissetulevate aadresside muutmine - - - Edit sending address - Väljaminevate aadresside muutmine - - - The entered address "%1" is already in the address book. - Selline aadress on juba olemas: "%1" - - - The entered address "%1" is not a valid Bitcoin address. - Sisestatud aadress "%1" ei ole Bitcoinis kehtiv. - - - Could not unlock wallet. - Rahakotti ei avatud - - - New key generation failed. - Tõrge uue võtme loomisel. - FreespaceChecker @@ -590,18 +356,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoini tuumik - version versioon - - About Bitcoin Core - Kirjeldus Bitcoini Tuumast - Command-line options Käsurea valikud @@ -621,10 +379,6 @@ Welcome Teretulemast - - Bitcoin Core - Bitcoini tuumik - Error Tõrge @@ -771,17 +525,6 @@ Hiljutised tehingud - - PaymentServer - - URI handling - URI käsitsemine - - - Cannot start bitcoin: click-to-pay handler - Bitcoin ei käivitu: vajuta-maksa toiming - - PeerTableModel @@ -796,13 +539,6 @@ N/A - - QRImageWidget - - Save QR Code - Salvesta QR kood - - RPCConsole @@ -885,10 +621,6 @@ &Console &Konsool - - Build date - Valmistusaeg - Debug log file Debugimise logifail @@ -944,18 +676,6 @@ Remove Eemalda - - Copy label - Märgise kopeerimine - - - Copy message - Kopeeri sõnum - - - Copy amount - Kopeeri summa - ReceiveRequestDialog @@ -963,62 +683,7 @@ Copy &Address &Kopeeri Aadress - - Address - Aadress - - - Amount - Kogus - - - Label - Silt - - - Message - Sõnum - - - Resulting URI too long, try to reduce the text for label / message. - Tulemuseks on liiga pikk URL, püüa lühendada märgise/teate teksti. - - - Error encoding URI into QR Code. - Tõrge URI'st QR koodi loomisel - - - - RecentRequestsTableModel - - Date - Kuupäev - - - Label - Silt - - - Message - Sõnum - - - Amount - Kogus - - - (no label) - (silti pole) - - - (no message) - (sõnum puudub) - - - (no amount) - (summa puudub) - - + SendCoinsDialog @@ -1089,39 +754,7 @@ S&end S&aada - - Confirm send coins - Müntide saatmise kinnitamine - - - Copy amount - Kopeeri summa - - - Copy fee - Kopeeri tasu - - - or - või - - - The amount to pay must be larger than 0. - Makstav summa peab olema suurem kui 0. - - - The amount exceeds your balance. - Summa ületab jäägi. - - - The total exceeds your balance when the %1 transaction fee is included. - Summa koos tehingu tasuga %1 ületab sinu jääki. - - - (no label) - (silti pole) - - + SendCoinsEntry @@ -1132,10 +765,6 @@ Pay &To: Maksa &: - - Enter a label for this address to add it to your address book - Aadressiraamatusse sisestamiseks märgista aadress - &Label: &Märgis @@ -1230,69 +859,9 @@ Reset all verify message fields Tühjenda kõik sõnumi kinnitamise väljad - - Click "Sign Message" to generate signature - Signatuuri genereerimiseks vajuta "Allkirjasta Sõnum" - - - The entered address is invalid. - Sisestatud aadress ei kehti. - - - Please check the address and try again. - Palun kontrolli aadressi ning proovi uuesti. - - - The entered address does not refer to a key. - Sisestatud aadress ei viita võtmele. - - - Wallet unlock was cancelled. - Rahakoti avamine katkestati. - - - Private key for the entered address is not available. - Sisestatud aadressi privaatvõti ei ole saadaval. - - - Message signing failed. - Sõnumi signeerimine ebaõnnestus. - - - Message signed. - Sõnum signeeritud. - - - The signature could not be decoded. - Signatuuri ei õnnestunud dekodeerida. - - - Please check the signature and try again. - Palun kontrolli signatuuri ning proovi uuesti. - - - The signature did not match the message digest. - Signatuur ei kattunud sõnumi kokkuvõttega. - - - Message verification failed. - Sõnumi kontroll ebaõnnestus. - - - Message verified. - Sõnum kontrollitud. - SplashScreen - - Bitcoin Core - Bitcoini tuumik - - - The Bitcoin Core developers - Bitcoini Tuuma arendajad - [testnet] [testnet] @@ -1305,366 +874,16 @@ KB/s - - TransactionDesc - - Open until %1 - Avatud kuni %1 - - - %1/offline - %1/offline'is - - - %1/unconfirmed - %1/kinnitamata - - - %1 confirmations - %1 kinnitust - - - Status - Staatus - - - Date - Kuupäev - - - Source - Allikas - - - Generated - Genereeritud - - - From - Saatja - - - To - Saaja - - - own address - oma aadress - - - label - märgis - - - Credit - Krediit - - - not accepted - mitte aktsepteeritud - - - Debit - Deebet - - - Transaction fee - Tehingu tasu - - - Net amount - Neto summa - - - Message - Sõnum - - - Comment - Kommentaar - - - Transaction ID - Tehingu ID - - - Debug information - Debug'imise info - - - Transaction - Tehing - - - Inputs - Sisendid - - - Amount - Kogus - - - true - õige - - - false - vale - - - , has not been successfully broadcast yet - , veel esitlemata - - - unknown - tundmatu - - TransactionDescDialog - - Transaction details - Tehingu üksikasjad - This pane shows a detailed description of the transaction Paan kuvab tehingu detailid - - TransactionTableModel - - Date - Kuupäev - - - Type - Tüüp - - - Open until %1 - Avatud kuni %1 - - - Confirmed (%1 confirmations) - Kinnitatud (%1 kinnitust) - - - This block was not received by any other nodes and will probably not be accepted! - Antud klotsi pole saanud ükski osapool ning tõenäoliselt seda ei aktsepteerita! - - - Generated but not accepted - Loodud, kuid aktsepteerimata - - - Label - Silt - - - Received with - Saadud koos - - - Received from - Kellelt saadud - - - Sent to - Saadetud - - - Payment to yourself - Makse iseendale - - - Mined - Mine'itud - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Tehingu staatus. Kinnituste arvu kuvamiseks liigu hiire noolega selle peale. - - - Date and time that the transaction was received. - Tehingu saamise kuupäev ning kellaaeg. - - - Type of transaction. - Tehingu tüüp. - - - Amount removed from or added to balance. - Jäägile lisatud või eemaldatud summa. - - - - TransactionView - - All - Kõik - - - Today - Täna - - - This week - Jooksev nädal - - - This month - Jooksev kuu - - - Last month - Eelmine kuu - - - This year - Jooksev aasta - - - Range... - Ulatus... - - - Received with - Saadud koos - - - Sent to - Saadetud - - - To yourself - Iseendale - - - Mined - Mine'itud - - - Other - Muu - - - Enter address or label to search - Otsimiseks sisesta märgis või aadress - - - Min amount - Vähim summa - - - Copy address - Aadressi kopeerimine - - - Copy label - Märgise kopeerimine - - - Copy amount - Kopeeri summa - - - Copy transaction ID - Kopeeri tehingu ID - - - Edit label - Märgise muutmine - - - Show transaction details - Kuva tehingu detailid - - - Exporting Failed - Eksportimine Ebaõnnestus - - - Comma separated file (*.csv) - Komaeraldatud fail (*.csv) - - - Confirmed - Kinnitatud - - - Date - Kuupäev - - - Type - Tüüp - - - Label - Silt - - - Address - Aadress - - - ID - ID - - - Range: - Ulatus: - - - to - saaja - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Müntide saatmine - - - - WalletView - - &Export - &Ekspordi - - - Export the data in the current tab to a file - Ekspordi kuvatava vahelehe sisu faili - - - Backup Wallet - Varundatud Rahakott - - - Wallet Data (*.dat) - Rahakoti andmed (*.dat) - - - Backup Failed - Varundamine nurjus - - - Backup Successful - Varundamine õnnestus - - bitcoin-core @@ -1695,6 +914,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Luba välisühendusi (vaikeväärtus: 1 kui puudub -proxy või -connect) + + Bitcoin Core + Bitcoini tuumik + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Määratud aadressiga sidumine ning sellelt kuulamine. IPv6 jaoks kasuta vormingut [host]:port @@ -1707,10 +930,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications See on test-versioon - kasutamine omal riisikol - ära kasuta mining'uks ega kaupmeeste programmides - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Hoiatus: toimus wallet.dat faili andmete päästmine! Originaal wallet.dat nimetati kaustas %s ümber wallet.{ajatempel}.bak'iks, jäägi või tehingute ebakõlade puhul tuleks teha backup'ist taastamine. - Block creation options: Blokeeri loomise valikud: @@ -1767,26 +986,10 @@ (default: %u) (vaikimisi: %u) - - Cannot resolve -whitebind address: '%s' - Tundmatu -whitebind aadress: '%s' - Information Informatsioon - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<amount> jaoks vigane kogus: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - -minrelaytxfee=<amount> jaoks vigane kogus: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - -mintxfee=<amount> jaoks vigane kogus: '%s' - RPC server options: RPC serveri valikud: @@ -1823,10 +1026,6 @@ Warning Hoiatus - - wallet.dat corrupt, salvage failed - wallet.dat fail on katki, päästmine ebaõnnestus - Password for JSON-RPC connections JSON-RPC ühenduste salasõna @@ -1835,10 +1034,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Käivita käsklus, kui parim plokk muutub (käskluse %s asendatakse ploki hash'iga) - - This help message - Käesolev abitekst - Allow DNS lookups for -addnode, -seednode and -connect -addnode, -seednode ja -connect tohivad kasutada DNS lookup'i @@ -1847,18 +1042,10 @@ Loading addresses... Aadresside laadimine... - - Error loading wallet.dat: Wallet corrupted - Viga wallet.dat käivitamisel. Vigane rahakkott - (default: %s) (vaikimisi: %s) - - Error loading wallet.dat - Viga wallet.dat käivitamisel - Invalid -proxy address: '%s' Vigane -proxi aadress: '%s' @@ -1867,18 +1054,6 @@ Unknown network specified in -onlynet: '%s' Kirjeldatud tundmatu võrgustik -onlynet'is: '%s' - - Cannot resolve -bind address: '%s' - Tundmatu -bind aadress: '%s' - - - Cannot resolve -externalip address: '%s' - Tundmatu -externalip aadress: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - -paytxfee=<amount> jaoks vigane kogus: '%s' - Insufficient funds Liiga suur summa diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index ca6b6489d..cbe246f44 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -25,10 +25,6 @@ C&lose &Itxi - - &Copy Address - &Kopiatu helbidea - Delete the currently selected address from the list Ezabatu aukeratutako helbideak listatik @@ -45,73 +41,6 @@ &Delete &Ezabatu - - Choose the address to send coins to - Aukeratu helbidea txanponak bidaltzeko - - - Choose the address to receive coins with - Aukeratu helbidea txanponak jasotzeko - - - C&hoose - &Aukeratu - - - Sending addresses - Helbideak bidaltzen - - - Receiving addresses - Helbideak jasotzen - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Hauek dira zure Bitcoin helbideak dirua bidaltzeko. Beti egiaztatu diru-kantitatea eta jasotzeko helbidea bidali baino lehen. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Hauek dira zure Bitcoin helbideak dirua jasotzeko. Gomendagarria da erabiltzea jasotzeko helbide berri bat operazio bakoitzeko. - - - Copy &Label - Kopiatu &Etiketa - - - &Edit - &Editatu - - - Export Address List - Esportatu helbide lista - - - Comma separated file (*.csv) - Komaz bereizitako artxiboa (*.csv) - - - Exporting Failed - Esportatua okerra - - - There was an error trying to save the address list to %1. Please try again. - Errakuntza bat egon da gordetzen %1 helbide listan. Mesedez, saiatu berriro. - - - - AddressTableModel - - Label - Etiketa - - - Address - Helbidea - - - (no label) - (etiketarik ez) - AskPassphraseDialog @@ -131,79 +60,7 @@ Repeat new passphrase Errepikatu pasahitz berria - - Encrypt wallet - Enkriptatu zorroa - - - This operation needs your wallet passphrase to unlock the wallet. - Eragiketa honek zorroaren pasahitza behar du zorroa desblokeatzeko. - - - Unlock wallet - Desblokeatu zorroa - - - This operation needs your wallet passphrase to decrypt the wallet. - Eragiketa honek zure zorroaren pasahitza behar du, zorroa desenkriptatzeko. - - - Decrypt wallet - Desenkriptatu zorroa - - - Change passphrase - Aldatu pasahitza - - - Confirm wallet encryption - Berretsi zorroaren enkriptazioa - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Abisua: Zuk enkriptatzen baduzu zure diruzorroa eta zure pasahitza galtzen baduzu, <b>BITCOIN GUZTIAK GALDUKO DITUZU</b>! - - - Are you sure you wish to encrypt your wallet? - Seguru zaude nahi duzula zure diruzorroa enkriptatu? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core orain itxiko da enkriptazio prozezua amaitzeko. Gogoratu enkriptatzean zure diruzorroa ez duzula guztiz babesten zure Bitcoinak lapurretatik infektatzen zure ordenagailua Malwareekin. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - GARRANTZITSUA: Aurreko seguritate-kopiak ordeztuko dire berriekin, enkriptatutak. Segurtasun arrazoigaitik, aurreko kopiak ezin dira erabili hasiko zarenean zure diruzorro enkriptatu berriarekin. - - - Wallet encrypted - Zorroa enkriptatuta - - - Wallet encryption failed - Zorroaren enkriptazioak huts egin du - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Zorroaren enkriptazioak huts egin du barne-errore baten ondorioz. Zure zorroa ez da enkriptatu. - - - The supplied passphrases do not match. - Eman dituzun pasahitzak ez datoz bat. - - - Wallet unlock failed - Zorroaren desblokeoak huts egin du - - - The passphrase entered for the wallet decryption was incorrect. - Zorroa desenkriptatzeko sartutako pasahitza okerra da. - - - Wallet decryption failed - Zorroaren desenkriptazioak huts egin du - - + BanTableModel @@ -298,9 +155,6 @@ Zorroa <b>enkriptatuta</b> eta <b>blokeatuta</b> dago une honetan - - ClientModel - CoinControlDialog @@ -315,18 +169,6 @@ Date Data - - Copy address - Kopiatu helbidea - - - Copy label - Kopiatu etiketa - - - (no label) - (etiketarik ez) - EditAddressDialog @@ -342,34 +184,6 @@ &Address &Helbidea - - New receiving address - Jasotzeko helbide berria - - - New sending address - Bidaltzeko helbide berria - - - Edit receiving address - Editatu jasotzeko helbidea - - - Edit sending address - Editatu bidaltzeko helbidea - - - The entered address "%1" is already in the address book. - Sartu berri den helbidea, "%1", helbide-liburuan dago jadanik. - - - Could not unlock wallet. - Ezin desblokeatu zorroa. - - - New key generation failed. - Gako berriaren sorrerak huts egin du. - FreespaceChecker @@ -397,9 +211,6 @@ Inprimakia - - PaymentServer - PeerTableModel @@ -410,9 +221,6 @@ Kopurua - - QRImageWidget - RPCConsole @@ -430,10 +238,6 @@ &Message: Mezua - - Copy label - Kopiatu etiketa - ReceiveRequestDialog @@ -441,45 +245,6 @@ Copy &Address &Kopiatu helbidea - - Address - Helbidea - - - Amount - Kopurua - - - Label - Etiketa - - - Message - Mezua - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiketa - - - Message - Mezua - - - Amount - Kopurua - - - (no label) - (etiketarik ez) - SendCoinsDialog @@ -503,18 +268,6 @@ Confirm the send action Berretsi bidaltzeko ekintza - - Confirm send coins - Berretsi txanponak bidaltzea - - - The amount to pay must be larger than 0. - Ordaintzeko kopurua 0 baino handiagoa izan behar du. - - - (no label) - (etiketarik ez) - SendCoinsEntry @@ -526,10 +279,6 @@ Pay &To: Ordaindu &honi: - - Enter a label for this address to add it to your address book - Sartu etiketa bat helbide honetarako, eta gehitu zure helbide-liburuan - &Label: &Etiketa: @@ -583,248 +332,22 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Zabalik %1 arte - - - %1/unconfirmed - %1/konfirmatu gabe - - - %1 confirmations - %1 konfirmazioak - - - Date - Data - - - Message - Mezua - - - Transaction - Transakzioaren - - - Amount - Kopurua - - - , has not been successfully broadcast yet - , ez da arrakastaz emititu oraindik - - - unknown - ezezaguna - - TransactionDescDialog - - Transaction details - Transakzioaren xehetasunak - This pane shows a detailed description of the transaction Panel honek transakzioaren deskribapen xehea erakusten du - - TransactionTableModel - - Date - Data - - - Type - Mota - - - Open until %1 - Zabalik %1 arte - - - Confirmed (%1 confirmations) - Konfirmatuta (%1 konfirmazio) - - - This block was not received by any other nodes and will probably not be accepted! - Bloke hau ez du beste inongo nodorik jaso, eta seguruenik ez da onartuko! - - - Generated but not accepted - Sortua, baina ez onartua - - - Label - Etiketa - - - Received with - Jasota honekin: - - - Sent to - Hona bidalia: - - - Payment to yourself - Ordainketa zeure buruari - - - Mined - Bildua - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Transakzioaren egoera. Pasatu sagua gainetik konfirmazio kopurua ikusteko. - - - Date and time that the transaction was received. - Transakzioa jasotako data eta ordua. - - - Type of transaction. - Transakzio mota. - - - Amount removed from or added to balance. - Saldoan kendu edo gehitutako kopurua. - - - - TransactionView - - All - Denak - - - Today - Gaur - - - This week - Aste honetan - - - This month - Hil honetan - - - Last month - Azken hilean - - - This year - Aurten - - - Range... - Muga... - - - Received with - Jasota honekin: - - - Sent to - Hona bidalia: - - - To yourself - Zeure buruari - - - Mined - Bildua - - - Other - Beste - - - Enter address or label to search - Sartu bilatzeko helbide edo etiketa - - - Min amount - Kopuru minimoa - - - Copy address - Kopiatu helbidea - - - Copy label - Kopiatu etiketa - - - Exporting Failed - Esportatua okerra - - - Comma separated file (*.csv) - Komaz bereizitako artxiboa (*.csv) - - - Date - Data - - - Type - Mota - - - Label - Etiketa - - - Address - Helbidea - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Bidali txanponak - - - - WalletView - - &Export - &Esportatu - - - Export the data in the current tab to a file - Esportatu datuak uneko fitxategian - - bitcoin-core Options: Aukerak - - This help message - Laguntza mezu hau - Rescanning... Birbilatzen... diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 02c216765..5bebb3582 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -15,27 +15,23 @@ Copy the currently selected address to the system clipboard - کپی نشانی انتخاب شده به حافظهٔ سیستم + کپی نشانی انتخاب شده کنونی به حافظه‌ی سیستم &Copy - &رونوشت + &کپی C&lose &بستن - - &Copy Address - &کپی نشانی - Delete the currently selected address from the list - حذف نشانی انتخاب‌شده از لیست + حذف نشانی انتخاب‌شده کنونی از لیست Export the data in the current tab to a file - خروجی گرفتن داده‌های برگهٔ فعلی به یک پرونده + خروجی گرفتن داده‌های برگه‌ی فعلی به یک فایل &Export @@ -45,69 +41,6 @@ &Delete &حذف - - Choose the address to send coins to - آدرس مورد نظر برای ارسال کوین ها را انتخاب کنید - - - Choose the address to receive coins with - آدرس موردنظر برای دریافت کوین ها را انتخاب کنید. - - - Sending addresses - آدرس های ارسال کننده - - - Receiving addresses - آدرس های دریافت کننده - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - این‌ها نشانی‌های بیت‌کوین شما برای ارسال وجود هستند. همیشه قبل از ارسال سکه‌ها، نشانی دریافت‌کننده و مقدار ارسالی را بررسی کنید. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - این‌ها نشانی‌های بیت‌کوین شما برای دریافت وجوه هستند. توصیه می‌شود یک نشانی دریافت جدید برای هر تبادل استفاده کنید. - - - Copy &Label - کپی و برچسب‌&گذاری - - - &Edit - &ویرایش - - - Export Address List - استخراج لیست آدرس - - - Comma separated file (*.csv) - پروندهٔ نوع CSV جداشونده با کاما (*.csv) - - - Exporting Failed - استخراج انجام نشد - - - There was an error trying to save the address list to %1. Please try again. - خطایی هنگام تلاش برای ذخیرهٔ لیست آدرس ها در %1 رخ داد. - - - - AddressTableModel - - Label - برچسب - - - Address - آدرس - - - (no label) - (بدون برچسب) - AskPassphraseDialog @@ -127,97 +60,13 @@ Repeat new passphrase تکرار گذرواژهٔ جدید - - Encrypt wallet - رمزنگاری کیف پول - - - This operation needs your wallet passphrase to unlock the wallet. - انجام این عملیات نیازمند گذرواژهٔ کیف پول شما برای باز کردن قفل آن است. - - - Unlock wallet - باز کردن قفل کیف پول - - - This operation needs your wallet passphrase to decrypt the wallet. - انجام این عملیات نیازمند گذرواژهٔ کیف پول شما برای رمزگشایی کردن آن است. - - - Decrypt wallet - رمزگشایی کیف پول - - - Change passphrase - تغییر گذرواژه - - - Confirm wallet encryption - تأیید رمزنگاری کیف پول - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - هشدار: اگر کیف پول خود را رمزنگاری کنید و گذرواژه را فراموش کنید، <b>تمام دارایی بیت‌کوین خود را از دست خواهید داد</b>! - - - Are you sure you wish to encrypt your wallet? - آیا مطمئن هستید که می‌خواهید کیف پول خود را رمزنگاری کنید؟ - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - هسته بیت‌کوین هم اکنون بسته می‌شود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پول‌تان نمی‌تواند به طور کامل بیت‌کوین‌های شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانه‌ی شما را آلوده می‌کنند، محافظت نماید. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - مهم: هر نسخهٔ پشتیبانی که تا کنون از کیف پول خود تهیه کرده‌اید، باید با کیف پول رمزنگاری شدهٔ جدید جایگزین شود. به دلایل امنیتی، پروندهٔ قدیمی کیف پول بدون رمزنگاری، تا زمانی که از کیف پول رمزنگاری‌شدهٔ جدید استفاده نکنید، غیرقابل استفاده خواهد بود. - - - Warning: The Caps Lock key is on! - هشدار: کلید Caps Lock روشن است! - - - Wallet encrypted - کیف پول رمزنگاری شد - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - رمز جدید کیف پول خود را وارد کنید.<br/>از رمز عبوری استفاده کنید که<b> حداقل 10 کاراکتر تصادفی </b> و یا <b> حداقل 8 حرف داشته باشد.</b> - - - Enter the old passphrase and new passphrase to the wallet. - رمز عبور قدیمی و رمز عبور جدید کیف پول خود را وارد گنید. - - - Wallet encryption failed - رمزنگاری کیف پول با شکست مواجه شد - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - رمزنگاری کیف پول بنا به یک خطای داخلی با شکست مواجه شد. کیف پول شما رمزنگاری نشد. - - - The supplied passphrases do not match. - گذرواژه‌های داده شده با هم تطابق ندارند. - - - Wallet unlock failed - بازگشایی قفل کیف‌پول با شکست مواجه شد - - - The passphrase entered for the wallet decryption was incorrect. - گذرواژهٔ وارد شده برای رمزگشایی کیف پول نادرست بود. - - - Wallet decryption failed - رمزگشایی ناموفق کیف پول - - - Wallet passphrase was successfully changed. - گذرواژهٔ کیف پول با موفقیت عوض شد. - BanTableModel + + IP/Netmask + آی‌پی/نت‌ماسک + BitcoinGUI @@ -257,6 +106,10 @@ Quit application خروج از برنامه + + &About %1 + &حدود%1 + About &Qt دربارهٔ &کیوت @@ -293,10 +146,6 @@ Open &URI... باز کردن &آدرس - - Importing blocks from disk... - دریافت بلوک‌ها از دیسک... - Reindexing blocks on disk... بازنشانی بلوک‌ها روی دیسک... @@ -341,10 +190,6 @@ &Receive &دریافت - - Show information about Bitcoin Core - نمایش اطلاعات در مورد بیت‌کوین - &Show / Hide &نمایش/ عدم نمایش @@ -381,14 +226,6 @@ Tabs toolbar نوارابزار برگه‌ها - - Bitcoin Core - هسته Bitcoin - - - &About Bitcoin Core - درباره هسته ی بیت کوین - Show the list of used sending addresses and labels نمایش لیست آدرس های ارسال و لیبل ها @@ -461,6 +298,36 @@ Catching up... به‌روز رسانی... + + Date: %1 + + تاریخ: %1 + + + + Amount: %1 + + مقدار: %1 + + + + Type: %1 + + نوع: %1 + + + + Label: %1 + + برچسب: %1 + + + + Address: %1 + + نشانی: %1 + + Sent transaction تراکنش ارسال شد @@ -478,13 +345,6 @@ کیف پول <b>رمزنگاری شده</b> است و هم‌اکنون <b>قفل</b> است - - ClientModel - - Network Alert - پیام شبکه - - CoinControlDialog @@ -519,6 +379,10 @@ Change: پول خورد: + + (un)select all + (لغو)انتخاب همه + Tree mode مدل درختی @@ -555,78 +419,6 @@ Priority اولویت - - Copy address - کپی نشانی - - - Copy label - کپی برچسب - - - Copy amount - کپی مقدار - - - Copy transaction ID - کپی شناسهٔ تراکنش - - - highest - بیشترین - - - higher - بیشتر - - - high - زیاد - - - medium-high - متوسط متمایل به زیاد - - - medium - متوسط - - - low-medium - متوسط متمایل به کم - - - low - کم - - - lower - کمتر - - - lowest - کمترین - - - none - هیچکدام - - - yes - بله - - - no - خیر - - - (no label) - (بدون برچسب) - - - (change) - (تغییر) - EditAddressDialog @@ -642,38 +434,6 @@ &Address &نشانی - - New receiving address - نشانی دریافتی جدید - - - New sending address - نشانی ارسالی جدید - - - Edit receiving address - ویرایش نشانی دریافتی - - - Edit sending address - ویرایش نشانی ارسالی - - - The entered address "%1" is already in the address book. - نشانی وارد شده «%1» در حال حاضر در دفترچه وجود دارد. - - - The entered address "%1" is not a valid Bitcoin address. - نشانی وارد شده «%1» یک نشانی معتبر بیت‌کوین نیست. - - - Could not unlock wallet. - نمی‌توان کیف پول را رمزگشایی کرد. - - - New key generation failed. - ایجاد کلید جدید با شکست مواجه شد. - FreespaceChecker @@ -700,17 +460,13 @@ HelpMessageDialog - - Bitcoin Core - هسته Bitcoin - version نسخه - About Bitcoin Core - درباره هسته ی بیت کوین + About %1 + درباره %1 Command-line options @@ -732,12 +488,8 @@ خوش‌آمدید - Welcome to Bitcoin Core. - به هسته بیت کوین خوش آمدید. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - از آنجایی که این اولین اجرای برنامه است، شما می‌توانید مسیر ذخیرهٔ داده‌ها را انتخاب کنید. + Welcome to %1. + به %1 خوش‌آمدید. Use the default data directory @@ -747,10 +499,6 @@ Use a custom data directory: استفاده از یک مسیر سفارشی: - - Bitcoin Core - هسته Bitcoin - Error خطا @@ -773,6 +521,10 @@ &Main &عمومی + + Accept connections from outside + پذیرش اتصالات از بیرون + Reset all client options to default. بازنشانی تمام تنظیمات به پیش‌فرض. @@ -813,6 +565,18 @@ Port of the proxy (e.g. 9050) درگاه پراکسی (مثال 9050) + + IPv4 + آی‌پی نسخه 4 + + + IPv6 + آی‌پی نسخه 6 + + + Tor + تور + &Window &پنجره @@ -925,33 +689,6 @@ تراکنش های اخیر - - PaymentServer - - URI handling - مدیریت URI - - - Payment request rejected - درخواست پرداخت رد شد. - - - Payment request error - خطای درخواست پرداخت - - - Cannot start bitcoin: click-to-pay handler - نمی‌توان بیت‌کوین را اجرا کرد: کنترل‌کنندهٔ کلیک-و-پرداخت - - - Payment request expired. - درخواست پرداخت منقضی شد. - - - Invalid payment request. - درخواست پرداخت نامعتبر - - PeerTableModel @@ -961,6 +698,22 @@ Amount مبلغ + + %1 d + %1 روز + + + %1 h + %1 ساعت + + + %1 m + %1 دقیقه + + + %1 s + %1 ثانیه + None هیچکدام @@ -969,14 +722,11 @@ N/A ناموجود - - - QRImageWidget - Save QR Code - ذخیرهٔ کد QR + %1 ms + %1 میلیونم ثانیه - + RPCConsole @@ -999,6 +749,10 @@ Debug window پنجرهٔ اشکالزدایی + + General + عمومی + Startup time زمان آغاز به کار @@ -1023,6 +777,10 @@ Current number of blocks تعداد فعلی بلوک‌ها + + Memory usage + مصرف حافظه + Received دریافتی @@ -1039,6 +797,10 @@ Services سرویس ها + + Last Receive + آخرین دریافتی + Last block time زمان آخرین بلوک @@ -1056,8 +818,8 @@ جمع کل: - Build date - ساخت تاریخ + In: + در: Debug log file @@ -1067,10 +829,6 @@ Clear console پاکسازی کنسول - - Welcome to the Bitcoin Core RPC console. - به کنسول RPC هسته بیت کوین خوش آمدید. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. دکمه‌های بالا و پایین برای پیمایش تاریخچه و <b>Ctrl-L</b> برای پاک کردن صفحه. @@ -1079,6 +837,18 @@ Type <b>help</b> for an overview of available commands. برای نمایش یک مرور کلی از دستورات ممکن، عبارت <b>help</b> را بنویسید. + + never + هرگز + + + Yes + بله + + + No + خیر + Unknown ناشناخته @@ -1098,6 +868,10 @@ &Message: پیام: + + Clear + پاک‌کردن + Show نمایش @@ -1106,14 +880,6 @@ Remove حذف کردن - - Copy label - کپی برچسب - - - Copy amount - کپی مقدار - ReceiveRequestDialog @@ -1125,53 +891,6 @@ Copy &Address &کپی نشانی - - Address - نشانی - - - Amount - مبلغ - - - Label - برچسب - - - Message - پیام - - - Resulting URI too long, try to reduce the text for label / message. - URL ایجاد شده خیلی طولانی است. سعی کنید طول برچسب و یا پیام را کمتر کنید. - - - Error encoding URI into QR Code. - خطا در تبدیل نشانی اینترنتی به صورت کد QR. - - - - RecentRequestsTableModel - - Date - تاریخ - - - Label - برچسب - - - Message - پیام - - - Amount - مبلغ - - - (no label) - (بدون برچسب) - SendCoinsDialog @@ -1215,6 +934,14 @@ Transaction Fee: هزینهٔ تراکنش: + + Hide + پنهان کردن + + + normal + نرمال + fast سریع @@ -1243,43 +970,7 @@ S&end &ارسال - - Confirm send coins - ارسال سکه را تأیید کنید - - - Copy amount - کپی مقدار - - - or - یا - - - The amount to pay must be larger than 0. - مبلغ پرداخت باید بیشتر از ۰ باشد. - - - The amount exceeds your balance. - میزان پرداخت از تراز شما بیشتر است. - - - The total exceeds your balance when the %1 transaction fee is included. - با احتساب هزینهٔ %1 برای هر تراکنش، مجموع میزان پرداختی از مبلغ تراز شما بیشتر می‌شود. - - - Payment request expired. - درخواست پرداخت منقضی شد. - - - (no label) - (بدون برچسب) - - - Are you sure you want to send? - آیا مطمئن هستید که می خواهید ارسال کنید؟ - - + SendCoinsEntry @@ -1290,10 +981,6 @@ Pay &To: پرداخ&ت به: - - Enter a label for this address to add it to your address book - برای این نشانی یک برچسب وارد کنید تا در دفترچهٔ آدرس ذخیره شود - &Label: &برچسب: @@ -1334,7 +1021,11 @@ Pay To: پرداخت به: - + + Memo: + یادداشت: + + ShutdownWindow @@ -1416,69 +1107,9 @@ Reset all verify message fields بازنشانی تمام فیلدهای پیام - - Click "Sign Message" to generate signature - برای ایجاد یک امضای جدید روی «امضای پیام» کلیک کنید - - - The entered address is invalid. - نشانی وارد شده نامعتبر است. - - - Please check the address and try again. - لطفاً نشانی را بررسی کنید و دوباره تلاش کنید. - - - The entered address does not refer to a key. - نشانی وارد شده به هیچ کلیدی اشاره نمی‌کند. - - - Wallet unlock was cancelled. - عملیات باز کرن قفل کیف پول لغو شد. - - - Private key for the entered address is not available. - کلید خصوصی برای نشانی وارد شده در دسترس نیست. - - - Message signing failed. - امضای پیام با شکست مواجه شد. - - - Message signed. - پیام امضا شد. - - - The signature could not be decoded. - امضا نمی‌تواند کدگشایی شود. - - - Please check the signature and try again. - لطفاً امضا را بررسی نموده و دوباره تلاش کنید. - - - The signature did not match the message digest. - امضا با خلاصهٔ پیام مطابقت ندارد. - - - Message verification failed. - شناسایی پیام با شکست مواجه شد. - - - Message verified. - پیام شناسایی شد. - SplashScreen - - Bitcoin Core - هسته Bitcoin - - - The Bitcoin Core developers - توسعه‌دهندگان هسته بیت‌کوین - [testnet] آزمایش شبکه @@ -1491,394 +1122,16 @@ کیلوبایت - - TransactionDesc - - Open until %1 - باز تا %1 - - - %1/offline - %1/آفلاین - - - %1/unconfirmed - %1/تأیید نشده - - - %1 confirmations - %1 تأییدیه - - - Status - وضعیت - - - , broadcast through %n node(s) - ، پخش از طریق %n گره - - - Date - تاریخ - - - Source - منبع - - - Generated - تولید شده - - - From - فرستنده - - - To - گیرنده - - - own address - آدرس شما - - - label - برچسب - - - Credit - بدهی - - - matures in %n more block(s) - بلوغ در %n بلوک دیگر - - - not accepted - پذیرفته نشد - - - Debit - اعتبار - - - Transaction fee - هزینهٔ تراکنش - - - Net amount - مبلغ خالص - - - Message - پیام - - - Comment - نظر - - - Transaction ID - شناسهٔ تراکنش - - - Debug information - اطلاعات اشکال‌زدایی - - - Transaction - تراکنش - - - Inputs - ورودی‌ها - - - Amount - مبلغ - - - true - درست - - - false - نادرست - - - , has not been successfully broadcast yet - ، هنوز با موفقیت ارسال نشده - - - Open for %n more block(s) - باز برای %n بلوک دیگر - - - unknown - ناشناس - - TransactionDescDialog - - Transaction details - جزئیات تراکنش - This pane shows a detailed description of the transaction این پانل شامل توصیف کاملی از جزئیات تراکنش است - - TransactionTableModel - - Date - تاریخ - - - Type - نوع - - - Open for %n more block(s) - باز برای %n بلوک دیگر - - - Open until %1 - باز شده تا %1 - - - Confirmed (%1 confirmations) - تأیید شده (%1 تأییدیه) - - - This block was not received by any other nodes and will probably not be accepted! - این بلوک از هیچ همتای دیگری دریافت نشده است و احتمال می‌رود پذیرفته نشود! - - - Generated but not accepted - تولید شده ولی قبول نشده - - - Offline - آفلاین - - - Label - برچسب - - - Unconfirmed - تایید نشده - - - Received with - دریافت‌شده با - - - Received from - دریافت‌شده از - - - Sent to - ارسال‌شده به - - - Payment to yourself - پر داخت به خودتان - - - Mined - استخراج‌شده - - - (n/a) - (ناموجود) - - - Transaction status. Hover over this field to show number of confirmations. - وضعیت تراکنش. نشانگر را روی این فیلد نگه دارید تا تعداد تأییدیه‌ها نشان داده شود. - - - Date and time that the transaction was received. - تاریخ و ساعت دریافت تراکنش. - - - Type of transaction. - نوع تراکنش. - - - Amount removed from or added to balance. - مبلغ کسر شده و یا اضافه شده به تراز. - - - - TransactionView - - All - همه - - - Today - امروز - - - This week - این هفته - - - This month - این ماه - - - Last month - ماه گذشته - - - This year - امسال - - - Range... - محدوده... - - - Received with - دریافت‌شده با - - - Sent to - ارسال به - - - To yourself - به خودتان - - - Mined - استخراج‌شده - - - Other - دیگر - - - Enter address or label to search - برای جست‌‌وجو نشانی یا برچسب را وارد کنید - - - Min amount - مبلغ حداقل - - - Copy address - کپی نشانی - - - Copy label - کپی برچسب - - - Copy amount - کپی مقدار - - - Copy transaction ID - کپی شناسهٔ تراکنش - - - Edit label - ویرایش برچسب - - - Show transaction details - نمایش جزئیات تراکنش - - - Exporting Failed - استخراج انجام نشد - - - Exporting Successful - استخراج موفق - - - Comma separated file (*.csv) - پروندهٔ نوع CSV جداشونده با کاما (*.csv) - - - Confirmed - تأیید شده - - - Date - تاریخ - - - Type - نوع - - - Label - برچسب - - - Address - نشانی - - - ID - شناسه - - - Range: - محدوده: - - - to - به - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - ارسال وجه - - - - WalletView - - &Export - &صدور - - - Export the data in the current tab to a file - داده ها نوارِ جاری را به فایل انتقال دهید - - - Backup Wallet - نسخهٔ پشتیبان کیف پول - - - Wallet Data (*.dat) - دادهٔ کیف پول (*.dat) - - - Backup Failed - خطا در پشتیبان‌گیری - - - Backup Successful - پشتیبان‌گیری موفق - - bitcoin-core @@ -1909,6 +1162,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) پذیرش اتصالات از بیرون (پیش فرض:1 بدون پراکسی یا اتصال) + + Bitcoin Core + هسته Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 مقید به نشانی داده شده باشید و همیشه از آن پیروی کنید. از نشانه گذاری استاندار IPv6 به صورت Host]:Port] استفاده کنید. @@ -1929,6 +1186,14 @@ Connect only to the specified node(s) تنها در گره (های) مشخص شده متصل شوید + + Connection options: + گزینه‌های اتصال: + + + Copyright (C) %i-%i + حق تألیف (C) %i-%i + Corrupted block database detected یک پایگاه داده ی بلوک خراب یافت شد @@ -1941,6 +1206,10 @@ Error initializing block database خطا در آماده سازی پایگاه داده ی بلوک + + Error loading %s + خطا در بارگیری %s + Error loading block database خطا در بارگذاری پایگاه داده ها @@ -1961,30 +1230,34 @@ Importing... در حال پیاده‌سازی... + + Loading banlist... + بارگذاری لیست‌سیاه... + + + Print this help message and exit + چاپ ایت پیام کمک و خروج + + + Print version and exit + چاپ نسخه و خروج + Verifying blocks... - در حال بازبینی بلوک ها... + در حال بازبینی بلوک‌ها... Verifying wallet... در حال بازبینی کیف پول... + + Wallet options: + گزینه‌های کیف پول: + Information اطلاعات - - Invalid amount for -maxtxfee=<amount>: '%s' - میزان وجه اشتباه برای maxtxfee=<میزان وجه>: %s - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - میزان وجه اشتباه برای minrelaytxfee=<میزان وجه>: %s - - - Invalid amount for -mintxfee=<amount>: '%s' - میزان وجه اشتباه برای mintxfee=<میزان وجه>: %s - Send trace/debug info to console instead of debug.log file اطلاعات ردگیری/اشکال‌زدایی را به جای فایل لاگ اشکال‌زدایی به کنسول بفرستید @@ -1993,6 +1266,18 @@ Shrink debug.log file on client startup (default: 1 when no -debug) فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد) + + Transaction amount too small + مقدار تراکنش بسیار کم است + + + Transaction amounts must be positive + مقادیر تراکنش باید مثبت باشد + + + Transaction too large + تراکنش بسیار بزرگ است + Username for JSON-RPC connections JSON-RPC شناسه برای ارتباطات @@ -2001,6 +1286,10 @@ Warning هشدار + + Warning: unknown new rules activated (versionbit %i) + هشدار: قوانین جدید ناشناخته‌ای فعال شده‌اند (نسخه‌بیت %i) + Password for JSON-RPC connections JSON-RPC عبارت عبور برای ارتباطات @@ -2009,10 +1298,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) زمانی که بهترین بلاک تغییر کرد، دستور را اجرا کن (%s در cmd با block hash جایگزین شده است) - - This help message - پیام کمکی - Allow DNS lookups for -addnode, -seednode and -connect به DNS اجازه بده تا برای addnode ، seednode و اتصال جستجو کند @@ -2021,14 +1306,6 @@ Loading addresses... بار گیری آدرس ها - - Error loading wallet.dat: Wallet corrupted - خطا در بارگیری wallet.dat: کیف پول خراب شده است - - - Error loading wallet.dat - خطا در بارگیری wallet.dat - Invalid -proxy address: '%s' آدرس پراکسی اشتباه %s @@ -2037,18 +1314,6 @@ Unknown network specified in -onlynet: '%s' شبکه مشخص شده غیرقابل شناسایی در onlynet: '%s' - - Cannot resolve -bind address: '%s' - آدرس قابل اتصال- شناسایی نیست %s - - - Cannot resolve -externalip address: '%s' - آدرس خارجی قابل اتصال- شناسایی نیست %s - - - Invalid amount for -paytxfee=<amount>: '%s' - میزان وجه اشتباه برای paytxfee=<میزان وجه>: %s - Insufficient funds بود جه نا کافی diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index 8bbfc7242..b329612de 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -21,10 +21,6 @@ C&lose بستن - - &Copy Address - کپی آدرس - Delete the currently selected address from the list حذف آدرس های انتخاب شده از لیست @@ -41,65 +37,6 @@ &Delete حذف - - Choose the address to send coins to - انتخاب آدرس جهت ارسال کوین ها به آن آدرس - - - Choose the address to receive coins with - انتخاب آدرس جهت دریافت کوین ها از آن آدرس - - - C&hoose - انتخاب - - - Sending addresses - ارسال آدرس ها - - - Receiving addresses - دریافت آدرس ها - - - Copy &Label - کپی برچسب - - - &Edit - ویرایش - - - Export Address List - صدور لیست آدرس - - - Comma separated file (*.csv) - فایل سی اس وی (*.csv) - - - Exporting Failed - صدور با شکست مواجه شد - - - There was an error trying to save the address list to %1. Please try again. - خطایی به هنگام ذخیره لیست آدرس در %1 رخ داده است. لطفا دوباره تلاش کنید. - - - - AddressTableModel - - Label - برچسب - - - Address - حساب - - - (no label) - (برچسب ندارد) - AskPassphraseDialog @@ -119,74 +56,6 @@ Repeat new passphrase رمز/پَس فرِیز را دوباره وارد کنید - - Encrypt wallet - wallet را رمزگذاری کنید - - - This operation needs your wallet passphrase to unlock the wallet. - برای انجام این عملکرد به رمز/پَس فرِیزِwallet نیاز است تا آن را از حالت قفل درآورد. - - - Unlock wallet - باز کردن قفل wallet - - - This operation needs your wallet passphrase to decrypt the wallet. - برای کشف رمز wallet، به رمز/پَس فرِیزِwallet نیاز است. - - - Decrypt wallet - کشف رمز wallet - - - Change passphrase - تغییر رمز/پَس فرِیز - - - Confirm wallet encryption - رمزگذاری wallet را تایید کنید - - - Warning: The Caps Lock key is on! - اخطار: کلید Caps Lock فعال است! - - - Wallet encrypted - تایید رمزگذاری - - - Enter the old passphrase and new passphrase to the wallet. - رمز قدیمی و جدید کیف پول را وارد کنید. - - - Wallet encryption failed - رمزگذاری تایید نشد - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - رمزگذاری به علت خطای داخلی تایید نشد. wallet شما رمزگذاری نشد - - - The supplied passphrases do not match. - رمزهای/پَس فرِیزهایِ وارد شده با هم تطابق ندارند - - - Wallet unlock failed - قفل wallet باز نشد - - - The passphrase entered for the wallet decryption was incorrect. - رمزهای/پَس فرِیزهایِ وارد شده wallet برای کشف رمز اشتباه است. - - - Wallet decryption failed - کشف رمز wallet انجام نشد - - - Wallet passphrase was successfully changed. - رمز عبور کیف پول با موفقیت تغییر کرد. - BanTableModel @@ -322,13 +191,6 @@ wallet رمزگذاری شد و در حال حاضر قفل است - - ClientModel - - Network Alert - هشدار شبکه - - CoinControlDialog @@ -347,22 +209,6 @@ Confirmed تایید شده - - Copy address - آدرس را کپی کنید - - - Copy label - برچسب را کپی کنید - - - Copy amount - میزان وجه کپی شود - - - (no label) - (برچسب ندارد) - EditAddressDialog @@ -378,39 +224,6 @@ &Address حساب& - - New receiving address - حساب دریافت کننده جدید - - - - New sending address - حساب ارسال کننده جدید - - - Edit receiving address - ویرایش حساب دریافت کننده - - - Edit sending address - ویرایش حساب ارسال کننده - - - The entered address "%1" is already in the address book. - حساب وارد شده «%1» از پیش در دفترچه حساب ها موجود است. - - - The entered address "%1" is not a valid Bitcoin address. - آدرس وارد شده "%1" یک آدرس صحیح برای bitcoin نسشت - - - Could not unlock wallet. - عدم توانیی برای قفل گشایی wallet - - - New key generation failed. - عدم توانیی در ایجاد کلید جدید - FreespaceChecker @@ -474,9 +287,6 @@ اطلاعات نمایش داده شده ممکن است روزآمد نباشد. wallet شما به صورت خودکار بعد از برقراری اتصال با شبکه bitcoin به روز می شود اما این فرایند هنوز تکمیل نشده است. - - PaymentServer - PeerTableModel @@ -487,9 +297,6 @@ میزان - - QRImageWidget - RPCConsole @@ -531,68 +338,13 @@ &Message: پیام: - - Copy label - برچسب را کپی کنید - - - Copy amount - میزان وجه کپی شود - - + ReceiveRequestDialog Copy &Address کپی آدرس - - Address - حساب - - - Amount - میزان - - - Label - برچسب - - - Message - پیام - - - Resulting URI too long, try to reduce the text for label / message. - متن وارد شده طولانی است، متنِ برچسب/پیام را کوتاه کنید - - - Error encoding URI into QR Code. - خطای تبدیل URI به کد QR - - - - RecentRequestsTableModel - - Date - تاریخ - - - Label - برچسب - - - Message - پیام - - - Amount - میزان - - - (no label) - (برچسب ندارد) - SendCoinsDialog @@ -624,27 +376,7 @@ S&end و ارسال - - Confirm send coins - تایید ارسال بیت کوین ها - - - Copy amount - میزان وجه کپی شود - - - The amount to pay must be larger than 0. - میزان پرداخت باید بیشتر از 0 باشد - - - The amount exceeds your balance. - مقدار مورد نظر از مانده حساب بیشتر است. - - - (no label) - (برچسب ندارد) - - + SendCoinsEntry @@ -655,10 +387,6 @@ Pay &To: پرداخت و به چه کسی - - Enter a label for this address to add it to your address book - یک برچسب برای این آدرس بنویسید تا به دفترچه آدرسهای شما اضافه شود - &Label: و برچسب @@ -690,10 +418,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - هسته بیت کوین در حال خاموش شدن است... - Do not shut down the computer until this window disappears. تا پیش از بسته شدن این پنجره کامپیوتر خود را خاموش نکنید. @@ -732,287 +456,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - باز کن تا %1 - - - %1/unconfirmed - %1 / تایید نشده - - - %1 confirmations - %1 تایید - - - Date - تاریخ - - - label - برچسب - - - Message - پیام - - - Transaction ID - شناسه کاربری - - - Amount - میزان - - - , has not been successfully broadcast yet - ، هنوز با موفقیت ارسال نگردیده است - - - unknown - ناشناس - - TransactionDescDialog - - Transaction details - جزئیات تراکنش - This pane shows a detailed description of the transaction این بخش جزئیات تراکنش را نشان می دهد - - TransactionTableModel - - Date - تاریخ - - - Type - گونه - - - Open until %1 - باز کن تا %1 - - - Confirmed (%1 confirmations) - تایید شده (%1 تاییدها) - - - This block was not received by any other nodes and will probably not be accepted! - این block توسط گره های دیگری دریافت نشده است و ممکن است قبول نشود - - - Generated but not accepted - تولید شده اما قبول نشده است - - - Label - برچسب - - - Received with - دریافت با - - - Received from - دریافت شده از - - - Sent to - ارسال به - - - Payment to yourself - وجه برای شما - - - Mined - استخراج شده - - - (n/a) - خالی - - - Transaction status. Hover over this field to show number of confirmations. - وضعیت تراکنش. با اشاره به این بخش تعداد تاییدها نمایش داده می شود - - - Date and time that the transaction was received. - زمان و تاریخی که تراکنش دریافت شده است - - - Type of transaction. - نوع تراکنش - - - Amount removed from or added to balance. - میزان وجه کم شده یا اضافه شده به حساب - - - - TransactionView - - All - همه - - - Today - امروز - - - This week - این هفته - - - This month - این ماه - - - Last month - ماه گذشته - - - This year - این سال - - - Range... - حدود.. - - - Received with - دریافت با - - - Sent to - ارسال به - - - To yourself - به شما - - - Mined - استخراج شده - - - Other - دیگر - - - Enter address or label to search - آدرس یا برچسب را برای جستجو وارد کنید - - - Min amount - حداقل میزان وجه - - - Copy address - آدرس را کپی کنید - - - Copy label - برچسب را کپی کنید - - - Copy amount - میزان وجه کپی شود - - - Edit label - برچسب را ویرایش کنید - - - Exporting Failed - صدور با شکست مواجه شد - - - Exporting Successful - صدور با موفقیت انجام شد - - - Comma separated file (*.csv) - Comma separated file (*.csv) فایل جداگانه دستوری - - - Confirmed - تایید شده - - - Date - تاریخ - - - Type - گونه - - - Label - برچسب - - - Address - حساب - - - ID - شناسه کاربری - - - Range: - دامنه: - - - to - به - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - سکه های ارسالی - - - - WalletView - - &Export - صدور - - - Export the data in the current tab to a file - صدور داده نوار جاری به یک فایل - - - Backup Wallet - گرفتن نسخه پیشتیبان از Wallet - - - Wallet Data (*.dat) - داده های Wallet -(*.dat) - - - Backup Failed - عملیات گرفتن نسخه پیشتیبان انجام نشد - - bitcoin-core @@ -1035,18 +488,6 @@ The transaction amount is too small to send after the fee has been deducted مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد - - Invalid amount for -maxtxfee=<amount>: '%s' - میزان اشتباه است for -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - میزان اشتباه است for -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - میزان اشتباه است for -mintxfee=<amount>: '%s' - RPC server options: گزینه های سرویس دهنده RPC: @@ -1071,22 +512,10 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) دستور را وقتی بهترین بلاک تغییر کرد اجرا کن (%s در دستور توسط block hash جایگزین شده است) - - This help message - این پیام راهنما - Loading addresses... لود شدن آدرسها.. - - Error loading wallet.dat: Wallet corrupted - خطا در هنگام لود شدن wallet.dat: Wallet corrupted - - - Error loading wallet.dat - خطا در هنگام لود شدن wallet.dat - Set minimum block size in bytes (default: %u) تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u) @@ -1103,10 +532,6 @@ Specify pid file (default: %s) فایل pid را مشخص کنید (پیش فرض: %s) - - Invalid amount for -paytxfee=<amount>: '%s' - میزان اشتباه است for -paytxfee=<amount>: '%s' - Insufficient funds وجوه ناکافی diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 0fb6aebb9..c2226e9b9 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -25,10 +25,6 @@ C&lose S&ulje - - &Copy Address - &Kopioi osoite - Delete the currently selected address from the list Poista valittu osoite listalta @@ -45,73 +41,6 @@ &Delete &Poista - - Choose the address to send coins to - Valitse osoite johon kolikot lähetetään - - - Choose the address to receive coins with - Valitse osoite johon vastaanotetaan kolikoita - - - C&hoose - V&alitse - - - Sending addresses - Lähettävä osoite - - - Receiving addresses - Vastaanottava osoite - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Nämä ovat sinun Bitcoin osoitteita maksujen lähetykseen. Tarkista aina summa ja vastaanottajan osoite ennenkuin lähetät kolikkoja. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Nämä ovat sinun Bitcoin-osoitteesi suoritusten vastaanottamiseen. Suositellaan että annat uuden osoitteen kullekin transaktiolle. - - - Copy &Label - Kopioi &nimike - - - &Edit - &Muokkaa - - - Export Address List - Vie osoitekirja - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Exporting Failed - Vienti epäonnistui - - - There was an error trying to save the address list to %1. Please try again. - Virhe tallentaessa osoitelistaa %1. Yritä uudelleen. - - - - AddressTableModel - - Label - Nimi - - - Address - Osoite - - - (no label) - (ei nimikettä) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Toista uusi tunnuslause - - Encrypt wallet - Salaa lompakko - - - This operation needs your wallet passphrase to unlock the wallet. - Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause sen avaamiseksi. - - - Unlock wallet - Avaa lompakko - - - This operation needs your wallet passphrase to decrypt the wallet. - Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause salauksen purkuun. - - - Decrypt wallet - Pura lompakon salaus - - - Change passphrase - Vaihda tunnuslause - - - Confirm wallet encryption - Vahvista lompakon salaus - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Varoitus: Jos salaat lompakkosi ja menetät tunnuslauseesi, <b>MENETÄT KAIKKI BITCOINISI</b>! - - - Are you sure you wish to encrypt your wallet? - Haluatko varmasti salata lompakkosi? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core sammuu nyt viimeistelläkseen kryptaamisen. Muista että lompakon kryptaaminen ei voi täysin suojata bitcoinejasi varkaudelta malwaren saastuttamalla tietokoneella. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - TÄRKEÄÄ: Kaikki vanhat lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat suojatun lompakon käytön. - - - Warning: The Caps Lock key is on! - Varoitus: Caps Lock on käytössä! - - - Wallet encrypted - Lompakko salattu - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Anna salauslause lompakkoon. <br/>Ole hyvä ja käytä lausetta jossa on <b>kymmenen tai enemmän satunnaista merkkiä</b> tai <b>kahdeksan tai useampi sanaa</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Syötä vanha ja uusi salasana lompakolle. - - - Wallet encryption failed - Lompakon salaus epäonnistui - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Lompakon salaaminen epäonnistui sisäisen virheen vuoksi. Lompakkoasi ei salattu. - - - The supplied passphrases do not match. - Annetut tunnuslauseet eivät täsmää. - - - Wallet unlock failed - Lompakon avaaminen epäonnistui. - - - The passphrase entered for the wallet decryption was incorrect. - Annettu tunnuslause oli väärä. - - - Wallet decryption failed - Lompakon salauksen purku epäonnistui. - - - Wallet passphrase was successfully changed. - Lompakon tunnuslause vaihdettiin onnistuneesti. - BanTableModel @@ -269,6 +110,10 @@ Quit application Sulje ohjelma + + &About %1 + &Tietoja %1 + About &Qt Tietoja &Qt @@ -305,14 +150,6 @@ Open &URI... Avaa &URI... - - Bitcoin Core client - Bitcoin Core ohjelma - - - Importing blocks from disk... - Tuodaan lohkoja levyltä - Reindexing blocks on disk... Ladataan lohkoindeksiä... @@ -357,10 +194,6 @@ &Receive &Vastaanota - - Show information about Bitcoin Core - Näytä tietoja Bitcoin Core:sta - &Show / Hide &Näytä / Piilota @@ -397,22 +230,10 @@ Tabs toolbar Välilehtipalkki - - Bitcoin Core - Bitcoin-ydin - Request payments (generates QR codes and bitcoin: URIs) Pyydä maksuja (Luo QR koodit ja bitcoin: URIt) - - &About Bitcoin Core - &Tietoja Bitcoin Core - - - Modify configuration options for Bitcoin Core - Muokkaa kokoonpanoasetuksia Bitcoin Corelle - Show the list of used sending addresses and labels Näytä lähettämiseen käytettyjen osoitteiden ja nimien lista @@ -429,10 +250,6 @@ &Command-line options &Komentorivin valinnat - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Näytä Bitcoin Core ohjeet saadaksesi listan mahdollisista Bitcoinin komentorivivalinnoista - %n active connection(s) to Bitcoin network %n aktiivinen yhteys Bitcoin-verkkoon%n aktiivista yhteyttä Bitcoin-verkkoon @@ -544,13 +361,6 @@ Lompakko on <b>salattu</b> ja tällä hetkellä <b>lukittuna</b> - - ClientModel - - Network Alert - Verkkohälytys - - CoinControlDialog @@ -629,150 +439,6 @@ Priority Prioriteetti - - Copy address - Kopioi osoite - - - Copy label - Kopioi nimi - - - Copy amount - Kopioi määrä - - - Copy transaction ID - Kopioi siirtotunnus - - - Lock unspent - Lukitse käyttämättömät - - - Unlock unspent - Avaa käyttämättömät - - - Copy quantity - Kopioi määrä - - - Copy fee - Kopioi palkkio - - - Copy after fee - Kopioi palkkion jälkeen - - - Copy bytes - Kopioi tavut - - - Copy priority - Kopioi prioriteetti - - - Copy dust - Kopioi tomu - - - Copy change - Kopioi vaihtoraha - - - highest - korkein - - - higher - korkeampi - - - high - korkea - - - medium-high - keski-korkea - - - medium - keskisuuri - - - low-medium - pieni-keskisuuri - - - low - pieni - - - lower - pienempi - - - lowest - pienin - - - (%1 locked) - (%1 lukittu) - - - none - ei mitään - - - This label turns red if the transaction size is greater than 1000 bytes. - Tämä nimi muuttuu punaiseksi mikäli rahansiirron koko on suurempi kuin 1000 tavua. - - - This label turns red if the priority is smaller than "medium". - Tämä nimi muuttuu punaiseksi mikäli prioriteetti on pienempi kuin "medium". - - - This label turns red if any recipient receives an amount smaller than %1. - Tämä nimike muuttuu punaiseksi mikäli mikä tahansa saaja vastaanottaa pienemmän määrän kuin %1. - - - Can vary +/- %1 satoshi(s) per input. - Saattaa vaihdella +/- %1 satoshia per syöte. - - - yes - kyllä - - - no - ei - - - This means a fee of at least %1 per kB is required. - Tämä tarkoittaa että vähintään %1 per kB palkkio on pakollinen. - - - Can vary +/- 1 byte per input. - Voi vaihdella +/- 1 tavu per syöte - - - Transactions with higher priority are more likely to get included into a block. - Rahansiirrot korkeammalla prioriteetilla sisällytetään varmemmin lohkoon. - - - (no label) - (ei nimeä) - - - change from %1 (%2) - Vaihda %1 (%2) - - - (change) - (vaihtoraha) - EditAddressDialog @@ -796,38 +462,6 @@ &Address &Osoite - - New receiving address - Uusi vastaanottava osoite - - - New sending address - Uusi lähettävä osoite - - - Edit receiving address - Muokkaa vastaanottajan osoitetta - - - Edit sending address - Muokkaa lähtevää osoitetta - - - The entered address "%1" is already in the address book. - Osoite "%1" on jo osoitekirjassa. - - - The entered address "%1" is not a valid Bitcoin address. - Antamasi osoite "%1" ei ole validi Bitcoin-osoite. - - - Could not unlock wallet. - Lompakkoa ei voitu avata. - - - New key generation failed. - Uuden avaimen luonti epäonnistui. - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin-ydin - version versio @@ -866,10 +496,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Tietoja Bitcoin Core - Command-line options Komentorivi parametrit @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u) - - Reset all settings changes made over the GUI - Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset - - + Intro Welcome Tervetuloa - - Welcome to Bitcoin Core. - Tervetuloa Bitcoin Core - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Tämän on ensimmäinen kerta kun Bitcoin Core on käynnistetty joten voit valita data-hakemiston paikan. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core lataa ja tallentaa kopion Bitcoinin lohkoketjusta. Vähintään %1GB dataa tullaan tallentamaan tähän hakemistoon ja tarve kasvaa ajan myötä. Lomakko tullaan myös tallentamaan tähän hakemistoon. - Use the default data directory Käytä oletuskansiota @@ -937,10 +547,6 @@ Use a custom data directory: Määritä oma kansio: - - Bitcoin Core - Bitcoin-ydin - Error: Specified data directory "%1" cannot be created. Virhe: Annettu datahakemistoa "%1" ei voida luoda. @@ -976,10 +582,6 @@ Select payment request file Valitse maksupyynnön tiedosto - - Select payment request file to open - Valitse maksypyynnön tiedosto avattavaksi - OptionsDialog @@ -1019,10 +621,6 @@ 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. Minimoi ikkuna ohjelman sulkemisen sijasta kun ikkuna suljetaan. Kun tämä asetus on käytössä, ohjelma suljetaan vain valittaessa valikosta Poistu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Käyttöliittymän kieli voidaan asettaa tässä. Tämä asetus tulee käyttöön vasta kun Bitcoin Core käynnistetään uudelleen. - 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 |. Ulkopuoliset URL-osoitteet (esim. block explorer,) jotka esiintyvät siirrot-välilehdellä valikossa. %s URL-osoitteessa korvataan siirtotunnuksella. Useampi URL-osoite on eroteltu pystyviivalla |. @@ -1047,14 +645,6 @@ &Network &Verkko - - Automatically start Bitcoin Core after logging in to the system. - Käynnistä Bitcoin Core automaattisesti järjestelmään kirjautumisen jälkeen. - - - &Start Bitcoin Core on system login - &Käynnistä Bitcoin Core järjestelmään kirjautuessa - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = jätä näin monta ydintä vapaaksi) @@ -1283,97 +873,6 @@ Nykyinen tase seurantaosoitetteissa - - PaymentServer - - URI handling - URI käsittely - - - Invalid payment address %1 - Virheellinen maksuosoite %1 - - - Payment request rejected - Maksupyyntö hylätty - - - Payment request network doesn't match client network. - Maksypyyntö verkossa ei täsmää asiakasohjelman verkkoon. - - - Payment request is not initialized. - Maksupyyntöä ei ole alustettu. - - - Requested payment amount of %1 is too small (considered dust). - Maksupyyntö %1 on liian pieni (huomioidaan tomuna). - - - Payment request error - Maksupyyntövirhe - - - Cannot start bitcoin: click-to-pay handler - Ei voida käynnistää bitcoin: klikkaa-maksu käsittelijää - - - Payment request fetch URL is invalid: %1 - Maksupyynnön haku URL on virheellinen: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URIa ei voitu jäsentää! Tämä voi johtua kelvottomasta Bitcoin-osoitteesta tai virheellisistä URI parametreista. - - - Payment request file handling - Maksupyynnön tiedoston käsittely - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Maksupyynnön tiedostoa ei voida lukea! Tämä voi aiheutua sopimattomasta maksupyyntötiedostosta. - - - Payment request expired. - Maksupyyntö on vanhentunut. - - - Unverified payment requests to custom payment scripts are unsupported. - Varmistamattomia maksupyyntöjä kustomoituun maksupalveluun ei tueta. - - - Invalid payment request. - Epäkelpo maksupyyntö. - - - Refund from %1 - Maksupalautus %1:sta - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua). - - - Error communicating with %1: %2 - Virhe kommunikoidessa %1n kanssa: %2 - - - Payment request cannot be parsed! - Maksupyyntöä ei voida jäsentää! - - - Bad response from server %1 - Huono vastaus palvelimelta %1 - - - Payment acknowledged - Rahansiirto tunnistettu - - - Network request error - Tietoverkon pyyntövirhe - - PeerTableModel @@ -1428,25 +927,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Tallenna kuva - - - &Copy Image - &Kopioi kuva - - - Save QR Code - Tallenna QR-koodi - - - PNG Image (*.png) - PNG kuva (*.png) - - RPCConsole @@ -1513,10 +993,6 @@ Memory usage Muistin käyttö - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Avaa Bitcoin Coren debug-loki tämänhetkisestä datahakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille. - Received Vastaanotetut @@ -1633,10 +1109,6 @@ Out: Ulos: - - Build date - Kääntöpäiväys - Debug log file Debug lokitiedosto @@ -1673,10 +1145,6 @@ &Unban Node &Poista solmukohdan esto - - Welcome to the Bitcoin Core RPC console. - Tervetuloa Bitcoin Coren RPC-konsoliin. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Ylös- ja alas-nuolet selaavat historiaa ja <b>Ctrl-L</b> tyhjentää ruudun. @@ -1804,18 +1272,6 @@ Remove Poista - - Copy label - Kopioi nimi - - - Copy message - Kopioi viesti - - - Copy amount - Kopioi määrä - ReceiveRequestDialog @@ -1835,73 +1291,6 @@ &Save Image... &Tallenna kuva - - Request payment to %1 - Vastaanota maksu %1 - - - Payment information - Maksutiedot - - - URI - URI - - - Address - Osoite - - - Amount - Määrä - - - Label - Nimi - - - Message - Viesti - - - Resulting URI too long, try to reduce the text for label / message. - Tuloksen URI liian pitkä, yritä lyhentää otsikon tekstiä / viestiä. - - - Error encoding URI into QR Code. - Virhe käännettäessä URI:a QR-koodiksi. - - - - RecentRequestsTableModel - - Date - Aika - - - Label - Nimi - - - Message - Viesti - - - Amount - Määrä - - - (no label) - (ei nimeä) - - - (no message) - (ei viestiä) - - - (no amount) - (ei määrää) - SendCoinsDialog @@ -2013,14 +1402,6 @@ fast nopea - - Send as zero-fee transaction if possible - Lähetä siirtokuluttomana jos mahdollista - - - (confirmation may take longer) - (vahvistaminen voi viedä kauemmin) - Send to multiple recipients at once Lähetä usealla vastaanottajalle samanaikaisesti @@ -2053,118 +1434,6 @@ S&end &Lähetä - - Confirm send coins - Hyväksy Bitcoinien lähettäminen - - - %1 to %2 - %1 to %2 - - - Copy quantity - Kopioi määrä - - - Copy amount - Kopioi määrä - - - Copy fee - Kopioi palkkio - - - Copy after fee - Kopioi palkkion jälkeen - - - Copy bytes - Kopioi tavut - - - Copy priority - Kopioi prioriteetti - - - Copy change - Kopioi vaihtoraha - - - Total Amount %1 - Kokonaismäärä %1 - - - or - tai - - - The amount to pay must be larger than 0. - Maksettavan summan tulee olla suurempi kuin 0 Bitcoinia. - - - The amount exceeds your balance. - Määrä ylittää käytettävissä olevan saldon. - - - The total exceeds your balance when the %1 transaction fee is included. - Kokonaismäärä ylittää saldosi kun %1 maksukulu lisätään summaan. - - - Transaction creation failed! - Rahansiirron luonti epäonnistui! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Rahansiirto hylättiin! Tämä saattaa tapahtua jos lompakossa olevat kolikot on jo kulutettu, kuten jos käytät kopioita wallet.dat tiedostosta ja kolikot oli jos käytetty mutta ei merkattu täällä. - - - A fee higher than %1 is considered an absurdly high fee. - Rahansiirtokulua %1 ja sitä suurempia määriä pidetään järjenvastaisen korkeana kuluna. - - - Payment request expired. - Maksupyyntö on vanhentunut. - - - Pay only the required fee of %1 - Maksa vain vaadittu kulu kooltaan %1 - - - Estimated to begin confirmation within %n block(s). - Vahvistuminen alkaa arviolta %n lohkon päästä.Vahvistuminen alkaa arviolta %n lohkon päästä. - - - The recipient address is not valid. Please recheck. - Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen. - - - Duplicate address found: addresses should only be used once each. - Duplikaattiosoite löytyi: kutakin osoitetta pitäisi käyttää vain kerran. - - - Warning: Invalid Bitcoin address - Varoitus: Virheellinen Bitcoin osoite - - - (no label) - (ei nimeä) - - - Warning: Unknown change address - Varoitus: Tuntematon vaihtorahan osoite - - - Copy dust - Kopioi tomu - - - Are you sure you want to send? - Haluatko varmasti lähettää? - - - added as transaction fee - lisätty rahansiirtomaksuna - SendCoinsEntry @@ -2176,10 +1445,6 @@ Pay &To: Maksun saaja: - - Enter a label for this address to add it to your address book - Anna nimi tälle osoitteelle, jos haluat lisätä sen osoitekirjaan - &Label: &Nimi: @@ -2247,10 +1512,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin core sulkeutuu... - Do not shut down the computer until this window disappears. Älä sammuta tietokonetta ennenkuin tämä ikkuna katoaa. @@ -2334,69 +1595,9 @@ Reset all verify message fields Tyhjennä kaikki varmista-viesti-kentät - - Click "Sign Message" to generate signature - Klikkaa "Allekirjoita Viesti luodaksesi allekirjoituksen - - - The entered address is invalid. - Syötetty osoite on virheellinen. - - - Please check the address and try again. - Tarkista osoite ja yritä uudelleen. - - - The entered address does not refer to a key. - Syötetyn osoitteen avainta ei löydy. - - - Wallet unlock was cancelled. - Lompakon avaaminen peruttiin. - - - Private key for the entered address is not available. - Yksityistä avainta syötetylle osoitteelle ei ole saatavilla. - - - Message signing failed. - Viestin allekirjoitus epäonnistui. - - - Message signed. - Viesti allekirjoitettu. - - - The signature could not be decoded. - Allekirjoitusta ei pystytty tulkitsemaan. - - - Please check the signature and try again. - Tarkista allekirjoitus ja yritä uudelleen. - - - The signature did not match the message digest. - Allekirjoitus ei täsmää viestin tiivisteeseen. - - - Message verification failed. - Viestin varmistus epäonnistui. - - - Message verified. - Viesti varmistettu. - SplashScreen - - Bitcoin Core - Bitcoin-ydin - - - The Bitcoin Core developers - Bitcoin Core kehittäjät - [testnet] [testnet] @@ -2409,422 +1610,13 @@ KB/s - - TransactionDesc - - Open until %1 - Avoinna %1 asti - - - conflicted - ristiriitainen - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/vahvistamaton - - - %1 confirmations - %1 vahvistusta - - - Status - Tila - - - , broadcast through %n node(s) - lähetetty %n noodin läpilähetetty %n noodin läpi - - - Date - Päivämäärä - - - Source - Lähde - - - Generated - Generoitu - - - From - Lähettäjä - - - To - Saaja - - - own address - oma osoite - - - watch-only - vain katseltava - - - label - nimi - - - Credit - Credit - - - matures in %n more block(s) - kypsyy %n lohkon kuluttuakypsyy %n lohkon kuluttua - - - not accepted - ei hyväksytty - - - Debit - Debit - - - Total debit - Yhteensä debit - - - Total credit - Yhteensä credit - - - Transaction fee - Maksukulu - - - Net amount - Netto määrä - - - Message - Viesti - - - Comment - Viesti - - - Transaction ID - Siirtotunnus - - - Merchant - Kauppias - - - 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. - Luodut kolikot täytyy kypsyttää %1 lohkoa kunnes ne voidaan käyttää. Kun loit tämän lohkon, se lähetettiin verkkoon lisänä lohkoketjuun. Jos se epäonnistuu pääsemään ketjuun sen tila tulee muuttumaan "ei hyväksytty" ja sitä ei voida käyttää. Tämä voi ajoittain tapahtua kun toisen solmun lohko luodaan samanaikaisesti omasi kanssa. - - - Debug information - Debug tiedot - - - Transaction - Rahansiirto - - - Inputs - Sisääntulot - - - Amount - Määrä - - - true - tosi - - - false - epätosi - - - , has not been successfully broadcast yet - , ei ole vielä onnistuneesti lähetetty - - - Open for %n more block(s) - Avoinna %n lisälohkolleAvoinna %n lisälohkolle - - - unknown - tuntematon - - TransactionDescDialog - - Transaction details - Rahansiirron yksityiskohdat - This pane shows a detailed description of the transaction Tämä ruutu näyttää yksityiskohtaisen tiedon rahansiirrosta - - TransactionTableModel - - Date - Päivämäärä - - - Type - Laatu - - - Immature (%1 confirmations, will be available after %2) - Epäkypsä (%1 varmistusta, saatavilla %2 jälkeen) - - - Open for %n more block(s) - Avoinna %n lisälohkolleAvoinna %n lisälohkolle - - - Open until %1 - Avoinna %1 asti - - - Confirmed (%1 confirmations) - Vahvistettu (%1 vahvistusta) - - - This block was not received by any other nodes and will probably not be accepted! - Tätä lohkoa ei vastaanotettu mistään muusta solmusta ja sitä ei mahdollisesti hyväksytä! - - - Generated but not accepted - Generoitu mutta ei hyväksytty - - - Offline - Offline - - - Label - Nimi - - - Unconfirmed - Varmistamaton - - - Confirming (%1 of %2 recommended confirmations) - Varmistetaan (%1 kehoitetusta %2 varmistuksesta) - - - Conflicted - Ristiriitainen - - - Received with - Vastaanotettu osoitteella - - - Received from - Vastaanotettu - - - Sent to - Saaja - - - Payment to yourself - Maksu itsellesi - - - Mined - Louhittu - - - watch-only - vain katseltava - - - (n/a) - (ei saatavilla) - - - Transaction status. Hover over this field to show number of confirmations. - Rahansiirron tila. Siirrä osoitin kentän päälle nähdäksesi vahvistusten lukumäärä. - - - Date and time that the transaction was received. - Rahansiirron vastaanottamisen päivämäärä ja aika. - - - Type of transaction. - Rahansiirron laatu. - - - Whether or not a watch-only address is involved in this transaction. - Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei. - - - User-defined intent/purpose of the transaction. - Käyttäjän määrittämä käyttötarkoitus rahansiirrolle. - - - Amount removed from or added to balance. - Saldoon lisätty tai siitä vähennetty määrä. - - - - TransactionView - - All - Kaikki - - - Today - Tänään - - - This week - Tällä viikolla - - - This month - Tässä kuussa - - - Last month - Viime kuussa - - - This year - Tänä vuonna - - - Range... - Alue... - - - Received with - Vastaanotettu osoitteella - - - Sent to - Saaja - - - To yourself - Itsellesi - - - Mined - Louhittu - - - Other - Muu - - - Enter address or label to search - Anna etsittävä osoite tai tunniste - - - Min amount - Minimimäärä - - - Copy address - Kopioi osoite - - - Copy label - Kopioi nimi - - - Copy amount - Kopioi määrä - - - Copy transaction ID - Kopioi siirtotunnus - - - Copy raw transaction - Kopioi rahansiirron raakavedos - - - Edit label - Muokkaa nimeä - - - Show transaction details - Näytä rahansiirron yksityiskohdat - - - Export Transaction History - Vie rahansiirtohistoria - - - Watch-only - Vain katseltava - - - Exporting Failed - Vienti epäonnistui - - - There was an error trying to save the transaction history to %1. - Rahansiirron historian tallentamisessa tapahtui virhe paikkaan %1. - - - Exporting Successful - Vienti onnistui - - - The transaction history was successfully saved to %1. - Rahansiirron historia tallennettiin onnistuneesti paikkaan %1. - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Confirmed - Vahvistettu - - - Date - Aika - - - Type - Laatu - - - Label - Nimi - - - Address - Osoite - - - ID - ID - - - Range: - Alue: - - - to - kenelle - - UnitDisplayStatusBarControl @@ -2832,55 +1624,6 @@ Yksikkö jossa määrät näytetään. Klikkaa valitaksesi toisen yksikön. - - WalletFrame - - No wallet has been loaded. - Lomakkoa ei ole ladattu. - - - - WalletModel - - Send Coins - Lähetä Bitcoineja - - - - WalletView - - &Export - &Vie... - - - Export the data in the current tab to a file - Vie auki olevan välilehden tiedot tiedostoon - - - Backup Wallet - Varmuuskopioi lompakko - - - Wallet Data (*.dat) - Lompakkodata (*.dat) - - - Backup Failed - Varmuuskopio epäonnistui - - - There was an error trying to save the wallet data to %1. - Lompakon tallennuksessa tapahtui virhe %1. - - - The wallet data was successfully saved to %1. - Lompakko tallennettiin onnistuneesti tiedostoon %1. - - - Backup Successful - Varmuuskopio Onnistui - - bitcoin-core @@ -2907,10 +1650,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Jos <category> on toimittamatta tai jos <category> = 1, tulosta kaikki debug-tieto. - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Tarkistathan että tietokoneesi päivämäärä ja kellonaika ovat oikeassa! Jos kellosi on väärässä, Bitcoin Core ei toimi oikein. - Prune configured below the minimum of %d MiB. Please use a higher number. Karsinta konfiguroitu alle minimin %d MiB. Käytä surempaa numeroa. @@ -2951,6 +1690,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Hyväksy yhteyksiä ulkopuolelta (vakioasetus: 1 jos -proxy tai -connect ei määritelty) + + Bitcoin Core + Bitcoin-ydin + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee on asetettu erittäin suureksi! Tämä on rahansiirtokulu jonka voit maksaa kun arvioitu rahansirtokulu ei ole saatavilla. @@ -2971,10 +1714,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Tämä on esi-julkaistu testiversio - Käytä omalla riskillä - Ei saa käytää louhimiseen tai kauppasovelluksiin. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Käytä UPnP:ta kuuntelevan portin kartoitukseen (oletus: 1 kun kuunnellaan ja -proxy ei käytössä) @@ -2995,10 +1734,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Varoitus: Olemme vertaisverkon kanssa ristiriidassa! Sinun tulee päivittää tai toisten solmujen tulee päivitää. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Salli vertaisten yhdistää annetusta verkkomaskista tai IP-osoitteesta. Voidaan määrittää useampia kertoja. @@ -3123,18 +1858,10 @@ Wallet options: Lompakon valinnat: - - You need to rebuild the database using -reindex to change -txindex - Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Salli JSON-RPC-yhteydet määritetystä lähteestä. Kelvolliset arvot <ip> ovat yksittäinen IP (esim. 1.2.3.4), verkko/verkkomaski (esim. 1.2.3.4/255.255.255.0) tai verkko/luokaton reititys (esim. 1.2.3.4/24). Tätä valintatapaa voidaan käyttää useita kertoja - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Ei voida lukita data-hakemistoa %s. Bitcoin Core on luultavasti jo käynnissä. - Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) Paljasta omat IP-osoitteet (oletus: 1 kun kuunnellaan ja -externalip tai -proxy ei ole käytössä) @@ -3147,10 +1874,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Aseta maksimikoko korkea prioriteetti/pieni palkkio rahansiirtoihin tavuissa (oletus: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Aseta kolikoiden luomiseen tarkoitettujen säikeiden lukumäärä (-1 = kaikki ytimet, oletus: %d) - (default: %u) (oletus: %u) @@ -3159,30 +1882,10 @@ Accept public REST requests (default: %u) Hyväksy julkisia REST-pyyntöjä (oletus: %u) - - Activating best chain... - Aktivoidaan parhainta ketjua... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Yritä palauttaa yksityiset avaimet korruptoituneesta wallet.dat-tiedostosta käynnistyksen yhteydessä - - - Cannot resolve -whitebind address: '%s' - -whitebind -osoitetta '%s' ei voida jäsentää - Connect through SOCKS5 proxy Yhdistä SOCKS5 proxin kautta - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Bitcoin kehittäjät - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista - Error reading from database, shutting down. Virheitä tietokantaa luettaessa, ohjelma pysäytetään. @@ -3191,18 +1894,6 @@ Information Tietoa - - Invalid amount for -maxtxfee=<amount>: '%s' - Virheellinen määrä -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Virheellinen määrä -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Virheellinen määrä -mintxfee=<amount>: '%s' - Keep at most <n> unconnectable transactions in memory (default: %u) Pidä enimmillään <n> yhdistämiskelvotonta rahansiirtoa muistissa (oletus: %u) @@ -3215,10 +1906,6 @@ RPC server options: RPC-palvelimen valinnat: - - Receive and display P2P network alerts (default: %u) - Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u) - Rescan the block chain for missing wallet transactions on startup Uudelleenskannaa lohkoketju käynnistyksen yhteydessä puuttuvien lompakon rahansiirtojen vuoksi @@ -3279,10 +1966,6 @@ Username for JSON-RPC connections Käyttäjätunnus JSON-RPC-yhteyksille - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Lompakko tarvitsee uudelleenkirjoittaa: käynnistä Bitcoin uudelleen - Warning Varoitus @@ -3299,10 +1982,6 @@ ZeroMQ notification options: ZeroMQ-ilmoitusasetukset: - - wallet.dat corrupt, salvage failed - wallet.dat -lompakkotiedosto korruptoitunut, korjaaminen epäonnistui - Password for JSON-RPC connections Salasana JSON-RPC-yhteyksille @@ -3311,10 +1990,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Suorita käsky kun paras lohko muuttuu (%s cmd on vaihdettu block hashin kanssa) - - This help message - Tämä ohjeviesti - Allow DNS lookups for -addnode, -seednode and -connect Salli DNS kyselyt -addnode, -seednode ja -connect yhteydessä @@ -3323,10 +1998,6 @@ Loading addresses... Ladataan osoitteita... - - Error loading wallet.dat: Wallet corrupted - Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut - -maxtxfee is set very high! Fees this large could be paid on a single transaction. -maxtxfee on asetettu erittäin suureksi! Tämänkokoisia kuluja saatetaan maksaa yhdessä rahansiirrossa. @@ -3339,10 +2010,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Älä pidä rahansiirtoja muistivarannoissa kauemmin kuin <n> tuntia (oletus: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Virhe lukiessa wallet.dat-tiedostoa! Kaikki avaimet luettiin onnistuneesti, mutta rahansiirtotiedot tai osoitekirjan sisältö saattavat olla muuttuneita tai vääriä. - How thorough the block verification of -checkblocks is (0-4, default: %u) Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) @@ -3359,14 +2026,6 @@ Always query for peer addresses via DNS lookup (default: %u) Pyydä vertaisten osoitteita aina DNS-kyselyjen avulla (oletus: %u) - - Error loading wallet.dat - Virhe ladattaessa wallet.dat-tiedostoa - - - Generate coins (default: %u) - Luo kolikoita (oletus: %u) - How many blocks to check at startup (default: %u, 0 = all) Kuinka monta lohkoa tarkistetaan käynnistyksessä (oletus: %u, 0 = kaikki) @@ -3451,18 +2110,6 @@ Unknown network specified in -onlynet: '%s' Tuntematon verkko -onlynet parametrina: '%s' - - Cannot resolve -bind address: '%s' - -bind osoitteen '%s' selvittäminen epäonnistui - - - Cannot resolve -externalip address: '%s' - -externalip osoitteen '%s' selvittäminen epäonnistui - - - Invalid amount for -paytxfee=<amount>: '%s' - -paytxfee=<amount>: '%s' on virheellinen - Insufficient funds Lompakon saldo ei riitä diff --git a/src/qt/locale/bitcoin_fil.ts b/src/qt/locale/bitcoin_fil.ts deleted file mode 100644 index fba823837..000000000 --- a/src/qt/locale/bitcoin_fil.ts +++ /dev/null @@ -1,157 +0,0 @@ - - - AddressBookPage - - Create a new address - Gumawa ng bagong address - - - Copy the currently selected address to the system clipboard - Kopyahin ang napiling tahanan sa clipboard - - - &Copy - Kumopya - - - C&lose - Isarado - - - &Copy Address - Tumulad ng kinatatahanan - - - Delete the currently selected address from the list - Alisin ang napiling address sa pagpipilian - - - Choose the address to send coins to - Pumili ng pagpapadalahang address - - - Choose the address to receive coins with - Piliin ang address ng nagpadala - - - C&hoose - Piliin - - - Sending addresses - Address pagpapadala - - - Receiving addresses - Address bilang pagtanggap - - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 65808c774..fe745f99b 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -15,7 +15,7 @@ Copy the currently selected address to the system clipboard - Copier l'adresse courante sélectionnée dans le presse-papiers + Copier l'adresse sélectionnée actuellement dans le presse-papiers &Copy @@ -25,17 +25,13 @@ C&lose &Fermer - - &Copy Address - &Copier l'adresse - Delete the currently selected address from the list - Supprimer l'adresse actuellement sélectionnée de la liste + Supprimer de la liste l'adresse sélectionnée actuellement Export the data in the current tab to a file - Exporter les données de l'onglet courant vers un fichier + Exporter les données de l'onglet actuel vers un fichier &Export @@ -45,73 +41,6 @@ &Delete &Supprimer - - Choose the address to send coins to - Choisir l'adresse à laquelle envoyer des pièces - - - Choose the address to receive coins with - Choisir l'adresse avec laquelle recevoir des pièces - - - C&hoose - C&hoisir - - - Sending addresses - Adresses d'envoi - - - Receiving addresses - Adresses de réception - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Voici vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l'adresse du destinataire avant d'envoyer des pièces. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Voici vos adresses Bitcoin pour recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction. - - - Copy &Label - Copier l'é&tiquette - - - &Edit - &Modifier - - - Export Address List - Exporter la liste d'adresses - - - Comma separated file (*.csv) - Valeurs séparées par des virgules (*.csv) - - - Exporting Failed - L'exportation a échoué - - - There was an error trying to save the address list to %1. Please try again. - Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez ressayer plus tard. - - - - AddressTableModel - - Label - Étiquette - - - Address - Adresse - - - (no label) - (aucune étiquette) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Répéter la phrase de passe - - Encrypt wallet - Chiffrer le portefeuille - - - This operation needs your wallet passphrase to unlock the wallet. - Cette opération nécessite votre phrase de passe pour déverrouiller le portefeuille. - - - Unlock wallet - Déverrouiller le portefeuille - - - This operation needs your wallet passphrase to decrypt the wallet. - Cette opération nécessite votre phrase de passe pour déchiffrer le portefeuille. - - - Decrypt wallet - Déchiffrer le portefeuille - - - Change passphrase - Changer la phrase de passe - - - Confirm wallet encryption - Confirmer le chiffrement du portefeuille - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avertissement : si vous chiffrez votre portefeuille et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! - - - Are you sure you wish to encrypt your wallet? - Êtes-vous sûr de vouloir chiffrer votre portefeuille ? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core va maintenant se fermer pour terminer le processus de chiffrement. Souvenez-vous que le chiffrement de votre portefeuille ne peut pas vous protéger complètement contre le vol de vos bitcoins par des programmes malveillants infectant votre ordinateur. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT : Toute sauvegarde précédente de votre fichier de portefeuille devrait être remplacée par le nouveau fichier de portefeuille chiffré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de portefeuille non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau portefeuille chiffré. - - - Warning: The Caps Lock key is on! - Avertissement : la touche Verr. Maj. est activée ! - - - Wallet encrypted - Portefeuille chiffré - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Saisissez une nouvelle phrase de passe pour le portefeuille.<br/>Veuillez utiliser une phrase composée de <b>dix caractères aléatoires ou plus</b>, ou bien de <b>huit mots ou plus</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Saisir l'ancienne phrase de passe puis la nouvelle phrase de passe du portefeuille. - - - Wallet encryption failed - Le chiffrement du portefeuille a échoué - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Le chiffrement du portefeuille a échoué en raison d'une erreur interne. Votre portefeuille n'a pas été chiffré. - - - The supplied passphrases do not match. - Les phrases de passe saisies ne correspondent pas. - - - Wallet unlock failed - Le déverrouillage du portefeuille a échoué - - - The passphrase entered for the wallet decryption was incorrect. - La phrase de passe saisie pour déchiffrer le portefeuille était incorrecte. - - - Wallet decryption failed - Le déchiffrage du portefeuille a échoué - - - Wallet passphrase was successfully changed. - La phrase de passe du portefeuille a été modifiée avec succès. - BanTableModel @@ -251,7 +92,7 @@ Show general overview of wallet - Afficher une vue d’ensemble du portefeuille + Afficher une vue d’ensemble du porte-monnaie &Transactions @@ -269,6 +110,14 @@ Quit application Quitter l’application + + &About %1 + À &propos de %1 + + + Show information about %1 + Afficher des informations à propos de %1 + About &Qt À propos de &Qt @@ -281,13 +130,17 @@ &Options... &Options… + + Modify configuration options for %1 + Modifier les options de configuration de %1 + &Encrypt Wallet... - &Chiffrer le portefeuille... + &Chiffrer le porte-monnaie... &Backup Wallet... - Sauvegarder le &portefeuille... + Sauvegarder le &porte-monnaie... &Change Passphrase... @@ -305,14 +158,6 @@ Open &URI... Ouvrir un &URI... - - Bitcoin Core client - Client Bitcoin Core - - - Importing blocks from disk... - Importation des blocs à partir du disque... - Reindexing blocks on disk... Réindexation des blocs sur le disque... @@ -323,11 +168,11 @@ Backup wallet to another location - Sauvegarder le portefeuille vers un autre emplacement + Sauvegarder le porte-monnaie vers un autre emplacement Change the passphrase used for wallet encryption - Modifier la phrase de passe utilisée pour le chiffrement du portefeuille + Modifier la phrase de passe utilisée pour le chiffrement du porte-monnaie &Debug window @@ -347,7 +192,7 @@ Wallet - Portefeuille + Porte-monnaie &Send @@ -357,10 +202,6 @@ &Receive &Recevoir - - Show information about Bitcoin Core - Montrer des informations à propos de Bitcoin Core - &Show / Hide &Afficher / Cacher @@ -371,7 +212,7 @@ Encrypt the private keys that belong to your wallet - Chiffrer les clefs privées de votre portefeuille + Chiffrer les clefs privées de votre porte-monnaie Sign messages with your Bitcoin addresses to prove you own them @@ -397,22 +238,10 @@ Tabs toolbar Barre d'outils des onglets - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Demander des paiements (génère des codes QR et des URIs bitcoin:) - - &About Bitcoin Core - À &propos de Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifier les options de configuration de Bitcoin Core - Show the list of used sending addresses and labels Afficher la liste d'adresses d'envoi et d'étiquettes utilisées @@ -429,14 +258,18 @@ &Command-line options Options de ligne de &commande - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Afficher le message d'aide de Bitcoin Core pour obtenir une liste des options de ligne de commande Bitcoin possibles. - %n active connection(s) to Bitcoin network %n connexion active avec le réseau Bitcoin%n connexions actives avec le réseau Bitcoin + + Indexing blocks on disk... + Indexation des blocs sur le disque... + + + Processing blocks on disk... + Traitement des blocs sur le disque... + No block source available... Aucune source de blocs disponible... @@ -493,6 +326,14 @@ Up to date À jour + + Show the %1 help message to get a list with possible Bitcoin command-line options + Afficher le message d'aide de %1 pour obtenir la liste des options de ligne de commande Bitcoin possibles. + + + %1 client + Client %1 + Catching up... Rattrapage en cours… @@ -537,18 +378,11 @@ Wallet is <b>encrypted</b> and currently <b>unlocked</b> - Le portefeuille est <b>chiffré</b> et est actuellement <b>déverrouillé</b> + Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b> Wallet is <b>encrypted</b> and currently <b>locked</b> - Le portefeuille est <b>chiffré</b> et actuellement <b>verrouillé</b> - - - - ClientModel - - Network Alert - Alerte réseau + Le porte-monnaie est <b>chiffré</b> et actuellement <b>verrouillé</b> @@ -629,150 +463,6 @@ Priority Priorité - - Copy address - Copier l’adresse - - - Copy label - Copier l’étiquette - - - Copy amount - Copier le montant - - - Copy transaction ID - Copier l'ID de la transaction - - - Lock unspent - Verrouiller ce qui n'est pas dépensé - - - Unlock unspent - Déverrouiller ce qui n'est pas dépensé - - - Copy quantity - Copier la quantité - - - Copy fee - Copier les frais - - - Copy after fee - Copier le montant après les frais - - - Copy bytes - Copier les octets - - - Copy priority - Copier la priorité - - - Copy dust - Copier la poussière - - - Copy change - Copier la monnaie - - - highest - la plus élevée - - - higher - plus élevée - - - high - élevée - - - medium-high - moyennement-élevée - - - medium - moyenne - - - low-medium - moyennement-basse - - - low - basse - - - lower - plus basse - - - lowest - la plus basse - - - (%1 locked) - (%1 verrouillé) - - - none - aucun - - - This label turns red if the transaction size is greater than 1000 bytes. - Cette étiquette devient rouge si la taille de la transaction est plus grande que 1 000 octets. - - - This label turns red if the priority is smaller than "medium". - Cette étiquette devient rouge si la priorité est plus basse que « moyenne ». - - - This label turns red if any recipient receives an amount smaller than %1. - Cette étiquette devient rouge si un destinataire reçoit un montant inférieur à %1. - - - Can vary +/- %1 satoshi(s) per input. - Peut varier +/- %1 satoshi(s) par entrée. - - - yes - oui - - - no - non - - - This means a fee of at least %1 per kB is required. - Ceci signifie que des frais d'au moins %1 par ko sont exigés. - - - Can vary +/- 1 byte per input. - Peut varier +/- 1 octet par entrée. - - - Transactions with higher priority are more likely to get included into a block. - Les transactions à priorité plus haute sont plus à même d'être incluses dans un bloc. - - - (no label) - (aucune étiquette) - - - change from %1 (%2) - monnaie de %1 (%2) - - - (change) - (monnaie) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adresse - - New receiving address - Nouvelle adresse de réception - - - New sending address - Nouvelle adresse d’envoi - - - Edit receiving address - Modifier l’adresse de réception - - - Edit sending address - Modifier l’adresse d'envoi - - - The entered address "%1" is already in the address book. - L’adresse fournie « %1 » est déjà présente dans le carnet d'adresses. - - - The entered address "%1" is not a valid Bitcoin address. - L'adresse fournie « %1 » n'est pas une adresse Bitcoin valide. - - - Could not unlock wallet. - Impossible de déverrouiller le portefeuille. - - - New key generation failed. - Échec de génération de la nouvelle clef. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - À propos de Bitcoin Core + About %1 + À propos de %1 Command-line options @@ -907,8 +561,8 @@ Afficher l'écran d'accueil au démarrage (par défaut : %u) - Reset all settings changes made over the GUI - Réinitialiser tous les changements de paramètres appliqués à l'IUG + Reset all settings changed in the GUI + Réinitialiser tous les paramètres changés dans l'IUG @@ -918,16 +572,16 @@ Bienvenue - Welcome to Bitcoin Core. - Bienvenue à Bitcoin Core. + Welcome to %1. + Bienvenue à %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Comme c'est la première fois que le logiciel est lancé, vous pouvez choisir où Bitcoin Core stockera ses données. + As this is the first time the program is launched, you can choose where %1 will store its data. + Puisque c'est la première fois que le logiciel est lancé, vous pouvez choisir où %1 stockera ses données. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core va télécharger et stocker une copie de la chaîne de blocs Bitcoin. Au moins %1Go de données seront stockées dans ce répertoire et cela augmentera avec le temps. Le portefeuille sera également stocké dans ce répertoire. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 téléchargera et stockera une copie de la chaîne de blocs de Bitcoin. Au moins %2 Go de données seront stockés dans ce répertoire et sa taille augmentera avec le temps. Le porte-monnaie sera également stocké dans ce répertoire. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Utiliser un répertoire de données personnalisé : - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Erreur : le répertoire de données spécifié « %1 » ne peut pas être créé. @@ -976,10 +626,6 @@ Select payment request file Choisir le fichier de demande de paiement - - Select payment request file to open - Choisir le fichier de demande de paiement à ouvrir - OptionsDialog @@ -991,6 +637,14 @@ &Main Réglages &principaux + + Automatically start %1 after logging in to the system. + Démarrer %1 automatiquement après avoir ouvert une session sur l'ordinateur. + + + &Start %1 on system login + &Démarrer %1 lors de l'ouverture d'une session + Size of &database cache Taille du cache de la base de &données @@ -1019,10 +673,6 @@ 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. Minimiser au lieu de quitter l'application lorsque la fenêtre est fermée. Si cette option est activée, l'application ne sera fermée qu'en sélectionnant Quitter dans le menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - La langue de l'interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de Bitcoin. - 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 |. URL de tiers (par ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. @@ -1047,21 +697,13 @@ &Network &Réseau - - Automatically start Bitcoin Core after logging in to the system. - Démarrer Bitcoin Core automatiquement après avoir ouvert une session sur le système. - - - &Start Bitcoin Core on system login - &Démarrer Bitcoin Core lors de l'ouverture d'une session - (0 = auto, <0 = leave that many cores free) (0 = auto, < 0 = laisser ce nombre de cœurs inutilisés) W&allet - &Portefeuille + &Porte-monnaie Expert @@ -1139,6 +781,14 @@ &Window &Fenêtre + + &Hide the icon from the system tray. + &Cacher l'icône dans la zone de notification. + + + Hide tray icon + Cacher l'icône de la zone de notification + Show only a tray icon after minimizing the window. Afficher uniquement une icône système après minimisation. @@ -1159,6 +809,10 @@ User Interface &language: &Langue de l'interface utilisateur : + + The user interface language can be set here. This setting will take effect after restarting %1. + La langue de l'interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de %1. + &Unit to show amounts in: &Unité d'affichage des montants : @@ -1216,7 +870,7 @@ 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. - Les informations affichées peuvent être obsolètes. Votre portefeuille est automatiquement synchronisé avec le réseau Bitcoin lorsque la connexion s'établit, or ce processus n'est pas encore terminé. + Les informations affichées peuvent être obsolètes. Votre porte-monnaie est automatiquement synchronisé avec le réseau Bitcoin lorsque la connexion s'établit, or ce processus n'est pas encore terminé. Watch-only: @@ -1283,97 +937,6 @@ Solde total actuel dans des adresses juste-regarder - - PaymentServer - - URI handling - Gestion des URIs - - - Invalid payment address %1 - Adresse de paiement invalide %1 - - - Payment request rejected - La demande de paiement est rejetée - - - Payment request network doesn't match client network. - Le réseau de la demande de paiement ne correspond pas au réseau du client. - - - Payment request is not initialized. - La demande de paiement n'est pas initialisée. - - - Requested payment amount of %1 is too small (considered dust). - Le paiement demandé d'un montant de %1 est trop faible (considéré comme de la poussière). - - - Payment request error - Erreur de demande de paiement - - - Cannot start bitcoin: click-to-pay handler - Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin : - - - Payment request fetch URL is invalid: %1 - L'URL de récupération de la demande de paiement est invalide : %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L'URI ne peut pas être analysé ! Ceci peut être causé par une adresse Bitcoin invalide ou par des paramètres d'URI mal formés. - - - Payment request file handling - Gestion des fichiers de demande de paiement - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Le fichier de demande de paiement ne peut pas être lu ! Ceci peut être causé par un fichier de demande de paiement invalide. - - - Payment request expired. - Demande de paiement expirée. - - - Unverified payment requests to custom payment scripts are unsupported. - Les demandes de paiements non vérifiées à des scripts de paiement personnalisés ne sont pas prises en charge. - - - Invalid payment request. - Demande de paiement invalide. - - - Refund from %1 - Remboursement de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La demande de paiement %1 est trop grande (%2 octets, %3 octets permis). - - - Error communicating with %1: %2 - Erreur de communication avec %1 : %2 - - - Payment request cannot be parsed! - La demande de paiement ne peut pas être analysée ! - - - Bad response from server %1 - Mauvaise réponse du serveur %1 - - - Payment acknowledged - Le paiement a été confirmé - - - Network request error - Erreur de demande réseau - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Sauvegarder l'image... - - - &Copy Image - &Copier l'image - - - Save QR Code - Sauvegarder le code QR - - - PNG Image (*.png) - Image PNG (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Version BerkeleyDB utilisée + + Datadir + Datadir + Startup time Heure de démarrage @@ -1513,10 +1061,6 @@ Memory usage Utilisation de la mémoire - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation. - Received Reçu @@ -1565,6 +1109,18 @@ User Agent Agent utilisateur + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Ouvrir le journal de débogage de %1 depuis le répertoire de données actuel. Ceci peut prendre quelques secondes pour les journaux de grande taille. + + + Decrease font size + Diminuer la taille de police + + + Increase font size + Augmenter la taille de police + Services Services @@ -1633,10 +1189,6 @@ Out: Sortant : - - Build date - Date de compilation - Debug log file Journal de débogage @@ -1674,8 +1226,8 @@ &Réhabiliter le nœud - Welcome to the Bitcoin Core RPC console. - Bienvenue dans le console RPC de Bitcoin Core. + Welcome to the %1 RPC console. + Bienvenue sur la console RPC de %1. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove Enlever - - Copy label - Copier l’étiquette - - - Copy message - Copier le message - - - Copy amount - Copier le montant - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... &Sauvegarder l'image... - - Request payment to %1 - Demande de paiement à %1 - - - Payment information - Informations de paiement - - - URI - URI - - - Address - Adresse - - - Amount - Montant - - - Label - Étiquette - - - Message - Message - - - Resulting URI too long, try to reduce the text for label / message. - L'URI résultant est trop long, essayez de réduire le texte d'étiquette / de message. - - - Error encoding URI into QR Code. - Erreur d'encodage de l'URI en code QR. - - - - RecentRequestsTableModel - - Date - Date - - - Label - Étiquette - - - Message - Message - - - Amount - Montant - - - (no label) - (pas d'étiquette) - - - (no message) - (pas de message) - - - (no amount) - (aucun montant) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast rapide - - Send as zero-fee transaction if possible - Envoyer si possible une transaction sans frais - - - (confirmation may take longer) - (la confirmation pourrait prendre plus longtemps) - Send to multiple recipients at once Envoyer à plusieurs destinataires à la fois @@ -2061,118 +1526,6 @@ S&end E&nvoyer - - Confirm send coins - Confirmer l’envoi des pièces - - - %1 to %2 - %1 à %2 - - - Copy quantity - Copier la quantité - - - Copy amount - Copier le montant - - - Copy fee - Copier les frais - - - Copy after fee - Copier le montant après les frais - - - Copy bytes - Copier les octets - - - Copy priority - Copier la priorité - - - Copy change - Copier la monnaie - - - Total Amount %1 - Montant total %1 - - - or - ou - - - The amount to pay must be larger than 0. - Le montant à payer doit être supérieur à 0. - - - The amount exceeds your balance. - Le montant dépasse votre solde. - - - The total exceeds your balance when the %1 transaction fee is included. - Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus. - - - Transaction creation failed! - La création de la transaction a échoué ! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - La transaction a été rejetée ! Ceci peut arriver si certaines pièces de votre portefeuille étaient déjà dépensées, par exemple si vous avez utilisé une copie de wallet.dat et que des pièces ont été dépensées dans la copie sans être marquées comme telles ici. - - - A fee higher than %1 is considered an absurdly high fee. - Des frais supérieurs à %1 sont considérés comme ridiculement élevés. - - - Payment request expired. - Demande de paiement expirée. - - - Pay only the required fee of %1 - Payer seulement les frais exigés de %1 - - - Estimated to begin confirmation within %n block(s). - Il est estimé que la confirmation commencera dans %n bloc.Il est estimé que la confirmation commencera dans %n blocs. - - - The recipient address is not valid. Please recheck. - L'adresse du destinataire est invalide. Veuillez la vérifier. - - - Duplicate address found: addresses should only be used once each. - Adresse identique trouvée : chaque adresse ne devrait être utilisée qu'une fois. - - - Warning: Invalid Bitcoin address - Avertissement : adresse Bitcoin invalide - - - (no label) - (pas d'étiquette) - - - Warning: Unknown change address - Avertissement : adresse de monnaie rendue inconnue - - - Copy dust - Copier la poussière - - - Are you sure you want to send? - Êtes-vous sûr de vouloir envoyer ? - - - added as transaction fee - ajouté en tant que frais de transaction - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: &Payer à : - - Enter a label for this address to add it to your address book - Saisir une étiquette pour cette adresse afin de l’ajouter à votre carnet d’adresses - &Label: É&tiquette : @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Arrêt de Bitcoin Core... + %1 is shutting down... + Arrêt de %1... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields Réinitialiser tous les champs de vérification de message - - Click "Sign Message" to generate signature - Cliquez sur « Signer le message » pour générer la signature - - - The entered address is invalid. - L'adresse saisie est invalide. - - - Please check the address and try again. - Veuillez vérifier l'adresse et réessayer. - - - The entered address does not refer to a key. - L'adresse saisie ne fait pas référence à une clef. - - - Wallet unlock was cancelled. - Le déverrouillage du portefeuille a été annulé. - - - Private key for the entered address is not available. - La clef privée n'est pas disponible pour l'adresse indiquée. - - - Message signing failed. - La signature du message a échoué. - - - Message signed. - Le message a été signé. - - - The signature could not be decoded. - La signature n'a pu être décodée. - - - Please check the signature and try again. - Veuillez vérifier la signature et réessayer. - - - The signature did not match the message digest. - La signature ne correspond pas à l'empreinte du message. - - - Message verification failed. - Échec de la vérification du message. - - - Message verified. - Message vérifié. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Les développeurs Bitcoin Core - [testnet] [testnet] @@ -2429,422 +1718,13 @@ Ko/s - - TransactionDesc - - Open until %1 - Ouvert jusqu'à %1 - - - conflicted - en conflit - - - %1/offline - %1/hors ligne - - - %1/unconfirmed - %1/non confirmée - - - %1 confirmations - %1 confirmations - - - Status - État - - - , broadcast through %n node(s) - , diffusée à travers %n nœud, diffusée à travers %n nœuds - - - Date - Date - - - Source - Source - - - Generated - Généré - - - From - De - - - To - À - - - own address - votre propre adresse - - - watch-only - juste-regarder - - - label - étiquette - - - Credit - Crédit - - - matures in %n more block(s) - arrive à maturité dans %n bloc de plusarrive à maturité dans %n blocs de plus - - - not accepted - refusé - - - Debit - Débit - - - Total debit - Débit total - - - Total credit - Crédit total - - - Transaction fee - Frais de transaction - - - Net amount - Montant net - - - Message - Message - - - Comment - Commentaire - - - Transaction ID - ID de la transaction - - - Merchant - Marchand - - - 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. - Les pièces générées doivent mûrir pendant %1 blocs avant de pouvoir être dépensées. Lorsque vous avez généré ce bloc, il a été diffusé sur le réseau pour être ajouté à la chaîne de blocs. S’il échoue a intégrer la chaîne, son état sera modifié en « non accepté » et il ne sera pas possible de le dépenser. Ceci peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du votre. - - - Debug information - Informations de débogage - - - Transaction - Transaction - - - Inputs - Entrants - - - Amount - Montant - - - true - vrai - - - false - faux - - - , has not been successfully broadcast yet - , n’a pas encore été diffusée avec succès - - - Open for %n more block(s) - Ouvert pour %n bloc de plusOuvert pour %n blocs de plus - - - unknown - inconnu - - TransactionDescDialog - - Transaction details - Détails de la transaction - This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - - TransactionTableModel - - Date - Date - - - Type - Type - - - Immature (%1 confirmations, will be available after %2) - Immature (%1 confirmations, sera disponible après %2) - - - Open for %n more block(s) - Ouvert pour %n bloc de plusOuvert pour %n blocs de plus - - - Open until %1 - Ouvert jusqu'à %1 - - - Confirmed (%1 confirmations) - Confirmée (%1 confirmations) - - - This block was not received by any other nodes and will probably not be accepted! - Ce bloc n’a été reçu par aucun autre nœud et ne sera probablement pas accepté ! - - - Generated but not accepted - Généré mais pas accepté - - - Offline - Hors ligne - - - Label - Étiquette - - - Unconfirmed - Non confirmé - - - Confirming (%1 of %2 recommended confirmations) - Confirmation (%1 sur %2 confirmations recommandées) - - - Conflicted - En conflit - - - Received with - Reçue avec - - - Received from - Reçue de - - - Sent to - Envoyée à - - - Payment to yourself - Paiement à vous-même - - - Mined - Miné - - - watch-only - juste-regarder - - - (n/a) - (n.d) - - - Transaction status. Hover over this field to show number of confirmations. - État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations. - - - Date and time that the transaction was received. - Date et heure de réception de la transaction. - - - Type of transaction. - Type de transaction. - - - Whether or not a watch-only address is involved in this transaction. - Une adresse juste-regarder est-elle impliquée dans cette transaction. - - - User-defined intent/purpose of the transaction. - Intention/but de la transaction défini par l'utilisateur. - - - Amount removed from or added to balance. - Montant ajouté ou enlevé au solde. - - - - TransactionView - - All - Toutes - - - Today - Aujourd’hui - - - This week - Cette semaine - - - This month - Ce mois-ci - - - Last month - Le mois dernier - - - This year - Cette année - - - Range... - Intervalle… - - - Received with - Reçue avec - - - Sent to - Envoyée à - - - To yourself - À vous-même - - - Mined - Miné - - - Other - Autres - - - Enter address or label to search - Saisir une adresse ou une étiquette à rechercher - - - Min amount - Montant min. - - - Copy address - Copier l’adresse - - - Copy label - Copier l’étiquette - - - Copy amount - Copier le montant - - - Copy transaction ID - Copier l'ID de la transaction - - - Copy raw transaction - Copier la transaction brute - - - Edit label - Modifier l’étiquette - - - Show transaction details - Afficher les détails de la transaction - - - Export Transaction History - Exporter l'historique des transactions - - - Watch-only - Juste-regarder : - - - Exporting Failed - L'exportation a échoué - - - There was an error trying to save the transaction history to %1. - Une erreur est survenue lors de l'enregistrement de l'historique des transactions vers %1. - - - Exporting Successful - Exportation réussie - - - The transaction history was successfully saved to %1. - L'historique des transactions a été sauvegardée avec succès vers %1. - - - Comma separated file (*.csv) - Valeurs séparées par des virgules (*.csv) - - - Confirmed - Confirmée - - - Date - Date - - - Type - Type - - - Label - Étiquette - - - Address - Adresse - - - ID - ID - - - Range: - Intervalle : - - - to - à - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ Unité d'affichage des montants. Cliquer pour choisir une autre unité. - - WalletFrame - - No wallet has been loaded. - Aucun portefeuille de chargé. - - - - WalletModel - - Send Coins - Envoyer des pièces - - - - WalletView - - &Export - &Exporter - - - Export the data in the current tab to a file - Exporter les données de l'onglet courant vers un fichier - - - Backup Wallet - Sauvegarder le portefeuille - - - Wallet Data (*.dat) - Données de portefeuille (*.dat) - - - Backup Failed - Échec de la sauvegarde - - - There was an error trying to save the wallet data to %1. - Une erreur est survenue lors de l'enregistrement des données de portefeuille vers %1. - - - The wallet data was successfully saved to %1. - Les données de portefeuille ont été enregistrées avec succès vers %1 - - - Backup Successful - Sauvegarde réussie - - bitcoin-core @@ -2927,21 +1758,13 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Si <category> n'est pas indiqué ou si <category> = 1, extraire toutes les données de débogage. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Frais totaux maximaux (en %s) à utiliser en une seule transaction de portefeuille. Les définir trop bas pourrait interrompre les grosses transactions (par défaut : %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Veuillez vérifier que l'heure et la date de votre ordinateur sont justes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement. - Prune configured below the minimum of %d MiB. Please use a higher number. L'élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) - Élagage : la dernière synchronisation de portefeuille va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) + Élagage : la dernière synchronisation de porte-monnaie va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) @@ -2975,6 +1798,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepter les connexions entrantes (par défaut : 1 si aucun -proxy ou -connect ) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. La valeur -fallbackfee est très élevée ! Elle représente les frais de transaction que vous pourriez acquitter si aucune estimation de frais n'est proposée. @@ -2993,15 +1820,31 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de blocs avec -rescan au démarrage + Supprimer toutes les transactions du porte-monnaie et ne récupérer que ces parties de la chaîne de blocs avec -rescan au démarrage Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Erreur de chargement de %s : vous ne pouvez pas activer HD sur un porte-monnaie non HD existant + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID) + Exécuter la commande lorsqu'une transaction de porte-monnaie change (%s dans la commande est remplacée par TxID) + + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Réglage moyen maximal autorisé de décalage de l'heure d'un pair. La perspective locale du temps peut être influencée par les pairs, en avance ou en retard, de cette valeur. (Par défaut : %u secondes) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Frais totaux maximaux (en %s) à utiliser en une seule transaction de porte-monnaie ou transaction brute ; les définir trop bas pourrait interrompre les grosses transactions (par défaut : %s) + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Si vous trouvez %s utile, vous pouvez y contribuer. Vous trouverez davantage d'informations à propos du logiciel sur %s. Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -3015,14 +1858,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Argument non pris charge -whitelistalwaysrelay ignoré, utiliser -whitelistrelay et/ou -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) @@ -3039,22 +1874,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avertissement : le réseau ne semble pas totalement d'accord ! Quelques mineurs semblent éprouver des difficultés. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Avertissement : des versions de blocs inconnues sont minées ! Il est possible que des règles inconnues soient en vigeur - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Avertissement : nous ne semblons pas être en accord complet avec nos pairs ! Vous pourriez avoir besoin d'effectuer une mise à niveau, ou d'autres nœuds du réseau pourraient avoir besoin d'effectuer une mise à niveau. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Avertissement : wallet.dat corrompu, données récupérées ! Le fichier wallet.dat original a été enregistré en tant que wallet.{timestamp}.bak dans %s ; si votre solde ou transactions sont incorrects vous devriez effectuer une restauration depuis une sauvegarde. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Vous devez reconstruire la base de données avec -reindex-chainstate pour changer -txindex + + + %s corrupt, salvage failed + %s corrompu, la récupération a échoué + -maxmempool must be at least %d MB -maxmempool doit être d'au moins %d Mo @@ -3067,10 +1902,22 @@ Append comment to the user agent string Ajouter un commentaire à la chaîne d'agent utilisateur + + Attempt to recover private keys from a corrupt wallet on startup + Tenter de récupérer les clefs privées d'un porte-monnaie corrompu lors du démarrage + Block creation options: Options de création de bloc : + + Cannot resolve -%s address: '%s' + Impossible de résoudre l'adresse -%s : « %s » + + + Change index out of range + L'index de changement est hors échelle + Connect only to the specified node(s) Ne se connecter qu'au(x) nœud(s) spécifié(s) @@ -3079,17 +1926,21 @@ Connection options: Options de connexion : + + Copyright (C) %i-%i + Tous droits réservés (C) %i-%i + Corrupted block database detected Base corrompue de données des blocs détectée Debugging/Testing options: - Options de test/de débogage : + Options de débogage/de test : Do not load the wallet and disable wallet RPC calls - Ne pas charger le portefeuille et désactiver les appels RPC + Ne pas charger le porte-monnaie et désactiver les appels RPC Do you want to rebuild the block database now? @@ -3117,7 +1968,23 @@ Error initializing wallet database environment %s! - Erreur lors de l'initialisation de l'environnement de la base de données du portefeuille %s ! + Erreur lors de l'initialisation de l'environnement de la base de données du porte-monnaie %s ! + + + Error loading %s + Erreur lors du chargement de %s + + + Error loading %s: Wallet corrupted + Erreur lors du chargement de %s : porte-monnaie corrompu + + + Error loading %s: Wallet requires newer version of %s + Erreur lors du chargement de %s : le porte-monnaie exige une version plus récente de %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Erreur de chargement de %s : vous ne pouvez pas désactiver HD sur un porte-monnaie HD existant Error loading block database @@ -3147,6 +2014,10 @@ Invalid -onion address: '%s' Adresse -onion invalide : « %s » + + Invalid amount for -%s=<amount>: '%s' + Montant invalide pour -%s=<amount> : « %s » + Invalid amount for -fallbackfee=<amount>: '%s' Montant invalide pour -fallbackfee=<amount> : « %s » @@ -3155,6 +2026,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Garder la réserve de mémoire transactionnelle sous <n> mégaoctets (par défaut : %u) + + Loading banlist... + Chargement de la liste d'interdiction... + Location of the auth cookie (default: data dir) Emplacement du fichier témoin auth (par défaut : data dir) @@ -3171,6 +2046,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Seulement se connecter aux nœuds du réseau <net> (IPv4, IPv6 ou oignon) + + Print this help message and exit + Imprimer ce message d'aide et quitter + Print version and exit Imprimer la version et quitter @@ -3183,6 +2062,14 @@ Prune mode is incompatible with -txindex. Le mode élagage n'est pas compatible avec -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruire l'état de la chaîne et l'index des blocs à partir des fichiers blk*.dat sur le disque + + + Rebuild chain state from the currently indexed blocks + Reconstruire l'état de la chaîne à partir des blocs indexés actuellement + Set database cache size in megabytes (%d to %d, default: %d) Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) @@ -3193,7 +2080,11 @@ Specify wallet file (within data directory) - Spécifiez le fichier de portefeuille (dans le répertoire de données) + Spécifiez le fichier de porte-monnaie (dans le répertoire de données) + + + The source code is available from %s. + Le code source est disponible sur %s. Unsupported argument -benchmark ignored, use -debug=bench. @@ -3221,19 +2112,19 @@ Verifying wallet... - Vérification du portefeuille en cours... + Vérification du porte-monnaie en cours... Wallet %s resides outside data directory %s - Le portefeuille %s réside en dehors du répertoire de données %s + Le porte-monnaie %s réside en dehors du répertoire de données %s + + + Wallet debugging/testing options: + Options de débogage/de test du porte-monnaie : Wallet options: - Options du portefeuille : - - - You need to rebuild the database using -reindex to change -txindex - Vous devez reconstruire la base de données en utilisant -reindex afin de modifier -txindex + Options du porte-monnaie : Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3247,13 +2138,9 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Se lier à l'adresse donnée pour écouter des connexions JSON-RPC. Utiliser la notation [host]:port pour l'IPv6. Cette option peut être spécifiée plusieurs fois (par défaut : se lier à toutes les interfaces) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Impossible d’obtenir un verrou sur le répertoire de données %s. Bitcoin Core fonctionne probablement déjà. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) - Créer de nouveaux fichiers avec les permissions système par défaut, au lieu de umask 077 (effectif seulement avec la fonction du portefeuille désactivée) + Créer de nouveaux fichiers avec les permissions système par défaut, au lieu de umask 077 (effectif seulement avec la fonction du porte-monnaie désactivée) Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) @@ -3295,10 +2182,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Définir le nombre de fils de génération de pièces, si elle est activée (-1 = tous les cœurs, par défaut : %d) - The transaction amount is too small to send after the fee has been deducted Le montant de la transaction est trop bas pour être envoyé une fois que les frais ont été déduits @@ -3323,34 +2206,14 @@ Accept public REST requests (default: %u) Accepter les demandes REST publiques (par défaut : %u) - - Activating best chain... - Activation de la meilleure chaîne... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Tenter de récupérer les clefs privées d'un wallet.dat corrompu lors du démarrage - Automatically create Tor hidden service (default: %d) Créer automatiquement un service caché Tor (par défaut : %d) - - Cannot resolve -whitebind address: '%s' - Impossible de résoudre l'adresse -whitebind : « %s » - Connect through SOCKS5 proxy Se connecter par un mandataire SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright © 2009-%i Les développeurs de Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Erreur lors du chargement de wallet.dat : le portefeuille exige une version plus récente de Bitcoin Core - Error reading from database, shutting down. Erreur de lecture de la base de données, fermeture en cours. @@ -3363,22 +2226,6 @@ Information Informations - - Initialization sanity check failed. Bitcoin Core is shutting down. - L'initialisation du test de cohérence a échoué. Bitcoin est en cours de fermeture. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Montant invalide pour -maxtxfee=<amount> : « %s » - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Montant invalide pour -minrelayfee=<montant> : « %s » - - - Invalid amount for -mintxfee=<amount>: '%s' - Montant invalide pour -mintxfee=<montant> : « %s » - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Montant invalide pour -paytxfee=<montant> : « %s » (doit être au moins %s) @@ -3403,21 +2250,13 @@ RPC server options: Options du serveur RPC : - - Rebuild block chain index from current blk000??.dat files on startup - Reconstruire au démarrage l'index de la chaîne de blocs à partir des fichiers blk000??.dat actuels - - - Receive and display P2P network alerts (default: %u) - Recevoir et afficher les alertes du réseau poste à poste (par défaut : %u) - Reducing -maxconnections from %d to %d, because of system limitations. Réduction de -maxconnections de %d à %d, due aux restrictions du système Rescan the block chain for missing wallet transactions on startup - Réanalyser la chaîne de blocs au démarrage, à la recherche de transactions de portefeuille manquantes + Réanalyser la chaîne de blocs au démarrage, à la recherche de transactions de porte-monnaie manquantes Send trace/debug info to console instead of debug.log file @@ -3477,16 +2316,12 @@ Upgrade wallet to latest format on startup - Mettre à niveau le portefeuille au démarrage vers le format le plus récent + Mettre à niveau le porte-monnaie au démarrage vers le format le plus récent Username for JSON-RPC connections Nom d'utilisateur pour les connexions JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Le portefeuille avait besoin d'être réécrit : veuillez redémarrer Bitcoin Core pour terminer - Warning Avertissement @@ -3501,16 +2336,12 @@ Zapping all transactions from wallet... - Supprimer toutes les transactions du portefeuille... + Supprimer toutes les transactions du porte-monnaie... ZeroMQ notification options: Options de notification ZeroMQ - - wallet.dat corrupt, salvage failed - wallet.dat corrompu, la récupération a échoué - Password for JSON-RPC connections Mot de passe pour les connexions JSON-RPC @@ -3519,10 +2350,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Exécuter la commande lorsque le meilleur bloc change (%s dans cmd est remplacé par le hachage du bloc) - - This help message - Ce message d'aide - Allow DNS lookups for -addnode, -seednode and -connect Autoriser les recherches DNS pour -addnode, -seednode et -connect @@ -3531,10 +2358,6 @@ Loading addresses... Chargement des adresses… - - Error loading wallet.dat: Wallet corrupted - Erreur lors du chargement de wallet.dat : portefeuille corrompu - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission) @@ -3551,10 +2374,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Ne pas conserver de transactions dans la réserve de mémoire plus de <n> heures (par défaut : %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement, mais les données transactionnelles ou les entrées du carnet d'adresses sont peut-être manquantes ou incorrectes. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s) @@ -3591,6 +2410,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. L'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les mandataires SOCKS5 sont pris en charge. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argument non pris charge -whitelistalwaysrelay ignoré, utiliser -whitelistrelay et/ou -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s) @@ -3599,6 +2422,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Nom d'utilisateur et mot de passe haché pour les connexions JSON-RPC. Le champ <userpw> vient au format : <USERNAME>:<SALT>$<HASH>. Un script python canonique est inclus dans share/rpcuser. Cette option peut être spécifiée plusieurs fois. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Avertissement : des versions de blocs inconnues sont minées ! Il est possible que des règles inconnues soient en vigeur + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Avertissement : le fichier du porte-monnaie est corrompu, les données ont été récupérées ! Le fichier %s original a été enregistré en tant que %s dans %s ; si votre solde ou vos transactions sont incorrects, vous devriez restaurer une sauvegarde. + (default: %s) (par défaut : %s) @@ -3607,14 +2438,6 @@ Always query for peer addresses via DNS lookup (default: %u) Toujours demander les adresses des pairs par recherche DNS (par défaut : %u) - - Error loading wallet.dat - Erreur lors du chargement de wallet.dat - - - Generate coins (default: %u) - Générer des pièces (défaut : %u) - How many blocks to check at startup (default: %u, 0 = all) Nombre de blocs à vérifier au démarrage (par défaut : %u, 0 = tous) @@ -3641,7 +2464,7 @@ Make the wallet broadcast transactions - Obliger le portefeuille à diffuser les transactions + Obliger le porte-monnaie à diffuser les transactions Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) @@ -3699,18 +2522,6 @@ Unknown network specified in -onlynet: '%s' Réseau inconnu spécifié sur -onlynet : « %s » - - Cannot resolve -bind address: '%s' - Impossible de résoudre l'adresse -bind : « %s » - - - Cannot resolve -externalip address: '%s' - Impossible de résoudre l'adresse -externalip : « %s » - - - Invalid amount for -paytxfee=<amount>: '%s' - Montant invalide pour -paytxfee=<montant> : « %s » - Insufficient funds Fonds insuffisants @@ -3725,11 +2536,11 @@ Loading wallet... - Chargement du portefeuille… + Chargement du porte-monnaie… Cannot downgrade wallet - Impossible de revenir à une version inférieure du portefeuille + Impossible de revenir à une version inférieure du porte-monnaie Cannot write default address diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index 7e6925f96..fca1e6288 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -13,29 +13,6 @@ &Delete &Supprimer - - Sending addresses - envoyer adresse de reception - - - Comma separated file (*.csv) - Fichier séparé par une virgule (*.csv) - - - - AddressTableModel - - Label - Record - - - Address - Addresse - - - (no label) - (pas de record) - AskPassphraseDialog @@ -51,46 +28,19 @@ Repeat new passphrase Répéter Mot de Passe - - Encrypt wallet - Encrypter Porte-Feuille - - - This operation needs your wallet passphrase to unlock the wallet. - Cette opération nécessite le mot de passe de votre porte-feuille pour débarrer le porte-feuille. - - - Unlock wallet - Débarrer Porte-Feuille - - - This operation needs your wallet passphrase to decrypt the wallet. - Cette opération nécessite le mot de passe de votre porte-feuille pour le décrypter. - - + BanTableModel BitcoinGUI - - ClientModel - CoinControlDialog (un)select all Toute sélectionner - - Copy address - copier l'adresse - - - (no label) - (pas de record) - EditAddressDialog @@ -102,7 +52,7 @@ &Address Addresse - + FreespaceChecker @@ -125,18 +75,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -145,32 +89,9 @@ ReceiveRequestDialog - - Address - Addresse - - - Label - Record - - - - RecentRequestsTableModel - - Label - Record - - - (no label) - (pas de record) - SendCoinsDialog - - (no label) - (pas de record) - SendCoinsEntry @@ -187,50 +108,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Record - - - - TransactionView - - Copy address - copier l'adresse - - - Comma separated file (*.csv) - Fichier séparé par une virgule (*.csv) - - - Label - Record - - - Address - Addresse - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - bitcoin-core diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index 9a2ac551c..f7fd7e6a1 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -25,10 +25,6 @@ C&lose F&ermer - - &Copy Address - &Adresse de copie - Delete the currently selected address from the list Supprimer l'adresse sélectionnée de la liste @@ -45,74 +41,6 @@ &Delete &Supprimer - - Choose the address to send coins to - Choisissez une adresse où envoyer les bitcoins - - - Choose the address to receive coins with - Choisissez une adresse où recevoir les bitcoins - - - C&hoose - C&oisir - - - Sending addresses - Adresses d'envoi - - - Receiving addresses - Adresses de réception - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Voici vos adresses Bitcoin qui vous permettent d'envoyer des paiements. Vérifiez toujours le montant et l'adresse de réception avant d'envoyer des pièces. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Voici vos adresses Bitcoin qui vous permettent de recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction - - - Copy &Label - Copier &Étiquette - - - &Edit - &Éditer - - - Export Address List - Exporter la liste d'adresses - - - Comma separated file (*.csv) - Valeurs séparées par des virgules (*.csv) - - - Exporting Failed - Échec de l'export - - - There was an error trying to save the address list to %1. Please try again. - Il y a eu une erreur durant la tentative de sauvegarde de la liste d’adresse vers %1. -Réessayez. - - - - AddressTableModel - - Label - Étiquette - - - Address - Adresse - - - (no label) - (aucune étiquette) - AskPassphraseDialog @@ -132,86 +60,6 @@ Réessayez. Repeat new passphrase Répétez la phrase de passe - - Encrypt wallet - Chiffrer le porte-monnaie - - - This operation needs your wallet passphrase to unlock the wallet. - Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. - - - Unlock wallet - Déverrouiller le porte-monnaie - - - This operation needs your wallet passphrase to decrypt the wallet. - Cette opération nécessite votre phrase de passe pour décrypter le porte-monnaie. - - - Decrypt wallet - Décrypter le porte-monnaie - - - Change passphrase - Changer la phrase de passe - - - Confirm wallet encryption - Confirmer le chiffrement du porte-monnaie - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Attention: Si vous cryptez votre portefeuille et que vous perdez votre mot de passe vous <b> PERDREZ TOUS VOS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Êtes-vous sûr de de vouloir crypter votre portefeuille ? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core fermera maintenant pour finir le processus de chiffrement. Rappelez-vous que crypter votre portefeuille ne protége pas totalement vos bitcoins d'être volé par un malware ayant infecté votre ordinateur. - - - Warning: The Caps Lock key is on! - Attention : La touche majuscule est enfoncé. - - - Wallet encrypted - Porte-monnaie chiffré - - - Enter the old passphrase and new passphrase to the wallet. - Entrez l'ancien mot de passe et le nouveau mot de passe pour le portefeuille - - - Wallet encryption failed - Le chiffrement du porte-monnaie a échoué - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré. - - - The supplied passphrases do not match. - Les phrases de passe entrées ne correspondent pas. - - - Wallet unlock failed - Le déverrouillage du porte-monnaie a échoué - - - The passphrase entered for the wallet decryption was incorrect. - La phrase de passe entrée pour décrypter le porte-monnaie était erronée. - - - Wallet decryption failed - Le décryptage du porte-monnaie a échoué - - - Wallet passphrase was successfully changed. - Le changement du mot de passe du portefeuille à été effectué avec succès. - BanTableModel @@ -262,6 +110,14 @@ Réessayez. Quit application Quitter l'application + + &About %1 + &À propos de %1 + + + Show information about %1 + Afficher les informations sur %1 + About &Qt À propos de &Qt @@ -274,6 +130,10 @@ Réessayez. &Options... &Options... + + Modify configuration options for %1 + Modifier les options de configuration pour %1 + &Encrypt Wallet... &Chiffrer le portefeuille @@ -298,14 +158,6 @@ Réessayez. Open &URI... Ouvrir &URI - - Bitcoin Core client - Client Bitcoin Core - - - Importing blocks from disk... - Importer les blocs depuis le disque... - Reindexing blocks on disk... Réindexer les blocs sur le disque... @@ -350,10 +202,6 @@ Réessayez. &Receive &Réception - - Show information about Bitcoin Core - Montrer les informations à propos de Bitcoin Core - &Show / Hide &Montrer / Cacher @@ -386,22 +234,10 @@ Réessayez. Tabs toolbar Barre d'outils des onglets - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Demander des paiements (générer QR codes et bitcoin: URIs) - - &About Bitcoin Core - &À propos de Bitcoin - - - Modify configuration options for Bitcoin Core - Modifier les options de configuration de Bitcoin Core - Show the list of used sending addresses and labels Montrer la liste des adresses d'envois utilisées et les étiquettes @@ -521,13 +357,6 @@ Réessayez. Le porte-monnaie est <b>chiffré</b> et est actuellement <b>verrouillé</b> - - ClientModel - - Network Alert - Alerte réseau - - CoinControlDialog @@ -606,142 +435,6 @@ Réessayez. Priority Priorité - - Copy address - Copier l'adresse - - - Copy label - Copier l'étiquette - - - Copy amount - Copier le montant - - - Copy transaction ID - Copie ID transaction - - - Lock unspent - Verrouiller les non dépensés - - - Unlock unspent - Déverrouiller les non dépensés - - - Copy quantity - Copier la quantité - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy priority - Copier la priorité - - - Copy dust - Copier la poussière - - - Copy change - Copier changement - - - highest - le plus élevé - - - higher - plus haute - - - high - haut - - - medium-high - moyen-élevé - - - medium - moyen - - - low-medium - bas-moyen - - - low - bas - - - lower - inférieur - - - lowest - le plus bas - - - (%1 locked) - (%1 verrouillé) - - - none - aucun - - - This label turns red if the transaction size is greater than 1000 bytes. - Cette étiquette devient rouge si la taille de la transaction est plus grande que 1000 octets - - - This label turns red if the priority is smaller than "medium". - Cette étiquette devient rouge si la priorité est plus petite que "moyen" - - - Can vary +/- %1 satoshi(s) per input. - Peut varier de +/- %1 satoshi(s) par entrée. - - - yes - oui - - - no - non - - - This means a fee of at least %1 per kB is required. - Cela signifie que des frais d'au moins %1 par kO sont requis. - - - Can vary +/- 1 byte per input. - Peut varier de +/- 1 octet par entrée. - - - (no label) - (aucune étiquette) - - - change from %1 (%2) - changement de %1 (%2) - - - (change) - (changement) - EditAddressDialog @@ -757,38 +450,6 @@ Réessayez. &Address &Adresse - - New receiving address - Nouvelle adresse de réception - - - New sending address - Nouvelle adresse d'envoi - - - Edit receiving address - Éditer l'adresse de réception - - - Edit sending address - Éditer l'adresse d'envoi - - - The entered address "%1" is already in the address book. - L'adresse fournie « %1 » est déjà présente dans le carnet d'adresses. - - - The entered address "%1" is not a valid Bitcoin address. - L'adresse entrée "%1" n'est pas une adresse Bitcoin valide. - - - Could not unlock wallet. - Impossible de déverrouiller le porte-monnaie. - - - New key generation failed. - Échec de la génération de la nouvelle clef. - FreespaceChecker @@ -811,10 +472,6 @@ Réessayez. HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version @@ -824,8 +481,8 @@ Réessayez. (%1-bit) - About Bitcoin Core - À propos de Bitcoin Core + About %1 + A propos %1 Command-line options @@ -854,10 +511,6 @@ Réessayez. Welcome Bienvenue - - Welcome to Bitcoin Core. - Bienvenue sur Bitcoin Core. - Use the default data directory Utiliser le répertoire par défaut @@ -866,10 +519,6 @@ Réessayez. Use a custom data directory: Utiliser votre propre répertoire - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Erreur: Le répertoire de données "%1" n'a pas pu être créé. @@ -905,10 +554,6 @@ Réessayez. Select payment request file Sélectionner un fichier de demande de paiement - - Select payment request file to open - Sélectionnez le fichier de demande de paiement à ouvrir - OptionsDialog @@ -952,10 +597,6 @@ Réessayez. &Network &Réseau - - Automatically start Bitcoin Core after logging in to the system. - Démarrer automatiquement Bitcoin Core après s'être connecté au système. - Expert Expert @@ -1092,45 +733,6 @@ Réessayez. Transactions récentes - - PaymentServer - - Invalid payment address %1 - Adresse de paiement invalide %1 - - - Payment request rejected - Requête de paiement rejetée - - - Payment request is not initialized. - La demande de paiement n'a pas été initialisée. - - - Payment request error - Erreur lors de la requête de paiement - - - Payment request expired. - Demande de paiement expirée. - - - Invalid payment request. - Demande de paiement invalide. - - - Refund from %1 - Remboursement de %1 - - - Bad response from server %1 - Mauvaise réponse du serveur %1 - - - Network request error - Erreur de demande de réseau - - PeerTableModel @@ -1185,25 +787,6 @@ Réessayez. %1 ms - - QRImageWidget - - &Save Image... - &Sauvegarder image - - - &Copy Image - &Copier image - - - Save QR Code - Sauvegarder QR code - - - PNG Image (*.png) - Image PNG (*.png) - - RPCConsole @@ -1366,10 +949,6 @@ Réessayez. Out: Sortie: - - Build date - Date de création - Debug log file Fichier du journal de débogage @@ -1469,18 +1048,6 @@ Réessayez. Remove Retirer - - Copy label - Copier l'étiquette - - - Copy message - Copier message - - - Copy amount - Copier le montant - ReceiveRequestDialog @@ -1500,65 +1067,6 @@ Réessayez. &Save Image... &Sauvegarder image - - Request payment to %1 - Demande de paiement à %1 - - - Payment information - Informations de paiement - - - URI - URI - - - Address - Adresse - - - Amount - Montant - - - Label - Étiquette - - - Message - Message - - - - RecentRequestsTableModel - - Date - Date - - - Label - Étiquette - - - Message - Message - - - Amount - Montant - - - (no label) - (aucune étiquette) - - - (no message) - (pas de message) - - - (no amount) - (pas de montant) - SendCoinsDialog @@ -1666,91 +1174,7 @@ Réessayez. Confirm the send action Confirmer l'action d'envoi - - Confirm send coins - Confirmer l'envoi des pièces - - - %1 to %2 - %1 à %2 - - - Copy quantity - Copier la quantité - - - Copy amount - Copier le montant - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy priority - Copier la priorité - - - Copy change - Copier changement - - - Total Amount %1 - Montant Total %1 - - - or - ou - - - The amount to pay must be larger than 0. - Le montant à payer doit être supérieur à 0. - - - The amount exceeds your balance. - Le montant excède votre balance. - - - Transaction creation failed! - Échec de la création de la transaction - - - Payment request expired. - Demande de paiement expirée. - - - Pay only the required fee of %1 - Payer seulement les frais obligatoire de %1 - - - Warning: Invalid Bitcoin address - Attention: Adresse Bitcoin Invalide - - - (no label) - (aucune étiquette) - - - Copy dust - Copier la poussière - - - Are you sure you want to send? - Êtes-vous sûr de vouloir envoyer ? - - - added as transaction fee - Ajoute en tant que frais de transaction - - + SendCoinsEntry @@ -1761,10 +1185,6 @@ Réessayez. Pay &To: Payer &à : - - Enter a label for this address to add it to your address book - Entrez une étiquette pour cette adresse afin de l'ajouter à votre carnet d'adresses - &Label: &Étiquette : @@ -1859,41 +1279,9 @@ Réessayez. Verify &Message Vérifier &Message - - The entered address is invalid. - L'adresse entrée est invalide. - - - Please check the address and try again. - Vérifiez l'adresse et réessayer. - - - Message signed. - Message signé. - - - Please check the signature and try again. - Vérifiez la signature et réessayer. - - - Message verification failed. - Vérification du message échouée. - - - Message verified. - Message vérifié. - - + SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Les développeurs de Bitcoin Core - [testnet] [testnet] @@ -1906,410 +1294,16 @@ Réessayez. KO/s - - TransactionDesc - - Open until %1 - Ouvert jusqu'à %1 - - - %1/unconfirmed - %1/non confirmée - - - %1 confirmations - %1 confirmations - - - Status - État - - - Date - Date - - - Source - Source - - - Generated - Généré - - - From - De - - - To - Á - - - own address - Votre adresse - - - watch-only - Lecture uniquement - - - label - Étiquette - - - Credit - Crédit - - - not accepted - Pas accepté - - - Debit - Débit - - - Total debit - Débit total - - - Total credit - Crédit total - - - Transaction fee - Frais de transaction - - - Net amount - Montant net - - - Message - Message - - - Comment - Commentaire - - - Transaction ID - ID de transaction - - - Merchant - Marchant - - - Debug information - Information de débogage - - - Transaction - Transaction - - - Inputs - Entrées - - - Amount - Montant - - - true - vrai - - - false - faux - - - , has not been successfully broadcast yet - , n'a pas encore été diffusée avec succès - - - Open for %n more block(s) - Ouvert pour %n bloc de plusOuvert pour %n blocs de plus - - - unknown - inconnue - - TransactionDescDialog - - Transaction details - Détails de la transaction - This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - - TransactionTableModel - - Date - Date - - - Type - Type - - - Open for %n more block(s) - Ouvert pour %n bloc de plusOuvert pour %n blocs de plus - - - Open until %1 - Ouvert jusqu'à %1 - - - Confirmed (%1 confirmations) - Confirmée (%1 confirmations) - - - This block was not received by any other nodes and will probably not be accepted! - Ce bloc n'a été reçu par aucun autre nœud et ne sera probablement pas accepté ! - - - Generated but not accepted - Généré mais pas accepté - - - Offline - Hors ligne - - - Label - Étiquette - - - Unconfirmed - Non Confirmé - - - Received with - Reçues avec - - - Received from - Reçue de - - - Sent to - Envoyées à - - - Payment to yourself - Paiement à vous-même - - - Mined - Extraction - - - watch-only - Lecture uniquement - - - (n/a) - (indisponible) - - - Transaction status. Hover over this field to show number of confirmations. - État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations. - - - Date and time that the transaction was received. - Date et heure de réception de la transaction. - - - Type of transaction. - Type de transaction. - - - Amount removed from or added to balance. - Montant ajouté au ou enlevé du solde. - - - - TransactionView - - All - Toutes - - - Today - Aujourd'hui - - - This week - Cette semaine - - - This month - Ce mois - - - Last month - Mois dernier - - - This year - Cette année - - - Range... - Intervalle... - - - Received with - Reçues avec - - - Sent to - Envoyées à - - - To yourself - À vous-même - - - Mined - Extraction - - - Other - Autres - - - Enter address or label to search - Entrez une adresse ou une étiquette à rechercher - - - Min amount - Montant min - - - Copy address - Copier l'adresse - - - Copy label - Copier l'étiquette - - - Copy amount - Copier le montant - - - Copy transaction ID - Copie ID transaction - - - Edit label - Éditer l'étiquette - - - Show transaction details - Afficher les détails de la transaction - - - Export Transaction History - Exporter l'historique des transactions - - - Exporting Failed - Échec de l'export - - - Exporting Successful - Export réalisé avec sucés - - - Comma separated file (*.csv) - Valeurs séparées par des virgules (*.csv) - - - Confirmed - Confirmée - - - Date - Date - - - Type - Type - - - Label - Étiquette - - - Address - Adresse - - - ID - ID - - - Range: - Intervalle : - - - to - à - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Aucun portefeuille a été chargé. - - - - WalletModel - - Send Coins - Envoyer des pièces - - - - WalletView - - &Export - &Exporter... - - - Export the data in the current tab to a file - Exporter les données de l'onglet courant vers un fichier - - - Backup Wallet - Sauvegarder le porte-monnaie - - - Wallet Data (*.dat) - Données de porte-monnaie (*.dat) - - - Backup Failed - La sauvegarde a échoué - - - Backup Successful - Sauvegarde réussie - - bitcoin-core @@ -2332,6 +1326,10 @@ Réessayez. Run in the background as a daemon and accept commands Fonctionner en arrière-plan en tant que démon et accepter les commandes + + Bitcoin Core + Bitcoin Core + <category> can be: <category> peut être: @@ -2425,30 +1423,14 @@ Importation ... Password for JSON-RPC connections Mot de passe pour les connexions JSON-RPC - - This help message - Ce message d'aide - Loading addresses... Chargement des adresses... - - Error loading wallet.dat: Wallet corrupted - Erreur lors du chargement de wallet.dat : porte-monnaie corrompu - (default: %s) (défaut: %s) - - Error loading wallet.dat - Erreur lors du chargement de wallet.dat - - - Generate coins (default: %u) - Générer des pièces (défaut: %u) - Invalid -proxy address: '%s' Adresse -proxy invalide: '%s' diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 50b081d20..f3673b6dc 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -21,10 +21,6 @@ C&lose &Pechar - - &Copy Address - &Copiar Dirección - Delete the currently selected address from the list Borrar a dirección actualmente seleccionada da listaxe @@ -41,69 +37,6 @@ &Delete &Borrar - - Choose the address to send coins to - Escolle a dirección á que enviar moedas - - - Choose the address to receive coins with - Escolle a dirección da que recibir moedas - - - C&hoose - &Escoller - - - Sending addresses - Direccións para enviar - - - Receiving addresses - Direccións para recibir - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estas son as túas direccións Bitcoin para enviar pagos. Revisa sempre a cantidade e a dirección receptora antes de enviar moedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estas son as túas direccións Bitcoin para recibir pagos. Recoméndase empregar unha nova dirección de recepción por cada transacción. - - - Copy &Label - Copiar &Etiqueta - - - &Edit - &Modificar - - - Export Address List - Exportar Lista de Direccións - - - Comma separated file (*.csv) - Arquivo separado por comas (*.csv) - - - Exporting Failed - Exportación falida - - - - AddressTableModel - - Label - Etiqueta - - - Address - Dirección - - - (no label) - (sen etiqueta) - AskPassphraseDialog @@ -123,82 +56,6 @@ Repeat new passphrase Repite novo contrasinal - - Encrypt wallet - Encriptar moedeiro - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operación precisa o contrasinal do teu moedeiro para desbloquear o moedeiro. - - - Unlock wallet - Desbloquear moedeiro - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operación precisa o contrasinal do teu moedeiro para desencriptar o moedeiro. - - - Decrypt wallet - Desencriptar moedeiro - - - Change passphrase - Cambiar contrasinal - - - Confirm wallet encryption - Confirmar encriptación de moedeiro - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Precaución: Se encriptas o teu moedeiro e perdes o teu contrasinal, ti <b>PERDERÁS TÓDOLOS TEUS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Estás seguro de que desexas encriptar o teu moedeiro? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Calquera copia de seguridade previa que fixeses do teu arquivo de moedeiro debería ser substituída polo recén xerado arquivo encriptado de moedeiro. Por razóns de seguridade, as copias de seguridade previas de un arquivo de moedeiro desencriptado tornaránse inútiles no momento no que comeces a emprega-lo novo, encriptado, moedeiro. - - - Warning: The Caps Lock key is on! - Precaución: A tecla de Bloqueo de Maiúsculas está activada! - - - Wallet encrypted - Moedeiro encriptado - - - Wallet encryption failed - Encriptación de moedeiro fallida - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - A encriptación do moedeiro fallou por mor dun erro interno. O teu moedeiro non foi encriptado. - - - The supplied passphrases do not match. - Os contrasinais suministrados non coinciden. - - - Wallet unlock failed - Desbloqueo de moedeiro fallido - - - The passphrase entered for the wallet decryption was incorrect. - O contrasinal introducido para a desencriptación do moedeiro foi incorrecto. - - - Wallet decryption failed - Desencriptación de moedeiro fallida - - - Wallet passphrase was successfully changed. - Cambiouse con éxito o contrasinal do moedeiro. - BanTableModel @@ -265,10 +122,6 @@ &Receiving addresses... Direccións para recibir - - Importing blocks from disk... - Importando bloques de disco... - Reindexing blocks on disk... Reindexando bloques no disco... @@ -349,18 +202,10 @@ Tabs toolbar Barra de ferramentas - - Bitcoin Core - Core de Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Solicitar pagos (xenera códigos QR e bitcoin: URIs) - - &About Bitcoin Core - &Sobre Bitcoin Core - Show the list of used sending addresses and labels Amosar a listaxe de direccións e etiquetas para enviar empregadas @@ -430,13 +275,6 @@ O moedeiro está <b>encriptado</b> e actualmente <b>bloqueado</b> - - ClientModel - - Network Alert - Alerta de Rede - - CoinControlDialog @@ -495,110 +333,6 @@ Priority Prioridade - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidade - - - Copy transaction ID - Copiar ID de transacción - - - Lock unspent - Bloquear o aforrado - - - Unlock unspent - Desbloquear o aforrado - - - Copy quantity - Copiar cantidade - - - Copy fee - Copiar pago - - - Copy after fee - Copiar despóis do pago - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridade - - - Copy change - Copiar cambio - - - highest - O máis alto - - - higher - Máis alto que - - - high - alto - - - medium-high - medio-alto - - - low-medium - medio-baixo - - - low - baixo - - - lower - máis baixo que - - - lowest - o máis baixo - - - (%1 locked) - (%1 bloqueado) - - - yes - Si - - - no - non - - - Transactions with higher priority are more likely to get included into a block. - As transacción con maior prioridade teñen máis posibilidades de ser incluidas nun bloque - - - (no label) - (sen etiqueta) - - - (change) - (cambio) - EditAddressDialog @@ -622,38 +356,6 @@ &Address &Dirección - - New receiving address - Nova dirección para recibir - - - New sending address - Nova dirección para enviar - - - Edit receiving address - Modificar dirección para recibir - - - Edit sending address - Modificar dirección para enviar - - - The entered address "%1" is already in the address book. - A dirección introducida "%1" xa está no libro de direccións. - - - The entered address "%1" is not a valid Bitcoin address. - A dirección introducida '%1' non é unha dirección Bitcoin válida. - - - Could not unlock wallet. - Non se puido desbloquear o moedeiro. - - - New key generation failed. - A xeración de nova clave fallou. - FreespaceChecker @@ -680,18 +382,10 @@ HelpMessageDialog - - Bitcoin Core - Core de Bitcoin - version versión - - About Bitcoin Core - Sobre Bitcoin core - Command-line options Opcións da liña de comandos @@ -719,10 +413,6 @@ Use a custom data directory: Empregar un directorio de datos personalizado - - Bitcoin Core - Core de Bitcoin - Error Erro @@ -746,10 +436,6 @@ Select payment request file Seleccionar ficheiro de solicitude de pago - - Select payment request file to open - Seleccione ficheiro de solicitude de pago para abrir - OptionsDialog @@ -885,45 +571,6 @@ O teu balance actual total - - PaymentServer - - URI handling - Manexo de URI - - - Invalid payment address %1 - Dirección de pago %1 inválida - - - Requested payment amount of %1 is too small (considered dust). - A cantidade de %1 na solicitude de pado é moi pequena (considerada po). - - - Payment request error - Erro na petición de pago - - - Refund from %1 - Devolución dende %1 - - - Error communicating with %1: %2 - Erro comunicando con %1: %2 - - - Bad response from server %1 - Responsa errónea do servidor %1 - - - Payment acknowledged - Pago admitido - - - Network request error - Erro de solicitude de rede - - PeerTableModel @@ -946,21 +593,6 @@ N/A - - QRImageWidget - - &Save Image... - &Gardar Imaxe... - - - &Copy Image - &Copiar Imaxe - - - Save QR Code - Gardar Código QR - - RPCConsole @@ -1035,10 +667,6 @@ Out: Fóra: - - Build date - Data de construción - Debug log file Arquivo de log de depuración @@ -1106,15 +734,7 @@ &Request payment &Solicitar pago - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidade - - + ReceiveRequestDialog @@ -1133,66 +753,7 @@ &Save Image... &Gardar Imaxe... - - Request payment to %1 - Solicitar pago a %1 - - - Payment information - Información de Pago - - - URI - URI - - - Address - Dirección - - - Amount - Cantidade - - - Label - Etiqueta - - - Message - Mensaxe - - - Resulting URI too long, try to reduce the text for label / message. - A URI resultante é demasiado larga, tenta reducir o texto para a etiqueta / mensaxe. - - - Error encoding URI into QR Code. - Erro codificando URI nun Código QR. - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiqueta - - - Message - Mensaxe - - - Amount - Cantidade - - - (no label) - (sen etiqueta) - - SendCoinsDialog @@ -1259,74 +820,6 @@ S&end &Enviar - - Confirm send coins - Confirmar envío de moedas - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copiar cantidade - - - Copy amount - Copiar cantidade - - - Copy fee - Copiar pago - - - Copy after fee - Copiar despóis do pago - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridade - - - Copy change - Copiar cambio - - - The amount to pay must be larger than 0. - A cantidade a pagar debe ser maior que 0. - - - The amount exceeds your balance. - A cantidade sobrepasa o teu balance. - - - The total exceeds your balance when the %1 transaction fee is included. - O total sobrepasa o teu balance cando se inclúe a tarifa de transacción %1. - - - Warning: Invalid Bitcoin address - Atención: Enderezo Bitcoin non válido - - - (no label) - (sen etiqueta) - - - Warning: Unknown change address - Atención: Enderezo de cambio desconocido - - - Are you sure you want to send? - Seguro que queres enviar? - - - added as transaction fee - engadido como tarifa de transacción - SendCoinsEntry @@ -1338,10 +831,6 @@ Pay &To: Pagar &A: - - Enter a label for this address to add it to your address book - Introduce unha etiqueta para esta dirección para engadila ao teu libro de direccións - &Label: &Etiqueta: @@ -1460,69 +949,9 @@ Reset all verify message fields Restaurar todos os campos de verificación de mensaxe - - Click "Sign Message" to generate signature - Click en "Asinar Mensaxe" para xerar sinatura - - - The entered address is invalid. - A dirección introducida é inválida. - - - Please check the address and try again. - Por favor comproba a dirección e proba de novo. - - - The entered address does not refer to a key. - A dirección introducida non se refire a ninguna clave. - - - Wallet unlock was cancelled. - Cancelouse o desbloqueo do moedeiro. - - - Private key for the entered address is not available. - A clave privada da dirección introducida non está dispoñible. - - - Message signing failed. - Fallou a sinatura da mensaxe. - - - Message signed. - Mensaxe asinada. - - - The signature could not be decoded. - A sinatura non puido ser decodificada. - - - Please check the signature and try again. - Por favor revise a sinatura e probe de novo. - - - The signature did not match the message digest. - A sinatura non coincide co resumo da mensaxe. - - - Message verification failed. - A verificación da mensaxe fallou. - - - Message verified. - Mensaxe verificada. - SplashScreen - - Bitcoin Core - Core de Bitcoin - - - The Bitcoin Core developers - Os desarrolladores de Bitcoin Core - [testnet] [testnet] @@ -1535,402 +964,16 @@ KB/s - - TransactionDesc - - Open until %1 - Aberto ata %1 - - - %1/offline - %1/fóra de liña - - - %1/unconfirmed - %1/sen confirmar - - - %1 confirmations - %1 confirmacións - - - Status - Estado - - - Date - Data - - - Source - Orixe - - - Generated - Xerado - - - From - Dende - - - To - A - - - own address - dirección propia - - - label - etiqueta - - - Credit - Crédito - - - not accepted - non aceptado - - - Debit - Débito - - - Transaction fee - Tarifa de transacción - - - Net amount - Cantidade neta - - - Message - Mensaxe - - - Comment - Comentario - - - Transaction ID - ID de Transacción - - - Merchant - Comerciante - - - 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. - As moedas xeradas deben madurar %1 bloques antes de que poidan ser gastadas. Cando xeraste este bloque, foi propagado á rede para ser engadido á cadeas de bloques. Se falla ao tentar meterse na cadea, o seu estado cambiará a "non aceptado" e non poderá ser gastado. Esto pode ocorrir ocasionalmente se outro nodo xera un bloque en poucos segundos de diferencia co teu. - - - Debug information - Información de depuración - - - Transaction - Transacción - - - Inputs - Entradas - - - Amount - Cantidade - - - true - verdadeiro - - - false - falso - - - , has not been successfully broadcast yet - , non foi propagado con éxito todavía - - - unknown - descoñecido - - TransactionDescDialog - - Transaction details - Detalles de transacción - This pane shows a detailed description of the transaction Este panel amosa unha descripción detallada da transacción - - TransactionTableModel - - Date - Data - - - Type - Tipo - - - Open until %1 - Aberto ata %1 - - - Confirmed (%1 confirmations) - Confirmado (%1 confirmacións) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloque non foi recibido por ningún outro nodo e probablemente non será aceptado! - - - Generated but not accepted - Xerado pero non aceptado - - - Label - Etiqueta - - - Received with - Recibido con - - - Received from - Recibido de - - - Sent to - Enviado a - - - Payment to yourself - Pago a ti mesmo - - - Mined - Minado - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Estado da transacción. Pasa por riba deste campo para amosar o número de confirmacións. - - - Date and time that the transaction was received. - Data e hora na que foi recibida a transacción. - - - Type of transaction. - Tipo de transacción. - - - Amount removed from or added to balance. - Cantidade borrada ou engadida no balance. - - - - TransactionView - - All - Todo - - - Today - Hoxe - - - This week - Esta semana - - - This month - Este mes - - - Last month - O último mes - - - This year - Este ano - - - Range... - Periodo... - - - Received with - Recibido con - - - Sent to - Enviado a - - - To yourself - A ti mesmo - - - Mined - Minado - - - Other - Outro - - - Enter address or label to search - Introduce dirección ou etiqueta para buscar - - - Min amount - Cantidade mínima - - - Copy address - Copiar dirección - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar cantidade - - - Copy transaction ID - Copiar ID de transacción - - - Edit label - Modificar etiqueta - - - Show transaction details - Amosar detalles da transacción - - - Export Transaction History - Exportar Historial de Transaccións - - - Exporting Failed - Exportación falida - - - There was an error trying to save the transaction history to %1. - Houbo un erro intentando salvar o historial de transaccións a %1. - - - Exporting Successful - Exportado correctamente - - - The transaction history was successfully saved to %1. - O historial de transaccións foi salvado correctamente en %1. - - - Comma separated file (*.csv) - Arquivo separado por comas (*.csv) - - - Confirmed - Confirmado - - - Date - Data - - - Type - Tipo - - - Label - Etiqueta - - - Address - Dirección - - - ID - ID - - - Range: - Periodo: - - - to - a - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Ningún moedeiro cargado - - - - WalletModel - - Send Coins - Moedas Enviadas - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar os datos da pestaña actual a un arquivo. - - - Backup Wallet - Copia de Seguridade de Moedeiro - - - Wallet Data (*.dat) - Datos de Moedeiro (*.dat) - - - Backup Failed - Copia de Seguridade Fallida - - - There was an error trying to save the wallet data to %1. - Houbo un erro intentando gardar os datos de moedeiro en %1. - - - The wallet data was successfully saved to %1. - Os datos do moedeiro foron gardados correctamente en %1. - - - Backup Successful - Copia de Seguridade Correcta - - bitcoin-core @@ -1961,6 +1004,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexións de fóra (por defecto: 1 se non -proxy ou -connect) + + Bitcoin Core + Core de Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Enlazar a unha dirección dada e escoitar sempre nela. Emprega a notación [host]:post para IPv6 @@ -1981,10 +1028,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Precaución: Non parece que esteamos totalmente de acordo cos nosos pares! Pode que precises actualizar, ou outros nodos poden precisar actualizarse. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Precaución: wallet.dat corrupto, datos salvagardados! O wallet.dat orixinal foi gardado como wallet.{timestamp}.bak en %s; se o teu balance ou transaccións son incorrectas deberías restauralas dende unha copia de seguridade. - <category> can be: <categoría> pode ser: @@ -2057,34 +1100,14 @@ Wallet %s resides outside data directory %s O moedeiro %s reside fóra do directorio de datos %s - - You need to rebuild the database using -reindex to change -txindex - Precisas reconstruír a base de datos empregando -reindex para cambiar -txindex - Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe) - - Cannot resolve -whitebind address: '%s' - Non se pode resolver dirección -whitebind: '%s' - Information Información - - Invalid amount for -maxtxfee=<amount>: '%s' - Cantidade inválida para -maxtxfee=<cantidade>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Cantidade inválida para -minrelaytxfee=<cantidade>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Cantidade inválida para -mintxfee=<cantidade>: '%s' - Send trace/debug info to console instead of debug.log file Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log @@ -2117,10 +1140,6 @@ Warning Precaución - - wallet.dat corrupt, salvage failed - wallet.dat corrupto, fallou o gardado - Password for JSON-RPC connections Contrasinal para conexións JSON-RPC @@ -2129,10 +1148,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executar comando cando o mellor bloque cambie (%s no comando é sustituído polo hash do bloque) - - This help message - Esta mensaxe de axuda - Allow DNS lookups for -addnode, -seednode and -connect Permitir lookup de DNS para -addnote, -seednote e -connect @@ -2141,14 +1156,6 @@ Loading addresses... Cargando direccións... - - Error loading wallet.dat: Wallet corrupted - Erro cargando wallet.dat: Moedeiro corrupto - - - Error loading wallet.dat - Erro cargando wallet.dat - Invalid -proxy address: '%s' Dirección -proxy inválida: '%s' @@ -2157,18 +1164,6 @@ Unknown network specified in -onlynet: '%s' Rede descoñecida especificada en -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Non se pode resolver a dirección -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Non se pode resolver dirección -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Cantidade inválida para -paytxfee=<cantidade>: '%s' - Insufficient funds Fondos insuficientes diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index d937e211b..fbe16364e 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - לחץ משק ימני כדי לערוך כתובת או חברה + לחץ מקש ימני כדי לערוך כתובת או תווית Create a new address @@ -11,7 +11,7 @@ &New - &חדשה + &חדש Copy the currently selected address to the system clipboard @@ -25,10 +25,6 @@ C&lose סגירה - - &Copy Address - העתקת כתובת - Delete the currently selected address from the list מחיקת הכתובת שנבחרה מהרשימה @@ -45,73 +41,6 @@ &Delete מ&חיקה - - Choose the address to send coins to - נא לבחור את הכתובת המבוקשת לשליחת המטבעות - - - Choose the address to receive coins with - נא לבחור את הכתובת המבוקשת לקבלת המטבעות - - - C&hoose - בחירה - - - Sending addresses - כתובות לשליחה - - - Receiving addresses - כתובות לקבלה - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - אלה כתובת הביטקוין שלך לצורך שליחת תשלומים. תמיד יש לבדוק את הכמות ואת כתובות מקבלי התשלומים לפני שליחת מטבעות. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - אלה כתובות הביטקוין שלך לצורך קבלת תשלומים. מומלץ להשתמש בכתובת קבלה חדשה לכל העברה. - - - Copy &Label - העתקת &תווית - - - &Edit - ע&ריכה - - - Export Address List - יצוא רשימת כתובות - - - Comma separated file (*.csv) - קובץ מופרד בפסיקים (‎*.csv) - - - Exporting Failed - היצוא נכשל - - - There was an error trying to save the address list to %1. Please try again. - אירעה שגיאה בעת הניסיון לשמור את רשימת הכתובת אל %1. נא לנסות שוב. - - - - AddressTableModel - - Label - תווית - - - Address - כתובת - - - (no label) - (אין תווית) - AskPassphraseDialog @@ -131,98 +60,14 @@ Repeat new passphrase נא לחזור על מילת הצופן החדשה - - Encrypt wallet - הצפנת הארנק - - - This operation needs your wallet passphrase to unlock the wallet. - פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפתוח את הארנק. - - - Unlock wallet - פתיחת ארנק - - - This operation needs your wallet passphrase to decrypt the wallet. - פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפענח את הארנק. - - - Decrypt wallet - פענוח ארנק - - - Change passphrase - שינוי מילת צופן - - - Confirm wallet encryption - אישור הצפנת הארנק - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - אזהרה: הצפנת הארנק ואיבוד מילת הצופן עשויה להוביל <b>לאיבוד כל הביטקוינים שלך</b>! - - - Are you sure you wish to encrypt your wallet? - האם אכן להצפין את הארנק? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - ליבת ביטקוין תיסגר עכשיו כדי לסיים את תליך ההצפנה. זכור כי הצפנה אינה יכולה להגן עלייך באופן מלא מגניבה שמקורה בתוכנות זדוניות המצויות במחשב שלך. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - לתשומת לבך: כל גיבוי קודם שביצעת לארנק שלך יש להחליף בקובץ הארנק המוצפן שזה עתה נוצר. מטעמי אבטחה, גיבויים קודמים של קובץ הארנק הבלתי-מוצפן יהפכו לחסרי תועלת עם התחלת השימוש בארנק החדש המוצפן. - - - Warning: The Caps Lock key is on! - זהירות: מקש Caps Lock פעיל! - - - Wallet encrypted - הארנק הוצפן - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - נא להזין את מילת הצופן החדשה לארנק.<br/>כדאי להשתמש במילת צופן המורכבת מ<b>עשרה תווים אקראיים ומעלה</b>, או <b>שמונה מילים ומעלה</b>. - - - Enter the old passphrase and new passphrase to the wallet. - הכנס את מילת הצופן הישנה ומילת צופן חדשה לארנק שלך. - - - Wallet encryption failed - הצפנת הארנק נכשלה - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - הצפנת הארנק נכשלה עקב שגיאה פנימית. הארנק שלך לא הוצפן. - - - The supplied passphrases do not match. - מילות הצופן שסופקו אינן תואמות. - - - Wallet unlock failed - פתיחת הארנק נכשלה - - - The passphrase entered for the wallet decryption was incorrect. - מילת הצופן שהוכנסה לפענוח הארנק שגויה. - - - Wallet decryption failed - פענוח הארנק נכשל - - - Wallet passphrase was successfully changed. - מילת הצופן של הארנק שונתה בהצלחה. - BanTableModel - + + Banned Until + חסום עד + + BitcoinGUI @@ -261,6 +106,14 @@ Quit application יציאה מהתכנית + + &About %1 + &אודות %1 + + + Show information about %1 + הצג מידע על %1 + About &Qt על אודות Qt @@ -297,14 +150,6 @@ Open &URI... פתיחת &כתובת משאב… - - Bitcoin Core client - לקוח ליבה של ביטקוין - - - Importing blocks from disk... - מקטעים מיובאים מהכונן… - Reindexing blocks on disk... המקטעים נוספים למפתח בכונן… @@ -349,10 +194,6 @@ &Receive &קבלה - - Show information about Bitcoin Core - הצגת מידע על ליבת ביטקוין - &Show / Hide ה&צגה / הסתרה @@ -389,18 +230,10 @@ Tabs toolbar סרגל כלים לשוניות - - Bitcoin Core - ליבת ביטקוין - Request payments (generates QR codes and bitcoin: URIs) בקשת תשלומים (יצירה של קודים מסוג QR וסכימות כתובות משאב של :bitcoin) - - &About Bitcoin Core - על &אודות ליבת ביטקוין - Show the list of used sending addresses and labels הצג את רשימת הכתובות לשליחה שהיו בשימוש לרבות התוויות @@ -418,8 +251,8 @@ אפשרויות &שורת הפקודה - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - הצגת הודעות העזרה של ליבת ביטקוין כדי לקבל רשימה עם אפשרויות שורת הפקודה האפשריות של ביטקוין + Processing blocks on disk... + מעבד בלוקים על הדיסק... No block source available... @@ -478,15 +311,12 @@ הארנק <b>מוצפן</b> ו<b>נעול</b> כרגע - - ClientModel - - Network Alert - אזעקת רשת - - CoinControlDialog + + Coin Selection + בחירת מטבע + Quantity: כמות: @@ -535,6 +365,14 @@ Amount כמות + + Received with label + התקבל עם תווית + + + Received with address + התקבל עם כתובת + Date תאריך @@ -551,138 +389,6 @@ Priority עדיפות - - Copy address - העתקת כתובת - - - Copy label - העתקת תווית - - - Copy amount - העתקת כמות - - - Copy transaction ID - העתקת מזהה העברה - - - Lock unspent - נעילת יתרה - - - Unlock unspent - פתיחת יתרה - - - Copy quantity - העתקת כמות - - - Copy fee - העתקת עמלה - - - Copy after fee - העתקת אחרי עמלה - - - Copy bytes - העתקת בתים - - - Copy priority - העתקת עדיפות - - - Copy dust - העתקת אבק - - - Copy change - העתקת עודף - - - highest - הגבוה ביותר - - - higher - גבוה יותר - - - high - גבוה - - - medium-high - בינוני - גבוה - - - medium - בינוני - - - low-medium - בינוני - נמוך - - - low - נמוך - - - lower - נמוך יותר - - - lowest - הנמוך ביותר - - - (%1 locked) - (%1 נעול) - - - none - ללא - - - Can vary +/- %1 satoshi(s) per input. - יכולה להשתנות ב+/- %1 סטושי לקלט. - - - yes - כן - - - no - לא - - - This means a fee of at least %1 per kB is required. - זאת אומרת שנחוצה עמלה של לא פחות מ־%1 לכל קילו בית. - - - Can vary +/- 1 byte per input. - הערך יכול להיות +/- בית אחד לכל קלט. - - - Transactions with higher priority are more likely to get included into a block. - העברות עם עדיפות גבוהה, יותר סיכוי שיכנסו לתוך המקטע. - - - (no label) - (אין תווית) - - - change from %1 (%2) - עודף מ־%1 (%2) - - - (change) - (עודף) - EditAddressDialog @@ -706,38 +412,6 @@ &Address &כתובת - - New receiving address - כתובת חדשה לקבלה - - - New sending address - כתובת חדשה לשליחה - - - Edit receiving address - עריכת כתובת לקבלה - - - Edit sending address - עריכת כתובת לשליחה - - - The entered address "%1" is already in the address book. - הכתובת שהוכנסה „%1“ כבר נמצאת בפנקס הכתובות. - - - The entered address "%1" is not a valid Bitcoin address. - הכתובת שהוכנסה „%1“ אינה כתובת ביטקוין תקנית. - - - Could not unlock wallet. - פתיחת הארנק נכשלה. - - - New key generation failed. - יצירת מפתח חדש נכשלה. - FreespaceChecker @@ -764,10 +438,6 @@ HelpMessageDialog - - Bitcoin Core - ליבת ביטקוין - version גרסה @@ -776,10 +446,6 @@ (%1-bit) (%1-סיביות) - - About Bitcoin Core - על אודות ליבת ביטקוין - Command-line options אפשרויות שורת פקודה @@ -792,7 +458,19 @@ command-line options אפשרויות שורת פקודה - + + UI Options: + אפשרויות ממשק + + + Start minimized + התחל ממוזער + + + Reset all settings changed in the GUI + איפוס כל שינויי הגדרות התצוגה + + Intro @@ -800,16 +478,8 @@ ברוך בואך - Welcome to Bitcoin Core. - ברוך בואך לליבת ביטקוין - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - מכיוון שזאת הפעם הראשונה שהתכנית פועלת ניתן לבחור איפה ליבת ביטקוין תאחסן את הנתונים שלה. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - לקוח ביטקוין יוריד וישמור העתק של שרשרת המקטעים של ביטקוין. לפחות %1 ג״ב מהנתונים יאוחסנו בתיקייה זו, והיא תגדל עם הזמן. הארנק גם יאוחסן בתיקייה הזו. + Welcome to %1. + ברוך הבא ל %1. Use the default data directory @@ -819,10 +489,6 @@ Use a custom data directory: שימוש בתיקיית נתונים מותאמת אישית: - - Bitcoin Core - ליבת ביטקוין - Error: Specified data directory "%1" cannot be created. שגיאה: לא ניתן ליצור את תיקיית הנתונים שצוינה „%1“. @@ -850,10 +516,6 @@ Select payment request file בחירת קובץ בקשת תשלום - - Select payment request file to open - בחירת קובץ בקשת תשלום לפתיחה - OptionsDialog @@ -957,6 +619,18 @@ Port of the proxy (e.g. 9050) הפתחה של המתווך (למשל 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &חלון @@ -1080,6 +754,10 @@ Your current balance in watch-only addresses המאזן הנוכחי שלך בכתובות לקריאה בלבד + + Spendable: + ניתנים לבזבוז + Recent transactions העברות אחרונות @@ -1097,85 +775,6 @@ המאזן הכולל הנוכחי בכתובות לצפייה בלבד - - PaymentServer - - URI handling - תפעול כתובות משאב - - - Invalid payment address %1 - כתובת תשלום שגויה %1 - - - Payment request rejected - בקשת התשלום נדחתה - - - Payment request network doesn't match client network. - רשת בקשת התשלום אינה תואמת לרשת הלקוח. - - - Payment request is not initialized. - בקשת התשלום לא החלה. - - - Requested payment amount of %1 is too small (considered dust). - הסכום על סך %1 הנדרש לתשלום קטן מדי (נחשב לאבק) - - - Payment request error - שגיאה בבקשת תשלום - - - Cannot start bitcoin: click-to-pay handler - לא ניתן להתחיל את ביטקוין: טיפול בלחיצה–לתשלום - - - Payment request fetch URL is invalid: %1 - כתובת אחזור בקשת התשלום שגויה: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - לא ניתן לנתח את כתובת המשאב! מצב זה יכול לקרות עקב כתובת ביטקוין שגויה או פרמטרים שגויים בכתובת המשאב. - - - Payment request file handling - טיפול בקובצי בקשות תשלום - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - לא ניתן לקרוא את קובץ בקשת התשלום! מצב כזה יכול לקרות בעקבות קובץ בקשת תשלום פגום. - - - Unverified payment requests to custom payment scripts are unsupported. - בקשות תשלום בלתי מאומתות לסקריפטים לתשלום מותאמים אישית אינן נתמכות. - - - Refund from %1 - החזר מ־%1 - - - Error communicating with %1: %2 - שגיאה בתקשורת עם %1: %2 - - - Payment request cannot be parsed! - לא ניתן לפענח את בקשת התשלום! - - - Bad response from server %1 - מענה שגוי משרת %1 - - - Payment acknowledged - התשלום התקבל - - - Network request error - שגיאת בקשת שרת - - PeerTableModel @@ -1226,25 +825,6 @@ %1 מילישניות - - QRImageWidget - - &Save Image... - &שמירת תמונה… - - - &Copy Image - ה&עתקת תמונה - - - Save QR Code - שמירת קוד QR - - - PNG Image (*.png) - תמונת PNG ‏(‎*.png) - - RPCConsole @@ -1275,6 +855,10 @@ Using BerkeleyDB version שימוש ב־BerkeleyDB גרסה + + Datadir + Datadir + Startup time זמן עלייה @@ -1299,6 +883,18 @@ Current number of blocks מספר המקטעים הנוכחי + + Memory Pool + מאגר זכרון + + + Current number of transactions + מספר הפעולה הנוכחי + + + Memory usage + שימוש בזכרון + Received התקבלו @@ -1311,10 +907,18 @@ &Peers &עמיתים + + Banned peers + משתמשים חסומים + Select a peer to view detailed information. נא לבחור בעמית כדי להציג מידע מפורט. + + Whitelisted + ברשימה הלבנה + Direction כיוון @@ -1323,10 +927,26 @@ Version גרסה + + Starting Block + בלוק התחלה + + + Synced Blocks + בלוקים מסונכרנים + User Agent סוכן משתמש + + Decrease font size + הקטן גודל גופן + + + Increase font size + הגדל גודל גופן + Services שירותים @@ -1351,6 +971,10 @@ Ping Time זמן המענה + + Time Offset + הפרש זמן + Last block time זמן המקטע האחרון @@ -1383,10 +1007,6 @@ Out: יוצא: - - Build date - תאריך בנייה - Debug log file קובץ יומן ניפוי @@ -1395,6 +1015,22 @@ Clear console ניקוי מסוף הבקרה + + Ban Node for + חסום משתמש ל + + + 1 &day + 1& יום + + + 1 &week + 1 & שבוע + + + 1 &year + 1 & שנה + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. יש להשתמש בחצים למעלה ולמטה כדי לנווט בהיסטוריה, וב־<b>Ctrl-L</b> כדי לנקות את המסך. @@ -1518,18 +1154,6 @@ Remove הסרה - - Copy label - העתקת תווית - - - Copy message - העתקת הודעה - - - Copy amount - העתקת כמות - ReceiveRequestDialog @@ -1549,73 +1173,6 @@ &Save Image... &שמירת תמונה… - - Request payment to %1 - בקשת תשלום לטובת %1 - - - Payment information - מידע על תשלום - - - URI - כתובת משאב - - - Address - כתובת - - - Amount - כמות - - - Label - תווית - - - Message - הודעה - - - Resulting URI too long, try to reduce the text for label / message. - כתובת המשאב המתקבלת ארוכה מדי, כדאי לנסות לצמצם את הטקסט בתווית / הודעה. - - - Error encoding URI into QR Code. - שגיאה בקידוד כתובת משאב לקוד QR - - - - RecentRequestsTableModel - - Date - תאריך - - - Label - תווית - - - Message - הודעה - - - Amount - כמות - - - (no label) - (אין תווית) - - - (no message) - (אין הודעה) - - - (no amount) - (אין סכום) - SendCoinsDialog @@ -1679,6 +1236,42 @@ Transaction Fee: עמלת העברה: + + Choose... + בחר... + + + per kilobyte + עבור קילו-בית + + + Hide + הסתר + + + total at least + סה''כ לפחות + + + Recommended: + מומלץ: + + + Custom: + מותאם אישית: + + + Confirmation time: + זמן האישור: + + + normal + רגיל + + + fast + מהיר + Send to multiple recipients at once שליחה למספר מוטבים בו־זמנית @@ -1711,90 +1304,6 @@ S&end &שליחה - - Confirm send coins - אישור שליחת מטבעות - - - %1 to %2 - %1 אל %2 - - - Copy quantity - העתקת כמות - - - Copy amount - העתקת כמות - - - Copy fee - העתקת עמלה - - - Copy after fee - העתקת אחרי עמלה - - - Copy bytes - העתקת בתים - - - Copy priority - העתקת עדיפות - - - Copy change - העתקת עודף - - - or - או - - - The amount to pay must be larger than 0. - הכמות לתשלום חייבת להיות גדולה מ־0. - - - The amount exceeds your balance. - הכמות עולה על המאזן שלך. - - - The total exceeds your balance when the %1 transaction fee is included. - הכמות הכוללת, ובכללה עמלת העברה בסך %1, עולה על המאזן שלך. - - - Transaction creation failed! - יצירת ההעברה נכשלה! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - ההעברה נדחתה! מצב כזה עשוי לקרות אם חלק מהמטבעות בארנק שלך כבר הושקעו, כמו למשל עקב שימוש בעותק של wallet.dat והמטבעות הושקעו בעותק אבל לא סומנו כאילו הושקעו דרך כאן. - - - Warning: Invalid Bitcoin address - אזהרה: כתובת ביטקוין שגויה - - - (no label) - (אין תווית) - - - Warning: Unknown change address - אזהרה: כתובת עודף בלתי ידועה - - - Copy dust - העתקת אבק - - - Are you sure you want to send? - האם אכן לשלוח? - - - added as transaction fee - נוסף כעמלת העברה - SendCoinsEntry @@ -1806,10 +1315,6 @@ Pay &To: לשלם ל&טובת: - - Enter a label for this address to add it to your address book - נא להכניס תווית לכתובת הזאת כדי להוסיף לפנקס הכתובות - &Label: ת&ווית: @@ -1846,6 +1351,10 @@ Message: הודעה: + + This is an authenticated payment request. + זוהי בקשה מאומתת לתשלום. + Enter a label for this address to add it to the list of used addresses יש להזין תווית עבור כתובת זו כדי להוסיף אותה לרשימת הכתובות בשימוש @@ -1865,10 +1374,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - ליבת ביטקוין נסגרת… - Do not shut down the computer until this window disappears. אין לכבות את המחשב עד שחלון זה נעלם. @@ -1952,69 +1457,9 @@ Reset all verify message fields איפוס כל שדות אימות ההודעה - - Click "Sign Message" to generate signature - יש ללחוץ על „חתימה על ההודעה“ כדי לחולל חתימה - - - The entered address is invalid. - הכתובת שהוכנסה אינה תקינה. - - - Please check the address and try again. - נא לבדוק את הכתובת לנסות שנית. - - - The entered address does not refer to a key. - הכתובת שהוכנסה אינה מתייחסת למפתח. - - - Wallet unlock was cancelled. - פתיחת הארנק בוטלה. - - - Private key for the entered address is not available. - המפתח הפרטי עבור הכתובת שהוכנסה אינו זמין. - - - Message signing failed. - החתימה על ההודעה נכשלה. - - - Message signed. - ההודעה נחתמה. - - - The signature could not be decoded. - לא ניתן לפענח את החתימה. - - - Please check the signature and try again. - נא לבדוק את החתימה ולנסות שנית. - - - The signature did not match the message digest. - החתימה לא תואמת את תקציר ההודעה. - - - Message verification failed. - אימות ההודעה נכשל. - - - Message verified. - ההודעה אומתה. - SplashScreen - - Bitcoin Core - ליבת ביטקוין - - - The Bitcoin Core developers - מתכנתי ליבת ביטקוין - [testnet] [רשת-בדיקה] @@ -2027,398 +1472,13 @@ ק״ב/ש׳ - - TransactionDesc - - Open until %1 - פתוחה עד %1 - - - conflicted - מתנגש - - - %1/offline - %1/מנותק - - - %1/unconfirmed - %1/המתנה לאישור - - - %1 confirmations - %1 אישורים - - - Status - מצב - - - Date - תאריך - - - Source - מקור - - - Generated - נוצר - - - From - מאת - - - To - אל - - - own address - כתובת עצמית - - - watch-only - צפייה בלבד - - - label - תווית - - - Credit - זיכוי - - - not accepted - לא התקבל - - - Debit - חיוב - - - Total debit - סך כל החיוב - - - Total credit - סך כל האשראי - - - Transaction fee - עמלת העברה - - - Net amount - כמות נקייה - - - Message - הודעה - - - Comment - הערה - - - Transaction ID - מזהה העברה - - - Merchant - סוחר - - - 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. - מטבעות חדשים שנוצרו חייבים להבשיל במשך %1 מקטעים לפני שניתן לנצל אותם. כשמקטע זה נוצר הוא משודר ברשת על מנת שייכנס לשרשרת המקטעים. אם הוא לא ייכנס לשרשרת, מצבו ישתנה ל„לא התקבל“ ולא ניתן יהיה לנצלו. מצב כזה יכול לקרות מדי פעם אם במקרה מפרק אחר יצר מקטע בהבדל של שניות בודדות ממך. - - - Debug information - מידע ניפוי - - - Transaction - העברה - - - Inputs - קלטים - - - Amount - כמות - - - true - אמת - - - false - שקר - - - , has not been successfully broadcast yet - , טרם שודר בהצלחה - - - unknown - לא ידוע - - TransactionDescDialog - - Transaction details - פרטי ההעברה - This pane shows a detailed description of the transaction חלונית זו מציגה תיאור מפורט של ההעברה - - TransactionTableModel - - Date - תאריך - - - Type - סוג - - - Immature (%1 confirmations, will be available after %2) - לא בשל (%1 אישורים, יהיו זמינים לאחר %2) - - - Open until %1 - פתוחה עד %1 - - - Confirmed (%1 confirmations) - מאושר (%1 אישורים) - - - This block was not received by any other nodes and will probably not be accepted! - המקטע הזה לא נקלט על ידי אף מפרק אחר, וכנראה לא יתקבל! - - - Generated but not accepted - נוצר אך לא התקבל - - - Offline - מנותק - - - Label - תווית - - - Unconfirmed - ללא אישור - - - Confirming (%1 of %2 recommended confirmations) - מתקבל אישור (%1 מתוך %2 אישורים מומלצים) - - - Conflicted - מתנגש - - - Received with - התקבל עם - - - Received from - התקבל מאת - - - Sent to - נשלח אל - - - Payment to yourself - תשלום לעצמך - - - Mined - נכרה - - - watch-only - צפייה בלבד - - - (n/a) - (לא זמין) - - - Transaction status. Hover over this field to show number of confirmations. - מצב ההעברה. יש להמתין עם הסמן מעל שדה זה כדי לראות את מספר האישורים. - - - Date and time that the transaction was received. - התאריך והשעה בה ההעברה הזאת התקבלה. - - - Type of transaction. - סוג ההעברה. - - - Whether or not a watch-only address is involved in this transaction. - האם כתובות לצפייה בלבד מעורבות בהעברה זאת או שלא. - - - Amount removed from or added to balance. - הכמות שהתווספה או הוסרה מהיתרה. - - - - TransactionView - - All - הכול - - - Today - היום - - - This week - השבוע - - - This month - החודש - - - Last month - החודש שעבר - - - This year - השנה - - - Range... - טווח… - - - Received with - התקבל עם - - - Sent to - נשלח אל - - - To yourself - לעצמך - - - Mined - נכרה - - - Other - אחר - - - Enter address or label to search - נא להכניס כתובת או תווית לחיפוש - - - Min amount - כמות מזערית - - - Copy address - העתקת כתובת - - - Copy label - העתקת תווית - - - Copy amount - העתקת כמות - - - Copy transaction ID - העתקת מזהה העברה - - - Edit label - עריכת תווית - - - Show transaction details - הצגת פרטי העברה - - - Export Transaction History - יצוא היסטוריית העברות - - - Watch-only - צפייה בלבד - - - Exporting Failed - היצוא נכשל - - - There was an error trying to save the transaction history to %1. - אירעה שגיאה בעת ניסיון לשמור את היסטוריית ההעברות אל %1. - - - Exporting Successful - היצוא בוצע בהצלחה - - - The transaction history was successfully saved to %1. - היסטוריית ההעברות נשמרה ל־%1 בהצלחה. - - - Comma separated file (*.csv) - קובץ מופרד בפסיקים (‎*.csv) - - - Confirmed - מאושר - - - Date - תאריך - - - Type - סוג - - - Label - תווית - - - Address - כתובת - - - ID - מזהה - - - Range: - טווח: - - - to - אל - - UnitDisplayStatusBarControl @@ -2426,55 +1486,6 @@ יחידת המידה להצגת הסכומים. יש ללחוץ כדי לבחור ביחידת מידה אחרת. - - WalletFrame - - No wallet has been loaded. - לא נטען ארנק - - - - WalletModel - - Send Coins - שליחת מטבעות - - - - WalletView - - &Export - י&צוא - - - Export the data in the current tab to a file - יצוא הנתונים מהלשונית הנוכחית לקובץ - - - Backup Wallet - גיבוי ארנק - - - Wallet Data (*.dat) - נתוני ארנק (‎*.dat) - - - Backup Failed - גיבוי נכשל - - - There was an error trying to save the wallet data to %1. - אירעה שגיאה בעת ניסיון לשמירת נתוני הארנק אל %1. - - - The wallet data was successfully saved to %1. - נתוני הארנק נשמרו בהצלחה אל %1. - - - Backup Successful - הגיבוי הושלם בהצלחה - - bitcoin-core @@ -2497,6 +1508,10 @@ Accept command line and JSON-RPC commands קבלת פקודות משורת הפקודה ומ־JSON-RPC + + Error: A fatal internal error occurred, see debug.log for details + שגיאה: סניה קלמה קריטית פנימית קרטה, פנה ל debug.log לפרטים + Run in the background as a daemon and accept commands ריצה כסוכן ברקע וקבלת פקודות @@ -2505,6 +1520,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) קבלת חיבורים מבחוץ (בררת מחדל: 1 ללא ‎-proxy או ‎-connect) + + Bitcoin Core + ליבת ביטקוין + + + The %s developers + ה %s מפתחים + Bind to given address and always listen on it. Use [host]:port notation for IPv6 להתאגד לכתובת נתונה להאזין לה תמיד. יש להשתמש בצורה ‎[host]:port עבור IPv6. @@ -2521,10 +1544,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications זוהי בניית ניסיון טרום-שחרור - השימוש בה על אחריותך - אין להשתמש לצורך כריה או יישומי מסחר - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - לא ניתן להתאגד אל %s במחשב זה. כנראה שליבת ביטקוין כבר פועלת. - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. אזהרה: נראה שלא כל הרשת מסכימה! נראה שישנם כורים שנתקלים בבעיות. @@ -2533,10 +1552,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. אזהרה: נראה שישנה אי־הסכמה בינינו לבין שאר העמיתים שלנו! יתכן שעדיף לשדרג או שכל שאר העמיתים צריכים לשדרג. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - אזהרה: הקובץ wallet.dat הושחת, המידע חולץ! קובץ ה־wallet.dat המקורי נשמר בשם wallet.{timestamp}.bak במיקום %s; אם המאזן או ההעברות שגויים עליך לשחזר גיבוי. - <category> can be: <קטגוריה> יכולה להיות: @@ -2545,6 +1560,10 @@ Block creation options: אפשרויות יצירת מקטע: + + Change index out of range + אינדקס העודף מחוץ לתחום + Connect only to the specified node(s) התחבר רק לצמתים המצוינים @@ -2577,6 +1596,10 @@ Error initializing wallet database environment %s! שגיאה באתחול סביבת מסד נתוני הארנקים %s! + + Error loading %s + שגיאה בטעינת %s + Error loading block database שגיאה בטעינת מסד נתוני המקטעים @@ -2605,6 +1628,10 @@ Invalid -onion address: '%s' כתובת onion- שגויה: '%s' + + Loading banlist... + טוען רשימת חסומים... + Not enough file descriptors available. אין מספיק מידע על הקובץ @@ -2613,6 +1640,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) תמיד להתחבר למפרקים ברשת <net>‏ (ipv4,‏ ipv6 או onion) + + Print version and exit + הדפס גירסא וצא + Set database cache size in megabytes (%d to %d, default: %d) הגדרת גודל מטמון מסדי הנתונים במגה בתים (%d עד %d, בררת מחדל: %d) @@ -2638,53 +1669,29 @@ הארנק %s יושב מחוץ לתיקיית הנתונים %s - Wallet options: - אפשרויות הארנק: + Wallet debugging/testing options: + אפשרות דיבוג/בדיקת ארנק: - You need to rebuild the database using -reindex to change -txindex - עליך לבנות מחדש את מסד הנתונים תוך שימוש ב־‎-reindex על מנת לשנות את ‎-txindex + Wallet options: + אפשרויות הארנק: Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה) - Cannot resolve -whitebind address: '%s' - לא ניתן לפתור את הכתובת ‎-whitebind:‏ '%s' + The transaction amount is too small to send after the fee has been deducted + סכום העברה נמוך מדי לשליחה אחרי גביית העמלה Connect through SOCKS5 proxy התחברות דרך מתווך SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - כל הזכויות שמורות (C)‏ 2009‏-%i מתכנתי ליבת ביטקוין - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - אירעה שגיאה בטעינת wallet.dat: הארנק דורש גרסה חדשה יותר של ליבת ביטקוין - Information מידע - - Initialization sanity check failed. Bitcoin Core is shutting down. - בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת. - - - Invalid amount for -maxtxfee=<amount>: '%s' - כמות לא תקינה עבור -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - כמות לא תקינה עבור -paytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - כמות לא תקינה עבור ‎-mintxfee=<amount>‎:‏ '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) כמות לא תקינה עבור ‎-paytxfee=<amount>‎:‏ '%s' (חייבת להיות לפחות %s) @@ -2721,6 +1728,10 @@ Signing transaction failed החתימה על ההעברה נכשלה + + The transaction amount is too small to pay the fee + סכום ההעברה נמוך מכדי לשלם את העמלה + This is experimental software. זוהי תכנית נסיונית. @@ -2733,6 +1744,10 @@ Transaction amounts must be positive סכומי ההעברות חייבים להיות חיוביים + + Transaction too large for fee policy + ההעברה גבוהה מדי עבור מדיניות העמלות + Transaction too large סכום ההעברה גדול מדי @@ -2741,22 +1756,18 @@ Unable to bind to %s on this computer (bind returned error %s) לא ניתן להתאגד עם הפתחה %s במחשב זה (פעולת האיגוד החזירה את השגיאה %s) + + Upgrade wallet to latest format on startup + עדכן ארק לפורמט העדכני בהפעלה + Username for JSON-RPC connections שם משתמש לחיבורי JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - יש לכתוב את הארנק מחדש: נא להפעיל את ליבת ביטקוין מחדש כדי להשלים את הפעולה - Warning אזהרה - - wallet.dat corrupt, salvage failed - קובץ wallet.dat מושחת, החילוץ נכשל - Password for JSON-RPC connections ססמה לחיבורי JSON-RPC @@ -2765,10 +1776,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) יש לבצע פקודה זו כשהמקטע הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב המקטע) - - This help message - הודעת העזרה הזו - Allow DNS lookups for -addnode, -seednode and -connect הפעלת בדיקת DNS עבור ‎-addnode,‏ ‎-seednode ו־‎-connect @@ -2778,12 +1785,8 @@ הכתובות בטעינה… - Error loading wallet.dat: Wallet corrupted - שגיאה בטעינת הקובץ wallet.dat: הארנק מושחת - - - Error loading wallet.dat - שגיאה בטעינת הקובץ wallet.dat + (default: %s) + (ברירת מחדל: %s) Invalid -proxy address: '%s' @@ -2793,18 +1796,6 @@ Unknown network specified in -onlynet: '%s' רשת לא ידועה צוינה דרך ‎-onlynet:‏ '%s' - - Cannot resolve -bind address: '%s' - לא ניתן לפתור את הכתובת ‎-bind:‏ '%s' - - - Cannot resolve -externalip address: '%s' - לא ניתן לפתור את הכתובת ‎-externalip:‏ '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - כמות לא תקינה עבור ‎-paytxfee=<amount>‎:‏ '%s' - Insufficient funds אין מספיק כספים diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 377ff3a3f..86c53b4ce 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -9,41 +9,10 @@ Copy the currently selected address to the system clipboard चुनिन्दा पते को सिस्टम क्लिपबोर्ड पर कापी करे ! - - &Copy Address - &पता कॉपी करे - &Delete &मिटाए !! - - Copy &Label - &लेबल कॉपी करे - - - &Edit - &एडिट - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - - AddressTableModel - - Label - लेबल - - - Address - पता - - - (no label) - (कोई लेबल नही !) - AskPassphraseDialog @@ -59,63 +28,7 @@ Repeat new passphrase दोबारा नया पहचान शब्द/अक्षर डालिए ! - - Encrypt wallet - एनक्रिप्ट वॉलेट ! - - - This operation needs your wallet passphrase to unlock the wallet. - वॉलेट खोलने के आपका वॉलेट पहचान शब्द्‌/अक्षर चाईए ! - - - Unlock wallet - वॉलेट खोलिए - - - This operation needs your wallet passphrase to decrypt the wallet. - वॉलेट डीक्रिप्ट( विकोड) करने के लिए आपका वॉलेट पहचान शब्द्‌/अक्षर चाईए ! - - - Decrypt wallet - डीक्रिप्ट वॉलेट - - - Change passphrase - पहचान शब्द/अक्षर बदलिये ! - - - Confirm wallet encryption - वॉलेट एनक्रिपशन को प्रमाणित कीजिए ! - - - Wallet encrypted - वॉलेट एनक्रिप्ट हो गया ! - - - Wallet encryption failed - वॉलेट एनक्रिप्ट नही हुआ! - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - वॉलेट एनक्रिपशन नाकाम हो गया इंटर्नल एरर की वजह से! आपका वॉलेट एनक्रीपत नही हुआ है! - - - The supplied passphrases do not match. - आपके द्वारा डाले गये पहचान शब्द/अक्षर मिलते नही है ! - - - Wallet unlock failed - वॉलेट का लॉक नही खुला ! - - - The passphrase entered for the wallet decryption was incorrect. - वॉलेट डीक्रिप्ट करने के लिए जो पहचान शब्द/अक्षर डाले गये है वो सही नही है! - - - Wallet decryption failed - वॉलेट का डीक्रिप्ट-ष्ण असफल ! - - + BanTableModel @@ -223,9 +136,6 @@ वॉलेट एन्क्रिप्टेड है तथा अभी लॉक्ड है - - ClientModel - CoinControlDialog @@ -244,22 +154,6 @@ Confirmed पक्का - - Copy address - पता कॉपी करे - - - Copy label - लेबल कॉपी करे - - - Copy amount - कॉपी राशि - - - (no label) - (कोई लेबल नही !) - EditAddressDialog @@ -275,34 +169,6 @@ &Address &पता - - New receiving address - नया स्वीकार्य पता - - - New sending address - नया भेजने वाला पता - - - Edit receiving address - एडिट स्वीकार्य पता - - - Edit sending address - एडिट भेजने वाला पता - - - The entered address "%1" is already in the address book. - डाला गया पता "%1" एड्रेस बुक में पहले से ही मोजूद है| - - - Could not unlock wallet. - वॉलेट को unlock नहीं किया जा सकता| - - - New key generation failed. - नयी कुंजी का निर्माण असफल रहा| - FreespaceChecker @@ -354,9 +220,6 @@ फार्म - - PaymentServer - PeerTableModel @@ -372,9 +235,6 @@ - - QRImageWidget - RPCConsole @@ -397,52 +257,13 @@ &Label: लेबल: - - Copy label - लेबल कॉपी करे - - - Copy amount - कॉपी राशि - - + ReceiveRequestDialog Copy &Address &पता कॉपी करे - - Address - पता - - - Amount - राशि - - - Label - लेबल - - - - RecentRequestsTableModel - - Date - taareek - - - Label - लेबल - - - Amount - राशि - - - (no label) - (कोई लेबल नही !) - SendCoinsDialog @@ -466,22 +287,6 @@ Confirm the send action भेजने की पुष्टि करें - - Confirm send coins - सिक्के भेजने की पुष्टि करें - - - Copy amount - कॉपी राशि - - - The amount to pay must be larger than 0. - भेजा गया अमाउंट शुन्य से अधिक होना चाहिए| - - - (no label) - (कोई लेबल नही !) - SendCoinsEntry @@ -493,10 +298,6 @@ Pay &To: प्राप्तकर्ता: - - Enter a label for this address to add it to your address book - आपकी एड्रेस बुक में इस एड्रेस के लिए एक लेबल लिखें - &Label: लेबल: @@ -550,274 +351,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - खुला है जबतक %1 - - - %1/unconfirmed - %1/अपुष्ट - - - %1 confirmations - %1 पुष्टियाँ - - - Date - taareek - - - Transaction ID - ID - - - Amount - राशि - - - true - सही - - - false - ग़लत - - - , has not been successfully broadcast yet - , अभी तक सफलतापूर्वक प्रसारित नहीं किया गया है - - - unknown - अज्ञात - - TransactionDescDialog - - Transaction details - लेन-देन का विवरण - This pane shows a detailed description of the transaction ये खिड़की आपको लेन-देन का विस्तृत विवरण देगी ! - - TransactionTableModel - - Date - taareek - - - Type - टाइप - - - Open until %1 - खुला है जबतक %1 - - - Confirmed (%1 confirmations) - पक्के ( %1 पक्का करना) - - - This block was not received by any other nodes and will probably not be accepted! - यह ब्लॉक किसी भी और नोड को मिला नही है ! शायद यह ब्लॉक कोई भी नोड स्वीकारे गा नही ! - - - Generated but not accepted - जेनरेट किया गया किंतु स्वीकारा नही गया ! - - - Label - लेबल - - - Received with - स्वीकार करना - - - Received from - स्वीकार्य ओर से - - - Sent to - भेजा गया - - - Payment to yourself - भेजा खुद को भुगतान - - - Mined - माइंड - - - (n/a) - (लागू नहीं) - - - Transaction status. Hover over this field to show number of confirmations. - ट्रांसेक्शन स्तिथि| पुष्टियों की संख्या जानने के लिए इस जगह पर माउस लायें| - - - Date and time that the transaction was received. - तारीख तथा समय जब ये ट्रांसेक्शन प्राप्त हुई थी| - - - Type of transaction. - ट्रांसेक्शन का प्रकार| - - - Amount removed from or added to balance. - अमाउंट बैलेंस से निकला या जमा किया गया | - - - - TransactionView - - All - सभी - - - Today - आज - - - This week - इस हफ्ते - - - This month - इस महीने - - - Last month - पिछले महीने - - - This year - इस साल - - - Range... - विस्तार... - - - Received with - स्वीकार करना - - - Sent to - भेजा गया - - - To yourself - अपनेआप को - - - Mined - माइंड - - - Other - अन्य - - - Enter address or label to search - ढूँदने के लिए कृपा करके पता या लेबल टाइप करे ! - - - Min amount - लघुत्तम राशि - - - Copy address - पता कॉपी करे - - - Copy label - लेबल कॉपी करे - - - Copy amount - कॉपी राशि - - - Edit label - एडिट लेबल - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Confirmed - पक्का - - - Date - taareek - - - Type - टाइप - - - Label - लेबल - - - Address - पता - - - ID - ID - - - Range: - विस्तार: - - - to - तक - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - सिक्के भेजें| - - - - WalletView - - Backup Wallet - बैकप वॉलेट - - - Wallet Data (*.dat) - वॉलेट डेटा (*.dat) - - - Backup Failed - बैकप असफल - - - Backup Successful - बैकप सफल - - bitcoin-core diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index f9d744aa3..0d8d3d5c9 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -25,10 +25,6 @@ C&lose &Zatvori - - &Copy Address - &Kopiraj adresu - Delete the currently selected address from the list Brisanje trenutno odabrane adrese s popisa. @@ -45,73 +41,6 @@ &Delete Iz&briši - - Choose the address to send coins to - Odaberi adresu na koju šalješ novac - - - Choose the address to receive coins with - Odaberi adresu na koju primaš novac - - - C&hoose - &Odaberi - - - Sending addresses - Adresa za slanje - - - Receiving addresses - Adresa za primanje - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Ovo su vaše Bitcoin adrese za primanje novca. Preporučamo da koristite novu adresu za primanje za svaku transakciju. - - - Copy &Label - Kopiraj &oznaku - - - &Edit - &Uredi - - - Export Address List - Izvezi listu adresa - - - Comma separated file (*.csv) - Datoteka podataka odvojenih zarezima (*.csv) - - - Exporting Failed - Izvoz neuspješan - - - There was an error trying to save the address list to %1. Please try again. - Došlo je do pogreške kod spremanja liste adresa na %1. Molimo pokušajte ponovno. - - - - AddressTableModel - - Label - Oznaka - - - Address - Adresa - - - (no label) - (bez oznake) - AskPassphraseDialog @@ -131,90 +60,6 @@ Repeat new passphrase Ponovite novu lozinku - - Encrypt wallet - Šifriranje novčanika - - - This operation needs your wallet passphrase to unlock the wallet. - Ova operacija treba lozinku vašeg novčanika kako bi se novčanik otključao. - - - Unlock wallet - Otključaj novčanik - - - This operation needs your wallet passphrase to decrypt the wallet. - Ova operacija treba lozinku vašeg novčanika kako bi se novčanik dešifrirao. - - - Decrypt wallet - Dešifriranje novčanika. - - - Change passphrase - Promjena lozinke - - - Confirm wallet encryption - Potvrdi šifriranje novčanika - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINE!</b> - - - Are you sure you wish to encrypt your wallet? - Jeste li sigurni da želite šifrirati svoj novčanik? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - VAŽNO: Sve prethodne pričuve vašeg novčanika trebale bi biti zamijenjene novo stvorenom, šifriranom datotekom novčanika. Zbog sigurnosnih razloga, prethodne pričuve nešifriranog novčanika će postati beskorisne čim počnete koristiti novi, šifrirani novčanik. - - - Warning: The Caps Lock key is on! - Upozorenje: Tipka Caps Lock je uključena! - - - Wallet encrypted - Novčanik šifriran - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Unesite novu lozinku za novčanik. <br/>Molimo Vas da koristite zaporku od <b>deset ili više slučajnih znakova</b>, ili <b>osam ili više riječi.</b> - - - Enter the old passphrase and new passphrase to the wallet. - Unesite staru i novu lozinku za novčanik. - - - Wallet encryption failed - Šifriranje novčanika nije uspjelo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Šifriranje novčanika nije uspjelo zbog interne pogreške. Vaš novčanik nije šifriran. - - - The supplied passphrases do not match. - Priložene lozinke se ne podudaraju. - - - Wallet unlock failed - Otključavanje novčanika nije uspjelo - - - The passphrase entered for the wallet decryption was incorrect. - Lozinka za dešifriranje novčanika nije točna. - - - Wallet decryption failed - Dešifriranje novčanika nije uspjelo - - - Wallet passphrase was successfully changed. - Lozinka novčanika je uspješno promijenjena. - BanTableModel @@ -257,6 +102,10 @@ Quit application Izlazak iz programa + + &About %1 + &Više o %1 + About &Qt Više o &Qt @@ -293,14 +142,6 @@ Open &URI... Otvori &URI... - - Bitcoin Core client - Bitcoin Core klijent - - - Importing blocks from disk... - Importiranje blokova sa diska... - Reindexing blocks on disk... Re-indeksiranje blokova na disku... @@ -345,10 +186,6 @@ &Receive Pri&mi - - Show information about Bitcoin Core - Prikaži informacije o programu Bitcoin Core - &Show / Hide Po&kaži / Sakrij @@ -385,22 +222,10 @@ Tabs toolbar Traka kartica - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Zatraži uplatu (stvara QR kod i bitcoin: URI adresu) - - &About Bitcoin Core - &O programu Bitcoin Core - - - Modify configuration options for Bitcoin Core - Promijeni postavke programa - Show the list of used sending addresses and labels Prikaži popis korištenih adresa i oznaka za slanje novca @@ -417,10 +242,6 @@ &Command-line options Opcije &naredbene linije - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Ispis svih opcija naredbene linije programa sa kratkim opisom - %n active connection(s) to Bitcoin network %n aktivna veza na Bitcoin mrežu%n aktivnih veza na Bitcoin mrežu%n aktivnih veza na Bitcoin mrežu @@ -524,9 +345,6 @@ Novčanik je <b>šifriran</b> i trenutno <b>zaključan</b> - - ClientModel - CoinControlDialog @@ -593,87 +411,7 @@ Priority Prioriteta - - Copy address - Kopiraj adresu - - - Copy label - Kopiraj oznaku - - - Copy amount - Kopiraj iznos - - - Copy transaction ID - Kopiraj ID transakcije - - - highest - najviša - - - higher - viša - - - high - visoka - - - medium-high - srednje visoka - - - medium - srednja - - - low-medium - srednje niska - - - low - niska - - - lower - niža - - - lowest - najniža - - - This label turns red if the transaction size is greater than 1000 bytes. - Oznaka postane crvene boje ako je transakcija veća od 1000 bajtova. - - - This label turns red if the priority is smaller than "medium". - Oznaka postane crvene boje ako je prioriteta transakcije niža od "srednja" - - - This label turns red if any recipient receives an amount smaller than %1. - Oznaka postane crvene boje ako je iznos manji od %1 - - - yes - da - - - no - ne - - - Transactions with higher priority are more likely to get included into a block. - Transakcije više prioritete imaju veću vjerojatnost da budu prije dodane u novi blok. - - - (no label) - (bez oznake) - - + EditAddressDialog @@ -696,38 +434,6 @@ &Address &Adresa - - New receiving address - Nova adresa za primanje - - - New sending address - Nova adresa za slanje - - - Edit receiving address - Uredi adresu za primanje - - - Edit sending address - Uredi adresu za slanje - - - The entered address "%1" is already in the address book. - Upisana adresa "%1" je već u adresaru. - - - The entered address "%1" is not a valid Bitcoin address. - Upisana adresa "%1" nije valjana bitcoin adresa. - - - Could not unlock wallet. - Ne mogu otključati novčanik. - - - New key generation failed. - Stvaranje novog ključa nije uspjelo. - FreespaceChecker @@ -746,10 +452,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version verzija @@ -758,10 +460,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - O programu Bitcoin Core - Command-line options Opcije programa u naredbenoj liniji @@ -781,14 +479,6 @@ Welcome Dobrodošli - - Welcome to Bitcoin Core. - Dobrodošli u programu Bitcoin Core. - - - Bitcoin Core - Bitcoin Core - Error Greška @@ -812,10 +502,6 @@ Select payment request file Izaberi datoteku zahtjeva za plaćanje - - Select payment request file to open - Izaberi datoteku zahtjeva za plaćanje - OptionsDialog @@ -863,14 +549,6 @@ &Network &Mreža - - Automatically start Bitcoin Core after logging in to the system. - Program se automatski pokrene po prijavi u sustav. - - - &Start Bitcoin Core on system login - &Pokreni program kod prijave u sustav - W&allet &Novčanik @@ -963,13 +641,6 @@ Ukupno: - - PaymentServer - - URI handling - URI upravljanje - - PeerTableModel @@ -984,17 +655,6 @@ N/A - - QRImageWidget - - &Save Image... - &Spremi sliku... - - - Save QR Code - Spremi QR kod - - RPCConsole @@ -1081,10 +741,6 @@ Clear console Očisti konzolu - - Welcome to the Bitcoin Core RPC console. - Dobrodošli u Bitcoin RPC konzolu. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Koristite tipke gore i dolje za izbor već korištenih naredbi. <b>Ctrl-L</b> kako bi očistili ekran i povijest naredbi. @@ -1120,15 +776,7 @@ Show Pokaži - - Copy label - Kopiraj oznaku - - - Copy amount - Kopiraj iznos - - + ReceiveRequestDialog @@ -1147,65 +795,6 @@ &Save Image... &Spremi sliku... - - URI - URI - - - Address - Adresa - - - Amount - Iznos - - - Label - Oznaka - - - Message - Poruka - - - Resulting URI too long, try to reduce the text for label / message. - URI je predug, probajte skratiti tekst za naslov / poruku. - - - Error encoding URI into QR Code. - Greška kod kodiranja URI adrese u QR kod. - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Oznaka - - - Message - Poruka - - - Amount - Iznos - - - (no label) - (bez oznake) - - - (no message) - (bez poruke) - - - (no amount) - (bez iznosa) - SendCoinsDialog @@ -1277,35 +866,7 @@ S&end &Pošalji - - Confirm send coins - Potvrdi slanje novca - - - Copy amount - Kopiraj iznos - - - or - ili - - - The amount to pay must be larger than 0. - Iznos mora biti veći od 0. - - - The amount exceeds your balance. - Iznos je veći od raspoložljivog stanja novčanika. - - - The total exceeds your balance when the %1 transaction fee is included. - Iznos je veći od stanja novčanika kad se doda naknada za transakcije od %1. - - - (no label) - (bez oznake) - - + SendCoinsEntry @@ -1316,10 +877,6 @@ Pay &To: &Primatelj plaćanja: - - Enter a label for this address to add it to your address book - Unesite oznaku za ovu adresu kako bi ju dodali u vaš adresar - &Label: &Oznaka: @@ -1390,21 +947,9 @@ Verify &Message &Potvrdite poruku - - Wallet unlock was cancelled. - Otključavanje novčanika je otkazano. - - - Message signed. - Poruka je potpisana. - SplashScreen - - Bitcoin Core - Bitcoin Core - [testnet] [testnet] @@ -1413,350 +958,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Otvoren do %1 - - - %1/offline - %1 nije dostupan - - - %1/unconfirmed - %1/nepotvrđeno - - - %1 confirmations - %1 potvrda - - - Status - Status - - - Date - Datum - - - Source - Izvor - - - Generated - Generiran - - - From - Od - - - To - Za - - - own address - vlastita adresa - - - label - oznaka - - - Credit - Uplaćeno - - - not accepted - Nije prihvaćeno - - - Debit - Zaduženje - - - Transaction fee - Naknada za transakciju - - - Net amount - Neto iznos - - - Message - Poruka - - - Comment - Komentar - - - Transaction ID - ID transakcije - - - Transaction - Transakcija - - - Inputs - Unosi - - - Amount - Iznos - - - , has not been successfully broadcast yet - , još nije bio uspješno emitiran - - - unknown - nepoznato - - TransactionDescDialog - - Transaction details - Detalji transakcije - This pane shows a detailed description of the transaction Ovaj prozor prikazuje detaljni opis transakcije - - TransactionTableModel - - Date - Datum - - - Type - Tip - - - Open until %1 - Otvoren do %1 - - - Confirmed (%1 confirmations) - Potvrđen (%1 potvrda) - - - This block was not received by any other nodes and will probably not be accepted! - Ovaj blok nije bio primljen od strane bilo kojeg drugog čvora i vjerojatno neće biti prihvaćen! - - - Generated but not accepted - Generirano, ali nije prihvaćeno - - - Label - Oznaka - - - Received with - Primljeno s - - - Received from - Primljeno od - - - Sent to - Poslano za - - - Payment to yourself - Plaćanje samom sebi - - - Mined - Rudareno - - - (n/a) - (n/d) - - - Transaction status. Hover over this field to show number of confirmations. - Status transakcije - - - Date and time that the transaction was received. - Datum i vrijeme kad je transakcija primljena - - - Type of transaction. - Vrsta transakcije. - - - Amount removed from or added to balance. - Iznos odbijen od ili dodan k saldu. - - - - TransactionView - - All - Sve - - - Today - Danas - - - This week - Ovaj tjedan - - - This month - Ovaj mjesec - - - Last month - Prošli mjesec - - - This year - Ove godine - - - Range... - Raspon... - - - Received with - Primljeno s - - - Sent to - Poslano za - - - To yourself - Samom sebi - - - Mined - Rudareno - - - Other - Ostalo - - - Enter address or label to search - Unesite adresu ili oznaku za pretraživanje - - - Min amount - Min iznos - - - Copy address - Kopiraj adresu - - - Copy label - Kopiraj oznaku - - - Copy amount - Kopiraj iznos - - - Copy transaction ID - Kopiraj ID transakcije - - - Edit label - Izmjeni oznaku - - - Show transaction details - Prikaži detalje transakcije - - - Exporting Failed - Izvoz neuspješan - - - Comma separated file (*.csv) - Datoteka podataka odvojenih zarezima (*.csv) - - - Confirmed - Potvrđeno - - - Date - Datum - - - Type - Tip - - - Label - Oznaka - - - Address - Adresa - - - ID - ID - - - Range: - Raspon: - - - to - za - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Slanje novca - - - - WalletView - - &Export - &Izvoz - - - Export the data in the current tab to a file - Izvoz podataka iz trenutnog taba u datoteku - - - Backup Wallet - Arhiviranje novčanika - - - Wallet Data (*.dat) - Podaci novčanika (*.dat) - - - Backup Failed - Arhiviranje nije uspjelo - - bitcoin-core @@ -1779,6 +990,10 @@ Run in the background as a daemon and accept commands Izvršavaj u pozadini kao uslužnik i prihvaćaj komande + + Bitcoin Core + Bitcoin Core + Block creation options: Opcije za kreiranje bloka: @@ -1795,18 +1010,6 @@ Information Informacija - - Invalid amount for -maxtxfee=<amount>: '%s' - Nevaljali iznos za opciju -maxtxfee=<iznos>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Nevaljali iznos za opciju -minrelaytxfee=<iznos>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Nevaljali iznos za opciju -mintxfee=<iznos>: '%s' - Send trace/debug info to console instead of debug.log file Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku @@ -1827,10 +1030,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Izvršite naredbu kada se najbolji blok promjeni (%s u cmd je zamjenjen sa block hash) - - This help message - Ova poruka za pomoć - Allow DNS lookups for -addnode, -seednode and -connect Dozvoli DNS upite za -addnode, -seednode i -connect @@ -1839,22 +1038,10 @@ Loading addresses... Učitavanje adresa... - - Error loading wallet.dat: Wallet corrupted - Greška kod učitavanja datoteke wallet.dat: Novčanik pokvaren - - - Error loading wallet.dat - Greška kod učitavanja datoteke wallet.dat - Invalid -proxy address: '%s' Nevaljala -proxy adresa: '%s' - - Invalid amount for -paytxfee=<amount>: '%s' - Nevaljali iznos za opciju -paytxfee=<iznos>: '%s' - Insufficient funds Nedovoljna sredstva diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 839ee883b..bddc430f2 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -25,10 +25,6 @@ C&lose &Bezárás - - &Copy Address - &Cím másolása - Delete the currently selected address from the list Kiválasztott cím törlése a listából @@ -45,73 +41,6 @@ &Delete &Törlés - - Choose the address to send coins to - Válaszd ki a címet, ahová küldesz - - - Choose the address to receive coins with - Válaszd ki a címet, amivel fogadsz - - - C&hoose - &Kiválaszt - - - Sending addresses - Küldési címek - - - Receiving addresses - Fogadó címek - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Ezekről a címekről küldhetsz bitcoint. Mindig ellenőrizd a fogadó címet és a fizetendő összeget, mielőtt elküldöd. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Ezekkel a címekkel fogadhatsz bitcoint. Ajánlott minden tranzakcióhoz egy új fogadó címet használni. - - - Copy &Label - &Címke másolása - - - &Edit - Sz&erkesztés - - - Export Address List - Címjegyzék exportálása - - - Comma separated file (*.csv) - Vesszővel elválasztott fájl (*.csv) - - - Exporting Failed - Az exportálás sikertelen volt - - - There was an error trying to save the address list to %1. Please try again. - Hiba történt a címjegyzék %1 helyre való mentésekor. Kérlek próbáld újra. - - - - AddressTableModel - - Label - Címke - - - Address - Cím - - - (no label) - (nincs címke) - AskPassphraseDialog @@ -131,90 +60,6 @@ Repeat new passphrase Új jelszó újra - - Encrypt wallet - Tárca titkosítása - - - This operation needs your wallet passphrase to unlock the wallet. - A tárca megnyitásához a műveletnek szüksége van a tárcád jelszavára. - - - Unlock wallet - Tárca megnyitása - - - This operation needs your wallet passphrase to decrypt the wallet. - A tárca dekódolásához a műveletnek szüksége van a tárcád jelszavára. - - - Decrypt wallet - Tárca dekódolása - - - Change passphrase - Jelszó megváltoztatása - - - Confirm wallet encryption - Biztosan titkosítani akarod a tárcát? - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Figyelem: ha titkosítod a tárcát és elveszted a jelszavad, akkor <b>AZ ÖSSZES BITCOINOD ELVESZIK!</b> - - - Are you sure you wish to encrypt your wallet? - Biztosan titkosítani akarod a tárcád? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - FONTOS: A tárca-fájl minden korábbi mentését cseréld le ezzel az új, titkosított tárca-fájllal. Biztonsági okokból a tárca-fájl korábbi, titkosítás nélküli mentései használhatatlanná válnak, amint elkezded használni az új, titkosított tárcát. - - - Warning: The Caps Lock key is on! - Vigyázat: a Caps Lock be van kapcsolva! - - - Wallet encrypted - Tárca titkosítva - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Add meg a tárca új jelszavát.<br/>Olyan jelszót válassz, ami <b>legalább tíz véletlenszerű karakterből</b> vagy <b>legalább 8 véletlenszerű szóból</b> áll. - - - Enter the old passphrase and new passphrase to the wallet. - Add meg a tárcához a régi jelszavad és az új jelszavad. - - - Wallet encryption failed - A tárca titkosítása sikertelen. - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Tárca titkosítása belső hiba miatt sikertelen. A tárcád nem lett titkosítva. - - - The supplied passphrases do not match. - A megadott jelszavak nem egyeznek. - - - Wallet unlock failed - Tárca megnyitása sikertelen - - - The passphrase entered for the wallet decryption was incorrect. - Hibás jelszó. - - - Wallet decryption failed - Dekódolás sikertelen. - - - Wallet passphrase was successfully changed. - Jelszó megváltoztatva. - BanTableModel @@ -257,6 +102,10 @@ Quit application Kilépés az alkalmazásból + + &About %1 + &A %1-ról + About &Qt A &Qt-ról @@ -293,14 +142,6 @@ Open &URI... &URI azonosító megnyitása... - - Bitcoin Core client - Bitcoin Core kliens - - - Importing blocks from disk... - A blokkok importálása lemezről... - Reindexing blocks on disk... Lemezen lévő blokkok újraindexelése... @@ -345,10 +186,6 @@ &Receive &Fogadás - - Show information about Bitcoin Core - Bitcoin Core információ megjelenítése - &Show / Hide &Mutat / Elrejt @@ -385,22 +222,10 @@ Tabs toolbar Fül eszköztár - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Fizetési kérelem (QR-kódot és "bitcoin:" URI azonosítót hoz létre) - - &About Bitcoin Core - &A Bitcoin Core-ról - - - Modify configuration options for Bitcoin Core - Konfigurációs opciók módosítása a Bitcoin Core-hoz - Show the list of used sending addresses and labels A használt küldési címek és címkék megtekintése @@ -417,10 +242,6 @@ &Command-line options Paran&cssor kapcsolók - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - A Bitcoin Core súgóüzenet megjelenítése a Bitcoin lehetséges parancssori kapcsolóival. - %n active connection(s) to Bitcoin network %n aktív kapcsolat a Bitcoin hálózathoz%n aktív kapcsolat a Bitcoin hálózathoz @@ -532,13 +353,6 @@ Tárca <b>kódolva</b> és jelenleg <b>zárva</b>. - - ClientModel - - Network Alert - Hálózati figyelmeztetés - - CoinControlDialog @@ -617,150 +431,6 @@ Priority Prioritás - - Copy address - Cím másolása - - - Copy label - Címke másolása - - - Copy amount - Összeg másolása - - - Copy transaction ID - Tranzakcióazonosító másolása - - - Lock unspent - Megmaradt zárolása - - - Unlock unspent - Zárolás feloldása - - - Copy quantity - Mennyiség másolása - - - Copy fee - Díj másolása - - - Copy after fee - Utólagos díj másolása - - - Copy bytes - Byte-ok másolása - - - Copy priority - Prioritás másolása - - - Copy dust - Visszajáró másolása - - - Copy change - Visszajáró másolása - - - highest - legmagasabb - - - higher - magasabb - - - high - magas - - - medium-high - közepesen-magas - - - medium - közepes - - - low-medium - alacsony-közepes - - - low - alacsony - - - lower - alacsonyabb - - - lowest - legalacsonyabb - - - (%1 locked) - (%1 zárolva) - - - none - semmi - - - This label turns red if the transaction size is greater than 1000 bytes. - Ez a címke pirosra változik, ha a tranzakció mérete nagyobb mint 1000 bájt. - - - This label turns red if the priority is smaller than "medium". - Ez a címke pirosra változik, ha a prioritás kisebb mint "közepes". - - - This label turns red if any recipient receives an amount smaller than %1. - Ez a címke pirosra változik, ha bármely fogadónak %1-nál kevesebb összeg érkezik. - - - Can vary +/- %1 satoshi(s) per input. - Bemenetenként +/- %1 satoshi-val változhat - - - yes - igen - - - no - nem - - - This means a fee of at least %1 per kB is required. - Legalább %1 díj szüksége kB-onként. - - - Can vary +/- 1 byte per input. - Bemenetenként +/- 1 byte-al változhat. - - - Transactions with higher priority are more likely to get included into a block. - Nagyobb prioritású tranzakciók nagyobb valószínűséggel kerülnek be egy blokkba. - - - (no label) - (nincs címke) - - - change from %1 (%2) - visszajáró %1-ből (%2) - - - (change) - (visszajáró) - EditAddressDialog @@ -784,38 +454,6 @@ &Address &Cím - - New receiving address - Új fogadó cím - - - New sending address - Új küldő cím - - - Edit receiving address - Fogadó cím szerkesztése - - - Edit sending address - Küldő cím szerkesztése - - - The entered address "%1" is already in the address book. - A megadott "%1" cím már szerepel a címjegyzékben. - - - The entered address "%1" is not a valid Bitcoin address. - A megadott "%1" cím nem egy érvényes Bitcoin-cím. - - - Could not unlock wallet. - Tárca feloldása sikertelen - - - New key generation failed. - Új kulcs generálása sikertelen - FreespaceChecker @@ -838,10 +476,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version verzió @@ -850,10 +484,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - A Bitcoin Core-ról - Command-line options Parancssoros opciók @@ -873,14 +503,6 @@ Welcome Üdvözlünk - - Welcome to Bitcoin Core. - Üdvözlünk a Bitcoin Core-ban. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - A Bitcoin Core le fogja tölteni és tárolni fogja a Bitcoin blokklánc egy másolatát. Legalább %1GB adat lesz tárolva ebben a mappában, és ez folyamatosan nőni fog. A tárca szintén itt lesz tárolva. - Use the default data directory Az alapértelmezett adat könyvtár használata @@ -889,10 +511,6 @@ Use a custom data directory: Saját adatkönyvtár használata: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Hiba: A megadott "%1" adatkönyvtár nem hozható létre. @@ -924,10 +542,6 @@ Select payment request file Fizetési kérelmi fájl kiválasztása - - Select payment request file to open - Fizetés kérelmi fájl kiválasztása - OptionsDialog @@ -959,10 +573,6 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) A proxy IP címe (pl.: IPv4: 127.0.0.1 / IPv6: ::1) - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Itt beállíthatod a kezelőfelület nyelvét. A beállítás a Bitcoin újraindítása után lép érvénybe. - Third party transaction URLs Harmadik fél tranzakció URL-ek @@ -979,10 +589,6 @@ &Network &Hálózat - - &Start Bitcoin Core on system login - A Bitcoin elindítása bejelentkezéskor - W&allet T&árca @@ -1147,25 +753,6 @@ A legutóbbi tranzakciók - - PaymentServer - - URI handling - URI kezelés - - - Cannot start bitcoin: click-to-pay handler - A bitcoint nem lehet elindítani: click-to-pay handler - - - Payment request expired. - A fizetési kérelem lejárt - - - Invalid payment request. - Érvénytelen fizetési kérelem - - PeerTableModel @@ -1216,25 +803,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Kép mentése - - - &Copy Image - &Kép másolása - - - Save QR Code - QR kód mentése - - - PNG Image (*.png) - PNG kép (*.png) - - RPCConsole @@ -1369,10 +937,6 @@ Out: Ki: - - Build date - Fordítás dátuma - Debug log file Debug naplófájl @@ -1492,18 +1056,6 @@ Remove Eltávolítás - - Copy label - Címke másolása - - - Copy message - Üzenet másolása - - - Copy amount - Összeg másolása - ReceiveRequestDialog @@ -1523,73 +1075,6 @@ &Save Image... &Kép mentése - - Request payment to %1 - Fizetés kérése a %1-hez - - - Payment information - Kifizetés információ - - - URI - URI: - - - Address - Cím - - - Amount - Összeg - - - Label - Címke - - - Message - Üzenet - - - Resulting URI too long, try to reduce the text for label / message. - A keletkezett URI túl hosszú, próbálja meg csökkenteni a cimkeszöveg / üzenet méretét. - - - Error encoding URI into QR Code. - Hiba lépett fel az URI QR kóddá alakításakor - - - - RecentRequestsTableModel - - Date - Dátum - - - Label - Címke - - - Message - Üzenet - - - Amount - Összeg - - - (no label) - (nincs címke) - - - (no message) - (nincs üzenet) - - - (no amount) - (nincs összeg) - SendCoinsDialog @@ -1701,75 +1186,7 @@ S&end &Küldés - - Confirm send coins - Küldés megerősítése - - - Copy quantity - Mennyiség másolása - - - Copy amount - Összeg másolása - - - Copy fee - Díj másolása - - - Copy after fee - Utólagos díj másolása - - - Copy bytes - Byte-ok másolása - - - Copy priority - Prioritás másolása - - - Copy change - Visszajáró másolása - - - or - vagy - - - The amount to pay must be larger than 0. - A fizetendő összegnek nagyobbnak kell lennie 0-nál. - - - The amount exceeds your balance. - Nincs ennyi bitcoin az egyenlegeden. - - - The total exceeds your balance when the %1 transaction fee is included. - A küldeni kívánt összeg és a %1 tranzakciós díj együtt meghaladja az egyenlegeden rendelkezésedre álló összeget. - - - Payment request expired. - A fizetési kérelem lejárt - - - Warning: Invalid Bitcoin address - Figyelmeztetés: Érvénytelen Bitcoin cím - - - (no label) - (nincs címke) - - - Copy dust - Visszajáró másolása - - - Are you sure you want to send? - Biztos, hogy el akarod küldeni? - - + SendCoinsEntry @@ -1780,11 +1197,6 @@ Pay &To: Címzett: - - Enter a label for this address to add it to your address book - Milyen címkével kerüljön be ez a cím a címtáradba? - - &Label: Címke: @@ -1824,10 +1236,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - A Bitcoin Core leáll... - Do not shut down the computer until this window disappears. Ne állítsd le a számítógépet amíg ez az ablak el nem tűnik. @@ -1891,53 +1299,9 @@ Verify &Message Üzenet ellenőrzése - - The entered address is invalid. - A megadott cím nem érvényes. - - - Please check the address and try again. - Ellenőrizze a címet és próbálja meg újra. - - - Private key for the entered address is not available. - A megadott cím privát kulcsa nem található. - - - Message signing failed. - Üzenet aláírása nem sikerült. - - - Message signed. - Üzenet aláírva. - - - The signature could not be decoded. - Az aláírást nem sikerült dekódolni. - - - Please check the signature and try again. - Ellenőrizd az aláírást és próbáld újra. - - - Message verification failed. - Az üzenet ellenőrzése nem sikerült. - - - Message verified. - Üzenet ellenőrizve. - - + SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - A Bitcoin Core fejlesztői - [testnet] [teszthálózat] @@ -1950,378 +1314,16 @@ KB/s - - TransactionDesc - - Open until %1 - %1-ig megnyitva - - - %1/unconfirmed - %1/megerősítetlen - - - %1 confirmations - %1 megerősítés - - - Status - Állapot - - - Date - Dátum - - - Source - Forrás - - - Generated - Legenerálva - - - From - Űrlap - - - To - Címzett - - - own address - saját cím - - - label - címke - - - Credit - Jóváírás - - - not accepted - elutasítva - - - Debit - Terhelés - - - Transaction fee - Tranzakciós díj - - - Net amount - Nettó összeg - - - Message - Üzenet - - - Comment - Megjegyzés - - - Transaction ID - Tranzakcióazonosító - - - Debug information - Debug információ - - - Transaction - Tranzakció - - - Inputs - Bemenetek - - - Amount - Összeg - - - true - igaz - - - false - hamis - - - , has not been successfully broadcast yet - , még nem sikerült elküldeni. - - - unknown - ismeretlen - - TransactionDescDialog - - Transaction details - Tranzakció részletei - This pane shows a detailed description of the transaction Ez a mező a tranzakció részleteit mutatja - - TransactionTableModel - - Date - Dátum - - - Type - Típus - - - Open until %1 - %1-ig megnyitva - - - Confirmed (%1 confirmations) - Megerősítve (%1 megerősítés) - - - This block was not received by any other nodes and will probably not be accepted! - Ezt a blokkot egyetlen másik csomópont sem kapta meg, így valószínűleg nem lesz elfogadva! - - - Generated but not accepted - Legenerálva, de még el nem fogadva. - - - Offline - Offline - - - Label - Címke - - - Unconfirmed - Megerősítetlen: - - - Received with - Erre a címre - - - Received from - Erről az - - - Sent to - Erre a címre - - - Payment to yourself - Magadnak kifizetve - - - Mined - Kibányászva - - - (n/a) - (nincs) - - - Transaction status. Hover over this field to show number of confirmations. - Tranzakció állapota. Húzd ide a kurzort, hogy lásd a megerősítések számát. - - - Date and time that the transaction was received. - Tranzakció fogadásának dátuma és időpontja. - - - Type of transaction. - Tranzakció típusa. - - - Amount removed from or added to balance. - Az egyenleghez jóváírt vagy ráterhelt összeg. - - - - TransactionView - - All - Mind - - - Today - Mai - - - This week - Ezen a héten - - - This month - Ebben a hónapban - - - Last month - Múlt hónapban - - - This year - Ebben az évben - - - Range... - Tartomány ... - - - Received with - Erre a címre - - - Sent to - Erre a címre - - - To yourself - Magadnak - - - Mined - Kibányászva - - - Other - Más - - - Enter address or label to search - Írd be a keresendő címet vagy címkét - - - Min amount - Minimális összeg - - - Copy address - Cím másolása - - - Copy label - Címke másolása - - - Copy amount - Összeg másolása - - - Copy transaction ID - Tranzakcióazonosító másolása - - - Edit label - Címke szerkesztése - - - Show transaction details - Tranzakciós részletek megjelenítése - - - Watch-only - Csak megfigyelés - - - Exporting Failed - Az exportálás sikertelen volt - - - Exporting Successful - Sikeres exportálás - - - Comma separated file (*.csv) - Vesszővel elválasztott fájl (*.csv) - - - Confirmed - Megerősítve - - - Date - Dátum - - - Type - Típus - - - Label - Címke - - - Address - Cím - - - ID - Azonosító - - - Range: - Tartomány: - - - to - meddig - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Érmék küldése - - - - WalletView - - &Export - &Exportálás - - - Export the data in the current tab to a file - Jelenlegi nézet exportálása fájlba - - - Backup Wallet - Biztonsági másolat készítése a Tárcáról - - - Wallet Data (*.dat) - Tárca fájl (*.dat) - - - Backup Failed - Biztonsági másolat készítése sikertelen - - - Backup Successful - Sikeres biztonsági mentés - - bitcoin-core @@ -2356,6 +1358,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Kívülről érkező kapcsolatok elfogadása (alapértelmezett: 1, ha nem használt a -proxy vagy a -connect) + + Bitcoin Core + Bitcoin Core + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Parancs, amit akkor hajt végre, amikor egy tárca-tranzakció megváltozik (%s a parancsban lecserélődik a blokk TxID-re) @@ -2420,18 +1426,6 @@ Wallet options: Tárca beállítások: - - You need to rebuild the database using -reindex to change -txindex - Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex). - - - Cannot resolve -whitebind address: '%s' - Külső cím (-whitebind address) feloldása nem sikerült: '%s' - - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i A Bitcoin Core Fejlesztői - Error reading from database, shutting down. Hiba az adatbázis olvasásakor, leállítás @@ -2440,18 +1434,6 @@ Information Információ - - Invalid amount for -maxtxfee=<amount>: '%s' - Érvénytelen -maxtxfee=<amount>: '%s' összeg - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Érvénytelen -minrelaytxfee=<amount>: '%s' összeg - - - Invalid amount for -mintxfee=<amount>: '%s' - Érvénytelen -mintxfee=<amount>: '%s' összeg - Send trace/debug info to console instead of debug.log file trace/debug információ küldése a konzolra a debog.log fájl helyett @@ -2494,11 +1476,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Parancs, amit akkor hajt végre, amikor a legjobb blokk megváltozik (%s a cmd-ban lecserélődik a blokk hash-re) - - This help message - Ez a súgó-üzenet - - Allow DNS lookups for -addnode, -seednode and -connect DNS-kikeresés engedélyezése az addnode-nál és a connect-nél @@ -2507,14 +1484,6 @@ Loading addresses... Címek betöltése... - - Error loading wallet.dat: Wallet corrupted - Hiba a wallet.dat betöltése közben: meghibásodott tárca - - - Error loading wallet.dat - Hiba az wallet.dat betöltése közben - Invalid -proxy address: '%s' Érvénytelen -proxy cím: '%s' @@ -2523,18 +1492,6 @@ Unknown network specified in -onlynet: '%s' Ismeretlen hálózat lett megadva -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Csatlakozási cím (-bind address) feloldása nem sikerült: '%s' - - - Cannot resolve -externalip address: '%s' - Külső cím (-externalip address) feloldása nem sikerült: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Étvénytelen -paytxfee=<összeg> összeg: '%s' - Insufficient funds Nincs elég bitcoinod. diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index e1ec7ae7f..fe07ab7a2 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -25,10 +25,6 @@ C&lose T&utup - - &Copy Address - &Salin Alamat - Delete the currently selected address from the list Hapus alamat yang sementara dipilih dari daftar @@ -45,73 +41,6 @@ &Delete &Hapus - - Choose the address to send coins to - Pilihlah alamat kemana koin Anda akan dikirim - - - Choose the address to receive coins with - Pilihlah alamat dimana Anda akan menerima koin - - - C&hoose - P&ilihlah - - - Sending addresses - Alamat pengirim - - - Receiving addresses - Alamat penerima - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Alamat-alamat Anda untuk mengirim pembayaran. Periksalah jumlah dan alamat penerima setiap kali Anda mengirim Bitcoin. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Alamat-alamat Anda untuk menerima pembayaran. Dianjurkan agar Anda menggunakan alamat yang baru untuk setiap transaksi. - - - Copy &Label - Salin &Label - - - &Edit - &Ubah - - - Export Address List - Ekspor Daftar Alamat - - - Comma separated file (*.csv) - Berkas CSV (*.csv) - - - Exporting Failed - Proses Ekspor Gagal - - - There was an error trying to save the address list to %1. Please try again. - Terjadi kesalahan saat menyimpan daftar alamat ke %1. Silakan coba lagi. - - - - AddressTableModel - - Label - Label - - - Address - Alamat - - - (no label) - (tidak ada label) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Ulangi kata kunci baru - - Encrypt wallet - Enkripsi dompet - - - This operation needs your wallet passphrase to unlock the wallet. - Operasi ini memerlukan kata kunci dompet Anda untuk membuka dompet. - - - Unlock wallet - Buka dompet - - - This operation needs your wallet passphrase to decrypt the wallet. - Operasi ini memerlukan kata kunci dompet Anda untuk mendekripsi dompet. - - - Decrypt wallet - Dekripsi dompet - - - Change passphrase - Ubah kata kunci - - - Confirm wallet encryption - Konfirmasi enkripsi dompet - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Perhatian: Jika anda mengenkripsi dompet anda dan lupa kata kuncinya, anda akan <b>KEHILANGAN SELURUH BITCOIN ANDA</b>! - - - Are you sure you wish to encrypt your wallet? - Apakah Anda yakin ingin mengenkripsi dompet Anda? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core akan ditutup untuk menyelesaikan proses enkripsi. Mohon diingat bahwa mengenkripsi dompet Anda tidak akan sepenuhnya melindungi bitcoin Anda dari virus atau malware yang menginfeksi komputer Anda. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - PENTING: Setiap back up yang sudah Anda buat sebaiknya diganti dengan data dompet Anda yang baru dan terenkripsi. Untuk alasan keamanan, data back up tidak terenkripsi yang sudah Anda buat sebelumnya tidak akan dapat digunakan setelah Anda mulai menggunakan dompet yang baru dan terenkripsi. - - - Warning: The Caps Lock key is on! - Perhatian: tombol Caps Lock sementara aktif! - - - Wallet encrypted - Dompet terenkripsi - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Masukkan kata kunci untuk dompet Anda.<br/>Mohon gunakan kata kunci <b>yang terdiri dari 10 karakter acak</b>, atau <b>delapan atau beberapa kata lagi</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Masukkan kata kunci lama dan kata kunci baru dompet Anda. - - - Wallet encryption failed - Enkripsi dompet gagal - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Enkripsi dompet gagal karena kesalahan internal. Dompet Anda tidak dienkripsi. - - - The supplied passphrases do not match. - Kata kunci yang dimasukkan tidak cocok. - - - Wallet unlock failed - Gagal buka dompet - - - The passphrase entered for the wallet decryption was incorrect. - Kata kunci yang dimasukkan untuk dekripsi dompet tidak cocok. - - - Wallet decryption failed - Dekripsi dompet gagal - - - Wallet passphrase was successfully changed. - Kata kunci dompet Anda berhasil diubah. - BanTableModel @@ -305,14 +146,6 @@ Open &URI... Buka &URI - - Bitcoin Core client - Klien Bitcoin Core - - - Importing blocks from disk... - Mengimpor blok dari disk... - Reindexing blocks on disk... Mengindex ulang blok di dalam disk... @@ -357,10 +190,6 @@ &Receive &Menerima - - Show information about Bitcoin Core - Tampilkan informasi tentang Bitcoin Core - &Show / Hide &Tampilkan / Sembunyikan @@ -397,22 +226,10 @@ Tabs toolbar Baris tab - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Permintaan pembayaran (membuat kode QR dan bitcoin: URIs) - - &About Bitcoin Core - &Mengenai Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifikasi pengaturan konfigurasi untuk Bitcoin Core - Show the list of used sending addresses and labels Tampilkan daftar alamat dan label yang terkirim @@ -429,10 +246,6 @@ &Command-line options &pilihan Command-line - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Tampilkan pesan bantuan Bitcoin Core untuk mendapatkan daftar pilihan Command-line - %n active connection(s) to Bitcoin network %n koneksi aktif ke jaringan Bitcoin @@ -544,13 +357,6 @@ Dompet saat ini <b>terenkripsi</b> dan <b>terkunci</b> - - ClientModel - - Network Alert - Notifikasi Jaringan - - CoinControlDialog @@ -629,150 +435,6 @@ Priority Prioritas - - Copy address - Salin alamat - - - Copy label - Salin label - - - Copy amount - Salin jumlah - - - Copy transaction ID - Salin ID transaksi - - - Lock unspent - Kunci unspent. - - - Unlock unspent - Buka unspent - - - Copy quantity - Salin kuantitas - - - Copy fee - Salin biaya - - - Copy after fee - Salin dengan biaya - - - Copy bytes - Salin bytes - - - Copy priority - Salin prioritas - - - Copy dust - Salin dust - - - Copy change - Salin kembalian - - - highest - terbesar - - - higher - lebih besar - - - high - besar - - - medium-high - sedang-sampai-besar - - - medium - sedang - - - low-medium - sedikit-sampai-sedang - - - low - sedikit - - - lower - lebih sedikit - - - lowest - tersedikit - - - (%1 locked) - (%1 terkunci) - - - none - tidak satupun - - - This label turns red if the transaction size is greater than 1000 bytes. - Label ini akan menjadi merah apabila ukuran transaksi melebihi 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Label ini akan menjadi merah apabila prioritasnya lebih kecil dari "sedang" - - - This label turns red if any recipient receives an amount smaller than %1. - Label ini akan menjadi merah apabila penerima menerima jumlah yang lebih kecil dari %1. - - - Can vary +/- %1 satoshi(s) per input. - Dapat beragam +/- %1 satoshi per input. - - - yes - ya - - - no - tidak - - - This means a fee of at least %1 per kB is required. - Perlu biaya lebih dari %1 untuk setiap kB. - - - Can vary +/- 1 byte per input. - Dapat beragam +/- 1 byte per input. - - - Transactions with higher priority are more likely to get included into a block. - Transaksi dengan prioritas lebih tinggi akan lebih cepat dimasukkan kedalam blok. - - - (no label) - (tidak ada label) - - - change from %1 (%2) - kembalian dari %1 (%2) - - - (change) - (kembalian) - EditAddressDialog @@ -796,38 +458,6 @@ &Address &Alamat - - New receiving address - Alamat menerima baru - - - New sending address - Alamat mengirim baru - - - Edit receiving address - Ubah alamat menerima - - - Edit sending address - Ubah alamat mengirim - - - The entered address "%1" is already in the address book. - Alamat yang dimasukkan "%1" sudah ada di dalam buku alamat. - - - The entered address "%1" is not a valid Bitcoin address. - Alamat yang dimasukkan "%1" bukan alamat Bitcoin yang benar. - - - Could not unlock wallet. - Tidak dapat membuka dompet. - - - New key generation failed. - Pembuatan kunci baru gagal. - FreespaceChecker @@ -854,10 +484,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versi @@ -866,10 +492,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Mengenai Bitcoin Core - Command-line options Pilihan Command-line @@ -906,29 +528,13 @@ Show splash screen on startup (default: %u) Tampilkan layar kilat saat memulai (default: %u) - - Reset all settings changes made over the GUI - Reset semua pengaturan yang dibuat dari GUI - - + Intro Welcome Selamat Datang - - Welcome to Bitcoin Core. - Selamat Datang ke Bitcoin Core - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Ini adalah pertama kali program ini dijalankan, Anda dapat memilih dimana Bitcoin Core menyimpan data. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core akan mengunduh dan menyimpan salinan dari block chain Bitcoin. Setidaknya %1GB data akan disimpan di direktori ini, dan akan terus bertambah. Dompet Anda juga akan disimpan di direktori ini. - Use the default data directory Gunakan direktori data default. @@ -937,10 +543,6 @@ Use a custom data directory: Gunakan direktori pilihan Anda: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Kesalahan: Direktori data "%1" tidak dapat dibuat. @@ -976,10 +578,6 @@ Select payment request file Pilih data permintaan pembayaran - - Select payment request file to open - Pilih data permintaan pembayaran yang akan dibuka - OptionsDialog @@ -1019,10 +617,6 @@ 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. Minimalisasi aplikasi ketika jendela ditutup. Ketika pilihan ini dipilih, aplikasi akan menutup seluruhnya jika anda memilih Keluar di menu yang tersedia. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Bahasa interface pengguna bisa diubah disini. Pengaturan ini akan memberikan efek setelah Bitcoin Core di-restart. - 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 |. URL pihak ketika (misalnya sebuah block explorer) yang mumcul dalam tab transaksi sebagai konteks menu. %s dalam URL diganti dengan kode transaksi. URL dipisahkan dengan tanda vertikal |. @@ -1047,14 +641,6 @@ &Network &Jaringan - - Automatically start Bitcoin Core after logging in to the system. - Buka Bitcoin Core secara otomatis setelah Anda log-in ke sistem Anda. - - - &Start Bitcoin Core on system login - &Mulai Bitcoin Core saat log-in sistem - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = leave that many cores free) @@ -1235,53 +821,6 @@ Jumlah saldo Anda sekarang - - PaymentServer - - URI handling - Penanganan URI - - - Invalid payment address %1 - Alamat pembayaran salah %1 - - - Payment request rejected - Permintaan pembayaran ditolak - - - Requested payment amount of %1 is too small (considered dust). - Nilai pembayaran %1 yang diminta oleh Anda terlalu sedikit (dianggap debu). - - - Payment request error - Gagalan permintaan pembayaran - - - Payment request expired. - Permintaan pembayaran telah kadaluarsa - - - Refund from %1 - Pembayaran kembali dari %1 - - - Error communicating with %1: %2 - Masalah berkomunikasi dengan %1: %2 - - - Bad response from server %1 - Jawaban salah dari server %1 - - - Payment acknowledged - Pembayaran diakui - - - Network request error - Gagalan permintaan dari jaringan - - PeerTableModel @@ -1312,25 +851,6 @@ T/S - - QRImageWidget - - &Save Image... - &Simpan Gambaran... - - - &Copy Image - &Salin Gambaran - - - Save QR Code - Simpan Kode QR - - - PNG Image (*.png) - Gambar PNG (*.png) - - RPCConsole @@ -1431,10 +951,6 @@ Out: Keluar: - - Build date - Tanggal pembuatan - Debug log file Berkas catatan debug @@ -1459,10 +975,6 @@ 1 &year 1 &tahun - - Welcome to the Bitcoin Core RPC console. - Selamat datang di konsol RPC Bitcoin. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Gunakan panah keatas dan kebawah untuk menampilkan sejarah, dan <b>Ctrl-L</b> untuk bersihkan layar. @@ -1562,18 +1074,6 @@ Remove Menghapus - - Copy label - Salin label - - - Copy message - Salin Pesan - - - Copy amount - Salin nilai - ReceiveRequestDialog @@ -1593,73 +1093,6 @@ &Save Image... &Simpan Gambaran... - - Request payment to %1 - Minta pembayaran ke %1 - - - Payment information - Informasi pembayaran - - - URI - URI - - - Address - Alamat - - - Amount - Nilai - - - Label - Label - - - Message - Pesan - - - Resulting URI too long, try to reduce the text for label / message. - Hasil URI terlalu panjang, coba kurangi label / pesan. - - - Error encoding URI into QR Code. - Gagal mengubah URI ke kode QR. - - - - RecentRequestsTableModel - - Date - Tanggal - - - Label - Label - - - Message - Pesan: - - - Amount - Nilai - - - (no label) - (tidak ada label) - - - (no message) - (tidak ada pesan) - - - (no amount) - (tidak ada nilai) - SendCoinsDialog @@ -1771,98 +1204,6 @@ S&end K&irim - - Confirm send coins - Konfirmasi pengiriman koin - - - %1 to %2 - %1 ke %2 - - - Copy quantity - Salin kuantitas - - - Copy amount - Salin nilai - - - Copy fee - Salin biaya - - - Copy after fee - Salin dengan biaya - - - Copy bytes - Salin bytes - - - Copy priority - Salin prioritas - - - Copy change - Salin uang kembali - - - Total Amount %1 - Jumlah Total %1 - - - or - atau - - - The amount to pay must be larger than 0. - Nilai yang dibayar harus lebih besar dari 0. - - - The amount exceeds your balance. - Nilai melebihi saldo Anda. - - - The total exceeds your balance when the %1 transaction fee is included. - Jumlah melebihi saldo Anda ketika biaya transaksi %1 ditambahkan. - - - Transaction creation failed! - Gagal membuat transaksi! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Gagal: Transaksi ditolak. Ini mungkin terjadi jika beberapa dari koin dalam dompet Anda telah digunakan, seperti ketika Anda menggunakan salinan wallet.dat dan beberapa koin telah dibelanjakan dalam salinan tersebut tetapi disini tidak tertandai sebagai terpakai. - - - A fee higher than %1 is considered an absurdly high fee. - Biaya yang lebih tinggi dari %1 dianggap biaya tak masuk akal. - - - Payment request expired. - Permintaan pembayaran telah kadaluarsa - - - Warning: Invalid Bitcoin address - Awas: Alamat Bitcoin tidak sah - - - (no label) - (tidak ada label) - - - Copy dust - Salin dust - - - Are you sure you want to send? - Apakah Anda yakin ingin kirim? - - - added as transaction fee - ditambahkan sebagai biaya transaksi - SendCoinsEntry @@ -1874,10 +1215,6 @@ Pay &To: Kirim &Ke: - - Enter a label for this address to add it to your address book - Masukkan label bagi alamat ini untuk menambahkannya ke buku alamat Anda - &Label: &Label: @@ -1925,10 +1262,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core sementara dimatikan... - Do not shut down the computer until this window disappears. Kamu tidak dapat mematikan komputer sebelum jendela ini tertutup sendiri. @@ -2000,69 +1333,9 @@ Reset all verify message fields Hapus semua bidang verifikasi pesan - - Click "Sign Message" to generate signature - Tekan "Tandatangan Pesan" untuk menghasilan tanda tangan - - - The entered address is invalid. - Alamat yang dimasukkan tidak sesuai. - - - Please check the address and try again. - Silahkan periksa alamat dan coba lagi. - - - The entered address does not refer to a key. - Alamat itu tidak menghubungkan kunci. - - - Wallet unlock was cancelled. - Membuka kunci dompet dibatalkan. - - - Private key for the entered address is not available. - Kunci pribadi untuk alamat itu tidak tersedia. - - - Message signing failed. - Menandai pesan gagal. - - - Message signed. - Pesan ditandai. - - - The signature could not be decoded. - Tanda tangan tidak bisa diterjemahkan. - - - Please check the signature and try again. - Mohon periksa tanda tangan dan coba kembali - - - The signature did not match the message digest. - Tanda tangan tidak cocok dengan intisari pesan. - - - Message verification failed. - Verifikasi pesan gagal. - - - Message verified. - Pesan terverifikasi. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Pembangun Bitcoin Core - [testnet] [testnet] @@ -2075,430 +1348,16 @@ KB/s - - TransactionDesc - - Open until %1 - Buka hingga %1 - - - conflicted - Terkonflik - - - %1/offline - %1/tidak terhubung - - - %1/unconfirmed - %1/belum dikonfirmasi - - - %1 confirmations - %1 konfirmasi - - - Status - Status - - - , broadcast through %n node(s) - kirim lewat %n node - - - Date - Tanggal - - - Source - Sumber - - - Generated - Dibuat - - - From - Dari - - - To - Untuk - - - own address - Alamat saya sendiri - - - label - label - - - Credit - Kredit - - - matures in %n more block(s) - cukup tua sesudah %n blok lagi - - - not accepted - tidak diterima - - - Debit - Debet - - - Transaction fee - Biaya Transaksi - - - Net amount - Nilai bersih - - - Message - Pesan: - - - Comment - Komentar - - - Transaction ID - ID Transaksi - - - Merchant - Pedagang - - - Debug information - Informasi debug - - - Transaction - Transaksi - - - Inputs - Masukan - - - Amount - Nilai - - - true - benar - - - false - salah - - - , has not been successfully broadcast yet - , belum berhasil disiarkan - - - Open for %n more block(s) - Buka untuk %n blok lagi - - - unknown - tidak diketahui - - TransactionDescDialog - - Transaction details - Rincian transaksi - This pane shows a detailed description of the transaction Jendela ini menampilkan deskripsi rinci dari transaksi tersebut - - TransactionTableModel - - Date - Tanggal - - - Type - Jenis - - - Immature (%1 confirmations, will be available after %2) - Terlalu muda (cuma %1 konfirmasi, akan siap sesudah %2) - - - Open for %n more block(s) - Buka untuk %n blok lagi - - - Open until %1 - Buka hingga %1 - - - Confirmed (%1 confirmations) - Terkonfirmasi (%1 konfirmasi) - - - This block was not received by any other nodes and will probably not be accepted! - Blok ini tidak diterima oleh node lainnya dan kemungkinan tidak akan diterima! - - - Generated but not accepted - Terbuat tetapi tidak diterima - - - Offline - Tidak terhubung - - - Label - Label - - - Unconfirmed - Belum dikonfirmasi - - - Confirming (%1 of %2 recommended confirmations) - Sedang dikonfirmasi (%1 dari %2 konfirmasi disarankan) - - - Conflicted - Terkonflik - - - Received with - Diterima dengan - - - Received from - Diterima dari - - - Sent to - Terkirim ke - - - Payment to yourself - Pembayaran ke Anda sendiri - - - Mined - Tertambang - - - (n/a) - (t/s) - - - Transaction status. Hover over this field to show number of confirmations. - Status transaksi. Arahkan ke bagian ini untuk menampilkan jumlah konfrimasi. - - - Date and time that the transaction was received. - Tanggal dan waktu transaksi tersebut diterima. - - - Type of transaction. - Jenis transaksi. - - - Amount removed from or added to balance. - Nilai dihapus dari atau ditambahkan ke saldo. - - - - TransactionView - - All - Semua - - - Today - Hari ini - - - This week - Minggu ini - - - This month - Bulan ini - - - Last month - Bulan kemarin - - - This year - Tahun ini - - - Range... - Jarak... - - - Received with - DIterima dengan - - - Sent to - Terkirim ke - - - To yourself - Ke Anda sendiri - - - Mined - Ditambang - - - Other - Lainnya - - - Enter address or label to search - Masukkan alamat atau label untuk mencari - - - Min amount - Nilai min - - - Copy address - Salin alamat - - - Copy label - Salin label - - - Copy amount - Salin Nilai - - - Copy transaction ID - Menyalinkan ID transaksi - - - Edit label - Ubah label - - - Show transaction details - Tampilkan rincian transaksi - - - Export Transaction History - Expor Histori Transaksi - - - Exporting Failed - Proses Ekspor Gagal - - - Exporting Successful - Proses Ekspor Berhasil - - - The transaction history was successfully saved to %1. - Riwayat transaksi berhasil disimpan di %1. - - - Comma separated file (*.csv) - Berkas CSV (*.csv) - - - Confirmed - Terkonfirmasi - - - Date - Tanggal - - - Type - Jenis - - - Label - Label - - - Address - Alamat - - - ID - ID - - - Range: - Jarak: - - - to - ke - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Tidak ada dompet yang dibuka - - - - WalletModel - - Send Coins - Kirim Koin - - - - WalletView - - &Export - &Ekspor - - - Export the data in the current tab to a file - Ekspor data dalam tab sekarang ke sebuah berkas - - - Backup Wallet - Cadangkan Dompet - - - Wallet Data (*.dat) - Data Dompet (*.dat) - - - Backup Failed - Cadangkgan Gagal - - - The wallet data was successfully saved to %1. - Informasi dalam dompet berhasil disimpan di %1. - - - Backup Successful - Cadangkan Berhasil - - bitcoin-core @@ -2530,12 +1389,12 @@ Terima hubungan dari luar (standar: 1 kalau -proxy atau -connect tidak dipilih) - Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - Jalankan perintah ketika perubahan transaksi dompet (%s di cmd digantikan oleh TxID) + Bitcoin Core + Bitcoin Core - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Tidak bisa mengikat dengan %s di computer ini. Kemungkinan Bitcoin Core sudah mulai. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Jalankan perintah ketika perubahan transaksi dompet (%s di cmd digantikan oleh TxID) Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. @@ -2629,18 +1488,6 @@ Wallet options: Opsi dompet: - - You need to rebuild the database using -reindex to change -txindex - Harus membangun ulang database menggunakan -reindex supaya mengubah -txindex - - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Tidak bisa mengunci data directory %s. Kemungkinan Bitcoin Core sudah mulai. - - - Cannot resolve -whitebind address: '%s' - Tidak dapat menyelesaikan alamat -whitebind: '%s' - Connect through SOCKS5 proxy Hubungkan melalui proxy SOCKS5 @@ -2649,18 +1496,6 @@ Information Informasi - - Invalid amount for -maxtxfee=<amount>: '%s' - Nilai salah untuk -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Nilai yang salah untuk -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Nilai yang salah untuk -mintxfee=<amount>: '%s' - RPC server options: Opsi server RPC: @@ -2701,10 +1536,6 @@ Zapping all transactions from wallet... Setiap transaksi dalam dompet sedang di-'Zap'... - - wallet.dat corrupt, salvage failed - wallet.dat rusak, tidak bisa diperbaiki - Password for JSON-RPC connections Kata sandi untuk hubungan JSON-RPC @@ -2713,10 +1544,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Menjalankan perintah ketika perubahan blok terbaik (%s dalam cmd digantikan oleh hash blok) - - This help message - Pesan bantuan ini - Allow DNS lookups for -addnode, -seednode and -connect Izinkan peninjauan DNS untuk -addnote, -seednode dan -connect @@ -2725,14 +1552,6 @@ Loading addresses... Memuat alamat... - - Error loading wallet.dat: Wallet corrupted - Gagal memuat wallet.dat: Dompet rusak - - - Error loading wallet.dat - Gagal memuat wallet.dat - Invalid -proxy address: '%s' Alamat -proxy salah: '%s' @@ -2741,18 +1560,6 @@ Unknown network specified in -onlynet: '%s' Jaringan tidak diketahui yang ditentukan dalam -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Tidak dapat menyelesaikan alamat -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Tidak dapat menyelesaikan alamat -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Nilai salah untuk -paytxfee=<amount>: '%s' - Insufficient funds Saldo tidak mencukupi diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 2f14c4201..b92dbb2cb 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -25,10 +25,6 @@ C&lose C&hiudi - - &Copy Address - &Copia l'indirizzo - Delete the currently selected address from the list Rimuove dalla lista l'indirizzo attualmente selezionato @@ -45,73 +41,6 @@ &Delete &Elimina - - Choose the address to send coins to - Scegli l'indirizzo a cui inviare bitcoin - - - Choose the address to receive coins with - Scegli l'indirizzo con cui ricevere bitcoin - - - C&hoose - Sc&egli - - - Sending addresses - Indirizzi d'invio - - - Receiving addresses - Indirizzi di ricezione - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Questo è un elenco di indirizzi Bitcoin a cui puoi inviare pagamenti. Controlla sempre l'importo e l'indirizzo del beneficiario prima di inviare bitcoin. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Questi sono i tuoi indirizzi Bitcoin che puoi usare per ricevere pagamenti. Si raccomanda di generare un nuovo indirizzo per ogni transazione. - - - Copy &Label - Copia &l'etichetta - - - &Edit - &Modifica - - - Export Address List - Esporta Lista Indirizzi - - - Comma separated file (*.csv) - Testo CSV (*.csv) - - - Exporting Failed - Esportazione Fallita. - - - There was an error trying to save the address list to %1. Please try again. - Si è verificato un errore tentando di salvare la lista degli indirizzi su %1. Si prega di riprovare. - - - - AddressTableModel - - Label - Etichetta - - - Address - Indirizzo - - - (no label) - (nessuna etichetta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Ripeti la nuova passphrase - - Encrypt wallet - Cifra il portamonete - - - This operation needs your wallet passphrase to unlock the wallet. - Questa operazione necessita della passphrase per sbloccare il portamonete. - - - Unlock wallet - Sblocca il portamonete - - - This operation needs your wallet passphrase to decrypt the wallet. - Quest'operazione necessita della passphrase per decifrare il portamonete, - - - Decrypt wallet - Decifra il portamonete - - - Change passphrase - Cambia la passphrase - - - Confirm wallet encryption - Conferma la cifratura del portamonete - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Attenzione: perdendo la passphrase di un portamonete cifrato <b>TUTTI I PROPRI BITCOIN ANDRANNO PERSI</b>! - - - Are you sure you wish to encrypt your wallet? - Si è sicuri di voler cifrare il portamonete? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core si chiuderà per portare a termine il processo di cifratura. Si ricorda che la cifratura del portamonete non garantisce protezione totale contro i furti causati da infezioni malware. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: qualsiasi backup del file portamonete effettuato in precedenza dovrà essere sostituito con il file del portamonete cifrato appena generato. Per ragioni di sicurezza, i precedenti backup del file del portamonete non cifrato diventeranno inservibili non appena si inizierà ad utilizzare il nuovo portamonete cifrato. - - - Warning: The Caps Lock key is on! - Attenzione: il tasto Blocco maiuscole è attivo! - - - Wallet encrypted - Portamonete cifrato - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Inserisci la nuova passphrase per il portamonete.<br/>Si consiglia di utilizzare <b>almeno dieci caratteri casuali</b> oppure <b>otto o più parole</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Inserisci la vecchia e la nuova passphrase per il portamonete. - - - Wallet encryption failed - Cifratura del portamonete fallita - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Cifratura del portamonete fallita a causa di un errore interno. Il portamonete non è stato cifrato. - - - The supplied passphrases do not match. - Le passphrase inserite non corrispondono. - - - Wallet unlock failed - Sblocco del portamonete fallito - - - The passphrase entered for the wallet decryption was incorrect. - La passphrase inserita per la decifrazione del portamonete è errata. - - - Wallet decryption failed - Decifrazione del portamonete fallita - - - Wallet passphrase was successfully changed. - Passphrase del portamonete modificata con successo. - BanTableModel @@ -269,6 +110,10 @@ Quit application Chiudi applicazione + + &About %1 + &Informazioni su %1 + About &Qt Informazioni su &Qt @@ -305,14 +150,6 @@ Open &URI... Apri &URI... - - Bitcoin Core client - Bitcoin Core client - - - Importing blocks from disk... - Importazione blocchi dal disco... - Reindexing blocks on disk... Re-indicizzazione blocchi su disco... @@ -357,10 +194,6 @@ &Receive &Ricevi - - Show information about Bitcoin Core - Mostra le informazioni su Bitcoin Core - &Show / Hide &Mostra / Nascondi @@ -397,22 +230,10 @@ Tabs toolbar Barra degli strumenti - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Richiedi pagamenti (genera codici QR e bitcoin: URI) - - &About Bitcoin Core - &Informazioni su Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modifica opzioni di configurazione per Bitcoin Core - Show the list of used sending addresses and labels Mostra la lista degli indirizzi di invio utilizzati @@ -429,10 +250,6 @@ &Command-line options Opzioni della riga di &comando - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostra il messaggio di aiuto di Bitcoin Core per ottenere la lista delle opzioni della riga di comando valide. - %n active connection(s) to Bitcoin network %n connessione attiva alla rete Bitcoin%n connessioni alla rete Bitcoin attive @@ -544,13 +361,6 @@ Il portamonete è <b>cifrato</b> ed attualmente <b>bloccato</b> - - ClientModel - - Network Alert - Avviso di rete - - CoinControlDialog @@ -629,150 +439,6 @@ Priority Priorità - - Copy address - Copia l'indirizzo - - - Copy label - Copia l'etichetta - - - Copy amount - Copia importo - - - Copy transaction ID - Copia l'ID transazione - - - Lock unspent - Bloccare non spesi - - - Unlock unspent - Sbloccare non spesi - - - Copy quantity - Copia quantità - - - Copy fee - Copia commissione - - - Copy after fee - Copia dopo commissione - - - Copy bytes - Copia byte - - - Copy priority - Copia priorità - - - Copy dust - Copia trascurabile - - - Copy change - Copia resto - - - highest - massima - - - higher - molto alta - - - high - alta - - - medium-high - medio-alta - - - medium - media - - - low-medium - medio-bassa - - - low - bassa - - - lower - molto bassa - - - lowest - minima - - - (%1 locked) - (%1 bloccato) - - - none - nessuno - - - This label turns red if the transaction size is greater than 1000 bytes. - Questa etichetta diventerà rossa se la dimensione della transazione supererà i 1000 byte. - - - This label turns red if the priority is smaller than "medium". - Questa etichetta diventerà rossa se la priorità sarà inferiore a "media". - - - This label turns red if any recipient receives an amount smaller than %1. - Questa etichetta diventerà rossa se uno qualsiasi dei destinatari riceverà un importo inferiore a %1. - - - Can vary +/- %1 satoshi(s) per input. - Può variare di +/- %1 satoshi per input. - - - yes - - - - no - no - - - This means a fee of at least %1 per kB is required. - In tal caso sarà necessaria una commissione di almeno %1 per ogni kB. - - - Can vary +/- 1 byte per input. - Può variare di +/- 1 byte per input. - - - Transactions with higher priority are more likely to get included into a block. - Le transazioni con priorità più alta hanno più probabilità di essere incluse in un blocco. - - - (no label) - (nessuna etichetta) - - - change from %1 (%2) - resto da %1 (%2) - - - (change) - (resto) - EditAddressDialog @@ -796,38 +462,6 @@ &Address &Indirizzo - - New receiving address - Nuovo indirizzo di ricezione - - - New sending address - Nuovo indirizzo d'invio - - - Edit receiving address - Modifica indirizzo di ricezione - - - Edit sending address - Modifica indirizzo d'invio - - - The entered address "%1" is already in the address book. - L'indirizzo "%1" è già presente in rubrica. - - - The entered address "%1" is not a valid Bitcoin address. - L'indirizzo "%1" non è un indirizzo bitcoin valido. - - - Could not unlock wallet. - Impossibile sbloccare il portamonete. - - - New key generation failed. - Generazione della nuova chiave non riuscita. - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versione @@ -866,10 +496,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Informazioni su Bitcoin Core - Command-line options Opzioni della riga di comando @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Mostra schermata iniziale all'avvio (default: %u) - - Reset all settings changes made over the GUI - Reset di tutte le modifiche alle impostazioni eseguite da interfaccia grafica - - + Intro Welcome Benvenuto - - Welcome to Bitcoin Core. - Benvenuti su Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Visto che questa è la prima volta che il programma viene lanciato, puoi scegliere dove Bitcoin Core salverà i propri dati. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core scaricherà e salverà una copia della block chain di Bitcoin. Il portamonete ed almeno %1GB di dati saranno salvati in questa cartella. Si ricorda che lo spazio occupato andrà ad aumentare nel tempo. - Use the default data directory Usa la cartella dati predefinita @@ -937,10 +547,6 @@ Use a custom data directory: Usa una cartella dati personalizzata: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Errore: La cartella dati "%1" specificata non può essere creata. @@ -976,10 +582,6 @@ Select payment request file Seleziona il file di richiesta di pagamento - - Select payment request file to open - Seleziona il file di richiesta di pagamento da aprire - OptionsDialog @@ -1019,10 +621,6 @@ 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. Riduci ad icona invece di uscire dall'applicazione quando la finestra viene chiusa. Attivando questa opzione l'applicazione terminerà solo dopo aver selezionato Esci dal menu File. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - La lingua dell'interfaccia utente può essere impostata qui. L'applicazione delle modifiche avrà effetto dopo il riavvio di Bitcoin Core. - 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 |. URL di terze parti (ad es. un block explorer) che appaiono nella tabella delle transazioni come voci nel menu contestuale. "%s" nell'URL è sostituito dall'hash della transazione. @@ -1048,14 +646,6 @@ Per specificare più URL separarli con una barra verticale "|". &Network Rete - - Automatically start Bitcoin Core after logging in to the system. - Avvia automaticamente Bitcoin Core una volta effettuato l'accesso al sistema. - - - &Start Bitcoin Core on system login - &Avvia Bitcoin Core all'accesso al sistema - (0 = auto, <0 = leave that many cores free) (0 = automatico, <0 = lascia questo numero di core liberi) @@ -1284,97 +874,6 @@ Per specificare più URL separarli con una barra verticale "|". Saldo corrente totale negli indirizzi di sola lettura - - PaymentServer - - URI handling - Gestione URI - - - Invalid payment address %1 - Indirizzo di pagamento non valido %1 - - - Payment request rejected - Richiesta di pagamento respinta - - - Payment request network doesn't match client network. - La rete della richiesta di pagamento non corrisponde alla rete del client. - - - Payment request is not initialized. - La richiesta di pagamento non è stata inizializzata. - - - Requested payment amount of %1 is too small (considered dust). - L'importo di pagamento di %1 richiesto è troppo basso (considerato come trascurabile). - - - Payment request error - Errore di richiesta di pagamento - - - Cannot start bitcoin: click-to-pay handler - Impossibile avviare bitcoin: gestore click-to-pay - - - Payment request fetch URL is invalid: %1 - URL di recupero della Richiesta di pagamento non valido: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - Impossibile interpretare l'URI! I parametri URI o l'indirizzo Bitcoin potrebbero non essere corretti. - - - Payment request file handling - Gestione del file di richiesta del pagamento - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Impossibile leggere il file della richiesta di pagamento! Il file della richiesta di pagamento potrebbe non essere valido. - - - Payment request expired. - Richiesta di pagamento scaduta. - - - Unverified payment requests to custom payment scripts are unsupported. - Le richieste di pagamento non verificate verso script di pagamento personalizzati non sono supportate. - - - Invalid payment request. - Richiesta di pagamento non valida. - - - Refund from %1 - Rimborso da %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - La richiesta di pagamento %1 (%2 byte) supera la dimensione massima di %3 byte. - - - Error communicating with %1: %2 - Errore di comunicazione con %1: %2 - - - Payment request cannot be parsed! - La richiesta di pagamento non può essere analizzata! - - - Bad response from server %1 - Risposta errata da parte del server %1 - - - Payment acknowledged - Pagamento riconosciuto - - - Network request error - Errore di richiesta di rete - - PeerTableModel @@ -1429,25 +928,6 @@ Per specificare più URL separarli con una barra verticale "|". %1 ms - - QRImageWidget - - &Save Image... - &Salva Immagine... - - - &Copy Image - &Copia Immagine - - - Save QR Code - Salva codice QR - - - PNG Image (*.png) - Immagine PNG (*.png) - - RPCConsole @@ -1514,10 +994,6 @@ Per specificare più URL separarli con una barra verticale "|". Memory usage Utilizzo memoria - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Apre il file log di debug di Bitcoin Core dalla cartella dati attuale. Questa azione può richiedere alcuni secondi per file log di grandi dimensioni. - Received Ricevuto @@ -1634,10 +1110,6 @@ Per specificare più URL separarli con una barra verticale "|". Out: Uscita: - - Build date - Data di creazione - Debug log file File log del Debug @@ -1674,10 +1146,6 @@ Per specificare più URL separarli con una barra verticale "|". &Unban Node &Elimina Ban Nodo - - Welcome to the Bitcoin Core RPC console. - Benvenuto nella console RPC di Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Usa le frecce direzionali per scorrere la cronologia, e <b>Ctrl-L</b> per cancellarla. @@ -1805,18 +1273,6 @@ Per specificare più URL separarli con una barra verticale "|". Remove Rimuovi - - Copy label - Copia l'etichetta - - - Copy message - Copia il messaggio - - - Copy amount - Copia l'importo - ReceiveRequestDialog @@ -1836,73 +1292,6 @@ Per specificare più URL separarli con una barra verticale "|". &Save Image... &Salva Immagine... - - Request payment to %1 - Richiesta di pagamento a %1 - - - Payment information - Informazioni pagamento - - - URI - URI - - - Address - Indirizzo - - - Amount - Importo - - - Label - Etichetta - - - Message - Messaggio - - - Resulting URI too long, try to reduce the text for label / message. - L'URI risultante è troppo lungo, prova a ridurre il testo nell'etichetta / messaggio. - - - Error encoding URI into QR Code. - Errore nella codifica dell'URI nel codice QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etichetta - - - Message - Messaggio - - - Amount - Importo - - - (no label) - (nessuna etichetta) - - - (no message) - (nessun messaggio) - - - (no amount) - (nessun importo) - SendCoinsDialog @@ -2022,14 +1411,6 @@ Per specificare più URL separarli con una barra verticale "|". fast veloce - - Send as zero-fee transaction if possible - Invia come transazione a zero commissioni se possibile - - - (confirmation may take longer) - (la conferma potrebbe richiedere più tempo) - Send to multiple recipients at once Invia simultaneamente a più beneficiari @@ -2062,118 +1443,6 @@ Per specificare più URL separarli con una barra verticale "|". S&end &Invia - - Confirm send coins - Conferma l'invio di bitcoin - - - %1 to %2 - %1 a %2 - - - Copy quantity - Copia quantità - - - Copy amount - Copia importo - - - Copy fee - Copia commissione - - - Copy after fee - Copia dopo commissione - - - Copy bytes - Copia byte - - - Copy priority - Copia priorità - - - Copy change - Copia resto - - - Total Amount %1 - Ammontare Totale %1 - - - or - o - - - The amount to pay must be larger than 0. - L'importo da pagare deve essere maggiore di 0. - - - The amount exceeds your balance. - L'importo è superiore al tuo saldo attuale. - - - The total exceeds your balance when the %1 transaction fee is included. - Il totale è superiore al tuo saldo attuale includendo la commissione di %1. - - - Transaction creation failed! - Creazione transazione fallita! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - La transazione è stata respinta! Questo può accadere se alcuni bitcoin nel tuo portamonete sono già stati spesi, come nel caso in cui tu avessi utilizzato una copia del file wallet.dat per spendere bitcoin e questi non fossero stati considerati come spesi dal portamonete corrente. - - - A fee higher than %1 is considered an absurdly high fee. - Una commissione maggiore di %1 è considerata irragionevolmente elevata. - - - Payment request expired. - Richiesta di pagamento scaduta. - - - Pay only the required fee of %1 - Paga solamente la commissione richiesta di %1 - - - Estimated to begin confirmation within %n block(s). - Inizio delle conferme stimato entro %n blocco.Inizio delle conferme stimato entro %n blocchi. - - - The recipient address is not valid. Please recheck. - L'indirizzo del beneficiario non è valido. Si prega di ricontrollare. - - - Duplicate address found: addresses should only be used once each. - Rilevato un indirizzo duplicato Ciascun indirizzo dovrebbe essere utilizzato una sola volta. - - - Warning: Invalid Bitcoin address - Attenzione: Indirizzo Bitcoin non valido - - - (no label) - (nessuna etichetta) - - - Warning: Unknown change address - Attenzione: Indirizzo per il resto sconosciuto - - - Copy dust - Copia trascurabile - - - Are you sure you want to send? - Sei sicuro di voler inviare? - - - added as transaction fee - aggiunto come tassa di transazione - SendCoinsEntry @@ -2185,10 +1454,6 @@ Per specificare più URL separarli con una barra verticale "|". Pay &To: Paga &a: - - Enter a label for this address to add it to your address book - Inserisci un'etichetta per questo indirizzo, per aggiungerlo alla rubrica - &Label: &Etichetta: @@ -2260,10 +1525,6 @@ Per specificare più URL separarli con una barra verticale "|". ShutdownWindow - - Bitcoin Core is shutting down... - Arresto di Bitcoin Core in corso... - Do not shut down the computer until this window disappears. Non spegnere il computer fino a quando questa finestra non si sarà chiusa. @@ -2355,69 +1616,9 @@ Per specificare più URL separarli con una barra verticale "|". Reset all verify message fields Reimposta tutti i campi della verifica messaggio - - Click "Sign Message" to generate signature - Clicca "Firma il messaggio" per ottenere la firma - - - The entered address is invalid. - L'indirizzo inserito non è valido. - - - Please check the address and try again. - Per favore controlla l'indirizzo e prova di nuovo. - - - The entered address does not refer to a key. - L'indirizzo bitcoin inserito non è associato a nessuna chiave. - - - Wallet unlock was cancelled. - Sblocco del portamonete annullato. - - - Private key for the entered address is not available. - La chiave privata per l'indirizzo inserito non è disponibile. - - - Message signing failed. - Firma messaggio fallita. - - - Message signed. - Messaggio firmato. - - - The signature could not be decoded. - Non è stato possibile decodificare la firma. - - - Please check the signature and try again. - Per favore controlla la firma e prova di nuovo. - - - The signature did not match the message digest. - La firma non corrisponde al digest del messaggio. - - - Message verification failed. - Verifica messaggio fallita. - - - Message verified. - Messaggio verificato. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Gli sviluppatori di Bitcoin Core - [testnet] [testnet] @@ -2430,422 +1631,13 @@ Per specificare più URL separarli con una barra verticale "|". KB/s - - TransactionDesc - - Open until %1 - Aperto fino a %1 - - - conflicted - in conflitto - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/non confermata - - - %1 confirmations - %1 conferme - - - Status - Stato - - - , broadcast through %n node(s) - , trasmesso attraverso %n nodo, trasmessa attraverso %n nodi - - - Date - Data - - - Source - Sorgente - - - Generated - Generato - - - From - Da - - - To - A - - - own address - proprio indirizzo - - - watch-only - sola lettura - - - label - etichetta - - - Credit - Credito - - - matures in %n more block(s) - matura tra %n bloccomatura tra %n blocchi - - - not accepted - non accettate - - - Debit - Debito - - - Total debit - Debito totale - - - Total credit - Credito totale - - - Transaction fee - Commissione transazione - - - Net amount - Importo netto - - - Message - Messaggio - - - Comment - Commento - - - Transaction ID - ID della transazione - - - Merchant - Commerciante - - - 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. - È necessario attendere %1 blocchi prima che i bitcoin generati possano essere spesi. Al momento della generazione questo blocco è stato trasmesso alla rete in modo da poter essere aggiunto alla block chain. Se l'inserimento avrà esito negativo lo stato del blocco sarà modificato in "non accettato" ed esso risulterà non spendibile. Ciò può verificarsi occasionalmente nel caso in cui un altro blocco sia stato generato entro pochi secondi dal tuo. - - - Debug information - Informazione di debug - - - Transaction - Transazione - - - Inputs - Input - - - Amount - Importo - - - true - vero - - - false - falso - - - , has not been successfully broadcast yet - , non è ancora stata trasmessa con successo - - - Open for %n more block(s) - Aperto per %n altro bloccoAperto per altri %n blocchi - - - unknown - sconosciuto - - TransactionDescDialog - - Transaction details - Dettagli sulla transazione - This pane shows a detailed description of the transaction Questo pannello mostra una descrizione dettagliata della transazione - - TransactionTableModel - - Date - Data - - - Type - Tipo - - - Immature (%1 confirmations, will be available after %2) - Immaturo (%1 conferme, sarà disponibile fra %2) - - - Open for %n more block(s) - Aperto per %n altro bloccoAperto per altri %n blocchi - - - Open until %1 - Aperto fino a %1 - - - Confirmed (%1 confirmations) - Confermata (%1 conferme) - - - This block was not received by any other nodes and will probably not be accepted! - Questo blocco non è stato ricevuto da alcun altro nodo e probabilmente non sarà accettato! - - - Generated but not accepted - Generati, ma non accettati - - - Offline - Offline - - - Label - Etichetta - - - Unconfirmed - Non confermata - - - Confirming (%1 of %2 recommended confirmations) - In conferma (%1 di %2 conferme raccomandate) - - - Conflicted - In conflitto - - - Received with - Ricevuto tramite - - - Received from - Ricevuto da - - - Sent to - Inviato a - - - Payment to yourself - Pagamento a te stesso - - - Mined - Ottenuto dal mining - - - watch-only - sola lettura - - - (n/a) - (n/d) - - - Transaction status. Hover over this field to show number of confirmations. - Stato della transazione. Passare con il mouse su questo campo per visualizzare il numero di conferme. - - - Date and time that the transaction was received. - Data e ora in cui la transazione è stata ricevuta. - - - Type of transaction. - Tipo di transazione. - - - Whether or not a watch-only address is involved in this transaction. - Indica se un indirizzo di sola lettura sia o meno coinvolto in questa transazione. - - - User-defined intent/purpose of the transaction. - Intento/scopo della transazione definito dall'utente. - - - Amount removed from or added to balance. - Importo rimosso o aggiunto al saldo. - - - - TransactionView - - All - Tutti - - - Today - Oggi - - - This week - Questa settimana - - - This month - Questo mese - - - Last month - Il mese scorso - - - This year - Quest'anno - - - Range... - Intervallo... - - - Received with - Ricevuto tramite - - - Sent to - Inviato a - - - To yourself - A te stesso - - - Mined - Ottenuto dal mining - - - Other - Altro - - - Enter address or label to search - Inserisci un indirizzo o un'etichetta da cercare - - - Min amount - Importo minimo - - - Copy address - Copia l'indirizzo - - - Copy label - Copia l'etichetta - - - Copy amount - Copia l'importo - - - Copy transaction ID - Copia l'ID transazione - - - Copy raw transaction - Copia la transazione raw - - - Edit label - Modifica l'etichetta - - - Show transaction details - Mostra i dettagli della transazione - - - Export Transaction History - Esporta lo storico delle transazioni - - - Watch-only - Sola lettura - - - Exporting Failed - Esportazione Fallita. - - - There was an error trying to save the transaction history to %1. - Si è verificato un errore durante il salvataggio dello storico delle transazioni in %1. - - - Exporting Successful - Esportazione Riuscita - - - The transaction history was successfully saved to %1. - Lo storico delle transazioni e' stato salvato con successo in %1. - - - Comma separated file (*.csv) - Testo CSV (*.csv) - - - Confirmed - Confermato - - - Date - Data - - - Type - Tipo - - - Label - Etichetta - - - Address - Indirizzo - - - ID - ID - - - Range: - Intervallo: - - - to - a - - UnitDisplayStatusBarControl @@ -2853,55 +1645,6 @@ Per specificare più URL separarli con una barra verticale "|". Unità con cui visualizzare gli importi. Clicca per selezionare un'altra unità. - - WalletFrame - - No wallet has been loaded. - Non è stato caricato alcun portamonete. - - - - WalletModel - - Send Coins - Invia Bitcoin - - - - WalletView - - &Export - &Esporta - - - Export the data in the current tab to a file - Esporta su file i dati contenuti nella tabella corrente - - - Backup Wallet - Backup Portamonete - - - Wallet Data (*.dat) - Dati Portamonete (*.dat) - - - Backup Failed - Backup Fallito - - - There was an error trying to save the wallet data to %1. - Si è verificato un errore durante il salvataggio dei dati del portamonete in %1. - - - The wallet data was successfully saved to %1. - Il portamonete è stato correttamente salvato in %1. - - - Backup Successful - Backup eseguito con successo - - bitcoin-core @@ -2928,14 +1671,6 @@ Per specificare più URL separarli con una barra verticale "|". If <category> is not supplied or if <category> = 1, output all debugging information. Se <category> non è specificato oppure se <category> = 1, mostra tutte le informazioni di debug. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Totale massimo di commissioni (in %s) da usare in una singola transazione del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Per favore controllate che la data del computer e l'ora siano corrette. Se il vostro orologio è sbagliato Bitcoin non funzionerà correttamente. - Prune configured below the minimum of %d MiB. Please use a higher number. La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato. @@ -2976,6 +1711,10 @@ Per specificare più URL separarli con una barra verticale "|". Accept connections from outside (default: 1 if no -proxy or -connect) Accetta connessioni dall'esterno (predefinito: 1 se -proxy o -connect non sono utilizzati) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6 @@ -3004,10 +1743,6 @@ Per specificare più URL separarli con una barra verticale "|". This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) @@ -3028,10 +1763,6 @@ Per specificare più URL separarli con una barra verticale "|". Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Attenzione: Sembra che non vi sia pieno consenso con i nostri peer! Un aggiornamento da parte tua o degli altri nodi potrebbe essere necessario. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Attenzione: wallet.dat corrotto, dati recuperati! Il wallet.dat originale è stato salvato come wallet.{timestamp}.bak in %s. Se i dati relativi a saldo o transazioni non dovessero risultare corretti si consiglia di procedere al ripristino da un backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte. @@ -3192,10 +1923,6 @@ Per specificare più URL separarli con una barra verticale "|". Wallet options: Opzioni portamonete: - - You need to rebuild the database using -reindex to change -txindex - È necessario ricostruire il database usando -reindex per cambiare -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permette connessioni JSON-RPC dall'origine specificata. I valori validi per <ip> sono un singolo IP (ad es. 1.2.3.4), una network/netmask (ad es. 1.2.3.4/255.255.255.0) oppure una network/CIDR (ad es. 1.2.3.4/24). Questa opzione può essere specificata più volte. @@ -3208,10 +1935,6 @@ Per specificare più URL separarli con una barra verticale "|". Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Resta in attesa di connessioni JSON-RPC sull'indirizzo indicato. Usa la notazione [host]:porta per IPv6. Questa opzione può essere specificata più volte (predefinito: associa a tutte le interfacce) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Non è possibile ottenere un lock sulla cartella %s. Probabilmente Bitcoin Core è già in esecuzione. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crea nuovi file con i permessi di default del sistema, invece che con umask 077 (ha effetto solo con funzionalità di portamonete disabilitate) @@ -3256,10 +1979,6 @@ Per specificare più URL separarli con una barra verticale "|". Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinito: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Specifica il numero di thread per la generazione di bitcoin, se abilitata (-1 = tutti i core, predefinito: %d) - The transaction amount is too small to send after the fee has been deducted L'importo della transazione risulta troppo basso per l'invio una volta dedotte le commissioni. @@ -3284,34 +2003,14 @@ Per specificare più URL separarli con una barra verticale "|". Accept public REST requests (default: %u) Accetta richieste REST pubbliche (predefinito: %u) - - Activating best chain... - Attivazione della blockchain migliore... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Prova a recuperare le chiavi private da un wallet corrotto all'avvio - Automatically create Tor hidden service (default: %d) Crea automaticamente il servizio Tor (default: %d) - - Cannot resolve -whitebind address: '%s' - Impossibile risolvere indirizzo -whitebind: '%s' - Connect through SOCKS5 proxy Connessione attraverso un proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Gli sviluppatori di Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Errore durante il caricamento del file wallet.dat: il portamonete richiede una versione di Bitcoin Core più recente - Error reading from database, shutting down. Errore durante lalettura del database. Arresto in corso. @@ -3324,22 +2023,6 @@ Per specificare più URL separarli con una barra verticale "|". Information Informazioni - - Initialization sanity check failed. Bitcoin Core is shutting down. - Test di integrità iniziale fallito. Bitcoin Core si arresterà. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Importo non valido per -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Importo non valido per -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Importo non valido per -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Importo non valido per -paytxfee=<amount>: '%s' (deve essere almeno %s) @@ -3364,14 +2047,6 @@ Per specificare più URL separarli con una barra verticale "|". RPC server options: Opzioni server RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio - - - Receive and display P2P network alerts (default: %u) - Ricevi e visualizza gli alerts della rete P2P (default: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Riduzione -maxconnections da %d a %d a causa di limitazioni di sistema. @@ -3444,10 +2119,6 @@ Per specificare più URL separarli con una barra verticale "|". Username for JSON-RPC connections Nome utente per connessioni JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Il portamonete necessitava di essere riscritto: riavviare Bitcoin Core per completare l'operazione - Warning Attenzione @@ -3464,10 +2135,6 @@ Per specificare più URL separarli con una barra verticale "|". ZeroMQ notification options: Opzioni di notifica ZeroMQ - - wallet.dat corrupt, salvage failed - wallet.dat corrotto, recupero fallito - Password for JSON-RPC connections Password per connessioni JSON-RPC @@ -3476,10 +2143,6 @@ Per specificare più URL separarli con una barra verticale "|". Execute command when the best block changes (%s in cmd is replaced by block hash) Esegue un comando quando il miglior blocco cambia (%s nel cmd è sostituito dall'hash del blocco) - - This help message - Questo messaggio di aiuto - Allow DNS lookups for -addnode, -seednode and -connect Consente interrogazioni DNS per -addnode, -seednode e -connect @@ -3488,10 +2151,6 @@ Per specificare più URL separarli con una barra verticale "|". Loading addresses... Caricamento indirizzi... - - Error loading wallet.dat: Wallet corrupted - Errore caricamento wallet.dat: Portamonete corrotto - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx) @@ -3508,10 +2167,6 @@ Per specificare più URL separarli con una barra verticale "|". Do not keep transactions in the mempool longer than <n> hours (default: %u) Non mantenere le transazioni nella mempool più a lungo di <n> ore (default: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per la creazione della transazione (default: %s) @@ -3564,14 +2219,6 @@ Per specificare più URL separarli con una barra verticale "|". Always query for peer addresses via DNS lookup (default: %u) Interroga sempre i DNS per ottenere gli indirizzi dei peer (predefinito: %u) - - Error loading wallet.dat - Errore caricamento wallet.dat - - - Generate coins (default: %u) - Genera bitcoin (predefinito: %u) - How many blocks to check at startup (default: %u, 0 = all) Numero di blocchi da controllare all'avvio (predefinito: %u, 0 = tutti) @@ -3656,18 +2303,6 @@ Per specificare più URL separarli con una barra verticale "|". Unknown network specified in -onlynet: '%s' Rete sconosciuta specificata in -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Impossibile risolvere indirizzo -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Impossibile risolvere indirizzo -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Importo non valido per -paytxfee=<amount>: '%s' - Insufficient funds Fondi insufficienti diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts index 46ad0e933..f89f4bdc4 100644 --- a/src/qt/locale/bitcoin_it_IT.ts +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -25,10 +25,6 @@ C&lose chiudi - - &Copy Address - copia indirizzo - Delete the currently selected address from the list Cancella l'indirizzo attualmente selezionato dalla lista. @@ -45,70 +41,6 @@ &Delete Cancella - - Choose the address to send coins to - Scegli l'indirizzo a cui inviare denaro - - - Choose the address to receive coins with - Scegli l'indirizzo con cui ricevere i coin - - - C&hoose - Scegli - - - Sending addresses - Indirizzi mittenti - - - Receiving addresses - Indirizzi destinatari - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Questi sono gli indirizzi Bitcoin per l'invio di pagamenti. Controlla sempre la quantità e l'indirizzo di ricezione prima di inviare monete. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Questi sono i tuoi indirizzi Bitcoin per ricevere pagamenti. Si raccomanda di generare un nuovo indirizzo per ogni transazione - - - Copy &Label - copia etichetta - - - &Edit - Modifica - - - Export Address List - Esporta lista degli indirizzi - - - Comma separated file (*.csv) - Contenuto del file separato da virgole (*.csv) - - - Exporting Failed - Esportazione fallita - - - - AddressTableModel - - Label - Etichetta - - - Address - Indirizzo - - - (no label) - (nessuna etichetta) - - AskPassphraseDialog @@ -124,39 +56,7 @@ Repeat new passphrase Ripeti nuova passphrase - - Encrypt wallet - Cifra portagoflio - - - This operation needs your wallet passphrase to unlock the wallet. - Questa operazione richiede la passphrase del tuo portafoglio per sbloccare il portafoglio. - - - Unlock wallet - Sblocca portafoglio - - - Decrypt wallet - decifra portafoglio - - - Change passphrase - cambia passphrase - - - Confirm wallet encryption - conferma cifrazione del portagoglio - - - Wallet encrypted - portafoglio cifrato - - - Wallet unlock failed - sblocco portafoglio fallito - - + BanTableModel @@ -171,16 +71,8 @@ Transazioni - - ClientModel - CoinControlDialog - - (no label) - (nessuna etichetta) - - EditAddressDialog @@ -203,18 +95,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -223,34 +109,9 @@ ReceiveRequestDialog - - Address - Indirizzo - - - Label - Etichetta - - - - RecentRequestsTableModel - - Label - Etichetta - - - (no label) - (nessuna etichetta) - - SendCoinsDialog - - (no label) - (nessuna etichetta) - - SendCoinsEntry @@ -267,58 +128,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Etichetta - - - - TransactionView - - Exporting Failed - Esportazione fallita - - - Comma separated file (*.csv) - Contenuto del file separato da virgole (*.csv) - - - Label - Etichetta - - - Address - Indirizzo - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - Esporta - - - Export the data in the current tab to a file - Esportare i dati nella scheda corrente in un file - - bitcoin-core diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 06fd27fa1..b2dae186d 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -25,10 +25,6 @@ C&lose 閉じる(&C) - - &Copy Address - アドレスをコピー (&C) - Delete the currently selected address from the list 選択されたアドレスを一覧から削除する @@ -45,73 +41,6 @@ &Delete 削除(&D) - - Choose the address to send coins to - 送信先のアドレスを選択 - - - Choose the address to receive coins with - 支払いを受け取るアドレスを指定する - - - C&hoose - 選択(&C) - - - Sending addresses - アドレス送信中 - - - Receiving addresses - アドレス受信中 - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。 - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - これらは支払いを受け取るためのビットコインアドレスです。トランザクションごとに新しい受け取り用アドレスを作成することが推奨されます。 - - - Copy &Label - ラベルをコピー (&L) - - - &Edit - 編集 (&E) - - - Export Address List - アドレス帳をエクスポート - - - Comma separated file (*.csv) - CSVファイル (*.csv) - - - Exporting Failed - エクスポート失敗 - - - There was an error trying to save the address list to %1. Please try again. - トランザクション履歴を %1 へ保存する際にエラーが発生しました。再試行してください。 - - - - AddressTableModel - - Label - ラベル - - - Address - アドレス - - - (no label) - (ラベル無し) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase 新しいパスフレーズをもう一度 - - Encrypt wallet - ウォレットを暗号化する - - - This operation needs your wallet passphrase to unlock the wallet. - この操作はウォレットをアンロックするためにパスフレーズが必要です。 - - - Unlock wallet - ウォレットをアンロックする - - - This operation needs your wallet passphrase to decrypt the wallet. - この操作はウォレットの暗号化解除のためにパスフレーズが必要です。 - - - Decrypt wallet - ウォレットの暗号化を解除する - - - Change passphrase - パスフレーズの変更 - - - Confirm wallet encryption - ウォレットの暗号化を確認する - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 警告: もしもあなたのウォレットを暗号化してパスフレーズを失ってしまったなら、<b>あなたの Bitcoin はすべて失われます</b>! - - - Are you sure you wish to encrypt your wallet? - 本当にウォレットを暗号化しますか? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - 暗号化処理を完了させるため Bitcoin Core をいますぐ終了します。ウォレットの暗号化では、コンピュータに感染したマルウェアなどによるビットコインの盗難から完全に守ることはできないことにご注意ください。 - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 重要: 過去のウォレット ファイルのバックアップは、暗号化された新しいウォレット ファイルに取り替える必要があります。セキュリティ上の理由により、暗号化された新しいウォレットを使い始めると、暗号化されていないウォレット ファイルのバックアップはすぐに使えなくなります。 - - - Warning: The Caps Lock key is on! - 警告: Caps Lock キーがオンになっています! - - - Wallet encrypted - ウォレットは暗号化されました - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - ウォレットの新しいパスフレーズを入力してください。<br/><b>10文字以上のランダムな文字</b>で構成されたものか、<b>8単語以上の単語</b>で構成されたパスフレーズを使用してください。 - - - Enter the old passphrase and new passphrase to the wallet. - ウォレットの古いパスフレーズおよび新しいパスフレーズを入力してください。 - - - Wallet encryption failed - ウォレットの暗号化に失敗しました - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 内部エラーによりウォレットの暗号化が失敗しました。ウォレットは暗号化されませんでした。 - - - The supplied passphrases do not match. - パスフレーズが同じではありません。 - - - Wallet unlock failed - ウォレットのアンロックに失敗しました - - - The passphrase entered for the wallet decryption was incorrect. - ウォレットの暗号化解除のパスフレーズが正しくありません。 - - - Wallet decryption failed - ウォレットの暗号化解除に失敗しました - - - Wallet passphrase was successfully changed. - ウォレットのパスフレーズの変更が成功しました。 - BanTableModel @@ -269,6 +110,14 @@ Quit application アプリケーションを終了 + + &About %1 + %1 について (&A) + + + Show information about %1 + %1 の情報を表示 + About &Qt Qt について(&Q) @@ -281,6 +130,10 @@ &Options... オプション... (&O) + + Modify configuration options for %1 + %1 の設定を変更する + &Encrypt Wallet... ウォレットの暗号化... (&E) @@ -305,14 +158,6 @@ Open &URI... URI を開く (&U)... - - Bitcoin Core client - Bitcoinコア クライアント - - - Importing blocks from disk... - ディスクからブロックをインポートしています... - Reindexing blocks on disk... ディスク上のブロックのインデックスを再作成中... @@ -357,10 +202,6 @@ &Receive 入金 (&R) - - Show information about Bitcoin Core - Bitcoinコアに関する情報を表示 - &Show / Hide 見る/隠す (&S) @@ -397,22 +238,10 @@ Tabs toolbar タブツールバー - - Bitcoin Core - Bitcoin のコア - Request payments (generates QR codes and bitcoin: URIs) 支払いを要求する (QRコードとbitcoin:ではじまるURIを生成する) - - &About Bitcoin Core - ビットコインコアについて (&A) - - - Modify configuration options for Bitcoin Core - Bitcoin Core の設定を編集する - Show the list of used sending addresses and labels 使用済みの送金用アドレスとラベルの一覧を表示する @@ -429,14 +258,18 @@ &Command-line options コマンドラインオプション (&C) - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 有効な Bitcoin のコマンドライン オプションを見るために Bitcoin Core のヘルプメッセージを表示します。 - %n active connection(s) to Bitcoin network %n の Bitcoin ネットワークへのアクティブな接続 + + Indexing blocks on disk... + ディスク上のブロックのインデックスを作成しています... + + + Processing blocks on disk... + ディスク上のブロックを処理しています... + No block source available... 利用可能なブロックがありません... @@ -493,6 +326,14 @@ Up to date バージョンは最新です + + Show the %1 help message to get a list with possible Bitcoin command-line options + 有効な Bitcoin のコマンドライン オプションを見るために %1 のヘルプメッセージを表示します。 + + + %1 client + %1 クライアント + Catching up... 追跡中... @@ -544,13 +385,6 @@ ウォレットは<b>暗号化されて、ロックされています</b> - - ClientModel - - Network Alert - ネットワーク警告 - - CoinControlDialog @@ -629,150 +463,6 @@ Priority 優先度 - - Copy address - アドレスをコピーする - - - Copy label - ラベルをコピーする - - - Copy amount - 総額のコピー - - - Copy transaction ID - 取引 ID をコピー - - - Lock unspent - 未使用トランザクションをロックする - - - Unlock unspent - 未使用トランザクションをアンロックする - - - Copy quantity - 数量をコピーする - - - Copy fee - 手数料をコピーする - - - Copy after fee - 手数料差引後の値をコピーする - - - Copy bytes - バイト数をコピーする - - - Copy priority - 優先度をコピーする - - - Copy dust - ダストをコピーする - - - Copy change - 釣り銭をコピー - - - highest - 最高 - - - higher - 非常に高 - - - high - - - - medium-high - 中〜高 - - - medium - - - - low-medium - 低〜中 - - - low - - - - lower - 非常に低 - - - lowest - 最低 - - - (%1 locked) - (%1 がロック済み) - - - none - なし - - - This label turns red if the transaction size is greater than 1000 bytes. - トランザクションのサイズが1000バイトを超える場合にはこのラベルは赤色になります。 - - - This label turns red if the priority is smaller than "medium". - 優先度が「中」未満の場合、このラベルは赤色になります。 - - - This label turns red if any recipient receives an amount smaller than %1. - 受取人のうち誰かの受取額が %1 未満の場合にこのラベルは赤色になります。 - - - Can vary +/- %1 satoshi(s) per input. - ひとつの入力につき %1 satoshi 前後ずれることがあります。 - - - yes - はい - - - no - いいえ - - - This means a fee of at least %1 per kB is required. - これは少なくとも1kBあたり %1 の手数料が必要であることを意味します。 - - - Can vary +/- 1 byte per input. - ひとつの入力につき1バイト程度ずれることがあります。 - - - Transactions with higher priority are more likely to get included into a block. - より高い優先度を持つトランザクションの方がブロックに取り込まれやすくなります。 - - - (no label) - (ラベル無し) - - - change from %1 (%2) - %1 (%2) からのおつり - - - (change) - (おつり) - EditAddressDialog @@ -796,38 +486,6 @@ &Address アドレス帳 (&A) - - New receiving address - 新しい入金アドレス - - - New sending address - 新しい送信アドレス - - - Edit receiving address - 入金アドレスを編集 - - - Edit sending address - 送信アドレスを編集 - - - The entered address "%1" is already in the address book. - 入力されたアドレス "%1" は既にアドレス帳にあります。 - - - The entered address "%1" is not a valid Bitcoin address. - 入力されたアドレス "%1" は無効な Bitcoin アドレスです。 - - - Could not unlock wallet. - ウォレットをアンロックできませんでした。 - - - New key generation failed. - 新しいキーの生成に失敗しました。 - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin のコア - version バージョン @@ -867,8 +521,8 @@ (%1ビット) - About Bitcoin Core - Bitcoinコアについて + About %1 + %1 について Command-line options @@ -907,8 +561,8 @@ 起動時にスプラッシュ画面を表示する (初期値: %u) - Reset all settings changes made over the GUI - GUI 経由で行われた設定の変更を全てリセット + Reset all settings changed in the GUI + GUI で行われた設定の変更を全てリセット @@ -918,16 +572,16 @@ ようこそ - Welcome to Bitcoin Core. - ようこそ! + Welcome to %1. + %1 へようこそ。 - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - これはプログラム最初の起動です。Bitcoin Coreがデータを保存する場所を選択して下さい。 + As this is the first time the program is launched, you can choose where %1 will store its data. + これはプログラム最初の起動です。%1 がデータを保存する場所を選択して下さい。 - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Coreは、ビットコインのブロックチェーンのコピーを、ダウンロードして保存します。少なくとも%1ギガバイトのデータが、このディレクトリに保存されます。そしてそれは時間と共に増加します。またウォレットもこのディレクトリに保存されます。 + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 は、ビットコインのブロックチェーンのコピーを、ダウンロードして保存します。少なくとも %2 ギガバイトのデータが、このディレクトリに保存されます。そしてそれは時間と共に増加します。またウォレットもこのディレクトリに保存されます。 Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: 任意のデータ ディレクトリを使用: - - Bitcoin Core - Bitcoin のコア - Error: Specified data directory "%1" cannot be created. エラー: 指定のデータディレクトリ "%1" を作成できません。 @@ -976,10 +626,6 @@ Select payment request file 支払いリクエストファイルを選択してください - - Select payment request file to open - 開きたい支払いリクエストファイルを選択してください - OptionsDialog @@ -991,6 +637,14 @@ &Main メイン (&M) + + Automatically start %1 after logging in to the system. + システムにログインした際、自動的に %1 を起動する。 + + + &Start %1 on system login + システムにログインした時に %1 を起動 (&S) + Size of &database cache データベースキャッシュのサイズ (&D) @@ -1019,10 +673,6 @@ 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. ウィンドウを閉じる際にアプリケーションを終了するのではなく、最小化します。このオプションが有効化された場合、メニューから終了を選択した場合にのみアプリケーションは閉じられます。 - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - ユーザ・インタフェイス言語はここで設定できます。この設定はBitcoin Coreの再起動後に有効となります。 - 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 |. トランザクションタブのコンテキストメニュー項目に表示する、サードパーティURL (例えばブロックエクスプローラ)。URL中の%sはトランザクションのハッシュ値に置き換えられます。垂直バー | で区切ることで、複数のURLを指定できます。 @@ -1047,14 +697,6 @@ &Network ネットワーク (&N) - - Automatically start Bitcoin Core after logging in to the system. - システムにログインした際、自動的にBitcoin Coreを起動する。 - - - &Start Bitcoin Core on system login - システムへログインした際にBitcoin Coreを起動する (&S) - (0 = auto, <0 = leave that many cores free) (0 = 自動、0以上 = 指定した数のコアをフリーにする) @@ -1139,6 +781,14 @@ &Window ウインドウ (&W) + + &Hide the icon from the system tray. + システムトレイのアイコンを隠す (&H) + + + Hide tray icon + トレイアイコンを隠す + Show only a tray icon after minimizing the window. ウインドウを最小化したあとトレイ アイコンだけを表示する。 @@ -1159,6 +809,10 @@ User Interface &language: ユーザインターフェースの言語 (&l) : + + The user interface language can be set here. This setting will take effect after restarting %1. + ここでユーザインターフェースの言語を設定できます。設定を反映するには %1 を再起動します。 + &Unit to show amounts in: 額を表示する単位 (&U) : @@ -1283,97 +937,6 @@ 監視限定アドレス内の現在の全残高 - - PaymentServer - - URI handling - URI の操作 - - - Invalid payment address %1 - 支払いのアドレス「%1」は無効です - - - Payment request rejected - 支払い要求は拒否されました - - - Payment request network doesn't match client network. - 支払いリクエストのネットワークは現在のクライアントのネットワークに一致しません。 - - - Payment request is not initialized. - 支払いリクエストは開始されていません。 - - - Requested payment amount of %1 is too small (considered dust). - 要求された支払額 %1 は少なすぎます (ダストとみなされてしまいます)。 - - - Payment request error - 支払いのリクエストのエラーです - - - Cannot start bitcoin: click-to-pay handler - Bitcoin を起動できません: click-to-pay handler - - - Payment request fetch URL is invalid: %1 - 支払い要求の取得先URLが無効です: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI を解析できません! これは無効な Bitcoin アドレスあるいや不正な形式の URI パラメーターによって引き起こされる場合があります。 - - - Payment request file handling - 支払いリクエストファイルを処理しています - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - 支払いリクエストファイルを読み込めませんでした!無効な支払いリクエストファイルにより引き起こされた可能性があります。 - - - Payment request expired. - 支払いリクエストの期限が切れました。 - - - Unverified payment requests to custom payment scripts are unsupported. - カスタム支払いスクリプトに対する、検証されていない支払いリクエストはサポートされていません。 - - - Invalid payment request. - 無効な支払いリクエスト。 - - - Refund from %1 - %1 からの返金 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - 支払リクエスト %1 は大きすぎます(%2バイトですが、%3バイトまでが許されています)。 - - - Error communicating with %1: %2 - %1: %2とコミュニケーション・エラーです - - - Payment request cannot be parsed! - 支払リクエストを読み込めませんでした! - - - Bad response from server %1 - サーバーの返事は無効 %1 - - - Payment acknowledged - 支払いは確認しました - - - Network request error - ネットワーク・リクエストのエラーです - - PeerTableModel @@ -1428,25 +991,6 @@ %1ミリ秒 - - QRImageWidget - - &Save Image... - 画像を保存(&S) - - - &Copy Image - 画像をコピー(&C) - - - Save QR Code - QR コードの保存 - - - PNG Image (*.png) - PNG画像ファイル(*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version 使用中のBerkleyDBバージョン + + Datadir + データディレクトリ + Startup time 起動した日時 @@ -1513,10 +1061,6 @@ Memory usage メモリ使用量 - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - 現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。 - Received 受取 @@ -1565,6 +1109,18 @@ User Agent ユーザエージェント + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + 現在のデータディレクトリから %1 のデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。 + + + Decrease font size + 文字サイズを縮小 + + + Increase font size + 文字サイズを拡大 + Services サービス @@ -1633,10 +1189,6 @@ Out: 出力: - - Build date - ビルドの日付 - Debug log file デバッグ用ログファイル @@ -1674,8 +1226,8 @@ ノードのbanを解除する (&U) - Welcome to the Bitcoin Core RPC console. - Bitcoin CoreのRPCコンソールへようこそ。 + Welcome to the %1 RPC console. + %1 のRPCコンソールへようこそ。 Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove 削除 - - Copy label - ラベルをコピーする - - - Copy message - メッセージをコピーする - - - Copy amount - 総額のコピー - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... 画像を保存(&S) - - Request payment to %1 - %1 への支払いリクエストを行う - - - Payment information - 支払い情報 - - - URI - URI - - - Address - アドレス - - - Amount - 総額 - - - Label - ラベル - - - Message - メッセージ - - - Resulting URI too long, try to reduce the text for label / message. - URI が長くなり過ぎます。ラベルやメッセージのテキストを短くしてください。 - - - Error encoding URI into QR Code. - QR コード用の URI エンコードでエラー。 - - - - RecentRequestsTableModel - - Date - 日付 - - - Label - ラベル - - - Message - メッセージ - - - Amount - 総額 - - - (no label) - (ラベル無し) - - - (no message) - (メッセージなし) - - - (no amount) - (金額なし) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast 高速 - - Send as zero-fee transaction if possible - 可能な場合には手数料ゼロのトランザクションとして送金する - - - (confirmation may take longer) - (検証に長い時間がかかる可能性があります) - Send to multiple recipients at once 一度に複数の人に送る @@ -2061,118 +1526,6 @@ S&end 送金 (&E) - - Confirm send coins - コインを送る確認 - - - %1 to %2 - %1 から %2 - - - Copy quantity - 数量をコピーする - - - Copy amount - 総額のコピー - - - Copy fee - 手数料をコピーする - - - Copy after fee - 手数料差引後の値をコピーする - - - Copy bytes - バイト数をコピーする - - - Copy priority - 優先度をコピーする - - - Copy change - 釣り銭をコピー - - - Total Amount %1 - 合計: %1 - - - or - または - - - The amount to pay must be larger than 0. - 支払額は0より大きくないといけません。 - - - The amount exceeds your balance. - 額が残高を超えています。 - - - The total exceeds your balance when the %1 transaction fee is included. - %1 の取引手数料を含めると額が残高を超えています。 - - - Transaction creation failed! - トラザクションの作成に失敗しました! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - トランザクションは拒否されました。wallet.dat のコピーを使い、そしてコピーしたウォレットからコインを使用したことがマークされなかったときなど、ウォレットのいくつかのコインがすでに使用されている場合に、このエラーは起こるかもしれません。 - - - A fee higher than %1 is considered an absurdly high fee. - %1 よりも高い手数料の場合、手数料が高すぎると判断されます。 - - - Payment request expired. - 支払いリクエストの期限が切れました。 - - - Pay only the required fee of %1 - 要求手数料 %1 のみを支払う - - - Estimated to begin confirmation within %n block(s). - %n ブロック以内に検証が開始されると予想されます。 - - - The recipient address is not valid. Please recheck. - 受取アドレスが不正です。再チェックしてください。 - - - Duplicate address found: addresses should only be used once each. - 重複したアドレスが見つかりました: アドレスはそれぞれ一度のみ使用することができます。 - - - Warning: Invalid Bitcoin address - 警告:無効なBitcoinアドレスです - - - (no label) - (ラベル無し) - - - Warning: Unknown change address - 警告:未知のおつりアドレスです - - - Copy dust - ダストをコピーする - - - Are you sure you want to send? - 送ってよろしいですか? - - - added as transaction fee - 取引手数料として追加された - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: 送り先(&T): - - Enter a label for this address to add it to your address book - アドレス帳に追加するには、このアドレスのラベルを入力します - &Label: ラベル(&L): @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Coreをシャットダウンしています。 + %1 is shutting down... + %1 をシャットダウンしています... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields 入力項目の内容をすべて消去します - - Click "Sign Message" to generate signature - 署名を作成するには"メッセージの署名"をクリック - - - The entered address is invalid. - 不正なアドレスが入力されました。 - - - Please check the address and try again. - アドレスを確かめてからもう一度試してください。 - - - The entered address does not refer to a key. - 入力されたアドレスに関連するキーがありません。 - - - Wallet unlock was cancelled. - ウォレットのアンロックはキャンセルされました。 - - - Private key for the entered address is not available. - 入力されたアドレスのプライベート キーが無効です。 - - - Message signing failed. - メッセージの署名に失敗しました。 - - - Message signed. - メッセージに署名しました。 - - - The signature could not be decoded. - 署名がデコードできません。 - - - Please check the signature and try again. - 署名を確認してからもう一度試してください。 - - - The signature did not match the message digest. - 署名はメッセージ ダイジェストと一致しませんでした。 - - - Message verification failed. - メッセージの検証に失敗しました。 - - - Message verified. - メッセージは検証されました。 - SplashScreen - - Bitcoin Core - Bitcoin のコア - - - The Bitcoin Core developers - ビットコインコアの開発者 - [testnet] [testnet] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - ユニット %1 を開く - - - conflicted - 衝突 - - - %1/offline - %1/オフライン - - - %1/unconfirmed - %1/未検証 - - - %1 confirmations - %1 確認 - - - Status - ステータス - - - , broadcast through %n node(s) - %n ノードにブロードキャスト - - - Date - 日付 - - - Source - ソース - - - Generated - 生成された - - - From - 送信 - - - To - 受信 - - - own address - 自分のアドレス - - - watch-only - 監視限定 - - - label - ラベル - - - Credit - クレジット - - - matures in %n more block(s) - %n 以上のブロックが満期 - - - not accepted - 承認されなかった - - - Debit - 引き落とし額 - - - Total debit - 総出金額 - - - Total credit - 総入金額 - - - Transaction fee - 取引手数料 - - - Net amount - 正味金額 - - - Message - メッセージ - - - Comment - コメント - - - Transaction ID - 取引 ID - - - Merchant - 商人 - - - 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. - 生成されたコインは使う前に%1のブロックを完成させる必要があります。あなたが生成した時、このブロックはブロック チェーンに追加されるネットワークにブロードキャストされました。チェーンに追加されるのが失敗した場合、状態が"不承認"に変更されて使えなくなるでしょう。これは、別のノードがあなたの数秒前にブロックを生成する場合に時々起こるかもしれません。 - - - Debug information - デバッグ情報 - - - Transaction - 取引 - - - Inputs - 入力 - - - Amount - 総額 - - - true - 正しい - - - false - 正しくない - - - , has not been successfully broadcast yet - まだブロードキャストが成功していません - - - Open for %n more block(s) - %n 以上のブロックを開く - - - unknown - 未確認 - - TransactionDescDialog - - Transaction details - 取引の詳細 - This pane shows a detailed description of the transaction ここでは取引の詳細を表示しています - - TransactionTableModel - - Date - 日付 - - - Type - タイプ - - - Immature (%1 confirmations, will be available after %2) - 未成熟(%1検証。%2検証完了後に使用可能となります) - - - Open for %n more block(s) - %n 以上のブロックを開く - - - Open until %1 - ユニット %1 を開く - - - Confirmed (%1 confirmations) - 検証されました (%1 検証済み) - - - This block was not received by any other nodes and will probably not be accepted! - このブロックは他のどのノードによっても受け取られないで、多分受け入れられないでしょう! - - - Generated but not accepted - 生成されましたが承認されませんでした - - - Offline - オフライン - - - Label - ラベル - - - Unconfirmed - 未検証 - - - Confirming (%1 of %2 recommended confirmations) - 検証中(%2の推奨検証数のうち、%1検証が完了) - - - Conflicted - 衝突 - - - Received with - 受け取り - - - Received from - 送り主 - - - Sent to - 送り先 - - - Payment to yourself - 自分自身への支払い - - - Mined - 発掘した - - - watch-only - 監視限定 - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - 取引の状況。このフィールドの上にカーソルを置くと検証の数を表示します。 - - - Date and time that the transaction was received. - 取引を受信した日時。 - - - Type of transaction. - 取引の種類。 - - - Whether or not a watch-only address is involved in this transaction. - 監視限定アドレスがこのトランザクションに含まれているかどうか - - - User-defined intent/purpose of the transaction. - ユーザ定義のトランザクションの意図や目的。 - - - Amount removed from or added to balance. - 残高に追加または削除された総額。 - - - - TransactionView - - All - すべて - - - Today - 今日 - - - This week - 今週 - - - This month - 今月 - - - Last month - 先月 - - - This year - 今年 - - - Range... - 期間... - - - Received with - 送り主 - - - Sent to - 送り先 - - - To yourself - 自分自身 - - - Mined - 発掘した - - - Other - その他 - - - Enter address or label to search - 検索するアドレスまたはラベルを入力 - - - Min amount - 最小の額 - - - Copy address - アドレスをコピーする - - - Copy label - ラベルをコピーする - - - Copy amount - 総額のコピー - - - Copy transaction ID - 取引 ID をコピー - - - Copy raw transaction - 生トランザクションをコピー - - - Edit label - ラベルの編集 - - - Show transaction details - 取引の詳細を表示 - - - Export Transaction History - トランザクション履歴をエクスポートする - - - Watch-only - 監視限定 - - - Exporting Failed - エクスポートに失敗しました - - - There was an error trying to save the transaction history to %1. - トランザクション履歴を %1 へ保存する際にエラーが発生しました。 - - - Exporting Successful - エクスポートに成功しました - - - The transaction history was successfully saved to %1. - トランザクション履歴は正常に%1に保存されました。 - - - Comma separated file (*.csv) - テキスト CSV (*.csv) - - - Confirmed - 検証済み - - - Date - 日付 - - - Type - タイプ - - - Label - ラベル - - - Address - Helbidea - - - ID - ID - - - Range: - 期間: - - - to - から - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ 金額を表示する際の単位。クリックすることで他の単位を選択します。 - - WalletFrame - - No wallet has been loaded. - ウォレットがロードされていません - - - - WalletModel - - Send Coins - コインを送る - - - - WalletView - - &Export - エクスポート (&E) - - - Export the data in the current tab to a file - ファイルに現在のタブのデータをエクスポート - - - Backup Wallet - ウォレットのバックアップ - - - Wallet Data (*.dat) - ウォレット データ (*.dat) - - - Backup Failed - バックアップに失敗しました - - - There was an error trying to save the wallet data to %1. - ウォレットデータを%1へ保存する際にエラーが発生しました。 - - - The wallet data was successfully saved to %1. - ウォレット データは正常に%1に保存されました。 - - - Backup Successful - バックアップ成功 - - bitcoin-core @@ -2927,14 +1758,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. <category> が与えられなかった場合や <category> = 1 の場合には、すべてのデバッグ情報が出力されます。 - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - ひとつのウォレットトランザクションで使用する合計手数料 (%s 単位) の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - あなたのPCの日付と時刻が正しいことを確認して下さい! もしあなたの時計が正しくなければBitcoin Coreが正確に動作しません。 - Prune configured below the minimum of %d MiB. Please use a higher number. 剪定が最小値の %d MiB以下に設定されています。もっと大きな値を使用してください。 @@ -2975,6 +1798,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 外部からの接続を許可 (初期値: -proxy または -connect を使用していない場合は1) + + Bitcoin Core + Bitcoin のコア + + + The %s developers + %s の開発者 + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee が高すぎます!これは手数料の推定機能が利用できない場合に支払うトランザクション手数料です。 @@ -2991,6 +1822,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 指定のアドレスへバインドし、その上で常にリスンします。IPv6 は [ホスト名]:ポート番号 と表記します + + Cannot obtain a lock on data directory %s. %s is probably already running. + データ ディレクトリ %s のロックを取得することができません。おそらく %s は実行中です。 + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup ウォレットの全トランザクションを削除し、これらを-rescanオプションを用いることで起動時にブロックチェインのデータのみからリカバリします。 @@ -2999,6 +1834,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは<http://www.opensource.org/licenses/mit-license.php>を参照してください。 + + Error loading %s: You can't enable HD on a already existing non-HD wallet + %s の読み込みエラー: 非HDウォレットが既に存在するため、HDウォレットを有効化できません + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + %s の読み込みエラー! すべてのキーは正しく読み取れますが、取引データやアドレス帳のエントリが失われたか、正しくない可能性があります。 + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される) @@ -3007,6 +1850,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + 時間オフセット調整値のピア中央値に対する最大の許容値。ローカル時間の見込み値は、接続するピアにより前方ないし後方へ影響されます。(初期値: %u 秒) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + ひとつのウォレットトランザクションまたは生トランザクションで使用する合計手数料の最大値 (%s 単位)。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + あなたのPCの日付と時刻が正しいことを確認して下さい! もしあなたの時計が正しくなければ %s が正確に動作しません。 + + + Please contribute if you find %s useful. Visit %s for further information about the software. + %s が有用だと感じられた方はぜひプロジェクトへの貢献をお願いします。ソフトウェアのより詳細な情報については %s をご覧ください。 + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) スクリプト検証スレッドを設定 (%uから%dの間, 0 = 自動, <0 = たくさんのコアを自由にしておく, 初期値: %d) @@ -3019,14 +1878,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications これはリリース前のテストビルドです - 各自の責任で利用すること - 採掘や商取引に使用しないでください - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。 - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - サポートされていない引数 -whitelistalwaysrelay は無視されました。-whitelistrelay または -whitelistforcerelay を利用してください - Use UPnP to map the listening port (default: 1 when listening and no -proxy) リスン ポートの割当に UPnP を使用 (初期値: リスン中および-proxyが指定されていない場合は1) @@ -3043,22 +1894,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告: ネットワークは完全に同意しないみたいです。マイナーは何かの問題を経験してるみたいなんです。 - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - 警告: 未知のバージョンのブロックが採掘されました。未知のルールが導入された可能性があります - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 警告: ピアーと完全に同意しないみたいです!アップグレードは必要かもしれません、それとも他のノードはアップグレードは必要かもしれません。 - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - 警告: wallet.dat が壊れたのでデータを復旧しました! オリジナルの wallet.dat は wallet.{timestamp}.bak として %s に保存されました; もしもあなたの残高や取引が正しくないならバックアップから復元してください。 - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 与えられたネットマスクやIPアドレスから接続を行う、ホワイトリストのピア。複数回指定できます。 + + You need to rebuild the database using -reindex-chainstate to change -txindex + -txindex を変更するには -reindex-chainstate を使用してデータベースを再構築する必要があります + + + %s corrupt, salvage failed + %s が壊れています。復旧にも失敗しました + -maxmempool must be at least %d MB -maxmempoolは最低でも %d MB必要です @@ -3071,10 +1922,22 @@ Append comment to the user agent string ユーザエージェント文字列にコメントを + + Attempt to recover private keys from a corrupt wallet on startup + 起動時に壊れたウォレットから秘密鍵を復旧することを試す + Block creation options: ブロック作成オプション: + + Cannot resolve -%s address: '%s' + -%s アドレス '%s' を解決できません + + + Change index out of range + おつりのインデックスが範囲外です + Connect only to the specified node(s) 指定したノードだけに接続 @@ -3083,6 +1946,10 @@ Connection options: 接続オプション: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected 破損したブロック データベースが見つかりました @@ -3128,6 +1995,22 @@ Error initializing wallet database environment %s! ウォレットのデータベース環境 %s 初期化エラー! + + Error loading %s + %s 読み込みエラー + + + Error loading %s: Wallet corrupted + %s 読み込みエラー: ウォレットが壊れました + + + Error loading %s: Wallet requires newer version of %s + %s の読み込みに失敗しました: ウォレットの読み込みにはより新しいバージョンの %s が必要です + + + Error loading %s: You can't disable HD on a already existing HD wallet + %s の読み込みエラー: HDウォレットが既に存在するため、HDウォレットを無効化できません + Error loading block database ブロック データベースの読み込みエラー @@ -3152,10 +2035,18 @@ Incorrect or no genesis block found. Wrong datadir for network? 不正なブロックあるいは、生成されていないブロックが見つかりました。ネットワークの datadir が間違っていませんか? + + Initialization sanity check failed. %s is shutting down. + 初期化時の健全性チェックに失敗しました。%s を終了します。 + Invalid -onion address: '%s' 無効な -onion アドレス:'%s' + + Invalid amount for -%s=<amount>: '%s' + -%s=<数量> に対する不正な額: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' 不正な額 -fallbackfee=<amount>: '%s' @@ -3164,6 +2055,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) トランザクションのメモリ・プールの総量を <n> メガバイト以下に維持する (初期値: %u) + + Loading banlist... + banリストを読み込んでいます... + Location of the auth cookie (default: data dir) 認証クッキーの場所 (デフォルト: ) @@ -3180,6 +2075,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) <net> (ipv4, ipv6 または onion) ネットワーク内のノードだけに接続する + + Print this help message and exit + このヘルプメッセージを表示し終了する + Print version and exit バージョンを表示し終了 @@ -3192,6 +2091,14 @@ Prune mode is incompatible with -txindex. 剪定モードは-txindexと互換性がありません。 + + Rebuild chain state and block index from the blk*.dat files on disk + チェイン状態およびブロックインデックスをディスク上の blk*.dat ファイルから再構築する + + + Rebuild chain state from the currently indexed blocks + 既にインデックスされたブロックからチェイン状態を再構築する + Set database cache size in megabytes (%d to %d, default: %d) データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d) @@ -3204,6 +2111,14 @@ Specify wallet file (within data directory) ウォレットのファイルを指定 (データ・ディレクトリの中に) + + The source code is available from %s. + ソースコードは %s より入手可能です。 + + + Unable to bind to %s on this computer. %s is probably already running. + このコンピュータの %s にバインドすることができません。おそらく %s は既に実行されています。 + Unsupported argument -benchmark ignored, use -debug=bench. サポートされていない引数 -benchmark は無視されました。-debug=bench を使用してください。 @@ -3237,12 +2152,16 @@ 財布 %s はデータ・ディレクトリ%sの外にあります - Wallet options: - ウォレットオプション: + Wallet debugging/testing options: + ウォレットのデバッグ・テスト用オプション: - You need to rebuild the database using -reindex to change -txindex - -txindex を変更するには -reindex を使用してデータベースを再構築する必要があります + Wallet needed to be rewritten: restart %s to complete + ウォレットが書き直される必要がありました: 完了するために %s を再起動します + + + Wallet options: + ウォレットオプション: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3256,10 +2175,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) 指定されたアドレスに対して JSON-RPC 接続をリッスンしするようバインドします。IPv6の場合には [host]:port 表記を使用してください。このオプションは複数回指定することが可能です (初期値: すべてのインターフェースに対してバインドする) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - データ ディレクトリ %s のロックを取得することができません。おそらく Bitcoin Core は実行中です。 - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) umask 077 ではなく、システムのデフォルトパーミッションで新規ファイルを作成する (ウォレット機能が無効化されていた場合にのみ有効) @@ -3304,10 +2219,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 最優先/最低手数料の最大サイズをバイトで指定 (初期値: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - コイン生成が有効になっていた場合の利用スレッド数を設定する (-1 = すべてのコア, 初期値: %d) - The transaction amount is too small to send after the fee has been deducted 手数料差引後のトランザクションの金額が小さすぎるため、送金できません。 @@ -3316,6 +2227,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. この製品はOpenSSLプロジェクトにより開発されたソフトウェアをOpenSSLツールキットとして利用しています <https://www.openssl.org/>。また、Eric Young氏により開発された暗号ソフトウェア、Thomas Bernard氏により書かれたUPnPソフトウェアを用いています。 + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + BIP32 に従った階層的決定性鍵生成方式 (HD) を利用します。ウォレットの生成時ないし最初に起動した時にのみ有効です。 + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway ホワイトリストのピアはDoSによるアクセス禁止処理が無効化され、トランザクションは例えmempool内に既に存在していたとしても常にリレーされます。これは例えばゲートウェイに対して有用です @@ -3332,34 +2247,14 @@ Accept public REST requests (default: %u) 公開 REST リクエストを許可する (初期値: %u) - - Activating best chain... - 最優良のチェインを有効化しています... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - 起動時に壊れた wallet.dat から秘密鍵を復旧することを試す - Automatically create Tor hidden service (default: %d) Tor秘匿サービスを自動的に作成する (初期値: %d) - - Cannot resolve -whitebind address: '%s' - -whitebind アドレス '%s' を解決できません - Connect through SOCKS5 proxy SOCKS5 プロキシ経由で接続する - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Bitcoin Core 開発者 - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - wallet.dat の読み込みに失敗しました: ウォレットの読み込みにはより新しいバージョンの Bitcoin Core が必要です - Error reading from database, shutting down. データベースの読み込みエラー。シャットダウンします。 @@ -3372,22 +2267,6 @@ Information 情報 - - Initialization sanity check failed. Bitcoin Core is shutting down. - 初期化時の健全性チェックに失敗しました。Bitcoin Coreを終了します。 - - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<amount> に対する無効な数量です: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - 不正な額 -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - 不正な額 -minrelaytxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) -paytxfee=<amount> に対する無効な数量です: '%s' (少なくとも %s でなければいけません) @@ -3412,14 +2291,6 @@ RPC server options: RPCサーバのオプション: - - Rebuild block chain index from current blk000??.dat files on startup - 起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築 - - - Receive and display P2P network alerts (default: %u) - P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u) - Reducing -maxconnections from %d to %d, because of system limitations. システム上の制約から、-maxconnections を %d から %d に削減しました。 @@ -3492,10 +2363,6 @@ Username for JSON-RPC connections JSON-RPC 接続のユーザー名 - - Wallet needed to be rewritten: restart Bitcoin Core to complete - ウォレットが書き直される必要がありました: 完了するために Bitcoin Core を再起動します - Warning 警告 @@ -3516,10 +2383,6 @@ ZeroMQ notification options: ZeroMQ通知オプション: - - wallet.dat corrupt, salvage failed - wallet.dat が壊れ、復旧に失敗しました - Password for JSON-RPC connections JSON-RPC 接続のパスワード @@ -3528,10 +2391,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) 最良のブロックに変更する際にコマンドを実行 (cmd の %s はブロック ハッシュに置換される) - - This help message - このヘルプ メッセージ - Allow DNS lookups for -addnode, -seednode and -connect -addnode, -seednode と -connect で DNS ルックアップを許可する @@ -3540,10 +2399,6 @@ Loading addresses... アドレスを読み込んでいます... - - Error loading wallet.dat: Wallet corrupted - wallet.dat 読み込みエラー: ウォレットが壊れました - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する) @@ -3560,10 +2415,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) mempool内でトランザクションを <n> 時間以上保持しない (初期値: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - wallet.dat の読み込みエラー! すべてのキーは正しく読み取れますが、取引データやアドレス帳のエントリが失われたか、正しくない可能性があります。 - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) トランザクション作成の際、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s) @@ -3600,6 +2451,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. サポートされていない引数 -socks が見つかりました。SOCKSバージョンの設定はできないようになりました。SOCKS5プロキシのみがサポートされています。 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + サポートされていない引数 -whitelistalwaysrelay は無視されました。-whitelistrelay または -whitelistforcerelay を利用してください + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Tor 秘匿サービスを通し、別々の SOCKS5 プロキシを用いることでピアに到達する (初期値: %s) @@ -3608,6 +2463,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times JSON-RPC接続時のユーザ名とハッシュ化されたパスワード。<userpw> フィールドのフォーマットは <USERNAME>:<SALT>$<HASH>。標準的な Python スクリプトが share/rpcuser 内に含まれています。このオプションは複数回指定できます。 + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 未知のバージョンのブロックが採掘されました。未知のルールが導入された可能性があります + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + 警告: ウォレットファイルが破損していましたのでデータを復旧しました!元の %s は %s として %s に保存されました; 残高やトランザクションが正しくない場合にはバックアップから復元してください。 + (default: %s) (デフォルト: %s) @@ -3616,14 +2479,6 @@ Always query for peer addresses via DNS lookup (default: %u) DNS ルックアップを通してピアアドレスを常に問い合わせる (初期値: %u) - - Error loading wallet.dat - wallet.dat 読み込みエラー - - - Generate coins (default: %u) - コインを生成 (初期値: %u) - How many blocks to check at startup (default: %u, 0 = all) 起動時に点検するブロック数 (初期値: %u, 0=すべて) @@ -3708,18 +2563,6 @@ Unknown network specified in -onlynet: '%s' -onlynet で指定された '%s' は未知のネットワークです - - Cannot resolve -bind address: '%s' - -bind のアドレス '%s' を解決できません - - - Cannot resolve -externalip address: '%s' - -externalip のアドレス '%s' を解決できません - - - Invalid amount for -paytxfee=<amount>: '%s' - -paytxfee=<amount> の額 '%s' が無効です - Insufficient funds 残高不足 @@ -3730,7 +2573,7 @@ Add a node to connect to and attempt to keep the connection open - 接続するノードを追加し接続を持続するように試します + 接続するノードを追加し接続を保持します Loading wallet... diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 1a072d1df..22e7651f6 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -21,10 +21,6 @@ C&lose &დახურვა - - &Copy Address - &მისამართის კოპირება - Delete the currently selected address from the list მონიშნული მისამართის წაშლა სიიდან @@ -41,69 +37,6 @@ &Delete &წაშლა - - Choose the address to send coins to - აირჩიეთ მონეტების გაგზავნის მისამართი - - - Choose the address to receive coins with - აირჩიეთ მონეტების მიღების მისამართი - - - C&hoose - &არჩევა - - - Sending addresses - გაგზავნის მისამართი - - - Receiving addresses - მიღების მისამართი - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - ეს არის თქვენი Bitcoin-მისამართები გადახდების შესასრულებლად. მონეტების გაგზავნამდე ყოველთვის შეამოწმეთ თანხა და მიმღების მისამართი. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - ეს არის თქვენი Bitcoin-მისამართები გადახდების მისაღებად. რეკომენდებულია ყოველი ტრანსაქციისათვის ახალი მიღების მისამართის გამოყენება. - - - Copy &Label - ნიშნუ&ლის კოპირება - - - &Edit - რ&ედაქტირება - - - Export Address List - მისამართების სიის ექსპორტი - - - Comma separated file (*.csv) - CSV-ფაილი (*.csv) - - - Exporting Failed - ექსპორტი ვერ განხორციელდა - - - - AddressTableModel - - Label - ნიშნული - - - Address - მისამართი - - - (no label) - (არ არის ნიშნული) - AskPassphraseDialog @@ -123,82 +56,6 @@ Repeat new passphrase გაიმეორეთ ახალი ფრაზა-პაროლი - - Encrypt wallet - საფულის დაშიფრვა - - - This operation needs your wallet passphrase to unlock the wallet. - ეს ოპერაცია მოითხოვს თქვენი საფულის ფრაზა-პაროლს საფულის განსაბლოკად. - - - Unlock wallet - საფულის განბლოკვა - - - This operation needs your wallet passphrase to decrypt the wallet. - ეს ოპერაცია მოითხოვს თქვენი საფულის ფრაზა-პაროლს საფულის გასაშიფრად. - - - Decrypt wallet - საფულის გაშიფრვა - - - Change passphrase - ფრაზა-პაროლის შეცვლა - - - Confirm wallet encryption - დაადასტურეთ საფულის დაშიფრვა - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - ყურადღება: საფულის დაშიფრვის შემდეგ თუ თქვენ დაკარგავთ ფრაზა-პაროლს, <b>ყველა ბიტქოინი დაგეკარგებათ</b>! - - - Are you sure you wish to encrypt your wallet? - დარწმუნებული ხართ, რომ გინდათ საფულის დაშიფრვა? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - მნიშვნელოვანია: თქვენი საფულის ყველა ადრინდელი არქივი შეიცვლება ახლადგენერირებული დაშიფრული საფულის ფაილით. უსაფრთხოების მოსაზრებებით დაუშიფრავი საფულის ძველი არქივები ძალას დაკარგავს, როგორც კი დაიწყებთ ახალი, დაშიფრული საფულის გამოყენებას. - - - Warning: The Caps Lock key is on! - ყურადღება: ჩართულია Caps Lock რეჟიმი! - - - Wallet encrypted - საფულე დაშიფრულია - - - Wallet encryption failed - ვერ მოხერხდა საფულის დაშიფრვა - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - საფულის დაშიფრვა ვერ მოხერხდა სისტემაში შეცდომის გამო. თქვენი საფულე არ არის დაშფრული. - - - The supplied passphrases do not match. - ფრაზა-პაროლები არ ემთხვევა ერთმანეთს. - - - Wallet unlock failed - საფულის განბლოკვა ვერ მოხერხდა - - - The passphrase entered for the wallet decryption was incorrect. - საფულის განშიფრვის ფრაზა-პაროლი არაწორია - - - Wallet decryption failed - საფულის განშიფრვა ვერ მოხერხდა - - - Wallet passphrase was successfully changed. - საფულის ფრაზა-პაროლი შეცვლილია. - BanTableModel @@ -277,10 +134,6 @@ Open &URI... &URI-ის გახსნა... - - Importing blocks from disk... - ბლოკების იმპორტი დისკიდან... - Reindexing blocks on disk... დისკზე ბლოკების რეინდექსაცია... @@ -361,18 +214,10 @@ Tabs toolbar ბარათების პანელი - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) გადახდის მოთხოვნა (შეიქმნება QR-კოდები და bitcoin: ბმულები) - - &About Bitcoin Core - Bitcoin Core-ს შეს&ახებ - Show the list of used sending addresses and labels გამოყენებული გაგზავნის მისამართებისა და ნიშნულების სიის ჩვენება @@ -389,10 +234,6 @@ &Command-line options საკომანდო სტრიქონის ოპ&ციები - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Bitcoin Core-ს დახმარების ჩვენება Bitcoin-ის საკომანდო სტრიქონის დასაშვები ოპციების სანახავად - No block source available... ბლოკების წყარო მიუწვდომელია... @@ -450,13 +291,6 @@ საფულე <b>დაშიფრულია</b> და ამჟამად <b>დაბლოკილია</b> - - ClientModel - - Network Alert - ქსელური განგაში - - CoinControlDialog @@ -519,130 +353,6 @@ Priority პრიორიტეტი - - Copy address - მისამართის კოპირება - - - Copy label - ნიშნულის კოპირება - - - Copy amount - თანხის კოპირება - - - Copy transaction ID - ტრანსაქციის ID-ს კოპირება - - - Lock unspent - დაუხარჯავის დაბლოკვა - - - Unlock unspent - დაუხარჯავის განბლოკვა - - - Copy quantity - რაოდენობის კოპირება - - - Copy fee - საკომისიოს კოპირება - - - Copy after fee - დამატებითი საკომისიოს კოპირება - - - Copy bytes - ბაიტების კოპირება - - - Copy priority - პრიორიტეტის კოპირება - - - Copy change - ხურდის კოპირება - - - highest - უმაღლესი - - - higher - უფრო მაღალი - - - high - მაღალი - - - medium-high - საშუალოზე მაღალი - - - medium - საშუალო - - - low-medium - საშუალოზე დაბალი - - - low - დაბალი - - - lower - უფრო დაბალი - - - lowest - უდაბლესი - - - (%1 locked) - (%1 დაბლოკილია) - - - none - ცარიელი - - - yes - კი - - - no - არა - - - This means a fee of at least %1 per kB is required. - ეს ნიშნავს, რომ კილობაიტზე საკომისიო იქნება მინიმუმ %1 - - - Can vary +/- 1 byte per input. - შეიძლება იყოს +/- 1 ბაიტი ყოველ შესავალზე. - - - Transactions with higher priority are more likely to get included into a block. - მეტი პრიორიტეტის ტრანსაქციებს მეტი შანსი აქვს მოხვდეს ბლოკში. - - - (no label) - (არ არის ნიშნული) - - - change from %1 (%2) - ხურდა %1-დან (%2) - - - (change) - (ხურდა) - EditAddressDialog @@ -666,38 +376,6 @@ &Address მის&ამართი - - New receiving address - ახალი მიღების მისამართი - - - New sending address - ახალი გაგზავნის მისამართი - - - Edit receiving address - მიღების მისამართის შეცვლა - - - Edit sending address - გაგზავნის მისამართის შეცვლა - - - The entered address "%1" is already in the address book. - მისამართი "%1" უკვე არის მისამართების წიგნში. - - - The entered address "%1" is not a valid Bitcoin address. - შეყვანილი მისამართი "%1" არ არის ვალიდური Bitcoin-მისამართი. - - - Could not unlock wallet. - საფულის განბლოკვა ვერ მოხერხდა. - - - New key generation failed. - ახალი გასაღების გენერირება ვერ მოხერხდა - FreespaceChecker @@ -724,18 +402,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version ვერსია - - About Bitcoin Core - Bitcoin Core-ს შესახებ - Command-line options კომანდების ზოლის ოპციები @@ -755,18 +425,6 @@ Welcome მოგესალმებით - - Welcome to Bitcoin Core. - მოგესალმებათ Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - ეს პროგრამის პირველი გაშვებაა; შეგიძლიათ მიუთითოთ, სად შეინახოს მონაცემები Bitcoin Core-მ. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core გადმოტვირთავს და შეინახავს Bitcoin-ის ბლოკთა ჯაჭვს. მითითებულ კატალოგში დაგროვდება სულ ცოტა %1 გბ მონაცემები, და მომავალში უფრო გაიზრდება. საფულეც ამავე კატალოგში შეინახება. - Use the default data directory ნაგულისხმევი კატალოგის გამოყენება @@ -775,10 +433,6 @@ Use a custom data directory: მითითებული კატალოგის გამოყენება: - - Bitcoin Core - Bitcoin Core - Error შეცდომა @@ -802,10 +456,6 @@ Select payment request file გადახდის მოთხოვნის ფაილის არჩევა - - Select payment request file to open - გადახდის მოთხოვნის ფაილის არჩევა გასახსნელად - OptionsDialog @@ -989,61 +639,6 @@ თქვენი სრული მიმდინარე ბალანსი - - PaymentServer - - URI handling - URI-ების დამუშავება - - - Invalid payment address %1 - გადახდის მისამართი არასწორია: %1 - - - Requested payment amount of %1 is too small (considered dust). - მოთხოვნილი გადახდის %1 მოცულობა ძალიან მცირეა (ითვლება "მტვრად") - - - Payment request error - გადახდის მოთხოვნის შეცდომა - - - Cannot start bitcoin: click-to-pay handler - ვერ გაიშვა bitcoin: click-to-pay - - - Payment request fetch URL is invalid: %1 - არასწორია გადახდის მოთხოვნის URL: %1 - - - Payment request file handling - გადახდის მოთხოვნის ფაილის დამუშავება - - - Unverified payment requests to custom payment scripts are unsupported. - არავერიფიცირებული გადახდის მოთხოვნები გადახდის სამომხმარებლო სკრიპტებისათვის არ არის მხარდაჭერილი. - - - Refund from %1 - დაბრუნება %1-საგან - - - Error communicating with %1: %2 - ვერ გამოდის კავშირზე %1: %2 - - - Bad response from server %1 - ცუდი პასუხი სერვერისაგან %1 - - - Payment acknowledged - გადახდა მიღებულია - - - Network request error - ქსელური მოთხოვნის შეცდომა - - PeerTableModel @@ -1066,25 +661,6 @@ მიუწვდ. - - QRImageWidget - - &Save Image... - გამო&სახულების შენახვა... - - - &Copy Image - გამოსახულების &კოპირება - - - Save QR Code - QR-კოდის შენახვა - - - PNG Image (*.png) - PNG სურათი (*.png) - - RPCConsole @@ -1167,10 +743,6 @@ Out: გამავალი: - - Build date - შექმნის დრო - Debug log file დახვეწის ლოგ-ფაილი @@ -1274,18 +846,6 @@ Remove წაშლა - - Copy label - ნიშნულის კოპირება - - - Copy message - მესიჯის კოპირება - - - Copy amount - თანხის კოპირება - ReceiveRequestDialog @@ -1305,73 +865,6 @@ &Save Image... გამო&სახულების შენახვა... - - Request payment to %1 - %1-ის გადაზდის მოთხოვნა - - - Payment information - ინფორმაცია გადახდის შესახებ - - - URI - URI - - - Address - მისამართი - - - Amount - თანხა - - - Label - ნიშნული - - - Message - მესიჯი - - - Resulting URI too long, try to reduce the text for label / message. - URI ძალიან გრძელი გამოდის, შეამოკლეთ ნიშნულის/მესიჯის ტექსტი. - - - Error encoding URI into QR Code. - შედომა URI-ის QR-კოდში გადაყვანისას. - - - - RecentRequestsTableModel - - Date - თარიღი - - - Label - ნიშნული - - - Message - მესიჯი - - - Amount - თანხა - - - (no label) - (არ არის ნიშნული) - - - (no message) - (მესიჯები არ არის) - - - (no amount) - (თანხა არ არის) - SendCoinsDialog @@ -1463,86 +956,6 @@ S&end გაგ&ზავნა - - Confirm send coins - მონეტების გაგზავნის დადასტურება - - - %1 to %2 - %1-დან %2-ში - - - Copy quantity - რაოდენობის კოპირება - - - Copy amount - თანხის კოპირება - - - Copy fee - საკომისიოს კოპირება - - - Copy after fee - დამატებითი საკომისიოს კოპირება - - - Copy bytes - ბაიტების კოპირება - - - Copy priority - პრიორიტეტის კოპირება - - - Copy change - ხურდის კოპირება - - - or - ან - - - The amount to pay must be larger than 0. - გადახდის მოცულობა 0-ზე მეტი უნდა იყოს - - - The amount exceeds your balance. - თანხა აღემატება თქვენს ბალანსს - - - The total exceeds your balance when the %1 transaction fee is included. - საკომისიო %1-ის დამატების შემდეგ თანხა აჭარბებს თქვენს ბალანსს - - - Transaction creation failed! - შეცდომა ტრანსაქციის შექმნისას! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - ტრანსაქცია უარყოფილია! შესაძლოა მონეტების ნაწილი თქვენი საფულიდან უკვე გამოყენებულია, რაც შეიძლება მოხდეს wallet.dat-ის ასლის გამოყენებისას, როცა მონეტები გაიგზავნა სხვა ასლიდან, აქ კი არ არის გაგზავნილად მონიშნული. - - - Warning: Invalid Bitcoin address - ყურადღება: არასწორია Bitcoin-მისამართი - - - (no label) - (არ არის ნიშნული) - - - Warning: Unknown change address - ყურადღება: უცნობია ხურდის მისამართი - - - Are you sure you want to send? - დარწმუნებული ხართ, რომ გინდათ გაგზავნა? - - - added as transaction fee - დამატებულია საკომისიო - SendCoinsEntry @@ -1554,10 +967,6 @@ Pay &To: ადრესა&ტი: - - Enter a label for this address to add it to your address book - შეიყვანეთ ამ მისამართის ნიშნული მისამართების წიგნში დასამატებლად - &Label: ნიშნუ&ლი: @@ -1609,10 +1018,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core იხურება... - Do not shut down the computer until this window disappears. არ გამორთოთ კომპიუტერი ამ ფანჯრის გაქრობამდე. @@ -1688,69 +1093,9 @@ Reset all verify message fields ვერიფიკაციის ყველა ველის წაშლა - - Click "Sign Message" to generate signature - ხელმოწერის გენერირებისათვის დააჭირეთ "მესიჯის ხელმოწერა"-ს - - - The entered address is invalid. - შეყვანილი მისამართი არასწორია. - - - Please check the address and try again. - შეამოწმეთ მისამართი და სცადეთ ხელახლა. - - - The entered address does not refer to a key. - შეყვანილი მისამართი არ არის კავშირში გასაღებთან. - - - Wallet unlock was cancelled. - საფულის განბლოკვა შეწყვეტილია. - - - Private key for the entered address is not available. - ამ მისამართისათვის პირადი გასაღები მიუწვდომელია. - - - Message signing failed. - ვერ მოხერხდა მესიჯის ხელმოწერა. - - - Message signed. - მესიჯი ხელმოწერილია. - - - The signature could not be decoded. - ხელმოწერის დეკოდირება ვერ ხერხდება. - - - Please check the signature and try again. - შეამოწმეთ ხელმოწერა და სცადეთ ხელახლა. - - - The signature did not match the message digest. - ხელმოწერა არ შეესაბამება მესიჯის დაიჯესტს. - - - Message verification failed. - მესიჯის ვერიფიკაცია ვერ მოხერხდა. - - - Message verified. - მესიჯი ვერიფიცირებულია. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core-ს ავტორები - [testnet] [testnet] @@ -1763,426 +1108,16 @@ KB/s - - TransactionDesc - - Open until %1 - ღია იქნება სანამ %1 - - - conflicted - კონფლიქტშია - - - %1/offline - %1/გათიშულია - - - %1/unconfirmed - %1/დაუდასტურებელია - - - %1 confirmations - %1 დადასტურებულია - - - Status - სტატუსი - - - Date - თარიღი - - - Source - წყარო - - - Generated - გენერირებულია - - - From - გამგზავნი - - - To - მიმღები - - - own address - საკუთარი მისამართი - - - label - ნიშნული - - - Credit - კრედიტი - - - not accepted - უარყოფილია - - - Debit - დებიტი - - - Transaction fee - ტრანსაქციის საფასური - საკომისიო - - - Net amount - სუფთა თანხა - - - Message - მესიჯი - - - Comment - შენიშვნა - - - Transaction ID - ტრანსაქციის ID - - - Merchant - გამყიდველი - - - 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. - გენერირებული მონეტები გასაგზავნად მომწიფდება %1 ბლოკის შემდეგ. ეს ბლოკი გენერირების შემდეგ გავრცელებულ იქნა ქსელში ბლოკთა ჯაჭვზე დასამატებლად. თუ ის ვერ ჩაჯდა ჯაჭვში, მიეცემა სტატუსი "უარყოფილია" და ამ მონეტებს ვერ გამოიყენებთ. ასეთი რამ შეიძლება მოხდეს, თუ რომელიმე კვანძმა რამდენიმე წამით დაგასწროთ ბლოკის გენერირება. - - - Debug information - დახვეწის ინფორმაცია - - - Transaction - ტრანსაქცია - - - Inputs - ხარჯები - - - Amount - თანხა - - - true - ჭეშმარიტი - - - false - მცდარი - - - , has not been successfully broadcast yet - , დაგზავნა არ არის წარმატებით დასრულებული - - - unknown - უცნობია - - TransactionDescDialog - - Transaction details - ტრანსაქციის დეტალები - This pane shows a detailed description of the transaction ტრანსაქციის დაწვრილებითი აღწერილობა - - TransactionTableModel - - Date - თარიღი - - - Type - ტიპი - - - Immature (%1 confirmations, will be available after %2) - არ არის მომწიფებული (%1 დასტური, საჭიროა სულ %2) - - - Open until %1 - ღია იქნება სანამ %1 - - - Confirmed (%1 confirmations) - დადასტურებულია (%1დასტური) - - - This block was not received by any other nodes and will probably not be accepted! - ეს ბლოკი არ არის მიღებული არცერთი კვანძის მიერ და სავარაუდოდ უარყოფილია! - - - Generated but not accepted - გენერირებულია, მაგრამ უარყოფილია - - - Offline - ოფლაინშია - - - Label - ნიშნული - - - Unconfirmed - დაუდასტურებელია - - - Confirming (%1 of %2 recommended confirmations) - დადასტურებულია (%1, რეკომენდებულია %2) - - - Conflicted - კონფლიქტშია - - - Received with - შემოსულია - - - Received from - გამომგზავნი - - - Sent to - გაგზავნილია - - - Payment to yourself - გადახდილია საკუთარი თავისათვის - - - Mined - მოპოვებულია - - - (n/a) - (მიუწვდ.) - - - Transaction status. Hover over this field to show number of confirmations. - ტრანსაქციის სტატუსი. ველზე კურსორის შეყვანისას გამოჩნდება დასტურების რაოდენობა. - - - Date and time that the transaction was received. - ტრანსაქციის მიღების თარიღი და დრო. - - - Type of transaction. - ტრანსაქციის ტიპი. - - - Amount removed from or added to balance. - ბალანსიდან მოხსნილი ან დამატებული თანხა. - - - - TransactionView - - All - ყველა - - - Today - დღეს - - - This week - ამ კვირის - - - This month - ამ თვის - - - Last month - ბოლო თვის - - - This year - ამ წლის - - - Range... - შუალედი... - - - Received with - შემოსულია - - - Sent to - გაგზავნილია - - - To yourself - საკუთარი თავისათვის - - - Mined - მოპოვებულია - - - Other - სხვა - - - Enter address or label to search - შეიყვანეთ საძებნი მისამართი ან ნიშნული - - - Min amount - მინ. თანხა - - - Copy address - მისამართის კოპირება - - - Copy label - ნიშნულის კოპირება - - - Copy amount - თანხის კოპირება - - - Copy transaction ID - ტრანსაქციის ID-ს კოპირება - - - Edit label - ნიშნულის რედაქტირება - - - Show transaction details - ტრანსაქციის დეტალების ჩვენება - - - Export Transaction History - ტრანსაქციების ისტორიის ექსპორტი - - - Exporting Failed - ექსპორტი ვერ განხორციელდა - - - There was an error trying to save the transaction history to %1. - შეცდომა %1-ში ტრანსაქციების შენახვის მცდელობისას. - - - Exporting Successful - ეხპორტი განხორციელებულია - - - The transaction history was successfully saved to %1. - ტრანსაქციების ისტორია შენახულია %1-ში. - - - Comma separated file (*.csv) - CSV-ფაილი (*.csv) - - - Confirmed - დადასტურებულია - - - Date - თარიღი - - - Type - ტიპი - - - Label - ნიშნული - - - Address - მისამართი - - - ID - ID - - - Range: - შუალედი: - - - to - - - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - არ არის ჩატვირთული საფულე. - - - - WalletModel - - Send Coins - მონეტების გაგზავნა - - - - WalletView - - &Export - &ექსპორტი - - - Export the data in the current tab to a file - ამ ბარათიდან მონაცემების ექსპორტი ფაილში - - - Backup Wallet - საფულის არქივირება - - - Wallet Data (*.dat) - საფულის მონაცემები (*.dat) - - - Backup Failed - არქივირება ვერ მოხერხდა - - - There was an error trying to save the wallet data to %1. - შეცდომა %1-ში საფულის მონაცემების შენახვის მცდელობისას. - - - The wallet data was successfully saved to %1. - საფულის მონაცემები შენახულია %1-ში. - - - Backup Successful - არქივირება შესრულებულია - - bitcoin-core @@ -2213,6 +1148,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) გარედან შეერთებების დაშვება (ნაგულისხმევი: 1 თუ არ გამოიყენება -proxy ან -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის @@ -2233,10 +1172,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. ყურადღება: ჩვენ არ ვეთანხმებით ყველა პირს. შესაძლოა თქვენ ან სხვა კვანძებს განახლება გჭირდებათ. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - ყურადღება: wallet.dat დაზიანებულია! ორიგინალური wallet.dat შენახულია როგორც wallet.{timestamp}.bak %s-ში; თუ შეამჩნიეთ უზუსტობა ნაშთში ან ტრანსაქციებში, აღადგინეთ არქივიდან. - <category> can be: <category> შეიძლება იყოს: @@ -2321,10 +1256,6 @@ Wallet options: სფულის ოპციები: - - You need to rebuild the database using -reindex to change -txindex - საჭიროა ბაზის ხელახალი აგება, გამოიყენეთ -reindex რათა შეცვალოთ -txindex - Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) ბრძანების შესრულება შესაბამისი უწყების მიღებისას ან როცა შეინიშნება საგრძნობი გახლეჩა (cmd-ში %s შეიცვლება მესიჯით) @@ -2333,26 +1264,10 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d) - - Cannot resolve -whitebind address: '%s' - ვერ ხერხდება -whitebind მისამართის გარკვევა: '%s' - Information ინფორმაცია - - Invalid amount for -maxtxfee=<amount>: '%s' - დაუშვებელი მნიშვნელობა -pmaxtxfee<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - დაუშვებელი მნიშვნელობა -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - დაუშვებელი მნიშვნელობა -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად @@ -2389,10 +1304,6 @@ Zapping all transactions from wallet... ტრანსაქციების ჩახსნა საფულიდან... - - wallet.dat corrupt, salvage failed - wallet.dat დაზიანებულია, აღდგენა ვერ მოხერხდა - Password for JSON-RPC connections პაროლი JSON-RPC-შეერთებისათვის @@ -2401,10 +1312,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) კომანდის შესრულება უკეთესი ბლოკის გამოჩენისას (%s კომანდაში ჩანაცვლდება ბლოკის ჰეშით) - - This help message - ეს ტექსტი - Allow DNS lookups for -addnode, -seednode and -connect DNS-ძებნის დაშვება -addnode, -seednode და -connect-სათვის @@ -2413,14 +1320,6 @@ Loading addresses... მისამართების ჩატვირთვა... - - Error loading wallet.dat: Wallet corrupted - არ იტვირთება wallet.dat: საფულე დაზიანებულია - - - Error loading wallet.dat - არ იტვირთება wallet.dat - Invalid -proxy address: '%s' არასწორია მისამართი -proxy: '%s' @@ -2429,18 +1328,6 @@ Unknown network specified in -onlynet: '%s' -onlynet-ში მითითებულია უცნობი ქსელი: '%s' - - Cannot resolve -bind address: '%s' - ვერ ხერხდება -bind მისამართის გარკვევა: '%s' - - - Cannot resolve -externalip address: '%s' - ვერ ხერხდება -externalip მისამართის გარკვევა: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - დაუშვებელი მნიშვნელობა -paytxfee=<amount>: '%s' - Insufficient funds არ არის საკმარისი თანხა diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index cfa19d13f..ff0252126 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -25,25 +25,6 @@ &Delete Жою - - Comma separated file (*.csv) - Үтірмен бөлінген текст (*.csv) - - - - AddressTableModel - - Label - таңба - - - Address - Адрес - - - (no label) - (таңбасыз) - AskPassphraseDialog @@ -59,31 +40,7 @@ Repeat new passphrase Жаңа құпия сөзді қайта енгізу - - Encrypt wallet - Әмиянді шифрлау - - - This operation needs your wallet passphrase to unlock the wallet. - Бұл операциясы бойынша сіздің әмиянізді қоршаудан шығару үшін әмиянның құпия сөзі керек - - - Unlock wallet - Әмиянізді қоршаудан шығару - - - This operation needs your wallet passphrase to decrypt the wallet. - Бұл операциясы бойынша сіздің әмиянізді шифрлап тастау үшін әмиянның құпия сөзі керек - - - Decrypt wallet - Әмиянізді шифрлап тастау - - - Change passphrase - Құпия сөзді өзгерту - - + BanTableModel @@ -174,9 +131,6 @@ Жаңартылған - - ClientModel - CoinControlDialog @@ -219,15 +173,7 @@ Priority Басымдық - - no - жоқ - - - (no label) - (таңбасыз) - - + EditAddressDialog @@ -238,7 +184,7 @@ &Address Адрес - + FreespaceChecker @@ -265,9 +211,6 @@ OverviewPage - - PaymentServer - PeerTableModel @@ -278,9 +221,6 @@ Саны - - QRImageWidget - RPCConsole @@ -297,37 +237,6 @@ ReceiveRequestDialog - - Address - Адрес - - - Amount - Саны - - - Label - таңба - - - - RecentRequestsTableModel - - Date - Күні - - - Label - таңба - - - Amount - Саны - - - (no label) - (таңбасыз) - SendCoinsDialog @@ -351,10 +260,6 @@ Dust: Шаң - - (no label) - (таңбасыз) - SendCoinsEntry @@ -375,70 +280,12 @@ TrafficGraphWidget - - TransactionDesc - - Date - Күні - - - Amount - Саны - - TransactionDescDialog - - TransactionTableModel - - Date - Күні - - - Label - таңба - - - - TransactionView - - Comma separated file (*.csv) - Үтірмен бөлінген файл (*.csv) - - - Confirmed - Растық - - - Date - Күні - - - Label - таңба - - - Address - Адрес - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - Экспорт - - bitcoin-core diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 34aeafcd5..11e5d35af 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -25,10 +25,6 @@ C&lose 닫기(&L) - - &Copy Address - 주소 복사(&C) - Delete the currently selected address from the list 현재 목록에 선택한 주소 삭제 @@ -45,73 +41,6 @@ &Delete 삭제(&D) - - Choose the address to send coins to - 코인을 보내실 주소를 선택하세요 - - - Choose the address to receive coins with - 코인을 받으실 주소를 선택하세요 - - - C&hoose - 선택하기(&H) - - - Sending addresses - 타인 계좌 주소목록 - - - Receiving addresses - 내 계좌 주소목록 - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 비트코인을 보내는 계좌 주소입니다. 코인을 보내기 전에 잔고와 받는 주소를 항상 확인하세요. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - 비트코인을 받을 수 있는 계좌 주소입니다. 매 거래마다 새로운 주소 사용을 권장합니다. - - - Copy &Label - 라벨 복사(&L) - - - &Edit - 편집(&E) - - - Export Address List - 주소 목록 내보내기 - - - Comma separated file (*.csv) - 쉼표로 구분된 파일(*.csv) - - - Exporting Failed - 내보내기 실패 - - - There was an error trying to save the address list to %1. Please try again. - %1으로 주소 목록을 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요. - - - - AddressTableModel - - Label - 라벨 - - - Address - 주소 - - - (no label) - (라벨 없음) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase 새로운 암호 재확인 - - Encrypt wallet - 지갑 암호화 - - - This operation needs your wallet passphrase to unlock the wallet. - 이 작업을 실행하려면 사용자 지갑의 암호가 필요합니다. - - - Unlock wallet - 지갑 잠금해제 - - - This operation needs your wallet passphrase to decrypt the wallet. - 이 작업은 지갑을 해독하기 위해 사용자 지갑의 암호가 필요합니다. - - - Decrypt wallet - 지갑 해독 - - - Change passphrase - 암호 변경 - - - Confirm wallet encryption - 지갑 암호화 승인 - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 경고: 만약 암호화 된 지갑의 비밀번호를 잃어버릴 경우, <b>모든 비트코인들을 잃어버릴 수 있습니다</b>! - - - Are you sure you wish to encrypt your wallet? - 지갑 암호화를 허용하시겠습니까? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - 비트코인 코어는 암호화 과정을 마무리 하기 위해 종료됩니다. 당신의 지갑을 암호화하는 것이 여러분의 컴퓨터에 해를 끼치는 프로그램으로부터 여러분의 비트코인을 완전히 보호해주지는 못한다는 사실을 기억하십시오. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암호화 된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암호화 된 지갑을 사용하시기 바랍니다. - - - Warning: The Caps Lock key is on! - 경고: Caps Lock키가 켜져있습니다! - - - Wallet encrypted - 지갑 암호화 완료 - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - 지갑에 새로운 비밀문구를 입력하세요.<br/>비밀문구를 <b>열 개 이상의 무작위 글자</b> 혹은 <b>여덟개 이상의 단어로<b> 정하세요. - - - Enter the old passphrase and new passphrase to the wallet. - 지갑의 기존 암호와 새로운 암호를 입력해주세요. - - - Wallet encryption failed - 지갑 암호화 실패 - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 지갑 암호화는 내부 오류로 인해 실패했습니다. 당신의 지갑은 암호화 되지 않았습니다. - - - The supplied passphrases do not match. - 지정한 암호가 일치하지 않습니다. - - - Wallet unlock failed - 지갑을 열지 못했습니다. - - - The passphrase entered for the wallet decryption was incorrect. - 지갑 해독을 위한 암호가 틀렸습니다. - - - Wallet decryption failed - 지갑 해독에 실패하였습니다. - - - Wallet passphrase was successfully changed. - 지갑 비밀번호가 성공적으로 변경되었습니다. - BanTableModel @@ -305,14 +146,6 @@ Open &URI... &URI 열기... - - Bitcoin Core client - 비트코인 코어 클라이언트 - - - Importing blocks from disk... - 디스크에서 블록 가져오는 중... - Reindexing blocks on disk... 디스크에서 블록 다시 색인중... @@ -357,10 +190,6 @@ &Receive 받기(&R) - - Show information about Bitcoin Core - 비트코인 코어에 관한 정보입니다. - &Show / Hide 보이기/숨기기(&S) @@ -397,22 +226,10 @@ Tabs toolbar 툴바 색인표 - - Bitcoin Core - 비트코인 코어 - Request payments (generates QR codes and bitcoin: URIs) 지불 요청하기 (QR코드와 비트코인이 생성됩니다: URIs) - - &About Bitcoin Core - 비트코인 코어 소개(&A) - - - Modify configuration options for Bitcoin Core - 비트코인 코어에 대한 설정을 수정합니다. - Show the list of used sending addresses and labels 한번 이상 사용된 보내는 주소와 주소 제목의 목록을 보여줍니다. @@ -429,10 +246,6 @@ &Command-line options 명령줄 옵션(&C) - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 사용할 수 있는 비트코인 명령줄 옵션 목록을 가져오기 위해 Bitcoin-Qt 도움말 메시지를 표시합니다. - %n active connection(s) to Bitcoin network 비트코인 네트워크에 %n개의 연결이 활성화되어 있습니다. @@ -544,13 +357,6 @@ 지갑이 암호화 되었고 현재 잠겨져 있습니다 - - ClientModel - - Network Alert - 네트워크 경고 - - CoinControlDialog @@ -629,150 +435,6 @@ Priority 우선순위 - - Copy address - 주소 복사하기 - - - Copy label - 라벨 복사하기 - - - Copy amount - 거래액 복사 - - - Copy transaction ID - 거래 아이디 복사 - - - Lock unspent - 비트코인이 사용되지 않은 주소를 잠금 처리합니다. - - - Unlock unspent - 비트코인이 사용되지 않은 주소를 잠금 해제합니다. - - - Copy quantity - 수량 복사 - - - Copy fee - 수수료 복사 - - - Copy after fee - 수수료 이후 복사 - - - Copy bytes - bytes 복사 - - - Copy priority - 우선도 복사 - - - Copy dust - 더스트 복사 - - - Copy change - 잔돈 복사 - - - highest - 아주 높음 - - - higher - 보다 높음 - - - high - 높음 - - - medium-high - 약간 높음 - - - medium - 보통 - - - low-medium - 약간 낮음 - - - low - 낮음 - - - lower - 보다 낮음 - - - lowest - 아주 낮음 - - - (%1 locked) - (%1 잠금) - - - none - 없음 - - - This label turns red if the transaction size is greater than 1000 bytes. - 이 라벨은 1000바이트 이상의 거래가 이루어지면 붉게 변합니다. - - - This label turns red if the priority is smaller than "medium". - 이 라벨은 우선순위가 "보통" 이하인 경우 붉게 변합니다. - - - This label turns red if any recipient receives an amount smaller than %1. - 이 라벨은 수령인이 받은 액수가 잔고의 %1보다 작으면 붉게 변합니다. - - - Can vary +/- %1 satoshi(s) per input. - 입력마다 +/- %1 사토시가 변할 수 있습니다. - - - yes - - - - no - 아니요 - - - This means a fee of at least %1 per kB is required. - 이 뜻은 최소한 1kB 당 %1의 수수료가 필요하다는 의미입니다. - - - Can vary +/- 1 byte per input. - 입력마다 +/- 1 바이트가 변할 수 있습니다. - - - Transactions with higher priority are more likely to get included into a block. - 우선 순위가 높은 거래의 경우 블럭에 포함될 가능성이 더 많습니다. - - - (no label) - (라벨 없음) - - - change from %1 (%2) - ~로부터 변경 %1 (%2) - - - (change) - (잔돈) - EditAddressDialog @@ -796,38 +458,6 @@ &Address 주소(&A) - - New receiving address - 새로 받는 주소 - - - New sending address - 새로 보내는 주소 - - - Edit receiving address - 받는 주소 편집 - - - Edit sending address - 보내는 주소 편집 - - - The entered address "%1" is already in the address book. - 입력된 주소는"%1" 이미 주소록에 있습니다. - - - The entered address "%1" is not a valid Bitcoin address. - 입력한 "%1" 주소는 올바른 비트코인 주소가 아닙니다. - - - Could not unlock wallet. - 지갑을 열 수 없습니다. - - - New key generation failed. - 새로운 키 생성이 실패하였습니다. - FreespaceChecker @@ -854,10 +484,6 @@ HelpMessageDialog - - Bitcoin Core - 비트코인 코어 - version 버전 @@ -866,10 +492,6 @@ (%1-bit) (%1-비트) - - About Bitcoin Core - 비트코인 코어 소개 - Command-line options 명령줄 옵션 @@ -906,29 +528,13 @@ Show splash screen on startup (default: %u) 실행시 시작화면 보기 (기본값: %u) - - Reset all settings changes made over the GUI - GUI를 통해 수정된 모든 설정을 초기화 - - + Intro Welcome 환영합니다 - - Welcome to Bitcoin Core. - 비트코인 코어에 오신것을 환영합니다. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - 프로그램이 처음으로 실행되고 있습니다. 비트코인 코어가 어디에 데이터를 저장할지 선택할 수 있습니다. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - 비트코인 코어가 블럭체인의 복사본을 다운로드 저장합니다. 적어도 %1GB의 데이터가 이 폴더에 저장되며 시간이 경과할수록 점차 증가합니다. 그리고 지갑 또한 이 폴더에 저장됩니다. - Use the default data directory 기본 데이터 폴더를 사용하기 @@ -937,10 +543,6 @@ Use a custom data directory: 커스텀 데이터 폴더 사용: - - Bitcoin Core - 비트코인 코어 - Error: Specified data directory "%1" cannot be created. 오류: "%1" 지정한 데이터 디렉토리를 생성할 수 없습니다. @@ -976,10 +578,6 @@ Select payment request file 지불 요청 파일을 선택하세요 - - Select payment request file to open - 지불 요청 파일을 열기 위해서 선택하세요 - OptionsDialog @@ -1019,10 +617,6 @@ 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. 창을 닫으면 종료 대신 트레이로 보내기. 이 옵션을 활성화하면 메뉴에서 종료를 선택한 후에만 어플리케이션이 종료됩니다. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - 사용자 인터페이스 언어를 여기서 설정할 수 있습니다. 이 설정은 Bitcoin Core를 다시 시작할 때 적용됩니다. - 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 |. 서드-파티 URLs (예. 블록 탐색기)는 거래 탭의 컨텍스트 메뉴에 나타납니다. URL의 %s는 트랜잭션 해시값으로 대체됩니다. 여러 URLs는 수직 바 | 에서 나누어 집니다. @@ -1047,14 +641,6 @@ &Network 네트워크(&N) - - Automatically start Bitcoin Core after logging in to the system. - 시스템 로그인 후 자동으로 Bitcoin Core를 실행합니다. - - - &Start Bitcoin Core on system login - 시스템 로그인 후 Bitcoin Core 시작(&S) - (0 = auto, <0 = leave that many cores free) (0 = 자동, <0 = 지정된 코어 개수만큼 사용 안함) @@ -1283,97 +869,6 @@ 모니터링 지갑의 현재 잔액 - - PaymentServer - - URI handling - URI 조작중 - - - Invalid payment address %1 - 잘못된 지불 주소입니다 %1 - - - Payment request rejected - 지불 요청이 거부됨 - - - Payment request network doesn't match client network. - 지급 요청 네트워크가 클라이언트 네트워크와 일치되지 않습니다. - - - Payment request is not initialized. - 지불 요청이 초기화 되지 않았습니다. - - - Requested payment amount of %1 is too small (considered dust). - 요청한 금액 %1의 양이 너무 적습니다. (스팸성 거래로 간주) - - - Payment request error - 지불 요청 오류 - - - Cannot start bitcoin: click-to-pay handler - 비트코인을 시작할 수 없습니다: 지급제어기를 클릭하시오 - - - Payment request fetch URL is invalid: %1 - 대금 청구서의 URL이 올바르지 않습니다: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI의 파싱에 문제가 발생했습니다. 잘못된 비트코인 주소나 URI 파라미터 구성에 오류가 존재할 수 있습니다. - - - Payment request file handling - 지불이 파일 처리를 요청합니다 - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - 지불 요청 파일을 읽을 수 없습니다. 이것은 잘못된 지불 요청 파일에 의해 발생하는 오류일 수 있습니다. - - - Payment request expired. - 지불 요청이 만료됨. - - - Unverified payment requests to custom payment scripts are unsupported. - 임의로 변경한 결제 스크립트 기반의 대금 청구서 양식은 검증되기 전까지는 지원되지 않습니다. - - - Invalid payment request. - 잘못된 지불 요청. - - - Refund from %1 - %1 으로부터의 환불 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - 지불 요청 %1은 너무 큽니다 (%2 바이트, %3 바이트까지 허용됩니다). - - - Error communicating with %1: %2 - %1과 소통하는데 오류: %2 - - - Payment request cannot be parsed! - 지불요청을 처리할 수 없습니다. - - - Bad response from server %1 - 서버로 부터 반응이 없습니다 %1 - - - Payment acknowledged - 지불이 승인됨 - - - Network request error - 네트워크 요청 오류 - - PeerTableModel @@ -1428,25 +923,6 @@ %1 ms - - QRImageWidget - - &Save Image... - 이미지 저장(&S)... - - - &Copy Image - 이미지 복사(&C) - - - Save QR Code - QR코드 저장 - - - PNG Image (*.png) - PNG 이미지 (*.png) - - RPCConsole @@ -1513,10 +989,6 @@ Memory usage 메모리 사용량 - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - 현재의 데이터폴더에서 비트코인 디버그 파일을 엽니다. 용량이 큰 로그 파일은 몇 초가 걸릴 수 있습니다. - Received 받음 @@ -1633,10 +1105,6 @@ Out: Out: - - Build date - 빌드 날짜 - Debug log file 로그 파일 디버그 @@ -1673,10 +1141,6 @@ &Unban Node 노드 추방 취소(&U) - - Welcome to the Bitcoin Core RPC console. - 비트코인 RPC 콘솔에 오신걸 환영합니다 - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 <b>Ctrl-L</b>키를 사용하십시오. @@ -1804,18 +1268,6 @@ Remove 삭제 - - Copy label - 라벨 복사하기 - - - Copy message - 메시지 복사 - - - Copy amount - 거래액 복사 - ReceiveRequestDialog @@ -1835,73 +1287,6 @@ &Save Image... 이미지 저장(&S)... - - Request payment to %1 - %1에 지불을 요청했습니다 - - - Payment information - 지불 정보 - - - URI - URI - - - Address - 주소 - - - Amount - 거래액 - - - Label - 라벨 - - - Message - 메시지 - - - Resulting URI too long, try to reduce the text for label / message. - URI 결과가 너무 길음, 라벨/메세지의 글을 줄이도록 하세요. - - - Error encoding URI into QR Code. - QR코드 인코딩 오류 - - - - RecentRequestsTableModel - - Date - 날짜 - - - Label - 라벨 - - - Message - 메시지 - - - Amount - 거래액 - - - (no label) - (라벨 없음) - - - (no message) - (메세지가 없습니다) - - - (no amount) - (거래액 없음) - SendCoinsDialog @@ -2021,14 +1406,6 @@ fast 빠름 - - Send as zero-fee transaction if possible - 가능한 경우 수수료 없이 보내기 - - - (confirmation may take longer) - (거래 검증이 오래 걸릴 수 있습니다) - Send to multiple recipients at once 다수의 수령인들에게 한번에 보내기 @@ -2061,118 +1438,6 @@ S&end 보내기(&E) - - Confirm send coins - 코인 전송을 확인 - - - %1 to %2 - %1을(를) %2(으)로 - - - Copy quantity - 수량 복사 - - - Copy amount - 거래액 복사 - - - Copy fee - 수수료 복사 - - - Copy after fee - 수수료 이후 복사 - - - Copy bytes - bytes 복사 - - - Copy priority - 우선도 복사 - - - Copy change - 잔돈 복사 - - - Total Amount %1 - 총 액수 %1 - - - or - 또는 - - - The amount to pay must be larger than 0. - 지불하는 금액은 0 보다 커야 합니다. - - - The amount exceeds your balance. - 잔고를 초과하였습니다. - - - The total exceeds your balance when the %1 transaction fee is included. - %1 의 거래수수료를 포함하면 잔고를 초과합니다. - - - Transaction creation failed! - 거래를 생성하는 것을 실패하였습니다 - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - 거래가 거부되었습니다. 몇몇 코인들이 지갑에서 이미 사용된 경우, 예를 들어 코인을 이미 사용한 wallet.dat를 복사해서 사용한 경우 지금 지갑에 기록이 안되있어 이런 일이 생길 수 있습니다. - - - A fee higher than %1 is considered an absurdly high fee. - %1 보다 높은 수수료는 너무 높은 수수료 입니다. - - - Payment request expired. - 지불 요청이 만료됨. - - - Pay only the required fee of %1 - 오직 %1 만의 수수료를 지불하기 - - - Estimated to begin confirmation within %n block(s). - %n 블록 안에 거래검증이 시작 될것으로 예상합니다. - - - The recipient address is not valid. Please recheck. - 수령인 주소가 정확하지 않습니다. 재확인 바랍니다 - - - Duplicate address found: addresses should only be used once each. - 두개 이상의 주소입니다: 한번에 하나의 주소에만 작업할 수 있습니다. - - - Warning: Invalid Bitcoin address - 경고: 잘못된 비트코인주소입니다 - - - (no label) - (라벨 없음) - - - Warning: Unknown change address - 경고: 알려지지 않은 주소변경입니다 - - - Copy dust - 더스트 복사 - - - Are you sure you want to send? - 정말로 보내시겠습니까? - - - added as transaction fee - 거래 수수료로 추가됨 - SendCoinsEntry @@ -2184,10 +1449,6 @@ Pay &To: 송금할 대상(&T) : - - Enter a label for this address to add it to your address book - 주소록에 추가하려면 라벨을 입력하세요 - &Label: 라벨(&L) @@ -2259,10 +1520,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core이 종료 중입니다... - Do not shut down the computer until this window disappears. 창이 사라지기 전까지 컴퓨터를 끄지마시오. @@ -2354,69 +1611,9 @@ Reset all verify message fields 모든 검증 메시지 필드 재설정 - - Click "Sign Message" to generate signature - 서명을 만들려면 "메시지 서명"을 누르십시오 - - - The entered address is invalid. - 입력한 주소가 잘못되었습니다. - - - Please check the address and try again. - 주소를 확인하고 다시 시도하십시오. - - - The entered address does not refer to a key. - 입력한 주소는 키에서 참조하지 않습니다. - - - Wallet unlock was cancelled. - 지갑 잠금 해제를 취소했습니다. - - - Private key for the entered address is not available. - 입력한 주소에 대한 개인키가 없습니다. - - - Message signing failed. - 메시지 서명에 실패했습니다. - - - Message signed. - 메시지를 서명했습니다. - - - The signature could not be decoded. - 서명을 해독할 수 없습니다. - - - Please check the signature and try again. - 서명을 확인하고 다시 시도하십시오. - - - The signature did not match the message digest. - 메시지 다이제스트와 서명이 일치하지 않습니다. - - - Message verification failed. - 메시지 검증에 실패했습니다. - - - Message verified. - 메시지를 검증했습니다. - SplashScreen - - Bitcoin Core - 비트코인 코어 - - - The Bitcoin Core developers - 비트코인코어 개발자들 - [testnet] [테스트넷] @@ -2429,422 +1626,13 @@ KB/s - - TransactionDesc - - Open until %1 - %1 까지 열림 - - - conflicted - 충돌 - - - %1/offline - %1/오프라인 - - - %1/unconfirmed - %1/미확인 - - - %1 confirmations - %1 확인됨 - - - Status - 상태 - - - , broadcast through %n node(s) - %n 노드를 거쳐 전파합니다. - - - Date - 날짜 - - - Source - 소스 - - - Generated - 생성하다 - - - From - 으로부터 - - - To - 에게 - - - own address - 자신의 주소 - - - watch-only - 모니터링 지갑 - - - label - 라벨 - - - Credit - 예금 - - - matures in %n more block(s) - %n개 블럭 후에 코인 숙성이 완료됩니다. - - - not accepted - 허용되지 않는다 - - - Debit - 차변 - - - Total debit - 총 출금액 - - - Total credit - 총 입금액 - - - Transaction fee - 송금 수수료 - - - Net amount - 총 거래액 - - - Message - 메시지 - - - Comment - 설명 - - - Transaction ID - 아이디 - - - Merchant - 상인 - - - 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. - 신규 채굴된 코인이 사용되기 위해서는 %1 개의 블럭이 경과되어야 합니다. 블럭을 생성할 때 블럭체인에 추가되도록 네트워크에 전파되는 과정을 거치는데, 블럭체인에 포함되지 못하고 실패한다면 해당 블럭의 상태는 '미승인'으로 표현되고 비트코인 또한 사용될 수 없습니다. 이 현상은 다른 노드가 비슷한 시간대에 동시에 블럭을 생성할 때 종종 발생할 수 있습니다. - - - Debug information - 디버깅 정보 - - - Transaction - 송금 - - - Inputs - 입력 - - - Amount - 거래액 - - - true - - - - false - 거짓 - - - , has not been successfully broadcast yet - . 아직 성공적으로 통보하지 않음 - - - Open for %n more block(s) - %n 개의 추가 블록을 읽습니다. - - - unknown - 알수없음 - - TransactionDescDialog - - Transaction details - 거래 세부 내역 - This pane shows a detailed description of the transaction 이 창은 거래의 세부내역을 보여줍니다 - - TransactionTableModel - - Date - 날짜 - - - Type - 종류 - - - Immature (%1 confirmations, will be available after %2) - 충분히 숙성되지 않은 상태 (%1 승인, %2 후에 사용 가능합니다) - - - Open for %n more block(s) - %n 개의 추가 블록을 읽습니다. - - - Open until %1 - %1 까지 열림 - - - Confirmed (%1 confirmations) - 확인됨 (%1 확인됨) - - - This block was not received by any other nodes and will probably not be accepted! - 이 블럭은 다른 노드로부터 받지 않아 허용되지 않을 것임. - - - Generated but not accepted - 생성되었으나 거절됨 - - - Offline - 오프라인 - - - Label - 라벨 - - - Unconfirmed - 미확인 - - - Confirming (%1 of %2 recommended confirmations) - 승인 중 (권장되는 승인 회수 %2 대비 현재 승인 수 %1) - - - Conflicted - 충돌 - - - Received with - 보낸 주소 - - - Received from - 보낸 주소 - - - Sent to - 받는 주소 - - - Payment to yourself - 자신에게 지불 - - - Mined - 채굴 - - - watch-only - 모니터링 지갑 - - - (n/a) - (없음) - - - Transaction status. Hover over this field to show number of confirmations. - 거래상황. 마우스를 올리면 검증횟수가 표시됩니다. - - - Date and time that the transaction was received. - 거래가 이루어진 날짜와 시각. - - - Type of transaction. - 거래의 종류. - - - Whether or not a watch-only address is involved in this transaction. - 이 트랜잭션에 모니터링 지갑를 포함할지의 여부입니다. - - - User-defined intent/purpose of the transaction. - 트랜잭션에 대한 사용자 정의 intent/purpose - - - Amount removed from or added to balance. - 변경된 잔고. - - - - TransactionView - - All - 전체 - - - Today - 오늘 - - - This week - 이번주 - - - This month - 이번 달 - - - Last month - 지난 달 - - - This year - 올 해 - - - Range... - 범위... - - - Received with - 보낸 주소 - - - Sent to - 받는 주소 - - - To yourself - 자기거래 - - - Mined - 채굴 - - - Other - 기타 - - - Enter address or label to search - 검색하기 위한 주소 또는 표 입력 - - - Min amount - 최소 거래액 - - - Copy address - 주소 복사하기 - - - Copy label - 라벨 복사하기 - - - Copy amount - 거래액 복사 - - - Copy transaction ID - 거래 아이디 복사 - - - Copy raw transaction - 로우 트랜잭션 복사 - - - Edit label - 라벨 수정하기 - - - Show transaction details - 거래 내역 확인 - - - Export Transaction History - 거래 기록 내보내기 - - - Watch-only - 모니터링 지갑 - - - Exporting Failed - 내보내기 실패 - - - There was an error trying to save the transaction history to %1. - %1으로 거래 기록을 저장하는데 오류가 있었습니다. - - - Exporting Successful - 내보내기 성공 - - - The transaction history was successfully saved to %1. - 거래 기록이 성공적으로 %1에 저장되었습니다. - - - Comma separated file (*.csv) - 각각의 파일에 쉼표하기(*.csv) - - - Confirmed - 확인됨 - - - Date - 날짜 - - - Type - 종류 - - - Label - 라벨 - - - Address - 주소 - - - ID - 아이디 - - - Range: - 범위: - - - to - 상대방 - - UnitDisplayStatusBarControl @@ -2852,55 +1640,6 @@ 거래액을 표시하는 단위. 클릭해서 다른 단위를 선택할 수 있습니다. - - WalletFrame - - No wallet has been loaded. - 지갑 불러오기가 안됩니다 - - - - WalletModel - - Send Coins - 코인들 보내기 - - - - WalletView - - &Export - 내보내기(&E) - - - Export the data in the current tab to a file - 현재 탭에 있는 데이터를 파일로 내보내기 - - - Backup Wallet - 지갑 백업 - - - Wallet Data (*.dat) - 지갑 데이터(*.dat) - - - Backup Failed - 백업 실패 - - - There was an error trying to save the wallet data to %1. - 지갑 데이터를 %1 폴더에 저장하는 동안 오류가 발생했습니다. - - - The wallet data was successfully saved to %1. - 지갑 정보가 %1에 성공적으로 저장되었습니다 - - - Backup Successful - 백업 성공 - - bitcoin-core @@ -2927,14 +1666,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. <category>가 제공되지 않거나 <category> = 1 인 경우, 모든 디버깅 정보를 출력 - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - 하나의 지갑 트랜잭션에서의 총 수수료(%s)의 최대치; 너무 낮게 설정하면 큰 트랜잭션이 중지 됩니다 (기본값: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - 컴퓨터의 날짜와 시간이 올바른지 확인하십시오! 시간이 잘못되면 비트코인은 제대로 동작하지 않습니다. - Prune configured below the minimum of %d MiB. Please use a higher number. 블록 축소가 최소치의 %d MiB 밑으로 설정되어 있습니다. 더 높은 값을 사용해 보세요. @@ -2975,6 +1706,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 외부 접속을 승인합니다 + + Bitcoin Core + 비트코인 코어 + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee은 너무 높습니다! 이것은 수수료 예측을 이용할 수 없을 때 지불되는 트랜잭션 수수료입니다. @@ -3019,14 +1754,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - 이 컴퓨터의 %s에 바인딩 할 수 없습니다. 아마도 비트코인이 실행중인 것 같습니다. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - 지원하지 않는 인수 -whitelistalwaysrelay 는 무시됩니다, -whitelistrelay 나 -whitelistforcerelay 를 사용해 주세요. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: 열려있거나 -proxy 옵션을 사용하지 않을 시 1) @@ -3043,18 +1770,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 경고 : 모든 네트워크가 동의해야 하나, 일부 채굴자들에게 문제가 있는 것으로 보입니다. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - 경고: 알려지지 않은 버전의 블록이 채굴되었습니다. 알려지지 않은 규칙이 적용되었을 가능성이 있습니다. - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 경고: 현재 비트코인 버전이 다른 네트워크 참여자들과 동일하지 않는 것 같습니다. 당신 또는 다른 참여자들이 동일한 비트코인 버전으로 업그레이드 할 필요가 있습니다. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - 경고 : wallet.dat가 손상되어 데이터가 복구되었습니다. 원래의 wallet.dat 파일은 %s 후에 wallet.{timestamp}.bak 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 설정된 넷마스크 혹은 IP 주소로 화이트리스트에 포함된 피어에 접속합니다. 이 설정은 복수로 지정 할 수 있습니다. @@ -3236,12 +1955,12 @@ 지갑 %s는 데이터 디렉토리 %s 밖에 위치합니다. - Wallet options: - 지갑 옵션: + Wallet debugging/testing options: + 지갑 디버깅/테스트 옵션: - You need to rebuild the database using -reindex to change -txindex - -txindex를 바꾸기 위해서는 -reindex를 사용해서 데이터베이스를 재구성해야 합니다. + Wallet options: + 지갑 옵션: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3255,10 +1974,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) 선택된 주소로 고정하여 JSON-RPC 연결을 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. 이 옵션은 복수로 지정 할수 있습니다. (기본값: 모든 인터페이스에 고정) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - 데이터 디렉토리 %s에 락을 걸 수 없었습니다. 비트코인 코어가 이미 실행 중인 것으로 보입니다. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) umask 077 대신 시스템 기본 퍼미션으로 새 파일을 만듭니다 (지갑 기능이 비활성화 상태에서만 유효합니다) @@ -3303,10 +2018,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - 코인 생성에 대한 스레드 갯수 설정 (-1 = 모든 코어, 기본값: %d) - The transaction amount is too small to send after the fee has been deducted 거래액이 수수료를 지불하기엔 너무 작습니다 @@ -3331,34 +2042,14 @@ Accept public REST requests (default: %u) 공개 REST 요청을 허가 (기본값: %u) - - Activating best chain... - 최적 블록 체인을 활성화하는중... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - 시작시 망가진 wallet.dat에서 개인키 복원을 시도 - Automatically create Tor hidden service (default: %d) Tor서비스를 자동적으로 생성 (기본값: %d) - - Cannot resolve -whitebind address: '%s' - -whitebind 주소를 확인할 수 없습니다: '%s' - Connect through SOCKS5 proxy SOCK5 프록시를 통해 연결 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i The Bitcoin Core Developers - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - wallet.dat 불러오기 오류: 최신 버전의 Bitcoin Core이 필요합니다. - Error reading from database, shutting down. 블록 데이터베이스를 불러오는데 오류가 발생하였습니다, 종료됩니다. @@ -3371,22 +2062,6 @@ Information 정보 - - Initialization sanity check failed. Bitcoin Core is shutting down. - 무결성 확인 초기화가 실패했습니다. Bitcoin Core가 종료됩니다. - - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<amount>에 대한 양이 잘못되었습니다: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - 노드로 전달하기 위한 최저 거래 수수료가 부족합니다. - minrelaytxfee=<amount>: '%s' - - - - Invalid amount for -mintxfee=<amount>: '%s' - 최저 거래 수수료가 부족합니다. -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) 유효하지 않은 금액 -paytxfee=<amount>: "%s" (최소 %s 이상이어야 됨) @@ -3411,14 +2086,6 @@ RPC server options: RPC 서버 설정 - - Rebuild block chain index from current blk000??.dat files on startup - 현재의 blk000??.dat 파일들로부터 블록체인 색인을 재구성합니다. - - - Receive and display P2P network alerts (default: %u) - P2P 네트워크 알림을 수신후 표시합니다 (기본값: %u) - Reducing -maxconnections from %d to %d, because of system limitations. 시스템 한계로 인하여 -maxconnections를 %d 에서 %d로 줄였습니다. @@ -3487,10 +2154,6 @@ Username for JSON-RPC connections JSON-RPC 연결에 사용할 사용자 이름 - - Wallet needed to be rewritten: restart Bitcoin Core to complete - 지갑을 새로 써야 합니다: 완료하기 위하여 Bitcoin Core을 다시 시작하십시오. - Warning 경고 @@ -3511,10 +2174,6 @@ ZeroMQ notification options: ZeroMQ 알림 옵션: - - wallet.dat corrupt, salvage failed - wallet.dat 파일이 손상되었고 복구가 실패하였습니다. - Password for JSON-RPC connections JSON-RPC 연결에 사용할 암호 @@ -3523,10 +2182,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) 최고의 블럭이 변하면 명령을 실행(cmd 에 있는 %s 는 블럭 해시에 의해 대체되어 짐) - - This help message - 도움말 메시지입니다 - Allow DNS lookups for -addnode, -seednode and -connect -addnode, -seednode, -connect 옵션에 대해 DNS 탐색 허용 @@ -3535,10 +2190,6 @@ Loading addresses... 주소를 불러오는 중... - - Error loading wallet.dat: Wallet corrupted - wallet.dat 불러오기 오류: 지갑 오류 - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = 트랜잭션의 메타 데이터를 유지함 예. 계좌정보 와 지불 요구 정보, 2 = 트랜잭션 메타 데이터 파기) @@ -3555,10 +2206,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) 메모리 풀에 있는 트랜잭션 기록을 <n>시간 후 부터는 유지하지 않기 (기본값: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - 경고 : wallet.dat 파일을 읽는 중 오류가 발생했습니다. 주소 키는 모두 정확하게 로딩되었으나 거래 데이터와 주소록 필드에서 누락이나 오류가 존재할 수 있습니다. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) 해당 금액(%s/kB) 보다 적은 수수료는 수수료 면제로 간주됩니다.(기본값: %s) @@ -3595,6 +2242,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. 지원하지 않는 인수 -socks를 찾았습니다. 설정된 SOCKS의 버전은 더이상 사용할 수 없으며, SOCK5 프록시만을 지원합니다. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 지원하지 않는 인수 -whitelistalwaysrelay 는 무시됩니다, -whitelistrelay 나 -whitelistforcerelay 를 사용해 주세요. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Tor 서비스를 이용하여 피어에게 연결하기 위해 분리된 SOCKS5 프록시를 사용 (기본값: %s) @@ -3603,18 +2254,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times JSON-RPC 연결시 사용자 이름과 해시화된 암호문. <userpw> 필드는 <USERNAME>:<SALT>$<HASH> 포멧으로 구성되어 있습니다. 전형적 파이썬 스크립트에선 share/rpcuser가 포함되어 있습니다. 이 옵션은 여러번 지정할 수 있습니다. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 경고: 알려지지 않은 버전의 블록이 채굴되었습니다. 알려지지 않은 규칙이 적용되었을 가능성이 있습니다. + Always query for peer addresses via DNS lookup (default: %u) DNS lookup을 통해 항상 피어주소에 대한 쿼리 보내기 (기본값: %u) - - Error loading wallet.dat - wallet.dat 불러오기 오류 - - - Generate coins (default: %u) - 코인 생성 (기본값: %u) - How many blocks to check at startup (default: %u, 0 = all) 시작시 점검할 블록 갯수 (기본값: %u, 0 = 모두) @@ -3695,18 +2342,6 @@ Unknown network specified in -onlynet: '%s' -onlynet에 지정한 네트워크를 알 수 없습니다: '%s' - - Cannot resolve -bind address: '%s' - -bind 주소를 확인할 수 없습니다: '%s' - - - Cannot resolve -externalip address: '%s' - -externalip 주소를 확인할 수 없습니다: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - -paytxfee=<amount>에 대한 양이 잘못되었습니다: '%s' - Insufficient funds 자금 부족 diff --git a/src/qt/locale/bitcoin_ku_IQ.ts b/src/qt/locale/bitcoin_ku_IQ.ts new file mode 100644 index 000000000..da5e41a35 --- /dev/null +++ b/src/qt/locale/bitcoin_ku_IQ.ts @@ -0,0 +1,272 @@ + + + AddressBookPage + + Create a new address + ناوونیشانێکی نوێ دروست بکە + + + &New + &نوێ + + + &Copy + &ڕوونووس + + + C&lose + C&داخستن + + + &Export + &هەناردن + + + &Delete + &سڕینەوە + + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + &Send + &ناردن + + + &File + &پەرگە + + + &Settings + &سازکارییەکان + + + &Help + &یارمەتی + + + Error + هەڵە + + + Warning + ئاگاداری + + + Information + زانیاری + + + + CoinControlDialog + + Amount: + کۆ: + + + Priority: + لەپێشی: + + + Fee: + تێچوون: + + + Amount + سەرجەم + + + Date + رێکەت + + + Priority + لەپێشی + + + + EditAddressDialog + + + FreespaceChecker + + name + ناو + + + + HelpMessageDialog + + version + وەشان + + + + Intro + + Welcome + بەخێربێن + + + Error + هەڵە + + + + OpenURIDialog + + + OptionsDialog + + Options + هەڵبژاردنەکان + + + + OverviewPage + + Total: + گشتی + + + + PeerTableModel + + + QObject + + Amount + سەرجەم + + + + RPCConsole + + &Information + &زانیاری + + + Name + ناو + + + Version + وەشان + + + &Open + &کردنەوە + + + &Clear + &پاککردنەوە + + + Totals + گشتییەکان + + + Yes + بەڵێ + + + No + نەخێر + + + + ReceiveCoinsDialog + + &Amount: + &سەرجەم: + + + &Message: + &پەیام: + + + Clear + پاککردنەوە + + + Show + پیشاندان + + + Remove + سڕینەوە + + + + ReceiveRequestDialog + + + SendCoinsDialog + + Amount: + کۆ: + + + Priority: + لەپێشی: + + + Fee: + تێچوون: + + + fast + خێرا + + + + SendCoinsEntry + + Message: + پەیام: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDescDialog + + + UnitDisplayStatusBarControl + + + bitcoin-core + + Options: + هەڵبژاردنەکان: + + + Information + زانیاری + + + Warning + ئاگاداری + + + Error + هەڵە + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 51efd519c..14cb9c202 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -9,17 +9,6 @@ &Delete Ө&чүрүү - - - AddressTableModel - - Address - Дарек - - - (no label) - (аты жок) - AskPassphraseDialog @@ -70,23 +59,12 @@ Жаңыланган - - ClientModel - CoinControlDialog Date Дата - - none - жок - - - (no label) - (аты жок) - EditAddressDialog @@ -94,7 +72,7 @@ &Address &Дарек - + FreespaceChecker @@ -157,18 +135,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -209,29 +181,6 @@ ReceiveRequestDialog - - Address - Дарек - - - Message - Билдирүү - - - - RecentRequestsTableModel - - Date - Дата - - - Message - Билдирүү - - - (no label) - (аты жок) - SendCoinsDialog @@ -243,11 +192,7 @@ S&end &Жөнөтүү - - (no label) - (аты жок) - - + SendCoinsEntry @@ -279,54 +224,12 @@ TrafficGraphWidget - - TransactionDesc - - %1/offline - %1/тармакта эмес - - - Date - Дата - - - Message - Билдирүү - - TransactionDescDialog - - TransactionTableModel - - Date - Дата - - - - TransactionView - - Date - Дата - - - Address - Дарек - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - bitcoin-core diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index b11027d1e..ebaddba7e 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -9,10 +9,6 @@ Copy the currently selected address to the system clipboard Copia inscriptionem iam selectam in latibulum systematis - - &Copy Address - &Copia Inscriptionem - Delete the currently selected address from the list Dele active selectam inscriptionem ex enumeratione @@ -29,37 +25,6 @@ &Delete &Dele - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Hae sunt inscriptiones mittendi pensitationes. Semper inspice quantitatem et inscriptionem accipiendi antequam nummos mittis. - - - Copy &Label - Copia &Titulum - - - &Edit - &Muta - - - Comma separated file (*.csv) - Comma Separata Plica (*.csv) - - - - AddressTableModel - - Label - Titulus - - - Address - Inscriptio - - - (no label) - (nullus titulus) - AskPassphraseDialog @@ -79,82 +44,6 @@ Repeat new passphrase Itera novam tesseram - - Encrypt wallet - Cifra cassidile - - - This operation needs your wallet passphrase to unlock the wallet. - Huic operationi necesse est tessera cassidili tuo ut cassidile reseret. - - - Unlock wallet - Resera cassidile - - - This operation needs your wallet passphrase to decrypt the wallet. - Huic operationi necesse est tessera cassidili tuo ut cassidile decifret. - - - Decrypt wallet - Decifra cassidile - - - Change passphrase - Muta tesseram - - - Confirm wallet encryption - Confirma cifrationem cassidilis - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Monitio: Si cassidile tuum cifras et tesseram amittis, tu <b>AMITTES OMNES TUOS NUMMOS BITOS</b>! - - - Are you sure you wish to encrypt your wallet? - Certusne es te velle tuum cassidile cifrare? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - GRAVE: Oportet ulla prioria conservata quae fecisti de plica tui cassidilis reponi a nove generata cifrata plica cassidilis. Propter securitatem, prioria conservata de plica non cifrata cassidilis inutilia fiet simul atque incipis uti novo cifrato cassidili. - - - Warning: The Caps Lock key is on! - Monitio: Litterae ut capitales seratae sunt! - - - Wallet encrypted - Cassidile cifratum - - - Wallet encryption failed - Cassidile cifrare abortum est - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Cassidile cifrare abortum est propter internum errorem. Tuum cassidile cifratum non est. - - - The supplied passphrases do not match. - Tesserae datae non eaedem sunt. - - - Wallet unlock failed - Cassidile reserare abortum est. - - - The passphrase entered for the wallet decryption was incorrect. - Tessera inserta pro cassidilis decifrando prava erat. - - - Wallet decryption failed - Cassidile decifrare abortum est. - - - Wallet passphrase was successfully changed. - Tessera cassidilis successa est in mutando. - BanTableModel @@ -217,10 +106,6 @@ &Change Passphrase... &Muta tesseram... - - Importing blocks from disk... - Importans frusta ab disco... - Reindexing blocks on disk... Recreans indicem frustorum in disco... @@ -301,10 +186,6 @@ Tabs toolbar Tabella instrumentorum "Tabs" - - Bitcoin Core - Bitcoin Nucleus - &Command-line options Optiones mandati initiantis @@ -362,13 +243,6 @@ Cassidile <b>cifratum</b> est et iam nunc <b>seratum</b> - - ClientModel - - Network Alert - Monitio Retis - - CoinControlDialog @@ -387,26 +261,6 @@ Confirmed Confirmatum - - Copy address - Copia inscriptionem - - - Copy label - Copia titulum - - - Copy amount - Copia quantitatem - - - Copy transaction ID - Copia transactionis ID - - - (no label) - (nullus titulus) - EditAddressDialog @@ -422,48 +276,12 @@ &Address &Inscriptio - - New receiving address - Nova inscriptio accipiendi - - - New sending address - Nova inscriptio mittendi - - - Edit receiving address - Muta inscriptionem accipiendi - - - Edit sending address - Muta inscriptionem mittendi - - - The entered address "%1" is already in the address book. - Inserta inscriptio "%1" iam in libro inscriptionum est. - - - The entered address "%1" is not a valid Bitcoin address. - Inscriptio inserta "%1" non valida inscriptio Bitcoin est. - - - Could not unlock wallet. - Non potuisse cassidile reserare - - - New key generation failed. - Generare novam clavem abortum est. - FreespaceChecker HelpMessageDialog - - Bitcoin Core - Bitcoin Nucleus - version versio @@ -483,10 +301,6 @@ Intro - - Bitcoin Core - Bitcoin Nucleus - Error Error @@ -613,17 +427,6 @@ Fossum pendendum quod nondum maturum est - - PaymentServer - - URI handling - Tractatio URI - - - Cannot start bitcoin: click-to-pay handler - Bitcoin incipere non potest: cliccare-ad-pensandum handler - - PeerTableModel @@ -638,13 +441,6 @@ N/A - - QRImageWidget - - Save QR Code - Salva codicem QR - - RPCConsole @@ -699,10 +495,6 @@ &Console &Terminale - - Build date - Dies aedificandi - Debug log file Debug catalogi plica @@ -734,68 +526,13 @@ &Message: Nuntius: - - Copy label - Copia titulum - - - Copy amount - Copia quantitatem - - + ReceiveRequestDialog Copy &Address &Copia Inscriptionem - - Address - Inscriptio - - - Amount - Quantitas - - - Label - Titulus - - - Message - Nuntius - - - Resulting URI too long, try to reduce the text for label / message. - Resultato URI nimis longo, conare minuere verba pro titulo / nuntio. - - - Error encoding URI into QR Code. - Error codificandi URI in codicem QR. - - - - RecentRequestsTableModel - - Date - Dies - - - Label - Titulus - - - Message - Nuntius - - - Amount - Quantitas - - - (no label) - (nullus titulus) - SendCoinsDialog @@ -839,31 +576,7 @@ S&end &Mitte - - Confirm send coins - Confirma mittendum nummorum - - - Copy amount - Copia quantitatem - - - The amount to pay must be larger than 0. - Oportet quantitatem ad pensandum maiorem quam 0 esse. - - - The amount exceeds your balance. - Quantitas est ultra quod habes. - - - The total exceeds your balance when the %1 transaction fee is included. - Quantitas est ultra quod habes cum merces transactionis %1 includitur. - - - (no label) - (nullus titulus) - - + SendCoinsEntry @@ -874,10 +587,6 @@ Pay &To: Pensa &Ad: - - Enter a label for this address to add it to your address book - Insero titulum huic inscriptioni ut eam in tuum librum inscriptionum addas. - &Label: &Titulus: @@ -972,65 +681,9 @@ Reset all verify message fields Reconstitue omnes campos verificandi nuntii - - Click "Sign Message" to generate signature - Clicca "Signa Nuntium" ut signatio generetur - - - The entered address is invalid. - Inscriptio inserta non valida est. - - - Please check the address and try again. - Sodes inscriptionem proba et rursus conare. - - - The entered address does not refer to a key. - Inserta inscriptio clavem non refert. - - - Wallet unlock was cancelled. - Cassidilis reserare cancellatum est. - - - Private key for the entered address is not available. - Clavis privata absens est pro inserta inscriptione. - - - Message signing failed. - Nuntium signare abortum est. - - - Message signed. - Nuntius signatus. - - - The signature could not be decoded. - Signatio decodificari non potuit. - - - Please check the signature and try again. - Sodes signationem proba et rursus conare. - - - The signature did not match the message digest. - Signatio non convenit digesto nuntii - - - Message verification failed. - Nuntium verificare abortum est. - - - Message verified. - Nuntius verificatus. - SplashScreen - - Bitcoin Core - Bitcoin Nucleus - [testnet] [testnet] @@ -1039,362 +692,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Apertum donec %1 - - - %1/offline - %1/non conecto - - - %1/unconfirmed - %1/non confirmata - - - %1 confirmations - %1 confirmationes - - - Status - Status - - - Date - Dies - - - Source - Fons - - - Generated - Generatum - - - From - Ab - - - To - Ad - - - own address - inscriptio propria - - - label - titulus - - - Credit - Creditum - - - not accepted - non acceptum - - - Debit - Debitum - - - Transaction fee - Transactionis merces - - - Net amount - Cuncta quantitas - - - Message - Nuntius - - - Comment - Annotatio - - - Transaction ID - ID transactionis - - - Debug information - Informatio de debug - - - Transaction - Transactio - - - Inputs - Lectenda - - - Amount - Quantitas - - - true - verum - - - false - falsum - - - , has not been successfully broadcast yet - , nondum prospere disseminatum est - - - unknown - ignotum - - TransactionDescDialog - - Transaction details - Particularia transactionis - This pane shows a detailed description of the transaction Haec tabula monstrat descriptionem verbosam transactionis - - TransactionTableModel - - Date - Dies - - - Type - Typus - - - Open until %1 - Apertum donec %1 - - - Confirmed (%1 confirmations) - Confirmatum (%1 confirmationes) - - - This block was not received by any other nodes and will probably not be accepted! - Hoc frustum non acceptum est ab ulla alia nodis et probabiliter non acceptum erit! - - - Generated but not accepted - Generatum sed non acceptum - - - Label - Titulus - - - Received with - Acceptum cum - - - Received from - Acceptum ab - - - Sent to - Missum ad - - - Payment to yourself - Pensitatio ad te ipsum - - - Mined - Fossa - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Status transactionis. Supervola cum mure ut monstretur numerus confirmationum. - - - Date and time that the transaction was received. - Dies et tempus quando transactio accepta est. - - - Type of transaction. - Typus transactionis. - - - Amount removed from or added to balance. - Quantitas remota ex pendendo aut addita ei. - - - - TransactionView - - All - Omne - - - Today - Hodie - - - This week - Hac hebdomade - - - This month - Hoc mense - - - Last month - Postremo mense - - - This year - Hoc anno - - - Range... - Intervallum... - - - Received with - Acceptum cum - - - Sent to - Missum ad - - - To yourself - Ad te ipsum - - - Mined - Fossa - - - Other - Alia - - - Enter address or label to search - Insere inscriptionem vel titulum ut quaeras - - - Min amount - Quantitas minima - - - Copy address - Copia inscriptionem - - - Copy label - Copia titulum - - - Copy amount - Copia quantitatem - - - Copy transaction ID - Copia transactionis ID - - - Edit label - Muta titulum - - - Show transaction details - Monstra particularia transactionis - - - Comma separated file (*.csv) - Comma Separata Plica (*.csv) - - - Confirmed - Confirmatum - - - Date - Dies - - - Type - Typus - - - Label - Titulus - - - Address - Inscriptio - - - ID - ID - - - Range: - Intervallum: - - - to - ad - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Mitte Nummos - - - - WalletView - - &Export - &Exporta - - - Export the data in the current tab to a file - Exporta data in hac tabella in plicam - - - Backup Wallet - Conserva cassidile - - - Wallet Data (*.dat) - Data cassidilis (*.dat) - - - Backup Failed - Conservare abortum est. - - - Backup Successful - Successum in conservando - - bitcoin-core @@ -1425,6 +732,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accipe conexiones externas (praedefinitum: 1 nisi -proxy neque -connect) + + Bitcoin Core + Bitcoin Nucleus + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Conglutina ad inscriptionem datam et semper in eam ausculta. Utere [moderatrum]:porta notationem pro IPv6 @@ -1437,10 +748,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Hoc est prae-dimittum experimentala aedes - utere eo periculo tuo proprio - nolite utere fodendo vel applicationibus mercatoriis - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Monitio: wallet.data corrupta, data salvata! Originalis wallet.dat salvata ut wallet.{timestamp}.bak in %s; si pendendum tuum vel transactiones pravae sunt, oportet ab conservato restituere. - Block creation options: Optiones creandi frustorum: @@ -1493,26 +800,10 @@ Verifying wallet... Verificante cassidilem... - - Cannot resolve -whitebind address: '%s' - Non posse resolvere -whitebind inscriptionem: '%s' - Information Informatio - - Invalid amount for -maxtxfee=<amount>: '%s' - Quantitas non valida pro -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Quantitas non valida pro -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Quantitas non valida pro -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log @@ -1545,10 +836,6 @@ Warning Monitio - - wallet.dat corrupt, salvage failed - wallet.dat corrupta, salvare abortum est - Password for JSON-RPC connections Tessera pro conexionibus JSON-RPC @@ -1557,10 +844,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Pelle mandatum quando optissimum frustum mutat (%s in mandato substituitur ab hash frusti) - - This help message - Hic nuntius auxilii - Allow DNS lookups for -addnode, -seednode and -connect Permitte quaerenda DNS pro -addnode, -seednode, et -connect @@ -1569,14 +852,6 @@ Loading addresses... Legens inscriptiones... - - Error loading wallet.dat: Wallet corrupted - Error legendi wallet.dat: Cassidile corruptum - - - Error loading wallet.dat - Error legendi wallet.dat - Invalid -proxy address: '%s' Inscriptio -proxy non valida: '%s' @@ -1585,18 +860,6 @@ Unknown network specified in -onlynet: '%s' Ignotum rete specificatum in -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Non posse resolvere -bind inscriptonem: '%s' - - - Cannot resolve -externalip address: '%s' - Non posse resolvere -externalip inscriptionem: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Quantitas non valida pro -paytxfee=<quantitas>: '%s' - Insufficient funds Inopia nummorum diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 873a6939b..9e98baa77 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -25,10 +25,6 @@ C&lose &Užverti - - &Copy Address - &Kopijuoti adresą - Delete the currently selected address from the list Ištrinti pasirinktą adresą iš sąrašo @@ -45,73 +41,6 @@ &Delete &Trinti - - Choose the address to send coins to - Pasirinkite adresą kuriam siūsite monetas - - - Choose the address to receive coins with - Pasirinkite adresą su kuriuo gauti monetas - - - C&hoose - P&asirinkti - - - Sending addresses - Siunčiami adresai - - - Receiving addresses - Gaunami adresai - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Tai yra jūsų Bitcoin adresai mokėjimų siuntimui. Visada patikrinkite siunčiamą sumą ir gavėjo adresą prieš siųsdami monetas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Tai yra jūsų Bitcoin adresai mokėjimų gavimui. Rekomenduojame naudoti naujus gavimo adresus kiekvienai tranzakcijai. - - - Copy &Label - Kopijuoti ž&ymę - - - &Edit - &Keisti - - - Export Address List - Eksportuoti adresų sąrašą - - - Comma separated file (*.csv) - Kableliais atskirtų duomenų failas (*.csv) - - - Exporting Failed - Eksportavimas nepavyko - - - There was an error trying to save the address list to %1. Please try again. - Bandant išsaugoti adresų sąrašą - įvyko klaida keliant į %1. Prašome bandyti dar kartą. - - - - AddressTableModel - - Label - Žymė - - - Address - Adresas - - - (no label) - (nėra žymės) - AskPassphraseDialog @@ -131,78 +60,6 @@ Repeat new passphrase Pakartokite naują slaptafrazę - - Encrypt wallet - Užšifruoti piniginę - - - This operation needs your wallet passphrase to unlock the wallet. - Ši operacija reikalauja jūsų piniginės slaptafrazės jai atrakinti. - - - Unlock wallet - Atrakinti piniginę - - - This operation needs your wallet passphrase to decrypt the wallet. - Ši operacija reikalauja jūsų piniginės slaptafrazės jai iššifruoti. - - - Decrypt wallet - Iššifruoti piniginę - - - Change passphrase - Pakeisti slaptafrazę - - - Confirm wallet encryption - Patvirtinkite piniginės užšifravimą - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Dėmesio: jei užšifruosite savo piniginę ir pamesite slaptafrazę, jūs<b>PRARASITE VISUS SAVO BITCOINUS</b>! - - - Are you sure you wish to encrypt your wallet? - Ar tikrai norite šifruoti savo piniginę? - - - Warning: The Caps Lock key is on! - Įspėjimas: įjungtas Caps Lock klavišas! - - - Wallet encrypted - Piniginė užšifruota - - - Wallet encryption failed - Nepavyko užšifruoti piniginę - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Dėl vidinės klaidos nepavyko užšifruoti piniginę.Piniginė neužšifruota. - - - The supplied passphrases do not match. - Įvestos slaptafrazės nesutampa. - - - Wallet unlock failed - Nepavyko atrakinti piniginę - - - The passphrase entered for the wallet decryption was incorrect. - Neteisingai įvestas slaptažodis piniginės iššifravimui. - - - Wallet decryption failed - Nepavyko iššifruoti piniginės - - - Wallet passphrase was successfully changed. - Piniginės slaptažodis sėkmingai pakeistas. - BanTableModel @@ -249,6 +106,10 @@ Quit application Išjungti programą + + &About %1 + &Apie %1 + About &Qt Apie &Qt @@ -285,14 +146,6 @@ Open &URI... Atidaryti &URI... - - Bitcoin Core client - Bitcoin Core klientas - - - Importing blocks from disk... - Blokai importuojami iš disko... - Reindexing blocks on disk... Blokai iš naujo indeksuojami... @@ -337,10 +190,6 @@ &Receive &Gauti - - Show information about Bitcoin Core - Rodyti informaciją apie Bitcoin Core - &Show / Hide &Rodyti / Slėpti @@ -369,14 +218,6 @@ Tabs toolbar Kortelių įrankinė - - Bitcoin Core - Bitcoin branduolys - - - &About Bitcoin Core - &Apie Bitcoin Core - &Command-line options Komandinės eilutės parametrai @@ -418,13 +259,6 @@ Piniginė <b>užšifruota</b> ir šiuo metu <b>užrakinta</b> - - ClientModel - - Network Alert - Tinklo įspėjimas - - CoinControlDialog @@ -491,94 +325,6 @@ Priority Pirmumas - - Copy address - Kopijuoti adresą - - - Copy label - Kopijuoti žymę - - - Copy amount - Kopijuoti sumą - - - Copy quantity - Kopijuoti kiekį - - - Copy fee - Kopijuoti mokestį - - - Copy after fee - Kopijuoti po mokesčio - - - Copy bytes - Kopijuoti baitus - - - Copy priority - Kopijuoti pirmumą - - - highest - auksčiausias - - - higher - aukštesnis - - - high - aukštas - - - medium-high - vidutiniškai aukštas - - - medium - vidutiniškai - - - low-medium - žemai-vidutiniškas - - - low - žemas - - - lower - žemesnis - - - lowest - žemiausias - - - none - niekas - - - yes - taip - - - no - ne - - - (no label) - (nėra žymės) - - - (change) - (Graža) - EditAddressDialog @@ -594,38 +340,6 @@ &Address &Adresas - - New receiving address - Naujas gavimo adresas - - - New sending address - Naujas siuntimo adresas - - - Edit receiving address - Keisti gavimo adresą - - - Edit sending address - Keisti siuntimo adresą - - - The entered address "%1" is already in the address book. - Įvestas adresas „%1“ jau yra adresų knygelėje. - - - The entered address "%1" is not a valid Bitcoin address. - Įvestas adresas „%1“ nėra galiojantis Bitcoin adresas. - - - Could not unlock wallet. - Nepavyko atrakinti piniginės. - - - New key generation failed. - Naujo rakto generavimas nepavyko. - FreespaceChecker @@ -636,18 +350,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin branduolys - version versija - - About Bitcoin Core - Apie Bitcoin Core - Command-line options Komandinės eilutės parametrai @@ -667,14 +373,6 @@ Welcome Sveiki - - Welcome to Bitcoin Core. - Sveiki atvykę į Bitcoin Core. - - - Bitcoin Core - Bitcoin branduolys - Error Klaida @@ -841,29 +539,6 @@ Jūsų balansas - - PaymentServer - - URI handling - URI apdorojimas - - - Invalid payment address %1 - Neteisingas mokėjimo adresas %1 - - - Payment request rejected - Mokėjimo siuntimas atmestas - - - Payment request expired. - Mokėjimo siuntimas pasibaigė - - - Network request error - Tinklo užklausos klaida - - PeerTableModel @@ -886,21 +561,6 @@ nėra - - QRImageWidget - - &Copy Image - Kopijuoti nuotrauką - - - Save QR Code - Įrašyti QR kodą - - - PNG Image (*.png) - PNG paveikslėlis (*.png) - - RPCConsole @@ -979,10 +639,6 @@ Totals Viso: - - Build date - Kompiliavimo data - Debug log file Derinimo žurnalo failas @@ -1038,15 +694,7 @@ Clear Išvalyti - - Copy label - Kopijuoti žymę - - - Copy amount - Kopijuoti sumą - - + ReceiveRequestDialog @@ -1057,53 +705,6 @@ Copy &Address &Kopijuoti adresą - - Payment information - Mokėjimo informacija - - - Address - Adresas - - - Amount - Suma - - - Label - Žymė - - - Message - Žinutė - - - Error encoding URI into QR Code. - Klaida, koduojant URI į QR kodą. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Žymė - - - Message - Žinutė - - - Amount - Suma - - - (no label) - (nėra žymės) - SendCoinsDialog @@ -1171,55 +772,7 @@ S&end &Siųsti - - Confirm send coins - Patvirtinti monetų siuntimą - - - Copy quantity - Kopijuoti kiekį - - - Copy amount - Kopijuoti sumą - - - Copy fee - Kopijuoti mokestį - - - Copy after fee - Kopijuoti po mokesčio - - - Copy bytes - Kopijuoti baitus - - - Copy priority - Kopijuoti pirmumą - - - The amount to pay must be larger than 0. - Apmokėjimo suma turi būti didesnė nei 0. - - - The amount exceeds your balance. - Suma viršija jūsų balansą. - - - The total exceeds your balance when the %1 transaction fee is included. - Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą. - - - Payment request expired. - Mokėjimo siuntimas pasibaigė - - - (no label) - (nėra žymės) - - + SendCoinsEntry @@ -1230,10 +783,6 @@ Pay &To: Mokėti &gavėjui: - - Enter a label for this address to add it to your address book - Įveskite žymę šiam adresui kad galėtumėte įtraukti ją į adresų knygelę - &Label: Ž&ymė: @@ -1308,57 +857,9 @@ Verify &Message &Patikrinti žinutę - - Click "Sign Message" to generate signature - Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą - - - The entered address is invalid. - Įvestas adresas negalioja. - - - Please check the address and try again. - Prašom patikrinti adresą ir bandyti iš naujo. - - - Wallet unlock was cancelled. - Piniginės atrakinimas atšauktas. - - - Message signing failed. - Žinutės pasirašymas nepavyko. - - - Message signed. - Žinutė pasirašyta. - - - The signature could not be decoded. - Nepavyko iškoduoti parašo. - - - Please check the signature and try again. - Prašom patikrinti parašą ir bandyti iš naujo. - - - The signature did not match the message digest. - Parašas neatitinka žinutės. - - - Message verification failed. - Žinutės tikrinimas nepavyko. - - - Message verified. - Žinutė patikrinta. - - + SplashScreen - - Bitcoin Core - Bitcoin branduolys - [testnet] [testavimotinklas] @@ -1371,358 +872,16 @@ KB/s - - TransactionDesc - - Open until %1 - Atidaryta iki %1 - - - %1/offline - %1/neprisijungęs - - - %1/unconfirmed - %1/nepatvirtintas - - - %1 confirmations - %1 patvirtinimų - - - Status - Būsena - - - Date - Data - - - Source - Šaltinis - - - Generated - Sugeneruotas - - - From - Nuo - - - To - Kam - - - own address - savo adresas - - - label - žymė - - - Credit - Kreditas - - - not accepted - nepriimta - - - Debit - Debitas - - - Transaction fee - Sandorio mokestis - - - Net amount - Neto suma - - - Message - Žinutė - - - Comment - Komentaras - - - Transaction ID - Sandorio ID - - - Debug information - Derinimo informacija - - - Transaction - Sandoris - - - Amount - Suma - - - true - tiesa - - - false - netiesa - - - , has not been successfully broadcast yet - , transliavimas dar nebuvo sėkmingas - - - unknown - nežinomas - - TransactionDescDialog - - Transaction details - Sandorio detelės - This pane shows a detailed description of the transaction Šis langas sandorio detalų aprašymą - - TransactionTableModel - - Date - Data - - - Type - Tipas - - - Open until %1 - Atidaryta iki %1 - - - Confirmed (%1 confirmations) - Patvirtinta (%1 patvirtinimai) - - - This block was not received by any other nodes and will probably not be accepted! - Šis blokas negautas nė vienu iš mazgų ir matomai nepriimtas - - - Generated but not accepted - Išgauta bet nepriimta - - - Label - Žymė - - - Received with - Gauta su - - - Received from - Gauta iš - - - Sent to - Išsiųsta - - - Payment to yourself - Mokėjimas sau - - - Mined - Išgauta - - - (n/a) - nepasiekiama - - - Transaction status. Hover over this field to show number of confirmations. - Sandorio būklė. Užvedus pelės žymeklį ant šios srities matysite patvirtinimų skaičių. - - - Date and time that the transaction was received. - Sandorio gavimo data ir laikas - - - Type of transaction. - Sandorio tipas. - - - Amount removed from or added to balance. - Suma pridėta ar išskaičiuota iš balanso - - - - TransactionView - - All - Visi - - - Today - Šiandien - - - This week - Šią savaitę - - - This month - Šį mėnesį - - - Last month - Paskutinį mėnesį - - - This year - Šiais metais - - - Range... - Intervalas... - - - Received with - Gauta su - - - Sent to - Išsiųsta - - - To yourself - Skirta sau - - - Mined - Išgauta - - - Other - Kita - - - Enter address or label to search - Įveskite adresą ar žymę į paiešką - - - Min amount - Minimali suma - - - Copy address - Kopijuoti adresą - - - Copy label - Kopijuoti žymę - - - Copy amount - Kopijuoti sumą - - - Edit label - Taisyti žymę - - - Show transaction details - Rodyti sandėrio detales - - - Exporting Failed - Eksportavimas nepavyko - - - Comma separated file (*.csv) - Kableliais atskirtų duomenų failas (*.csv) - - - Confirmed - Patvirtintas - - - Date - Data - - - Type - Tipas - - - Label - Žymė - - - Address - Adresas - - - ID - ID - - - Range: - Grupė: - - - to - skirta - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Siųsti monetas - - - - WalletView - - &Export - &Eksportuoti - - - Export the data in the current tab to a file - Eksportuoti informaciją iš dabartinės lentelės į failą - - - Backup Wallet - Backup piniginę - - - Wallet Data (*.dat) - Piniginės duomenys (*.dat) - - - Backup Failed - Nepavyko padaryti atsarginės kopijos - - - Backup Successful - Atsarginė kopija sėkmingai padaryta - - bitcoin-core @@ -1745,6 +904,10 @@ Run in the background as a daemon and accept commands Dirbti fone kaip šešėlyje ir priimti komandas + + Bitcoin Core + Bitcoin branduolys + Connect only to the specified node(s) Prisijungti tik prie nurodyto mazgo @@ -1765,18 +928,6 @@ Information Informacija - - Invalid amount for -maxtxfee=<amount>: '%s' - Neteisinga suma -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Neteisinga suma -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Neteisinga suma -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo @@ -1793,10 +944,6 @@ Password for JSON-RPC connections Slaptažodis JSON-RPC sujungimams - - This help message - Pagelbos žinutė - Allow DNS lookups for -addnode, -seednode and -connect Leisti DNS paiešką sujungimui ir mazgo pridėjimui @@ -1805,22 +952,10 @@ Loading addresses... Užkraunami adresai... - - Error loading wallet.dat: Wallet corrupted - wallet.dat pakrovimo klaida, wallet.dat sugadintas - - - Error loading wallet.dat - wallet.dat pakrovimo klaida - Invalid -proxy address: '%s' Neteisingas proxy adresas: '%s' - - Invalid amount for -paytxfee=<amount>: '%s' - Neteisinga suma -paytxfee=<amount>: '%s' - Insufficient funds Nepakanka lėšų diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 5a59184b0..bac587569 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -21,10 +21,6 @@ C&lose &Aizvērt - - &Copy Address - &Kopēt adresi - Delete the currently selected address from the list Izdzēst iezīmētās adreses no saraksta @@ -41,73 +37,6 @@ &Delete &Dzēst - - Choose the address to send coins to - Izvēlies adresi uz kuru sūtīt bitcoins - - - Choose the address to receive coins with - Izvēlies adresi ar kuru saņemt bitcoins - - - C&hoose - &Izvēlēties - - - Sending addresses - Sūtīšanas adreses - - - Receiving addresses - Saņemšanas adreses - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Šīs ir jūsu Bitcoin adreses maksājumu sūtīšanai. Vienmēr pārbaudiet summu un saņēmēja adresi pirms monētu sūtīšanas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Šīs ir jūsu Bitcoin adreses maksājumu saņemšanai. Ir ieteicams katram darījumam izmantot jaunu saņemšanas adresi. - - - Copy &Label - Kopēt &Nosaukumu - - - &Edit - &Rediģēt - - - Export Address List - Eksportēt Adrešu Sarakstu - - - Comma separated file (*.csv) - Fails ar komatu kā atdalītāju (*.csv) - - - Exporting Failed - Eksportēšana Neizdevās - - - There was an error trying to save the address list to %1. Please try again. - Radās kļūda, saglabājot adrešu sarakstu %1. Lūdzu, mēģiniet vēlreiz! - - - - AddressTableModel - - Label - Nosaukums - - - Address - Adrese - - - (no label) - (bez nosaukuma) - AskPassphraseDialog @@ -127,90 +56,6 @@ Repeat new passphrase Jaunā parole vēlreiz - - Encrypt wallet - Šifrēt maciņu - - - This operation needs your wallet passphrase to unlock the wallet. - Lai veikto šo darbību, maciņš jāatslēdz ar paroli. - - - Unlock wallet - Atslēgt maciņu - - - This operation needs your wallet passphrase to decrypt the wallet. - Šai darbībai maciņš jāatšifrē ar maciņa paroli. - - - Decrypt wallet - Atšifrēt maciņu - - - Change passphrase - Mainīt paroli - - - Confirm wallet encryption - Apstiprināt maciņa šifrēšanu - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Brīdinājums: Ja tu nošifrē savu maciņu un pazaudē paroli, tu <b>PAZAUDĒSI VISAS SAVAS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Vai tu tiešām vēlies šifrēt savu maciņu? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core tiks aizvērts, lai pabeigtu šifrēšansa procesu. Atcerieties, ka jūsu maka šifrēšana nevar pilnībā pasargāt jūsu monētas no to nozagašanas, inficējot datoru ar ļaunprātīgām programmām. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - SVARĪGI: Iepriekšējie maka faila dublējumi ir jāaizvieto ar jauno, šifrēto maka failu. Drošības apsvērumu dēļ iepriekšējie nešifrētā maka dublējumi vairs nebūs derīgi, tiklīdz sāksiet izmantot jauno, šifrēto maku. - - - Warning: The Caps Lock key is on! - Brīdinājums: Caps Lock ir ieslēgts! - - - Wallet encrypted - Maciņš nošifrēts - - - Enter the old passphrase and new passphrase to the wallet. - Ievadiet veco un jauno maka paroli. - - - Wallet encryption failed - Maciņa šifrēšana neizdevās - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Maciņa šifrēšana neizdevās programmas kļūdas dēļ. Jūsu maciņš netika šifrēts. - - - The supplied passphrases do not match. - Ievadītās paroles nav vienādas. - - - Wallet unlock failed - Maciņu atšifrēt neizdevās - - - The passphrase entered for the wallet decryption was incorrect. - Maciņa atšifrēšanai ievadītā parole nav pareiza. - - - Wallet decryption failed - Maciņu neizdevās atšifrēt - - - Wallet passphrase was successfully changed. - Maciņa parole tika veiksmīgi nomainīta. - BanTableModel @@ -289,14 +134,6 @@ Open &URI... Atvērt &URI... - - Bitcoin Core client - Bitcoin Core klients - - - Importing blocks from disk... - Importē blokus no diska... - Reindexing blocks on disk... Bloku reindeksēšana no diska... @@ -341,10 +178,6 @@ &Receive &Saņemt - - Show information about Bitcoin Core - Parādīt informāciju par Bitcoin Core - &Show / Hide &Rādīt / Paslēpt @@ -381,18 +214,10 @@ Tabs toolbar Ciļņu rīkjosla - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Pieprasīt maksājumus (izveido QR kodu un bitcoin: URIs) - - &About Bitcoin Core - Par &Bitcoin Core - Open a bitcoin: URI or payment request Atvērt bitcoin URI vai maksājuma pieprasījumu @@ -454,13 +279,6 @@ Maciņš ir <b>šifrēts</b> un pašlaik <b>slēgts</b> - - ClientModel - - Network Alert - Tīkla brīdinājums - - CoinControlDialog @@ -523,118 +341,6 @@ Priority Prioritāte - - Copy address - Kopēt adresi - - - Copy label - Kopēt nosaukumu - - - Copy amount - Kopēt daudzumu - - - Copy transaction ID - Kopēt transakcijas ID - - - Lock unspent - Aizslēgt neiztērēto - - - Unlock unspent - Atslēgt neiztērēto - - - Copy quantity - Kopēt daudzumu - - - Copy fee - Kopēt maksu - - - Copy after fee - Kopēt pēc maksas - - - Copy bytes - Kopēt baitus - - - Copy priority - Kopēt prioritāti - - - Copy change - Kopēt atlikumu - - - highest - augstākais - - - higher - augstāks - - - high - augsts - - - medium-high - vidēji-augsts - - - medium - vidējs - - - low-medium - zemi-vidējs - - - low - zems - - - lower - zemāks - - - lowest - zemākais - - - (%1 locked) - (%1 aizslēgts) - - - none - neviena - - - yes - - - - no - - - - (no label) - (bez nosaukuma) - - - change from %1 (%2) - atlikums no %1 (%2) - - - (change) - (atlikums) - EditAddressDialog @@ -650,38 +356,6 @@ &Address &Adrese - - New receiving address - Jauna saņemšanas adrese - - - New sending address - Jauna nosūtīšanas adrese - - - Edit receiving address - Mainīt saņemšanas adresi - - - Edit sending address - Mainīt nosūtīšanas adresi - - - The entered address "%1" is already in the address book. - Nupat ierakstītā adrese "%1" jau atrodas adrešu grāmatā. - - - The entered address "%1" is not a valid Bitcoin address. - Ierakstītā adrese "%1" nav derīga Bitcoin adrese. - - - Could not unlock wallet. - Nav iespējams atslēgt maciņu. - - - New key generation failed. - Neizdevās ģenerēt jaunu atslēgu. - FreespaceChecker @@ -704,10 +378,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versija @@ -716,10 +386,6 @@ (%1-bit) (%1-biti) - - About Bitcoin Core - Par Bitcoin Core - Command-line options Komandrindas iespējas @@ -739,10 +405,6 @@ Welcome Sveiciens - - Welcome to Bitcoin Core. - Sveicināts Bitcoin Core - Use the default data directory Izmantot noklusēto datu mapi @@ -751,10 +413,6 @@ Use a custom data directory: Izmantot pielāgotu datu mapi: - - Bitcoin Core - Bitcoin Core - Error Kļūda @@ -778,10 +436,6 @@ Select payment request file Izvēlies maksājuma pieprasījuma datni - - Select payment request file to open - Izvēlies maksājuma pieprasījuma datni lai atvēru - OptionsDialog @@ -973,45 +627,6 @@ Jūsu kopējā tekošā bilance - - PaymentServer - - URI handling - URI apstrāde - - - Invalid payment address %1 - Nederīga maksājuma adrese %1 - - - Payment request rejected - Maksājuma pieprasījums noraidīts - - - Payment request network doesn't match client network. - Maksājuma pieprasījuma tīkls neatbilst klienta tīklam. - - - Payment request error - Maksājumu pieprasījuma kļūda - - - Cannot start bitcoin: click-to-pay handler - Nevar palaist Bitcoin: nospied-lai-maksātu apstrādātāju - - - Refund from %1 - Atmaksa no %1 - - - Payment acknowledged - Maksājums atzīts - - - Network request error - Tīkla pieprasījuma kļūda - - PeerTableModel @@ -1034,25 +649,6 @@ N/A - - QRImageWidget - - &Save Image... - &Saglabāt Attēlu... - - - &Copy Image - &Kopēt Attēlu - - - Save QR Code - Saglabāt QR kodu - - - PNG Image (*.png) - PNG Attēls (*.png) - - RPCConsole @@ -1135,10 +731,6 @@ Out: Iz.: - - Build date - Kompilācijas datums - Debug log file Atkļūdošanas žurnāla datne @@ -1222,18 +814,6 @@ Remove Noņemt - - Copy label - Kopēt nosaukumu - - - Copy message - Kopēt ziņojumu - - - Copy amount - Kopēt daudzumu - ReceiveRequestDialog @@ -1253,73 +833,6 @@ &Save Image... &Saglabāt Attēlu... - - Request payment to %1 - Pieprasīt maksājumu uz %1 - - - Payment information - Maksājuma informācija - - - URI - URI - - - Address - Adrese - - - Amount - Daudzums - - - Label - Nosaukums - - - Message - Ziņojums - - - Resulting URI too long, try to reduce the text for label / message. - Rezultāta URI pārāk garš, mēģiniet saīsināt nosaukumu vai ziņojumu. - - - Error encoding URI into QR Code. - Kļūda kodējot URI QR kodā. - - - - RecentRequestsTableModel - - Date - Datums - - - Label - Nosaukums - - - Message - Ziņojums - - - Amount - Daudzums - - - (no label) - (bez nosaukuma) - - - (no message) - (nav ziņojuma) - - - (no amount) - (nav summas) - SendCoinsDialog @@ -1407,78 +920,6 @@ S&end &Sūtīt - - Confirm send coins - Apstiprināt bitkoinu sūtīšanu - - - %1 to %2 - %1 līdz %2 - - - Copy quantity - Kopēt daudzumu - - - Copy amount - Kopēt daudzumu - - - Copy fee - Kopēt maksu - - - Copy after fee - Kopēt pēc maksas - - - Copy bytes - Kopēt baitus - - - Copy priority - Kopēt prioritāti - - - Copy change - Kopēt atlikumu - - - or - vai - - - The amount to pay must be larger than 0. - Nosūtāmajai summai jābūt lielākai par 0. - - - The amount exceeds your balance. - Daudzums pārsniedz pieejamo. - - - The total exceeds your balance when the %1 transaction fee is included. - Kopsumma pārsniedz pieejamo, ja pieskaitīta %1 transakcijas maksa. - - - Transaction creation failed! - Transakcijas izveidošana neizdevās! - - - Warning: Invalid Bitcoin address - Brīdinājums: Nederīga Bitcoin adrese - - - (no label) - (bez nosaukuma) - - - Warning: Unknown change address - Brīdinājums: Nezināma atlikuma adrese - - - added as transaction fee - pievienots kā transakcijas maksa - SendCoinsEntry @@ -1490,10 +931,6 @@ Pay &To: &Saņēmējs: - - Enter a label for this address to add it to your address book - Lai pievienotu adresi adrešu grāmatai, tai jādod nosaukums - &Label: &Nosaukums: @@ -1537,10 +974,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core tiek izslēgta... - Do not shut down the computer until this window disappears. Neizslēdziet datoru kamēr šis logs nepazūd. @@ -1612,69 +1045,9 @@ Reset all verify message fields Atiestatīt visus laukus - - Click "Sign Message" to generate signature - Nospied "Parakstīt Ziņojumu" lai ģenerētu parakstu - - - The entered address is invalid. - Ievadītā adrese ir nederīga. - - - Please check the address and try again. - Lūdzu pārbaudi adresi un mēģini vēlreiz. - - - The entered address does not refer to a key. - Ievadītā adrese neattiecas uz atslēgu. - - - Wallet unlock was cancelled. - Maciņa atslēgšana tika atcelta. - - - Private key for the entered address is not available. - Privātā atslēga priekš ievadītās adreses nav pieejama. - - - Message signing failed. - Neizdevās parakstīt ziņojumu. - - - Message signed. - Ziņojums parakstīts. - - - The signature could not be decoded. - Paraksts nevarēja tikt dekodēts. - - - Please check the signature and try again. - Lūdzu pārbaudi parakstu un mēģini vēlreiz. - - - The signature did not match the message digest. - Paraksts neatbilda ziņojuma apkopojumam. - - - Message verification failed. - Ziņojumu neizdevās pārbaudīt. - - - Message verified. - Ziņojums pārbaudīts. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core izstrādātāji - [testnet] [testnets] @@ -1687,410 +1060,16 @@ KB/s - - TransactionDesc - - Open until %1 - Atvērts līdz %1 - - - conflicted - pretrunā - - - %1/offline - %1/bezsaistē - - - %1/unconfirmed - %1/neapstiprinātas - - - %1 confirmations - %1 apstiprinājumu - - - Status - Status - - - Date - Datums - - - Source - Avots - - - Generated - Ģenerēts - - - From - No - - - To - Uz - - - own address - paša adrese - - - label - etiķete - - - Credit - Kredīts - - - not accepted - nav pieņemts - - - Debit - Debets - - - Transaction fee - Transakcijas maksa - - - Net amount - Neto summa - - - Message - Ziņojums - - - Comment - Komentārs - - - Transaction ID - Transakcijas ID - - - Merchant - Tirgotājs - - - Debug information - Atkļūdošanas informācija - - - Transaction - Transakcija - - - Inputs - Ieejas - - - Amount - Daudzums - - - true - patiess - - - false - nepatiess - - - , has not been successfully broadcast yet - , vēl nav veiksmīgi izziņots - - - unknown - nav zināms - - TransactionDescDialog - - Transaction details - Transakcijas detaļas - This pane shows a detailed description of the transaction Šis panelis parāda transakcijas detaļas - - TransactionTableModel - - Date - Datums - - - Type - Tips - - - Open until %1 - Atvērts līdz %1 - - - Confirmed (%1 confirmations) - Apstiprināts (%1 apstiprinājumu) - - - This block was not received by any other nodes and will probably not be accepted! - Neviens cits mezgls šo bloku nav saņēmis un droši vien netiks akceptēts! - - - Generated but not accepted - Ģenerēts, taču nav akceptēts - - - Offline - Bezsaitē - - - Label - Nosaukums - - - Unconfirmed - Neapstiprināts - - - Conflicted - Pretrunā - - - Received with - Saņemts ar - - - Received from - Saņemts no - - - Sent to - Nosūtīts - - - Payment to yourself - Maksājums sev - - - Mined - Atrasts - - - (n/a) - (nav pieejams) - - - Transaction status. Hover over this field to show number of confirmations. - Transakcijas statuss. Turiet peli virs šī lauka, lai redzētu apstiprinājumu skaitu. - - - Date and time that the transaction was received. - Transakcijas saņemšanas datums un laiks. - - - Type of transaction. - Transakcijas tips. - - - Amount removed from or added to balance. - Bilancei pievienotais vai atņemtais daudzums. - - - - TransactionView - - All - Visi - - - Today - Šodien - - - This week - Šonedēļ - - - This month - Šomēnes - - - Last month - Pēdējais mēnesis - - - This year - Šogad - - - Range... - Diapazons... - - - Received with - Saņemts ar - - - Sent to - Nosūtīts - - - To yourself - Sev - - - Mined - Atrasts - - - Other - Cits - - - Enter address or label to search - Ierakstiet meklējamo nosaukumu vai adresi - - - Min amount - Minimālais daudzums - - - Copy address - Kopēt adresi - - - Copy label - Kopēt nosaukumu - - - Copy amount - Kopēt daudzumu - - - Copy transaction ID - Kopēt transakcijas ID - - - Edit label - Mainīt nosaukumu - - - Show transaction details - Rādīt transakcijas detaļas - - - Export Transaction History - Eksportēt Transakciju Vēsturi - - - Exporting Failed - Eksportēšana Neizdevās - - - Exporting Successful - Eksportēšana Veiksmīga - - - The transaction history was successfully saved to %1. - Transakciju vēsture tika veiksmīgi saglabāta uz %1. - - - Comma separated file (*.csv) - Fails ar komatu kā atdalītāju (*.csv) - - - Confirmed - Apstiprināts - - - Date - Datums - - - Type - Tips - - - Label - Nosaukums - - - Address - Adrese - - - ID - ID - - - Range: - Diapazons: - - - to - uz - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Neviens maciņš nav ielādēts. - - - - WalletModel - - Send Coins - Sūtīt Bitkoinus - - - - WalletView - - &Export - &Eksportēt - - - Export the data in the current tab to a file - Datus no tekošā ieliktņa eksportēt uz failu - - - Backup Wallet - Izveidot maciņa rezerves kopiju - - - Wallet Data (*.dat) - Maciņa dati (*.dat) - - - Backup Failed - Rezerves kopēšana neizdevās - - - There was an error trying to save the wallet data to %1. - Notikusi kļūme mēģinot saglabāt maciņa datus uz %1. - - - The wallet data was successfully saved to %1. - Maciņa dati tika veiksmīgi saglabāti uz %1. - - - Backup Successful - Dublēšana Veiksmīga - - bitcoin-core @@ -2117,6 +1096,10 @@ Run in the background as a daemon and accept commands Darbināt fonā kā servisu un pieņemt komandas + + Bitcoin Core + Bitcoin Core + <category> can be: <category> var būt: @@ -2161,26 +1144,10 @@ Wallet options: Maciņa iespējas: - - Cannot resolve -whitebind address: '%s' - Nevar atrisināt -whitebind adresi: '%s' - Information Informācija - - Invalid amount for -maxtxfee=<amount>: '%s' - Nederīgs daudzums priekš -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Nederīgs daudzums priekš -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Nederīgs daudzums priekš -mintxfee=<amount>: '%s' - RPC server options: RPC servera iestatījumi: @@ -2213,10 +1180,6 @@ Warning Brīdinājums - - wallet.dat corrupt, salvage failed - wallet.dat ir bojāts, glābšana neizdevās - Password for JSON-RPC connections JSON-RPC savienojumu parole @@ -2225,10 +1188,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Izpildīt komandu, kad labāk atbilstošais bloks izmainās (%s cmd aizvieto ar bloka hešu) - - This help message - Šis palīdzības paziņojums - Allow DNS lookups for -addnode, -seednode and -connect Atļaut DNS uzmeklēšanu priekš -addnode, -seednode un -connect @@ -2237,14 +1196,6 @@ Loading addresses... Ielādē adreses... - - Error loading wallet.dat: Wallet corrupted - Nevar ielādēt wallet.dat: maciņš bojāts - - - Error loading wallet.dat - Kļūda ielādējot wallet.dat - Invalid -proxy address: '%s' Nederīga -proxy adrese: '%s' @@ -2253,18 +1204,6 @@ Unknown network specified in -onlynet: '%s' -onlynet komandā norādīts nepazīstams tīkls: '%s' - - Cannot resolve -bind address: '%s' - Nevar uzmeklēt -bind adresi: '%s' - - - Cannot resolve -externalip address: '%s' - Nevar atrisināt -externalip adresi: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Nederīgs daudzums priekš -paytxfree=<amount>: '%s' - Insufficient funds Nepietiek bitkoinu diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts index b7797063b..b696111a5 100644 --- a/src/qt/locale/bitcoin_mk_MK.ts +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -25,10 +25,6 @@ C&lose З&атвори - - &Copy Address - &Копирај Адреса - Delete the currently selected address from the list Избриши ја избраната адреса од листата @@ -45,57 +41,6 @@ &Delete &Избриши - - Choose the address to send coins to - Изберете адресата за да пратите биткоини - - - Choose the address to receive coins with - Изберете адресата за да примите биткоини - - - C&hoose - И&збери - - - Sending addresses - Адреси за праќање - - - Receiving addresses - Адреси за примање - - - Copy &Label - Копирај &Етикета - - - &Edit - &Уреди - - - Export Address List - Експортирај Листа со Адреси - - - Exporting Failed - Експортирањето не Успеа - - - - AddressTableModel - - Label - Етикета - - - Address - Адреса - - - (no label) - (без етикета) - AskPassphraseDialog @@ -111,70 +56,6 @@ Repeat new passphrase Повторете ја новата тајна фраза - - Encrypt wallet - Криптирање на паричник - - - Unlock wallet - Отклучи паричник - - - Decrypt wallet - Декриптирање на паричник - - - Change passphrase - Измени тајна фраза - - - Confirm wallet encryption - Потврдете го криптирањето на паричникот - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Предупредување: Ако го шифрирате вашиот паричник и ја изгубите вашата тајна фраза, ќе <b>ГИ ИЗГУБИТЕ СИТЕ ВАШИ БИТКОИНИ</b>! - - - Are you sure you wish to encrypt your wallet? - Дали сте сигурни дека сакате да криптирате вашиот паричник? - - - Warning: The Caps Lock key is on! - Предупредување: Caps Lock копчето е активно! - - - Wallet encrypted - Паричникот е криптиран - - - Wallet encryption failed - Криптирањето на паричникот е неуспешно - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Криптирањето на паричникот не успеа поради интерна грешка. Вашиот паричник не е криптиран. - - - The supplied passphrases do not match. - Приложените тајни фрази не се поклопуваат - - - Wallet unlock failed - Отклучувањето на паричникот е неуспешно - - - The passphrase entered for the wallet decryption was incorrect. - Тајната фраза која што ја внесовте за декриптирање на паричникот е неточна. - - - Wallet decryption failed - Декриптирањето на паричникот е неуспешно - - - Wallet passphrase was successfully changed. - Тајната фраза е успешно променета. - BanTableModel @@ -249,14 +130,6 @@ Open &URI... Отвори &URI... - - Bitcoin Core client - Биткоин Core софтверот - - - Importing blocks from disk... - Внесување на блокови од дискот... - Reindexing blocks on disk... Повторно индексирање на блокови од дискот... @@ -285,10 +158,6 @@ &Receive &Прими - - Show information about Bitcoin Core - Прикажи информации за Биткоин Core - &Show / Hide &Прикажи / Сокриј @@ -305,14 +174,6 @@ &Help &Помош - - Bitcoin Core - Биткоин Core - - - &About Bitcoin Core - &За Биткоин Core - Processed %n block(s) of transaction history. Обработен %n блок од историјата на трансакции.Обработени %n блокови од историјата на трансакции. @@ -384,9 +245,6 @@ - - ClientModel - CoinControlDialog @@ -429,126 +287,6 @@ Priority Приоритет - - Copy address - Копирај адреса - - - Copy label - Копирај етикета - - - Copy amount - Копирај сума - - - Lock unspent - Заклучи непотрошени - - - Unlock unspent - Отклучи непотрошени - - - Copy quantity - Копирај количина - - - Copy fee - Копирај провизија - - - Copy after fee - Копирај после провизија - - - Copy bytes - Копирај бајти - - - Copy priority - Копирај приоритет - - - Copy dust - Копирај прашина - - - Copy change - Копирај кусур - - - highest - највисок - - - higher - повисок - - - high - висок - - - medium-high - средно-висок - - - medium - среден - - - low-medium - ниско-среден - - - low - низок - - - lower - понизок - - - lowest - најнизок - - - none - нема - - - This label turns red if the transaction size is greater than 1000 bytes. - Оваа етикета станува црвена ако големината на трансакцијата е поголема од 1000 бајти. - - - This label turns red if the priority is smaller than "medium". - Оваа етикета станува црвена ако приоритетот е помал од "среден". - - - This label turns red if any recipient receives an amount smaller than %1. - Оваа етикета станува црвена ако примачот прими сума помала од %1. - - - yes - да - - - no - не - - - Transactions with higher priority are more likely to get included into a block. - Трансакциите со повисок приоритет имаат поголеми шанси да бидат вклучени во блок. - - - (no label) - (без етикета) - - - (change) - (кусур) - EditAddressDialog @@ -564,7 +302,7 @@ &Address &Адреса - + FreespaceChecker @@ -574,10 +312,6 @@ HelpMessageDialog - - Bitcoin Core - Биткоин Core - version верзија @@ -586,17 +320,9 @@ (%1-bit) (%1-бит) - - About Bitcoin Core - За Биткоин Core - Intro - - Bitcoin Core - Биткоин Core - Error Грешка @@ -655,9 +381,6 @@ Вкупно: - - PaymentServer - PeerTableModel @@ -688,21 +411,6 @@ %1 мс - - QRImageWidget - - &Save Image... - &Сними Слика... - - - Save QR Code - Сними QR Код - - - PNG Image (*.png) - PNG Слика (*.png) - - RPCConsole @@ -768,19 +476,7 @@ Show Прикажи - - Copy label - Копирај етикета - - - Copy message - Копирај порака - - - Copy amount - Копирај сума - - + ReceiveRequestDialog @@ -799,50 +495,7 @@ &Save Image... &Сними Слика... - - URI - URI - - - Address - Адреса - - - Amount - Сума - - - Label - Етикета - - - Message - Порака - - - - RecentRequestsTableModel - - Date - Дата - - - Label - Етикета - - - Message - Порака - - - Amount - Сума - - - (no label) - (без етикета) - - + SendCoinsDialog @@ -873,42 +526,6 @@ Dust: Прашина: - - Copy quantity - Копирај количина - - - Copy amount - Копирај сума - - - Copy fee - Копирај провизија - - - Copy after fee - Копирај после провизија - - - Copy bytes - Копирај бајти - - - Copy priority - Копирај приоритет - - - Copy change - Копирај кусур - - - (no label) - (без етикета) - - - Copy dust - Копирај прашина - SendCoinsEntry @@ -933,100 +550,26 @@ SplashScreen - - Bitcoin Core - Биткоин Core - TrafficGraphWidget - - TransactionDesc - - Date - Дата - - - Message - Порака - - - Amount - Сума - - TransactionDescDialog - - TransactionTableModel - - Date - Дата - - - Label - Етикета - - - - TransactionView - - Copy address - Копирај Адреса - - - Copy label - Копирај етикета - - - Copy amount - Копирај сума - - - Exporting Failed - Експортирањето не Успеа - - - Date - Дата - - - Label - Етикета - - - Address - Адреса - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Експорт - - - Export the data in the current tab to a file - Експортирај ги податоците од активното јазиче во датотека - - bitcoin-core Options: Опции: + + Bitcoin Core + Биткоин Core + Warning Предупредување diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index b79001006..e38320ac5 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -21,10 +21,6 @@ C&lose &Хаах - - &Copy Address - Хаягийг &Хуулбарлах - Delete the currently selected address from the list Одоо сонгогдсон байгаа хаягуудыг жагсаалтаас устгах @@ -41,65 +37,6 @@ &Delete &Устгах - - Choose the address to send coins to - Зооснуудыг илгээх хаягийг сонгоно уу - - - Choose the address to receive coins with - Зооснуудыг хүлээн авах хаягийг сонгоно уу - - - C&hoose - С&онго - - - Sending addresses - Илгээх хаягууд - - - Receiving addresses - Хүлээн авах хаяг - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Эдгээр Биткойн хаягууд нь илгээх хаягууд. Хүлээн авах хаяг болон тоо хэмжээг илгээхээсээ өмнө сайн нягталж үзэж байна уу - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Эдгээр Биткойн хаягууд нь хүлээн авах хаягууд. Гүйлгээ болгонд шинээр хаяг үүсгэхийг бид санал болгож байна. - - - Copy &Label - &Шошгыг хуулбарлах - - - &Edit - &Ѳѳрчлѳх - - - Export Address List - Экспорт хийх хаягуудын жагсаалт - - - Comma separated file (*.csv) - Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv) - - - - AddressTableModel - - Label - Шошго - - - Address - Хаяг - - - (no label) - (шошгогүй) - AskPassphraseDialog @@ -115,66 +52,6 @@ Repeat new passphrase Шинэ нууц үгийг давтана уу - - Encrypt wallet - Түрүйвчийг цоожлох - - - This operation needs your wallet passphrase to unlock the wallet. - Энэ үйлдэлийг гүйцэтгэхийн тулд та нууц үгээрээ түрүйвчийн цоожийг тайлах хэрэгтэй - - - Unlock wallet - Түрүйвчийн цоожийг тайлах - - - This operation needs your wallet passphrase to decrypt the wallet. - Энэ үйлдэлийг гүйцэтгэхийн тулд та эхлээд түрүйвчийн нууц үгийг оруулж цоожийг тайлах шаардлагтай. - - - Decrypt wallet - Түрүйвчийн цоожийг устгах - - - Change passphrase - Нууц үгийг солих - - - Confirm wallet encryption - Түрүйвчийн цоожийг баталгаажуулах - - - Wallet encrypted - Түрүйвч цоожлогдлоо - - - Wallet encryption failed - Түрүйвчийн цоожлол амжилттай болсонгүй - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Түрүйвчийн цоожлол дотоод алдаанаас үүдэн амжилттай болсонгүй. Түрүйвч цоожлогдоогүй байна. - - - The supplied passphrases do not match. - Таны оруулсан нууц үг таарсангүй - - - Wallet unlock failed - Түрүйвчийн цоож тайлагдсангүй - - - The passphrase entered for the wallet decryption was incorrect. - Таны оруулсан түрүйвчийн цоожийг тайлах нууц үг буруу байна - - - Wallet decryption failed - Түрүйвчийн цоож амжилттай устгагдсангүй - - - Wallet passphrase was successfully changed. - Түрүйвчийн нууц үг амжилттай ѳѳр - BanTableModel @@ -298,9 +175,6 @@ Түрүйвч <b>цоожтой</b> ба одоогоор цоож <b>хаалттай</b> байна - - ClientModel - CoinControlDialog @@ -323,31 +197,7 @@ Confirmed Баталгаажлаа - - Copy address - Хаягийг санах - - - Copy label - Шошгыг санах - - - Copy amount - Хэмжээг санах - - - Copy change - Ѳѳрчлѳлтийг санах - - - (no label) - (шошгогүй) - - - (change) - (ѳѳрчлѳх) - - + EditAddressDialog @@ -362,34 +212,6 @@ &Address &Хаяг - - New receiving address - Шинэ хүлээн авах хаяг - - - New sending address - Шинэ явуулах хаяг - - - Edit receiving address - Хүлээн авах хаягийг ѳѳрчлѳх - - - Edit sending address - Явуулах хаягийг ѳѳрчлѳх - - - The entered address "%1" is already in the address book. - Таны оруулсан хаяг "%1" нь хаягийн бүртгэлд ѳмнѳ нь орсон байна - - - Could not unlock wallet. - Түрүйвчийн цоожийг тайлж чадсангүй - - - New key generation failed. - Шинэ түлхүүр амжилттай гарсангүй - FreespaceChecker @@ -453,9 +275,6 @@ Хэрэглэж болох хэмжээ: - - PaymentServer - PeerTableModel @@ -470,13 +289,6 @@ Алга Байна - - QRImageWidget - - PNG Image (*.png) - PNG форматын зураг (*.png) - - RPCConsole @@ -562,18 +374,6 @@ Remove Устгах - - Copy label - Шошгыг санах - - - Copy message - Зурвасыг санах - - - Copy amount - Хэмжээг санах - ReceiveRequestDialog @@ -581,49 +381,6 @@ Copy &Address Хаягийг &Хуулбарлах - - Address - Хаяг - - - Amount - Хэмжээ - - - Label - Шошго - - - Message - Зурвас - - - - RecentRequestsTableModel - - Date - Огноо - - - Label - Шошго - - - Message - Зурвас - - - Amount - Хэмжээ - - - (no label) - (шошгогүй) - - - (no message) - (зурвас алга) - SendCoinsDialog @@ -671,43 +428,7 @@ S&end Яв&уул - - Confirm send coins - Зоос явуулахыг баталгаажуулна уу - - - Copy amount - Хэмжээг санах - - - Copy change - Ѳѳрчлѳлтийг санах - - - or - эсвэл - - - The amount to pay must be larger than 0. - Тѳлѳх хэмжээ 0.-оос их байх ёстой - - - The amount exceeds your balance. - Энэ хэмжээ таны балансаас хэтэрсэн байна. - - - The total exceeds your balance when the %1 transaction fee is included. - Гүйлгээний тѳлбѳр %1-ийг тооцхоор нийт дүн нь таны балансаас хэтрээд байна. - - - Warning: Invalid Bitcoin address - Анхаар:Буруу Биткойны хаяг байна - - - (no label) - (шошгогүй) - - + SendCoinsEntry @@ -718,10 +439,6 @@ Pay &To: Тѳлѳх &хаяг: - - Enter a label for this address to add it to your address book - Энэ хаягийг ѳѳрийн бүртгэлдээ авахын тулд шошго оруул - &Label: &Шошго: @@ -749,10 +466,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Биткойны цѳм хаагдаж байна... - Do not shut down the computer until this window disappears. Энэ цонхыг хаагдтал компьютерээ бүү унтраагаарай @@ -783,278 +496,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - %1 хүртэл нээлттэй - - - conflicted - зѳрчилдлѳѳ - - - %1/unconfirmed - %1/баталгаажаагүй - - - %1 confirmations - %1 баталгаажилтууд - - - Date - Огноо - - - Message - Зурвас - - - Transaction ID - Тодорхойлолт - - - Amount - Хэмжээ - - - , has not been successfully broadcast yet - , хараахан амжилттай цацагдаагүй байна - - - unknown - үл мэдэгдэх - - TransactionDescDialog - - Transaction details - Гүйлгээний мэдээллэл - This pane shows a detailed description of the transaction Гүйлгээний дэлгэрэнгүйг энэ бичил цонх харуулж байна - - TransactionTableModel - - Date - Огноо - - - Type - Тѳрѳл - - - Open until %1 - %1 хүртэл нээлттэй - - - Confirmed (%1 confirmations) - Баталгаажлаа (%1 баталгаажилт) - - - This block was not received by any other nodes and will probably not be accepted! - Энэ блокийг аль ч нод хүлээн авсангүй ба ер нь зѳвшѳѳрѳгдѳхгүй байж мэднэ! - - - Generated but not accepted - Үүсгэгдсэн гэхдээ хүлээн авагдаагүй - - - Label - Шошго - - - Unconfirmed - Баталгаажаагүй - - - Conflicted - Зѳрчилдлѳѳ - - - Received with - Хүлээн авсан хаяг - - - Received from - Хүлээн авагдсан хаяг - - - Sent to - Явуулсан хаяг - - - Payment to yourself - Ѳѳрлүүгээ хийсэн тѳлбѳр - - - Mined - Олборлогдсон - - - (n/a) - (алга байна) - - - Transaction status. Hover over this field to show number of confirmations. - Гүйлгээний байдал. Энд хулганыг авчирч баталгаажуулалтын тоог харна уу. - - - Date and time that the transaction was received. - Гүйлгээг хүлээн авсан огноо ба цаг. - - - Type of transaction. - Гүйлгээний тѳрѳл - - - Amount removed from or added to balance. - Балансаас авагдсан болон нэмэгдсэн хэмжээ. - - - - TransactionView - - All - Бүгд - - - Today - Ѳнѳѳдѳр - - - This week - Энэ долоо хоног - - - This month - Энэ сар - - - Last month - Ѳнгѳрсѳн сар - - - This year - Энэ жил - - - Received with - Хүлээн авсан хаяг - - - Sent to - Явуулсан хаяг - - - To yourself - Ѳѳрлүүгээ - - - Mined - Олборлогдсон - - - Other - Бусад - - - Enter address or label to search - Хайлт хийхийн тулд хаяг эсвэл шошгыг оруул - - - Min amount - Хамгийн бага хэмжээ - - - Copy address - Хаягийг санах - - - Copy label - Шошгыг санах - - - Copy amount - Хэмжээг санах - - - Edit label - Шошгыг ѳѳрчлѳх - - - Show transaction details - Гүйлгээний дэлгэрэнгүйг харуул - - - The transaction history was successfully saved to %1. - Гүйлгээнүй түүхийг %1-д амжилттай хадгаллаа. - - - Comma separated file (*.csv) - Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv) - - - Confirmed - Баталгаажлаа - - - Date - Огноо - - - Type - Тѳрѳл - - - Label - Шошго - - - Address - Хаяг - - - ID - Тодорхойлолт - - - to - -рүү/руу - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Ямар ч түрүйвч ачааллагдсангүй. - - - - WalletModel - - Send Coins - Зоос явуулах - - - - WalletView - - &Export - &Экспортдлох - - - Export the data in the current tab to a file - Сонгогдсон таб дээрхи дата-г экспортлох - - bitcoin-core @@ -1073,14 +524,6 @@ Loading addresses... Хаягуудыг ачааллаж байна... - - Error loading wallet.dat: Wallet corrupted - wallet.dat-ыг ачааллахад алдаа гарлаа: Түрүйвч эвдэрсэн байна - - - Error loading wallet.dat - wallet.dat-ыг ачааллахад алдаа гарлаа - Invalid -proxy address: '%s' Эдгээр прокси хаягнууд буруу байна: '%s' diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index df98dd839..de4c32c2d 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -17,10 +17,6 @@ &Copy &Salin - - &Copy Address - &Salin Alamat - &Export &Eksport @@ -29,30 +25,7 @@ &Delete &Padam - - Choose the address to send coins to - Pilih alamat untuk menghantar syiling - - - Choose the address to receive coins with - Pilih alamat untuk menerima syiling - - - C&hoose - &Pilih - - - Comma separated file (*.csv) - Fail yang dipisahkan dengan koma - - - - AddressTableModel - - Address - Alamat - - + AskPassphraseDialog @@ -66,9 +39,6 @@ Pilihan - - ClientModel - CoinControlDialog @@ -82,7 +52,7 @@ &Address Alamat - + FreespaceChecker @@ -101,18 +71,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -125,13 +89,6 @@ Copy &Address &Salin Alamat - - Address - Alamat - - - - RecentRequestsTableModel SendCoinsDialog @@ -155,42 +112,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - - TransactionView - - Comma separated file (*.csv) - Fail yang dipisahkan dengan koma - - - Address - Alamat - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Eksport - - bitcoin-core diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 94e02f890..b5ffdb2e1 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -25,10 +25,6 @@ C&lose &Lukk - - &Copy Address - &Kopier Adresse - Delete the currently selected address from the list Slett den valgte adressen fra listen. @@ -45,73 +41,6 @@ &Delete &Slett - - Choose the address to send coins to - Velg adressen å sende mynter til - - - Choose the address to receive coins with - Velg adressen til å motta mynter med - - - C&hoose - &Velg - - - Sending addresses - Utsendingsadresser - - - Receiving addresses - Mottaksadresser - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Dette er dine Bitcoin-adresser for å sende betalinger. Alltid sjekk beløp og mottakeradresse før sending av mynter. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dette er dine Bitcoin-adresser for å sende betalinger. Det er anbefalt å bruk en ny mottaksadresse for hver transaksjon. - - - Copy &Label - Kopier &Merkelapp - - - &Edit - &Rediger - - - Export Address List - Ekporter Adresseliste - - - Comma separated file (*.csv) - Kommaseparert fil (*.csv) - - - Exporting Failed - Eksportering feilet - - - There was an error trying to save the address list to %1. Please try again. - Det oppstod en feil under lagring av adresselisten til %1. Vennligst prøv på nytt. - - - - AddressTableModel - - Label - Merkelapp - - - Address - Adresse - - - (no label) - (ingen merkelapp) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Gjenta ny adgangsfrase - - Encrypt wallet - Krypter lommebok - - - This operation needs your wallet passphrase to unlock the wallet. - Denne operasjonen krever adgangsfrasen til lommeboken for å låse den opp. - - - Unlock wallet - Lås opp lommebok - - - This operation needs your wallet passphrase to decrypt the wallet. - Denne operasjonen krever adgangsfrasen til lommeboken for å dekryptere den. - - - Decrypt wallet - Dekrypter lommebok - - - Change passphrase - Endre adgangsfrase - - - Confirm wallet encryption - Bekreft kryptering av lommebok - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Advarsel: Hvis du krypterer lommeboken og mister adgangsfrasen, så vil du <b>MISTE ALLE DINE BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Er du sikker på at du vil kryptere lommeboken? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core vil nå avslutte for å fullføre krypteringsprosessen. Husk at kryptering av lommeboken ikke kan beskytte fullstendig mot tyveri av dine bitcoins hvis datamaskinen din er infisert av skadevare. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - VIKTIG: Tidligere sikkerhetskopier av din lommebokfil bør erstattes med den nylig genererte og krypterte filen, da de blir ugyldiggjort av sikkerhetshensyn så snart du begynner å bruke den nye krypterte lommeboken. - - - Warning: The Caps Lock key is on! - Advarsel: Caps Lock er på! - - - Wallet encrypted - Lommebok kryptert - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Oppgi adgangsfrasen til lommeboken.<br/>Vennligst bruk en adgangsfrase med <b>ti eller flere tilfeldige tegn</b>, eller <b>åtte eller flere ord</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Oppgi gammel og ny adgangsfrase til lommeboken. - - - Wallet encryption failed - Kryptering av lommebok feilet - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Kryptering av lommebok feilet på grunn av en intern feil. Din lommebok ble ikke kryptert. - - - The supplied passphrases do not match. - De angitte adgangsfrasene er ulike. - - - Wallet unlock failed - Opplåsing av lommebok feilet - - - The passphrase entered for the wallet decryption was incorrect. - Adgangsfrasen angitt for dekryptering av lommeboken var feil. - - - Wallet decryption failed - Dekryptering av lommebok feilet - - - Wallet passphrase was successfully changed. - Adgangsfrase for lommebok endret. - BanTableModel @@ -269,6 +110,10 @@ Quit application Avslutt applikasjonen + + &About %1 + &Om %1 + About &Qt Om &Qt @@ -305,14 +150,6 @@ Open &URI... Åpne &URI... - - Bitcoin Core client - Bitcoin Core-klient - - - Importing blocks from disk... - Importere blokker... - Reindexing blocks on disk... Reindekserer blokker på harddisk... @@ -357,10 +194,6 @@ &Receive &Motta - - Show information about Bitcoin Core - Vis informasjon om Bitcoin Core - &Show / Hide &Vis / Skjul @@ -397,22 +230,10 @@ Tabs toolbar Verktøylinje for faner - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Forespør betalinger (genererer QR-koder og bitcoin: URIer) - - &About Bitcoin Core - &Om Bitcoin Core - - - Modify configuration options for Bitcoin Core - Endre konfigurasjonsvalg for Bitcoin Core - Show the list of used sending addresses and labels Vis listen av brukte utsendingsadresser og merkelapper @@ -429,10 +250,6 @@ &Command-line options &Kommandolinjevalg - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Vis Bitcoin Core hjelpemeldingen for å få en liste med mulige kommandolinjevalg - %n active connection(s) to Bitcoin network %n aktiv forbindelse til Bitcoin-nettverket%n aktive forbindelser til Bitcoin-nettverket @@ -544,13 +361,6 @@ Lommeboken er <b>kryptert</b> og for tiden <b>låst</b> - - ClientModel - - Network Alert - Nettverksvarsel - - CoinControlDialog @@ -629,150 +439,6 @@ Priority Prioritet - - Copy address - Kopier adresse - - - Copy label - Kopier merkelapp - - - Copy amount - Kopier beløp - - - Copy transaction ID - Kopier transaksjons-ID - - - Lock unspent - Lås ubrukte - - - Unlock unspent - Lås opp ubrukte - - - Copy quantity - Kopier mengde - - - Copy fee - Kopier gebyr - - - Copy after fee - Kopier totalt - - - Copy bytes - Kopier bytes - - - Copy priority - Kopier prioritet - - - Copy dust - Kopier støv - - - Copy change - Kopier veksel - - - highest - høyest - - - higher - høyere - - - high - høy - - - medium-high - medium-høy - - - medium - medium - - - low-medium - lav-medium - - - low - lav - - - lower - lavere - - - lowest - lavest - - - (%1 locked) - (%1 låst) - - - none - ingen - - - This label turns red if the transaction size is greater than 1000 bytes. - Denne teksten blir rød hvis transaksjonsstørrelsen er større enn 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Denne teksten blir rød hvis prioriteten er lavere enn "medium". - - - This label turns red if any recipient receives an amount smaller than %1. - Denne teksten blir rød dersom en mottaker mottar et beløp mindre enn %1. - - - Can vary +/- %1 satoshi(s) per input. - Kan variere +/- %1 satoshi(er) per input. - - - yes - ja - - - no - nei - - - This means a fee of at least %1 per kB is required. - Dette betyr at et gebyr på minst %1 per KB er påkrevd. - - - Can vary +/- 1 byte per input. - Kan variere +/- 1 byte per input. - - - Transactions with higher priority are more likely to get included into a block. - Transaksjoner med høyere prioritet har mer sannsynlighet for å bli inkludert i en blokk. - - - (no label) - (ingen merkelapp) - - - change from %1 (%2) - veksel fra %1 (%2) - - - (change) - (veksel) - EditAddressDialog @@ -796,38 +462,6 @@ &Address &Adresse - - New receiving address - Ny mottaksadresse - - - New sending address - Ny utsendingsadresse - - - Edit receiving address - Rediger mottaksadresse - - - Edit sending address - Rediger utsendingsadresse - - - The entered address "%1" is already in the address book. - Den oppgitte adressen "%1" er allerede i adresseboken. - - - The entered address "%1" is not a valid Bitcoin address. - Den angitte adressed "%1" er ikke en gyldig Bitcoin-adresse. - - - Could not unlock wallet. - Kunne ikke låse opp lommeboken. - - - New key generation failed. - Generering av ny nøkkel feilet. - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versjon @@ -866,10 +496,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Om Bitcoin Core - Command-line options Kommandolinjevalg @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Vis velkomstbilde ved oppstart (default: %u) - - Reset all settings changes made over the GUI - Nullstill alle oppsettendringer gjort via det grafiske grensesnittet - - + Intro Welcome Velkommen - - Welcome to Bitcoin Core. - Velkommen til Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Siden dette er første gang programmet starter, kan du nå velge hvor Bitcoin Core skal lagre sine data. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core vil laste ned og lagre en kopi av Bitcoin sin blokkjede. Minst %1GB av data vil bli lagret i denne mappen, og det vil vokse over tid. Lommeboken vil også bli lagret i denne mappen. - Use the default data directory Bruk standard datamappe @@ -937,10 +547,6 @@ Use a custom data directory: Bruk en egendefinert datamappe: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Feil: Den oppgitte datamappen "%1" kan ikke opprettes. @@ -976,10 +582,6 @@ Select payment request file Velg fil for betalingsetterspørring - - Select payment request file to open - Velg fil for betalingsetterspørring å åpne - OptionsDialog @@ -1019,10 +621,6 @@ 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. Minimer i stedet for å avslutte applikasjonen når vinduet lukkes. Når dette er valgt, vil applikasjonen avsluttes kun etter at Avslutte er valgt i menyen. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Språk for brukergrensesnittet kan velges her. Denne innstillingen trer i kraft etter omstart av Bitcoin Core. - 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 |. Tredjepart URLer (f. eks. en blokkutforsker) som dukker opp i transaksjonsfanen som kontekst meny elementer. %s i URLen er erstattet med transaksjonen sin hash. Flere URLer er separert av en vertikal linje |. @@ -1047,14 +645,6 @@ &Network &Nettverk - - Automatically start Bitcoin Core after logging in to the system. - Start Bitcoin Core automatisk ved oppstart av datamaskinen. - - - &Start Bitcoin Core on system login - &Start Bitcoin Core ved oppstart av datamaskinen - (0 = auto, <0 = leave that many cores free) (0 = automatisk, <0 = la så mange kjerner være ledig) @@ -1283,97 +873,6 @@ Nåværende totale balanse i kun observerbare adresser - - PaymentServer - - URI handling - URI-håndtering - - - Invalid payment address %1 - Ugyldig betalingsadresse %1 - - - Payment request rejected - Betalingsetterspørring avvist - - - Payment request network doesn't match client network. - Nettverk for betalingsetterspørring er ikke i overensstemmelse med klientnettverket. - - - Payment request is not initialized. - Betalingsetterspørringen er ikke initialisert. - - - Requested payment amount of %1 is too small (considered dust). - Forespurt betalingsmengde på %1 er for liten (betraktet som støv). - - - Payment request error - Betalingsetterspørringsfeil - - - Cannot start bitcoin: click-to-pay handler - Kan ikke starte Bitcoin: klikk-og-betal håndterer - - - Payment request fetch URL is invalid: %1 - Hentelenke for betalingsetterspørring er ugyldig: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kan ikke fortolkes! Dette kan være forårsaket av en ugyldig Bitcoin-adresse eller feilformede URI-parametre. - - - Payment request file handling - Filhåndtering for betalingsetterspørring - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Betalingsetterspørringsfil kan ikke leses! Dette kan være forårsaket av en ugyldig betalingsetterspørringsfil. - - - Payment request expired. - Betalingsetterspørringen har utløpt. - - - Unverified payment requests to custom payment scripts are unsupported. - Uverifiserte betalingsforespørsler til egentilpassede betalingscript er ikke støttet. - - - Invalid payment request. - Ugyldig betalingsetterspørring. - - - Refund from %1 - Refundering fra %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Betalingsforespørsel %1 er for stor (%2 bytes, tillatt %3 bytes). - - - Error communicating with %1: %2 - Feil i kommunikasjonen med %1: %2 - - - Payment request cannot be parsed! - Betaingsetterspørrelse kan ikke fortolkes! - - - Bad response from server %1 - Dårlig svar fra server %1 - - - Payment acknowledged - Betaling erkjent - - - Network request error - Nettverksforespørsel feil - - PeerTableModel @@ -1428,25 +927,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Lagre Bilde... - - - &Copy Image - &Kopier Bilde - - - Save QR Code - Lagre QR-kode - - - PNG Image (*.png) - PNG-bilde (*.png) - - RPCConsole @@ -1513,10 +993,6 @@ Memory usage Minnebruk - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler. - Received Mottatt @@ -1633,10 +1109,6 @@ Out: Ut: - - Build date - Byggedato - Debug log file Loggfil for feilsøk @@ -1673,10 +1145,6 @@ &Unban Node Fjern &Utestengning av Node - - Welcome to the Bitcoin Core RPC console. - Velkommen til Bitcoin Core sin RPC-konsoll. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Bruk opp og ned pil for å navigere historikken, og <b>Ctrl-L</b> for å tømme skjermen. @@ -1804,18 +1272,6 @@ Remove Fjern - - Copy label - Kopier merkelapp - - - Copy message - Kopier melding - - - Copy amount - Kopier beløp - ReceiveRequestDialog @@ -1835,73 +1291,6 @@ &Save Image... &Lagre Bilde... - - Request payment to %1 - Etterspør betaling til %1 - - - Payment information - Betalingsinformasjon - - - URI - URI - - - Address - Adresse - - - Amount - Beløp - - - Label - Merkelapp - - - Message - Melding - - - Resulting URI too long, try to reduce the text for label / message. - Resultat URI for lang, prøv å redusere teksten for merkelapp / melding. - - - Error encoding URI into QR Code. - Feil ved koding av URI til QR-kode. - - - - RecentRequestsTableModel - - Date - Dato - - - Label - Merkelapp - - - Message - Melding - - - Amount - Beløp - - - (no label) - (ingen merkelapp) - - - (no message) - (ingen melding) - - - (no amount) - (intet beløp) - SendCoinsDialog @@ -2021,14 +1410,6 @@ fast rask - - Send as zero-fee transaction if possible - Send uten transaksjonsgebyr hvis mulig - - - (confirmation may take longer) - (bekreftelse kan ta lengre tid) - Send to multiple recipients at once Send til flere enn en mottaker @@ -2061,118 +1442,6 @@ S&end S&end - - Confirm send coins - Bekreft sending av bitcoins - - - %1 to %2 - %1 til %2 - - - Copy quantity - Kopier mengde - - - Copy amount - Kopier beløp - - - Copy fee - Kopier gebyr - - - Copy after fee - Kopier fra gebyr - - - Copy bytes - Kopier bytes - - - Copy priority - Kopier prioritet - - - Copy change - Kopier veksel - - - Total Amount %1 - Totalt Beløp %1 - - - or - eller - - - The amount to pay must be larger than 0. - Beløpet som skal betales må være over 0. - - - The amount exceeds your balance. - Beløpet overstiger saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - Totalbeløpet overstiger saldo etter at %1 transaksjonsgebyr er lagt til. - - - Transaction creation failed! - Opprettelse av transaksjon feilet! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transaksjonen ble avvist! Dette kan skje hvis noen av myntene i lommeboken allerede er brukt, som hvis du kopierte wallet.dat og mynter ble brukt i kopien uten å bli markert som brukt her. - - - A fee higher than %1 is considered an absurdly high fee. - Et gebyr høyere enn %1 er ansett som et absurd høyt gebyr. - - - Payment request expired. - Betalingsetterspørringen har utløpt. - - - Pay only the required fee of %1 - Betal kun påkrevd gebyr på %1 - - - Estimated to begin confirmation within %n block(s). - Anslått til å begynne bekreftelse innen %n blokk.Anslått til å begynne bekreftelse innen %n blokker. - - - The recipient address is not valid. Please recheck. - Mottakeradressen er ikke gyldig. Vennligst kontroller på nytt. - - - Duplicate address found: addresses should only be used once each. - Gjenbruk av adresse funnet: adresser skal bare brukes en gang hver. - - - Warning: Invalid Bitcoin address - Advarsel: Ugyldig Bitcoin-adresse - - - (no label) - (ingen merkelapp) - - - Warning: Unknown change address - Advarsel: Ukjent adresse for veksel - - - Copy dust - Kopier støv - - - Are you sure you want to send? - Er du sikker på at du vil sende? - - - added as transaction fee - lagt til som transaksjonsgebyr - SendCoinsEntry @@ -2184,10 +1453,6 @@ Pay &To: Betal &Til: - - Enter a label for this address to add it to your address book - Skriv inn en merkelapp for denne adressen for å legge den til i din adressebok - &Label: &Merkelapp: @@ -2259,10 +1524,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core lukker... - Do not shut down the computer until this window disappears. Slå ikke av datamaskinen før dette vinduet forsvinner. @@ -2354,69 +1615,9 @@ Reset all verify message fields Tilbakestill alle felter for meldingsverifikasjon - - Click "Sign Message" to generate signature - Klikk "Signer Melding" for å generere signatur - - - The entered address is invalid. - Angitt adresse er ugyldig. - - - Please check the address and try again. - Vennligst sjekk adressen og prøv igjen. - - - The entered address does not refer to a key. - Angitt adresse refererer ikke til en nøkkel. - - - Wallet unlock was cancelled. - Opplåsing av lommebok ble avbrutt. - - - Private key for the entered address is not available. - Privat nøkkel for den angitte adressen er ikke tilgjengelig. - - - Message signing failed. - Signering av melding feilet. - - - Message signed. - Melding signert. - - - The signature could not be decoded. - Signaturen kunne ikke dekodes. - - - Please check the signature and try again. - Vennligst sjekk signaturen og prøv igjen. - - - The signature did not match the message digest. - Signaturen passer ikke til meldingen. - - - Message verification failed. - Verifikasjon av melding feilet. - - - Message verified. - Melding verifisert. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core utviklerne - [testnet] [testnett] @@ -2429,422 +1630,13 @@ KB/s - - TransactionDesc - - Open until %1 - Åpen til %1 - - - conflicted - konflikt - - - %1/offline - %1/frakoblet - - - %1/unconfirmed - %1/ubekreftet - - - %1 confirmations - %1 bekreftelser - - - Status - Status - - - , broadcast through %n node(s) - , kringkast gjennom %n node, kringkast gjennom %n noder - - - Date - Dato - - - Source - Kilde - - - Generated - Generert - - - From - Fra - - - To - Til - - - own address - egen adresse - - - watch-only - kun observerbar - - - label - merkelapp - - - Credit - Kredit - - - matures in %n more block(s) - blir moden om %n blokkblir moden om %n blokker - - - not accepted - ikke akseptert - - - Debit - Debet - - - Total debit - Total debet - - - Total credit - Total kredit - - - Transaction fee - Transaksjonsgebyr - - - Net amount - Nettobeløp - - - Message - Melding - - - Comment - Kommentar - - - Transaction ID - Transaksjons-ID - - - Merchant - Forhandler - - - 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. - Genererte bitcoins må modnes %1 blokker før de kan brukes. Da du genererte denne blokken ble den kringkastet på nettverket for å bli lagt til i kjeden av blokker. Hvis den ikke kommer med i kjeden vil den endre seg til "ikke akseptert" og pengene vil ikke kunne brukes. Dette vil noen ganger skje hvis en annen node genererer en blokk noen sekunder i tid fra din egen. - - - Debug information - Informasjon for feilsøk - - - Transaction - Transaksjon - - - Inputs - Inndata - - - Amount - Beløp - - - true - sann - - - false - usann - - - , has not been successfully broadcast yet - , har ikke blitt kringkastet med hell enda - - - Open for %n more block(s) - Åpen for %n blokk tilÅpen for %n blokker til - - - unknown - ukjent - - TransactionDescDialog - - Transaction details - Transaksjonsdetaljer - This pane shows a detailed description of the transaction Her vises en detaljert beskrivelse av transaksjonen - - TransactionTableModel - - Date - Dato - - - Type - Type - - - Immature (%1 confirmations, will be available after %2) - Umoden (%1 bekreftelser, vil være tilgjengelig etter %2) - - - Open for %n more block(s) - Åpen for %n blokk tilÅpen for %n blokker til - - - Open until %1 - Åpen til %1 - - - Confirmed (%1 confirmations) - Bekreftet (%1 bekreftelser) - - - This block was not received by any other nodes and will probably not be accepted! - Denne blokken har ikke blitt mottatt av noen andre noder og vil sannsynligvis ikke bli akseptert! - - - Generated but not accepted - Generert men ikke akseptert - - - Offline - Frakoblet - - - Label - Merkelapp - - - Unconfirmed - Ubekreftet - - - Confirming (%1 of %2 recommended confirmations) - Bekrefter (%1 av %2 anbefalte bekreftelser) - - - Conflicted - Konflikt - - - Received with - Mottatt med - - - Received from - Mottatt fra - - - Sent to - Sendt til - - - Payment to yourself - Betaling til deg selv - - - Mined - Utvunnet - - - watch-only - kun observerbar - - - (n/a) - - - - - Transaction status. Hover over this field to show number of confirmations. - Transaksjonsstatus. Hold muspekeren over dette feltet for å se antall bekreftelser. - - - Date and time that the transaction was received. - Dato og tid for da transaksjonen ble mottat. - - - Type of transaction. - Type transaksjon. - - - Whether or not a watch-only address is involved in this transaction. - Hvorvidt en kun observerbar adresse er involvert i denne transaksjonen. - - - User-defined intent/purpose of the transaction. - Brukerdefinert intensjon/hensikt med transaksjonen. - - - Amount removed from or added to balance. - Beløp fjernet eller lagt til saldo. - - - - TransactionView - - All - Alle - - - Today - I dag - - - This week - Denne uken - - - This month - Denne måneden - - - Last month - Forrige måned - - - This year - Dette året - - - Range... - Intervall... - - - Received with - Mottatt med - - - Sent to - Sendt til - - - To yourself - Til deg selv - - - Mined - Utvunnet - - - Other - Andre - - - Enter address or label to search - Skriv inn adresse eller merkelapp for søk - - - Min amount - Minimumsbeløp - - - Copy address - Kopier adresse - - - Copy label - Kopier merkelapp - - - Copy amount - Kopier beløp - - - Copy transaction ID - Kopier transaksjons-ID - - - Copy raw transaction - Kopier råtransaksjon - - - Edit label - Rediger merkelapp - - - Show transaction details - Vis transaksjonsdetaljer - - - Export Transaction History - Eksporter Transaksjonshistorikk - - - Watch-only - Kun observer - - - Exporting Failed - Ekport Feilet - - - There was an error trying to save the transaction history to %1. - En feil oppstod ved lagring av transaksjonshistorikken til %1. - - - Exporting Successful - Ekport Fullført - - - The transaction history was successfully saved to %1. - Transaksjonshistorikken ble lagret til %1. - - - Comma separated file (*.csv) - Kommaseparert fil (*.csv) - - - Confirmed - Bekreftet - - - Date - Dato - - - Type - Type - - - Label - Merkelapp - - - Address - Adresse - - - ID - ID - - - Range: - Intervall: - - - to - til - - UnitDisplayStatusBarControl @@ -2852,55 +1644,6 @@ Enhet å vise beløper i. Klikk for å velge en annen enhet. - - WalletFrame - - No wallet has been loaded. - Ingen lommebok har blitt lastet. - - - - WalletModel - - Send Coins - Send Bitcoins - - - - WalletView - - &Export - &Eksporter - - - Export the data in the current tab to a file - Eksporter data fra nåværende fane til fil - - - Backup Wallet - Sikkerhetskopier Lommebok - - - Wallet Data (*.dat) - Lommebokdata (*.dat) - - - Backup Failed - Sikkerhetskopiering Feilet - - - There was an error trying to save the wallet data to %1. - En feil oppstod ved lagring av lommebok til %1. - - - The wallet data was successfully saved to %1. - Lommeboken ble lagret til %1. - - - Backup Successful - Sikkerhetskopiering Fullført - - bitcoin-core @@ -2927,14 +1670,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Hvis <category> ikke er oppgitt eller hvis <category> = 1, ta ut all informasjon for feilsøking. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maksimalt samlede gebyrer (i %s) til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Vennligst undersøk at din datamaskin har riktig dato og klokkeslett! Hvis klokken er stilt feil vil ikke Bitcoin Core fungere riktig. - Prune configured below the minimum of %d MiB. Please use a higher number. Beskjæringsmodus er konfigurert under minimum på %d MiB. Vennligst bruk et høyere nummer. @@ -2975,6 +1710,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Ta imot tilkoblinger fra utsiden (standardverdi: 1 hvis uten -proxy eller -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind til angitt adresse. Bruk [vertsmaskin]:port notasjon for IPv6 @@ -3003,10 +1742,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dette er en forhåndssluppet testversjon - bruk på egen risiko - ikke for bruk til blokkutvinning eller bedriftsapplikasjoner - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Bruk UPnP for lytteport (standardverdi: 1 ved lytting og uten -proxy) @@ -3027,10 +1762,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Advarsel: Vi ser ikke ut til å være enige med våre noder! Du må oppgradere, eller andre noder må oppgradere. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Advarsel: wallet.dat korrupt, data reddet! Original wallet.dat lagret som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaksjoner ikke er korrekte bør du gjenopprette fra en backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger. @@ -3191,10 +1922,6 @@ Wallet options: Valg for lommebok: - - You need to rebuild the database using -reindex to change -txindex - Du må gjenoppbygge databasen med å bruke -reindex for å endre -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Tillat JSON-RPC-tilkoblinger fra angitt kilde. Gyldig for <ip> er en enkelt IP (f. eks. 1.2.3.4), et nettverk/nettmaske (f. eks. 1.2.3.4/255.255.255.0) eller et nettverk/CIDR (f. eks. 1.2.3.4/24). Dette alternativet kan angis flere ganger @@ -3207,10 +1934,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Bind til gitt adresse for å lytte for JSON-RPC-tilkoblinger. Bruk [host]:port notasjon for IPv6. Dette alternativet kan angis flere ganger (standardverdi: bind til alle grensesnitt) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Ute av stand til å låse datamappen %s. Bitcoin Core kjører sannsynligvis allerede. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Opprett nye filer med standardtillatelser i systemet, i stedet for umask 077 (kun virksom med lommebokfunksjonalitet slått av) @@ -3255,10 +1978,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Angi antall tråder for mynt generering hvis aktivert (-1 = alle kjerner, standardverdi: %d) - The transaction amount is too small to send after the fee has been deducted Transaksjonsbeløpet er for lite til å sendes etter at gebyret er fratrukket @@ -3283,34 +2002,14 @@ Accept public REST requests (default: %u) Godta offentlige REST forespørsler (standardverdi: %u) - - Activating best chain... - Aktiverer beste kjede... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Forsøk å berge private nøkler fra en korrupt wallet.dat ved oppstart - Automatically create Tor hidden service (default: %d) Automatisk opprette Tor skjult tjeneste (standardverdi: %d) - - Cannot resolve -whitebind address: '%s' - Kan ikke løse -whitebind-adresse: '%s' - Connect through SOCKS5 proxy Koble til via SOCKS5-proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i utviklerne av Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Feil ved lasting av wallet.dat: Lommeboken krever en nyere versjon av Bitcoin Core - Error reading from database, shutting down. Feil ved lesing fra database, stenger ned. @@ -3323,22 +2022,6 @@ Information Informasjon - - Initialization sanity check failed. Bitcoin Core is shutting down. - Sunnhetssjekk ved oppstart feilet. Bitcoin Core stenges ned. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Ugyldig beløp for -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Ugyldig mengde for -minrelaytxfee=<beløp>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Ugyldig mengde for -mintxfee=<beløp>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Ugyldig beløp for -paytxfee=<amount>: '%s' (må være minst %s) @@ -3363,14 +2046,6 @@ RPC server options: Innstillinger for RPC-server: - - Rebuild block chain index from current blk000??.dat files on startup - Gjenopprett blokkjedeindeks fra gjeldende blk000??.dat filer ved oppstart - - - Receive and display P2P network alerts (default: %u) - Motta og vis P2P nettverksvarsler (standardvalg: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reduserer -maxconnections fra %d til %d, pga. systembegrensninger. @@ -3443,10 +2118,6 @@ Username for JSON-RPC connections Brukernavn for JSON-RPC forbindelser - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Lommeboken måtte skrives på nytt: start Bitcoin Core på nytt for å fullføre - Warning Advarsel @@ -3463,10 +2134,6 @@ ZeroMQ notification options: Valg for ZeroMQ-meldinger: - - wallet.dat corrupt, salvage failed - wallet.dat korrupt, bergning feilet - Password for JSON-RPC connections Passord for JSON-RPC forbindelser @@ -3475,10 +2142,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Utfør kommando når beste blokk endrer seg (%s i kommandoen erstattes med blokkens hash) - - This help message - Denne hjelpemeldingen - Allow DNS lookups for -addnode, -seednode and -connect Tillat oppslag i DNS for -addnode, -seednode og -connect @@ -3487,10 +2150,6 @@ Loading addresses... Laster adresser... - - Error loading wallet.dat: Wallet corrupted - Feil ved lasting av wallet.dat: Lommeboken er skadet - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon) @@ -3507,10 +2166,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Ikke hold transaksjoner i minnet lenger enn <n> timer (standard: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Gebyrer (i %s/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s) @@ -3563,14 +2218,6 @@ Always query for peer addresses via DNS lookup (default: %u) Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: %u) - - Error loading wallet.dat - Feil ved lasting av wallet.dat - - - Generate coins (default: %u) - Generer mynter (standardverdi: %u) - How many blocks to check at startup (default: %u, 0 = all) Hvor mange blokker skal sjekkes ved oppstart (standardverdi: %u, 0 = alle) @@ -3655,18 +2302,6 @@ Unknown network specified in -onlynet: '%s' Ukjent nettverk angitt i -onlynet '%s' - - Cannot resolve -bind address: '%s' - Kunne ikke slå opp -bind adresse: '%s' - - - Cannot resolve -externalip address: '%s' - Kunne ikke slå opp -externalip adresse: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Ugyldig beløp for -paytxfee=<beløp>: '%s' - Insufficient funds Utilstrekkelige midler diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index fe29959ab..3009c154e 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -25,10 +25,6 @@ C&lose S&luiten - - &Copy Address - &Kopiëer Adres - Delete the currently selected address from the list Verwijder het geselecteerde adres van de lijst @@ -45,73 +41,6 @@ &Delete &Verwijder - - Choose the address to send coins to - Kies het adres om munten naar te versturen - - - Choose the address to receive coins with - Kies het adres om munten op te ontvangen - - - C&hoose - K&iezen - - - Sending addresses - Verstuuradressen - - - Receiving addresses - Ontvang adressen - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Dit zijn uw Bitcoinadressen om betalingen mee te doen. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verstuurt. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dit zijn uw Bitcoinadressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. - - - Copy &Label - Kopiëer &Label - - - &Edit - &Bewerk - - - Export Address List - Exporteer adreslijst - - - Comma separated file (*.csv) - Kommagescheiden bestand (*.csv) - - - Exporting Failed - Export Mislukt - - - There was an error trying to save the address list to %1. Please try again. - Een fout is opgetreden tijdens het opslaan van deze adreslijst naar %1. Probeer het nogmaals. - - - - AddressTableModel - - Label - Label - - - Address - Adres - - - (no label) - (geen label) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Herhaal nieuw wachtwoord - - Encrypt wallet - Versleutel portemonnee - - - This operation needs your wallet passphrase to unlock the wallet. - Deze operatie vereist uw portemonneewachtwoord om de portemonnee te openen. - - - Unlock wallet - Open portemonnee - - - This operation needs your wallet passphrase to decrypt the wallet. - Deze operatie vereist uw portemonneewachtwoord om de portemonnee te ontsleutelen - - - Decrypt wallet - Ontsleutel portemonnee - - - Change passphrase - Wijzig wachtwoord - - - Confirm wallet encryption - Bevestig versleuteling van uw portemonnee - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Waarschuwing: Als u uw portemonnee versleutelt en uw wachtwoord vergeet, zult u <b>AL UW BITCOINS VERLIEZEN</b>! - - - Are you sure you wish to encrypt your wallet? - Weet u zeker dat u uw portemonnee wilt versleutelen? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core zal nu afsluiten om het versleutelingsproces te voltooien. Hou er rekening mee dat versleuteling van uw portemonnee u niet volledig beschermt tegen diefstal van jouw bitcoins door malware op je computer. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - BELANGRIJK: Elke eerder gemaakte backup van uw portemonneebestand dient u te vervangen door het nieuw gegenereerde, versleutelde portemonneebestand. Om veiligheidsredenen zullen eerdere backups van het niet-versleutelde portemonneebestand onbruikbaar worden zodra u uw nieuwe, versleutelde, portemonnee begint te gebruiken. - - - Warning: The Caps Lock key is on! - Waarschuwing: De Caps Locktoets staat aan! - - - Wallet encrypted - Portemonnee versleuteld - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Voer een nieuw wachtwoord in voor uw portemonnee.<br/>Gebruik een wachtwoord van <b>tien of meer willekeurige karakters</b>, of <b>acht of meer woorden</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Voer het oude en nieuwe wachtwoord in voor uw portemonnee. - - - Wallet encryption failed - Portemonneeversleuteling mislukt - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Portemonneeversleuteling mislukt door een interne fout. Uw portemonnee is niet versleuteld. - - - The supplied passphrases do not match. - De opgegeven wachtwoorden komen niet overeen - - - Wallet unlock failed - Portemonnee openen mislukt - - - The passphrase entered for the wallet decryption was incorrect. - Het opgegeven wachtwoord voor de portemonnee-ontsleuteling is niet correct. - - - Wallet decryption failed - Portemonnee-ontsleuteling mislukt - - - Wallet passphrase was successfully changed. - Portemonneewachtwoord is met succes gewijzigd. - BanTableModel @@ -269,6 +110,14 @@ Quit application Programma afsluiten + + &About %1 + &Over %1 + + + Show information about %1 + Toon informatie over %1 + About &Qt Over &Qt @@ -281,6 +130,10 @@ &Options... &Opties... + + Modify configuration options for %1 + Wijzig configuratieopties voor %1 + &Encrypt Wallet... &Versleutel Portemonnee... @@ -305,14 +158,6 @@ Open &URI... Open &URI... - - Bitcoin Core client - Bitcoin Coreapplicatie - - - Importing blocks from disk... - Blokken aan het importeren vanaf harde schijf... - Reindexing blocks on disk... Bezig met herindexeren van blokken op harde schijf... @@ -357,10 +202,6 @@ &Receive &Ontvangen - - Show information about Bitcoin Core - Toon informatie over Bitcoin Core - &Show / Hide &Toon / Verberg @@ -397,22 +238,10 @@ Tabs toolbar Tab-werkbalk - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Vraag betaling aan (genereert QR-codes en bitcoin: URI's) - - &About Bitcoin Core - &Over Bitcoin Core - - - Modify configuration options for Bitcoin Core - Wijzig configuratieopties voor Bitcoin Core - Show the list of used sending addresses and labels Toon de lijst met gebruikte verstuuradressen en -labels @@ -427,16 +256,20 @@ &Command-line options - &Opdrachytregelopties - - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoinopdrachtregelopties + &Opdrachtregelopties %n active connection(s) to Bitcoin network %n actieve verbinding met Bitcoinnetwerk%n actieve verbindingen met Bitcoinnetwerk + + Indexing blocks on disk... + Bezig met indexeren van blokken op harde schijf... + + + Processing blocks on disk... + Bezig met verwerken van blokken op harde schijf... + No block source available... Geen bron voor blokken beschikbaar... @@ -493,6 +326,14 @@ Up to date Bijgewerkt + + Show the %1 help message to get a list with possible Bitcoin command-line options + Toon het %1 hulpbericht om een lijst te krijgen met mogelijke Bitcoin commandoregelopties + + + %1 client + %1 client + Catching up... Aan het bijwerken... @@ -544,13 +385,6 @@ Portemonnee is <b>versleuteld</b> en momenteel <b>gesloten</b> - - ClientModel - - Network Alert - Netwerkwaarschuwing - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Prioriteit - - Copy address - Kopieer adres - - - Copy label - Kopieer label - - - Copy amount - Kopieer bedrag - - - Copy transaction ID - Kopieer transactie-ID - - - Lock unspent - Blokeer ongebruikte - - - Unlock unspent - Deblokkeer ongebruikte - - - Copy quantity - Kopieer aantal - - - Copy fee - Kopieerkosten - - - Copy after fee - Kopieernaheffing - - - Copy bytes - Kopieer bytes - - - Copy priority - Kopieer prioriteit - - - Copy dust - Kopieër stof - - - Copy change - Kopieer wisselgeld - - - highest - hoogste - - - higher - hoger - - - high - hoog - - - medium-high - gemiddeld hoog - - - medium - gemiddeld - - - low-medium - laag gemiddeld - - - low - laag - - - lower - lager - - - lowest - laagste - - - (%1 locked) - (%1 geblokeerd) - - - none - geen - - - This label turns red if the transaction size is greater than 1000 bytes. - Dit label wordt rood als de transactie groter is dan 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Dit label wordt rood als de prioriteit lager is dan "gemiddeld". - - - This label turns red if any recipient receives an amount smaller than %1. - Dit label wordt rood wanneer een ontvanger minder dan %1 krijgt. - - - Can vary +/- %1 satoshi(s) per input. - Kan per input +/- %1 satoshi(s) variëren. - - - yes - ja - - - no - nee - - - This means a fee of at least %1 per kB is required. - Dit betekent dat kosten van minimaal %1 per kB aan verbonden zijn. - - - Can vary +/- 1 byte per input. - Kan +/- 1 byte per invoer variëren. - - - Transactions with higher priority are more likely to get included into a block. - Transacties met een hogere prioriteit zullen eerder in een blok gezet worden. - - - (no label) - (geen label) - - - change from %1 (%2) - wijzig van %1 (%2) - - - (change) - (wijzig) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adres - - New receiving address - Nieuw ontvangstadres - - - New sending address - Nieuw adres om naar te versturen - - - Edit receiving address - Bewerk ontvangstadres - - - Edit sending address - Bewerk adres om naar te versturen - - - The entered address "%1" is already in the address book. - Het opgegeven adres "%1" bestaat al in uw adresboek. - - - The entered address "%1" is not a valid Bitcoin address. - Het opgegeven adres "%1" is een ongeldig Bitcoinadres - - - Could not unlock wallet. - Kon de portemonnee niet openen. - - - New key generation failed. - Genereren nieuwe sleutel mislukt. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versie @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - Over Bitcoin Core + About %1 + Over %1 Command-line options @@ -907,8 +561,8 @@ Toon opstartscherm bij opstarten (standaard: %u) - Reset all settings changes made over the GUI - Reset alle wijzigingen aan instellingen gedaan met de GUI + Reset all settings changed in the GUI + Reset alle wijzigingen aan instellingen gedaan in de GUI @@ -918,16 +572,16 @@ Welkom - Welcome to Bitcoin Core. - Welkom bij Bitcoin Core + Welcome to %1. + Welkom bij %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Omdat dit de eerste keer is dat het programma gestart is, kunt u nu kiezen waar Bitcoin Core de data moet opslaan. + As this is the first time the program is launched, you can choose where %1 will store its data. + Omdat dit de eerste keer is dat het programma gestart is, kunt u nu kiezen waar %1 de data moet opslaan. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core zal een kopie van de Bitcoinblokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 zal een kopie van de Bitcoin blokketen downloaden en opslaan. Tenminste %2 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Gebruik een persoonlijke gegevensmap: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Fout: De gespecificeerde directory "%1" kan niet worden gecreëerd. @@ -976,10 +626,6 @@ Select payment request file Selecteer betalingsverzoek bestand - - Select payment request file to open - Selecteer betalingsverzoek bestand om te openen - OptionsDialog @@ -991,6 +637,14 @@ &Main &Algemeen + + Automatically start %1 after logging in to the system. + Start %1 automatisch na inloggen in het systeem. + + + &Start %1 on system login + &Start %1 bij het inloggen op het systeem + Size of &database cache Grootte van de &databasecache @@ -1019,10 +673,6 @@ 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. Minimaliseren in plaats van de applicatie af te sluiten wanneer het venster is afgesloten. Als deze optie is ingeschakeld, zal de toepassing pas worden afgesloten na het selecteren van Exit in het menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Stel hier de taal van de applicatie in. Deze instelling zal van kracht worden na het herstarten van de applicatie. - 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 |. URL's van derden (bijvoorbeeld block explorer) die in de transacties tab verschijnen als contextmenuelementen. %s in de URL is vervangen door transactiehash. Verscheidene URL's zijn gescheiden door een verticale streep |. @@ -1047,14 +697,6 @@ &Network &Netwerk - - Automatically start Bitcoin Core after logging in to the system. - Bitcoin Core automatisch starten bij inloggen. - - - &Start Bitcoin Core on system login - &Start Bitcoin Core tijdens login. - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = laat dit aantal kernen vrij) @@ -1139,6 +781,14 @@ &Window &Scherm + + &Hide the icon from the system tray. + &Verberg het icoon van de systeembalk. + + + Hide tray icon + Verberg systeembalk icoon + Show only a tray icon after minimizing the window. Laat alleen een systeemvakicoon zien wanneer het venster geminimaliseerd is @@ -1159,6 +809,10 @@ User Interface &language: Taal &Gebruikersinterface: + + The user interface language can be set here. This setting will take effect after restarting %1. + De taal van de gebruikersinterface kan hier ingesteld worden. Deze instelling zal pas van kracht worden nadat %1 herstart wordt. + &Unit to show amounts in: &Eenheid om bedrag in te tonen: @@ -1283,97 +937,6 @@ Huidige balans in alleen-bekijkbare adressen. - - PaymentServer - - URI handling - URI-behandeling - - - Invalid payment address %1 - Ongeldig betalingsadres %1 - - - Payment request rejected - Betalingsverzoek geweigerd - - - Payment request network doesn't match client network. - Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk. - - - Payment request is not initialized. - Betalingsaanvraag is niet geïnitialiseerd. - - - Requested payment amount of %1 is too small (considered dust). - Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof). - - - Payment request error - Fout bij betalingsverzoek - - - Cannot start bitcoin: click-to-pay handler - Kan bitcoin niet starten: click-to-pay handler - - - Payment request fetch URL is invalid: %1 - URL om betalingsverzoek te verkrijgen is ongeldig: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoinadres of misvormde URI-parameters. - - - Payment request file handling - Betalingsverzoek bestandsafhandeling - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand. - - - Payment request expired. - Betalingsverzoek verlopen. - - - Unverified payment requests to custom payment scripts are unsupported. - Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund. - - - Invalid payment request. - Ongeldig betalingsverzoek. - - - Refund from %1 - Restitutie van %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Betalingsverzoek %1 is te groot (%2 bytes, toegestaan ​​%3 bytes). - - - Error communicating with %1: %2 - Fout bij communiceren met %1: %2 - - - Payment request cannot be parsed! - Betalingsverzoek kan niet juist worden ontleed of verwerkt! - - - Bad response from server %1 - Ongeldige respons van server %1 - - - Payment acknowledged - Betaling bevestigd - - - Network request error - Netwerkfout bij verzoek - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Afbeelding opslaan... - - - &Copy Image - &Afbeelding kopiëren - - - Save QR Code - Sla QR-code op - - - PNG Image (*.png) - PNG afbeelding (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Gebruikt BerkeleyDB versie + + Datadir + Data map + Startup time Opstarttijd @@ -1513,10 +1061,6 @@ Memory usage Geheugengebruik - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Open het Bitcoin Core debuglogbestand van de huidige gegevensmap. Dit kan enkele seconden duren voor grote logbestanden. - Received Ontvangen @@ -1565,6 +1109,18 @@ User Agent User Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Open het %1 debug-logbestand van de huidige datamap. Dit kan een aantal seconden duren voor grote logbestanden. + + + Decrease font size + Verklein lettergrootte + + + Increase font size + Vergroot lettergrootte + Services Diensten @@ -1627,16 +1183,12 @@ In: - In; + In: Out: Uit: - - Build date - Bouwdatum - Debug log file Debuglogbestand @@ -1674,8 +1226,8 @@ &Maak Ban Ongedaan voor Node - Welcome to the Bitcoin Core RPC console. - Welkom op de Bitcoin Core RPC console. + Welcome to the %1 RPC console. + Welkom bij de %1 RPC-console. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove Verwijder - - Copy label - Kopieer label - - - Copy message - Kopieer bericht - - - Copy amount - Kopieer bedrag - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... &Sla afbeelding op... - - Request payment to %1 - Betalingsverzoek tot %1 - - - Payment information - Betalingsinformatie - - - URI - URI - - - Address - Adres - - - Amount - Bedrag - - - Label - Label - - - Message - Bericht - - - Resulting URI too long, try to reduce the text for label / message. - Resulterende URI te lang, probeer de tekst korter te maken voor het label/bericht. - - - Error encoding URI into QR Code. - Fout tijdens encoderen URI in QR-code - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Label - - - Message - Bericht - - - Amount - Bedrag - - - (no label) - (geen label) - - - (no message) - (geen bericht) - - - (no amount) - (geen bedrag) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast snel - - Send as zero-fee transaction if possible - Indien mogelijk, verstuur zonder transactiekosten - - - (confirmation may take longer) - (bevestiging kan langer duren) - Send to multiple recipients at once Verstuur in een keer aan verschillende ontvangers @@ -2061,118 +1526,6 @@ S&end V&erstuur - - Confirm send coins - Bevestig versturen munten - - - %1 to %2 - %1 tot %2 - - - Copy quantity - Kopieer aantal - - - Copy amount - Kopieer bedrag - - - Copy fee - Kopieerkosten - - - Copy after fee - Kopieernaheffing - - - Copy bytes - Kopieer bytes - - - Copy priority - Kopieer prioriteit - - - Copy change - Kopieer wijziging - - - Total Amount %1 - Totaalbedrag %1 - - - or - of - - - The amount to pay must be larger than 0. - Het ingevoerde bedrag moet groter zijn dan 0. - - - The amount exceeds your balance. - Bedrag is hoger dan uw huidige saldo - - - The total exceeds your balance when the %1 transaction fee is included. - Totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend - - - Transaction creation failed! - Transactie creatie niet gelukt! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet. - - - A fee higher than %1 is considered an absurdly high fee. - Transactiekosten van meer dan %1 wordt beschouwd als een absurd hoge transactiekosten. - - - Payment request expired. - Betalingsverzoek verlopen. - - - Pay only the required fee of %1 - Betaal alleen de verplichte transactiekosten van %1 - - - Estimated to begin confirmation within %n block(s). - Schatting is dat bevestiging begint over %n blok.Schatting is dat bevestiging begint over %n blokken. - - - The recipient address is not valid. Please recheck. - Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren.. - - - Duplicate address found: addresses should only be used once each. - Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden. - - - Warning: Invalid Bitcoin address - Waarschuwing: Ongeldig Bitcoinadres - - - (no label) - (geen label) - - - Warning: Unknown change address - Waarschuwing: Onbekend wisselgeldadres - - - Copy dust - Kopieër stof - - - Are you sure you want to send? - Weet u zeker dat u wilt versturen? - - - added as transaction fee - toegevoegd als transactiekosten - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: Betaal &Aan: - - Enter a label for this address to add it to your address book - Vul een label in voor dit adres om het toe te voegen aan uw adresboek - &Label: &Label: @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core is aan het afsluiten... + %1 is shutting down... + %1 is aan het afsluiten... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields Verwijder alles in de invulvelden - - Click "Sign Message" to generate signature - Klik "Onderteken Bericht" om de handtekening te genereren - - - The entered address is invalid. - Het opgegeven adres is ongeldig. - - - Please check the address and try again. - Controleer s.v.p. het adres en probeer het opnieuw. - - - The entered address does not refer to a key. - Het opgegeven adres verwijst niet naar een sleutel. - - - Wallet unlock was cancelled. - Portemonnee-ontsleuteling is geannuleerd - - - Private key for the entered address is not available. - Geheime sleutel voor het ingevoerde adres is niet beschikbaar. - - - Message signing failed. - Ondertekenen van het bericht is mislukt. - - - Message signed. - Bericht ondertekend. - - - The signature could not be decoded. - De handtekening kon niet worden gedecodeerd. - - - Please check the signature and try again. - Controleer s.v.p. de handtekening en probeer het opnieuw. - - - The signature did not match the message digest. - De handtekening hoort niet bij het bericht. - - - Message verification failed. - Berichtverificatie mislukt. - - - Message verified. - Bericht correct geverifiëerd. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - De Bitcoin Core-ontwikkelaars - [testnet] [testnetwerk] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - Openen totdat %1 - - - conflicted - conflicterend - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/onbevestigd - - - %1 confirmations - %1 bevestigingen - - - Status - Status - - - , broadcast through %n node(s) - , uitgezonden naar %n node, uitgezonden naar %n nodes - - - Date - Datum - - - Source - Bron - - - Generated - Gegenereerd - - - From - Van - - - To - Aan - - - own address - eigen adres - - - watch-only - alleen-bekijkbaar - - - label - label - - - Credit - Credit - - - matures in %n more block(s) - komt tot wasdom na %n nieuw blokkomt tot wasdom na %n nieuwe blokken - - - not accepted - niet geaccepteerd - - - Debit - Debet - - - Total debit - Totaal debit - - - Total credit - Totaal credit - - - Transaction fee - Transactiekosten - - - Net amount - Netto bedrag - - - Message - Bericht - - - Comment - Opmerking - - - Transaction ID - Transactie-ID: - - - Merchant - Handelaar - - - 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. - Gegenereerde munten moeten %1 blokken rijpen voordat ze kunnen worden besteed. Toen dit blok gegenereerd werd, werd het uitgezonden naar het netwerk om aan de blokketen toegevoegd te worden. Als het niet lukt om in de keten toegevoegd te worden, zal de status te veranderen naar "niet geaccepteerd" en het zal deze niet besteedbaar zijn. Dit kan soms gebeuren als een ander knooppunt een blok genereert binnen een paar seconden na die van u. - - - Debug information - Debuginformatie - - - Transaction - Transactie - - - Inputs - Inputs - - - Amount - Bedrag - - - true - waar - - - false - onwaar - - - , has not been successfully broadcast yet - , is nog niet met succes uitgezonden - - - Open for %n more block(s) - Open voor nog %n blokOpen voor nog %n blokken - - - unknown - onbekend - - TransactionDescDialog - - Transaction details - Transactiedetails - This pane shows a detailed description of the transaction Dit venster laat een uitgebreide beschrijving van de transactie zien - - TransactionTableModel - - Date - Datum - - - Type - Type - - - Immature (%1 confirmations, will be available after %2) - Premature (%1 bevestigingen, zal beschikbaar zijn na %2) - - - Open for %n more block(s) - Open voor nog %n blokOpen voor nog %n blokken - - - Open until %1 - Open tot %1 - - - Confirmed (%1 confirmations) - Bevestigd (%1 bevestigingen) - - - This block was not received by any other nodes and will probably not be accepted! - Dit blok is niet ontvangen bij andere nodes en zal waarschijnlijk niet worden geaccepteerd! - - - Generated but not accepted - Gegenereerd maar niet geaccepteerd - - - Offline - Niet verbonden - - - Label - Label - - - Unconfirmed - Onbevestigd - - - Confirming (%1 of %2 recommended confirmations) - Bevestigen (%1 van %2 aanbevolen bevestigingen) - - - Conflicted - Conflicterend - - - Received with - Ontvangen met - - - Received from - Ontvangen van - - - Sent to - Verstuurd aan - - - Payment to yourself - Betaling aan uzelf - - - Mined - Gedolven - - - watch-only - alleen-bekijkbaar - - - (n/a) - (nvt) - - - Transaction status. Hover over this field to show number of confirmations. - Transactiestatus. Houd de muiscursor boven dit veld om het aantal bevestigingen te laten zien. - - - Date and time that the transaction was received. - Datum en tijd waarop deze transactie is ontvangen. - - - Type of transaction. - Type transactie. - - - Whether or not a watch-only address is involved in this transaction. - Of er een alleen-bekijken adres is betrokken bij deze transactie. - - - User-defined intent/purpose of the transaction. - Door gebruiker gedefinieerde intentie/doel van de transactie - - - Amount removed from or added to balance. - Bedrag verwijderd van of toegevoegd aan saldo - - - - TransactionView - - All - Alles - - - Today - Vandaag - - - This week - Deze week - - - This month - Deze maand - - - Last month - Vorige maand - - - This year - Dit jaar - - - Range... - Bereik... - - - Received with - Ontvangen met - - - Sent to - Verstuurd aan - - - To yourself - Aan uzelf - - - Mined - Gedolven - - - Other - Anders - - - Enter address or label to search - Vul adres of label in om te zoeken - - - Min amount - Min. bedrag - - - Copy address - Kopieer adres - - - Copy label - Kopieer label - - - Copy amount - Kopieer bedrag - - - Copy transaction ID - Kopieer transactie-ID - - - Copy raw transaction - Kopieer ruwe transactie - - - Edit label - Bewerk label - - - Show transaction details - Toon transactiedetails - - - Export Transaction History - Exporteer Transactiegeschiedenis - - - Watch-only - Alleen-bekijkbaar - - - Exporting Failed - Export Mislukt - - - There was an error trying to save the transaction history to %1. - Er is een fout opgetreden bij het opslaan van het transactiegeschiedenis naar %1. - - - Exporting Successful - Export Succesvol - - - The transaction history was successfully saved to %1. - Het transactiegeschiedenis was succesvol bewaard in %1. - - - Comma separated file (*.csv) - Kommagescheiden bestand (*.csv) - - - Confirmed - Bevestigd - - - Date - Datum - - - Type - Type - - - Label - Label - - - Address - Adres - - - ID - ID - - - Range: - Bereik: - - - to - naar - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ Eenheid om bedragen uit te drukken. Klik om een andere eenheid te selecteren. - - WalletFrame - - No wallet has been loaded. - Portemonnee werd niet geladen. - - - - WalletModel - - Send Coins - Verstuur Munten - - - - WalletView - - &Export - &Exporteer - - - Export the data in the current tab to a file - Exporteer de data in de huidige tab naar een bestand - - - Backup Wallet - Portemonnee backuppen - - - Wallet Data (*.dat) - Portemonneedata (*.dat) - - - Backup Failed - Backup Mislukt - - - There was an error trying to save the wallet data to %1. - Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1. - - - The wallet data was successfully saved to %1. - De portemonneedata is succesvol opgeslagen in %1. - - - Backup Successful - Backup Succesvol - - bitcoin-core @@ -2927,14 +1758,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Als er geen <categorie> is opgegeven of als de <categorie> 1 is, laat dan alle debugginginformatie zien. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maximum totale transactiekosten (in %s) om te gebruiken voor een enkele portemonneetransactie; als dit te laag is ingesteld kan het grote transacties verhinderen (default: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Check a.u.b. of de datum en tijd van uw computer correct zijn! Als uw klok verkeerd staat zal Bitcoin Core niet correct werken. - Prune configured below the minimum of %d MiB. Please use a higher number. Snoeien is geconfigureerd on het minimum van %d MiB. Gebruik a.u.b. een hoger aantal. @@ -2975,6 +1798,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Accepteer verbindingen van buitenaf (standaard: 1 als geen -proxy of -connect is opgegeven) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee is zeer hoog ingesteld! Dit zijn de transactie kosten die u mogelijk betaald wanneer de schattingen niet beschikbaar zijn. @@ -2991,6 +1818,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind aan opgegeven adres en luister er altijd op. Gebruik [host]:port notatie voor IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Kan geen lock verkrijgen op gegevensmap %s. %s draait waarschijnlijk al. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blokketen door -rescan tijdens het opstarten @@ -2999,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Waarschuwing: Fout bij het lezen van %s! Alle sleutels zijn in goede orde uitgelezen, maar transactiedata of adresboeklemma's zouden kunnen ontbreken of fouten bevatten. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID) @@ -3007,6 +1842,18 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuur regels (standaard: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Maximum toegestane peer tijd compensatie. Lokaal perspectief van tijd mag worden beinvloed door peers die met deze hoeveelheid voor of achter lopen. (standaard: %u seconden) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maximum totale transactiekosten (in %s) om te gebruiken in een enkele portemoneetransactie; als dit te laag is ingesteld kunnen grote transacties worden verhinderd (standaard: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Waarschuwing: Controleer dat de datum en tijd van uw computer correct zijn ingesteld! Bij een onjuist ingestelde klok zal %s niet goed werken. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) @@ -3019,14 +1866,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Niet ondersteund argument -whitelistalwaysrelay genegeerd, gebruik -whitelistrelay en/of -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven) @@ -3043,22 +1882,18 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Waarschuwing: Het lijkt erop dat het netwerk geen consensus kan vinden! Sommige delvers lijken problemen te ondervinden. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Waarschuwing: Onbekende blok versies worden gemined! Er zijn mogelijk onbekende regels in werking getreden - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Waarschuwing: Het lijkt erop dat we geen consensus kunnen vinden met onze peers! Mogelijk dient u te upgraden, of andere nodes moeten wellicht upgraden. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Waarschuwing: wallet.dat is corrupt, data is veiliggesteld! Originele wallet.dat is opgeslagen als wallet.{tijdstip}.bak in %s; als uw balans of transacties incorrect zijn dient u een backup terug te zetten. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Goedgekeurde peers die verbinden van het ingegeven netmask of IP adres. Kan meerdere keren gespecificeerd worden. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex-chainstate. + -maxmempool must be at least %d MB -maxmempool moet tenminste %d MB zijn @@ -3071,10 +1906,22 @@ Append comment to the user agent string Voeg commentaar toe aan de user agent string + + Attempt to recover private keys from a corrupt wallet on startup + Probeer privésleutels te herstellen van een corrupte wallet bij opstarten + Block creation options: Blokcreatie-opties: + + Cannot resolve -%s address: '%s' + Kan -%s adres niet herleiden: '%s' + + + Change index out of range + Wijzigingsindex buiten bereik + Connect only to the specified node(s) Verbind alleen naar de gespecificeerde node(s) @@ -3083,6 +1930,10 @@ Connection options: Verbindingsopties: + + Copyright (C) %i-%i + Auteursrecht (C) %i-%i + Corrupted block database detected Corrupte blokkendatabase gedetecteerd @@ -3127,6 +1978,18 @@ Error initializing wallet database environment %s! Probleem met initializeren van de database-omgeving %s! + + Error loading %s + Fout bij het laden van %s + + + Error loading %s: Wallet corrupted + Fout bij het laden van %s: Portomonnee corrupt + + + Error loading %s: Wallet requires newer version of %s + Fout bij laden %s: Portemonnee vereist een nieuwere versie van %s + Error loading block database Fout bij het laden van blokkendatabase @@ -3151,10 +2014,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Incorrect of geen genesisblok gevonden. Verkeerde datamap voor het netwerk? + + Initialization sanity check failed. %s is shutting down. + Initialisatie sanity check mislukt. %s is aan het afsluiten. + Invalid -onion address: '%s' Ongeldig -onion adres '%s' + + Invalid amount for -%s=<amount>: '%s' + Ongeldig bedrag voor -%s=<bedrag>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Ongeldig bedrag voor -fallbackfee=<bedrag>: '%s' @@ -3163,6 +2034,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) De transactiegeheugenpool moet onder de <n> megabytes blijven (standaard: %u) + + Loading banlist... + Verbanningslijst aan het laden... + Location of the auth cookie (default: data dir) Locatie van de auth cookie (standaard: data dir) @@ -3179,6 +2054,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion) + + Print this help message and exit + Print dit helpbericht en sluit af + Print version and exit Laat versie zien en sluit af @@ -3191,6 +2070,14 @@ Prune mode is incompatible with -txindex. Snoeimodus is niet-compatibel met -txindex + + Rebuild chain state and block index from the blk*.dat files on disk + Herbouw ketenstaat en block index met behulp van de blk*.dat bestanden op de hardeschijf + + + Rebuild chain state from the currently indexed blocks + Herbouw ketenstaat vanuit de huidige geindexeerde blokken + Set database cache size in megabytes (%d to %d, default: %d) Zet database cache grootte in megabytes (%d tot %d, standaard: %d) @@ -3203,6 +2090,10 @@ Specify wallet file (within data directory) Specificeer het portemonnee bestand (vanuit de gegevensmap) + + Unable to bind to %s on this computer. %s is probably already running. + Niet in staat om %s te verbinden op deze computer. %s draait waarschijnlijk al. + Unsupported argument -benchmark ignored, use -debug=bench. Niet-ondersteund argument -benchmark genegeerd, gebruik -debug=bench. @@ -3236,12 +2127,16 @@ Portemonnee %s bevindt zich buiten de gegevensmap %s - Wallet options: - Portemonnee instellingen: + Wallet debugging/testing options: + Portomonee debugging/testing opties: - You need to rebuild the database using -reindex to change -txindex - Om -txindex te kunnen veranderen dient u de database herbouwen met gebruik van -reindex. + Wallet needed to be rewritten: restart %s to complete + Portemonnee moest herschreven worden: Herstart %s om te voltooien + + + Wallet options: + Portemonnee instellingen: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3255,10 +2150,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Bind aan gegeven adres om te luisteren voor JSON-RPC verbindingen. Gebruik [host]:poort notatie voor IPv6. Deze optie kan meerdere keren gespecificeerd worden (standaard: bind aan alle interfaces. - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Kan geen lock verkrijgen op gegevensmap %s. Bitcoin Core draait waarschijnlijk al. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit) @@ -3303,10 +2194,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Stel maximumgrootte in bytes in voor hoge-prioriteits-/lage-transactiekosten-transacties (standaard: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Stel het aantal threads in voor het genereren van coins indien ingesteld (-1 = alle kernen, standaard: %d) - The transaction amount is too small to send after the fee has been deducted Het transactiebedrag is te klein om te versturen nadat de transactiekosten in mindering zijn gebracht @@ -3331,34 +2218,14 @@ Accept public REST requests (default: %u) Accepteer publieke REST-verzoeken (standaard: %u) - - Activating best chain... - Beste reeks activeren... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Probeer privésleutels te herstellen van een corrupte wallet.dat bij opstarten - Automatically create Tor hidden service (default: %d) Creëer automatisch verborgen dienst van Tor (standaard:%d) - - Cannot resolve -whitebind address: '%s' - Kan -whitebind adres niet herleiden: '%s' - Connect through SOCKS5 proxy Verbind door SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Auteursrecht (C) 2009-%i De Bitcoin Core Ontwikkelaars - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Fout bij laden wallet.dat: Portemonnee vereist een nieuwere versie van Bitcoin Core - Error reading from database, shutting down. Fout bij het lezen van de database, afsluiten. @@ -3371,22 +2238,6 @@ Information Informatie - - Initialization sanity check failed. Bitcoin Core is shutting down. - Initialisatie sanity check mislukt. Bitcoin Core is aan het afsluiten. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Ongeldig bedrag voor -minrelaytxfee=<bedrag>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Ongeldig bedrag voor -mintxfee=<bedrag>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Ongeldig bedrag voor -paytxfee=<bedrag>: '%s' (Minimum %s) @@ -3411,14 +2262,6 @@ RPC server options: RPC server opties: - - Rebuild block chain index from current blk000??.dat files on startup - Herbouwen blokketenindex vanuit huidige blk000??.dat-bestanden bij opstarten? - - - Receive and display P2P network alerts (default: %u) - Ontvang en toon P2P-netwerkwaarschuwingen (standaard: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Verminder -maxconnections van %d naar %d, vanwege systeembeperkingen. @@ -3491,10 +2334,6 @@ Username for JSON-RPC connections Gebruikersnaam voor JSON-RPC-verbindingen - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Portemonnee moest herschreven worden: Herstart Bitcoin Core om te voltooien - Warning Waarschuwing @@ -3515,10 +2354,6 @@ ZeroMQ notification options: ZeroMQ notificatieopties: - - wallet.dat corrupt, salvage failed - wallet.dat corrupt, veiligstellen mislukt - Password for JSON-RPC connections Wachtwoord voor JSON-RPC-verbindingen @@ -3527,10 +2362,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Voer opdracht uit zodra het beste blok verandert (%s in cmd wordt vervangen door blokhash) - - This help message - Dit helpbericht - Allow DNS lookups for -addnode, -seednode and -connect Sta DNS-naslag toe voor -addnode, -seednode en -connect @@ -3539,10 +2370,6 @@ Loading addresses... Adressen aan het laden... - - Error loading wallet.dat: Wallet corrupted - Fout bij laden wallet.dat: Portemonnee corrupt - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op) @@ -3559,10 +2386,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Bewaar transactie niet langer dan <n> uren in de geheugenpool (standaard: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Fout tijdens lezen van wallet.dat! Alle sleutels zijn correct te lezen, maar de transactiondatabase of adresboekingangen zijn mogelijk verdwenen of incorrect. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Transactiekosten (in %s/kB) kleiner dan dit worden beschouwd dat geen transactiekosten in rekening worden gebracht voor transactiecreatie (standaard: %s) @@ -3599,6 +2422,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Niet-ondersteund argument -socks gevonden. Instellen van SOCKS-versie is niet meer mogelijk, alleen SOCKS5-proxies worden ondersteund. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Niet ondersteund argument -whitelistalwaysrelay genegeerd, gebruik -whitelistrelay en/of -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Gebruik een aparte SOCKS5 proxy om verborgen diensten van Tor te bereiken (standaard: %s) @@ -3607,6 +2434,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Gebruikersnaam en gehasht wachtwoord voor JSON-RPC-verbindingen. De velden <userpw> is in het formaat: <GEBRUIKERSNAAM>:<SALT>$<HASH>. Een kanoniek Pythonscript is inbegrepen in de share/rpcuser. Deze optie kan meerdere keren worden meegegeven + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Waarschuwing: Onbekende blok versies worden gemined! Er zijn mogelijk onbekende regels in werking getreden + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Waarschuwing: portomonee bestand is corrupt, data is veiliggesteld! Originele %s is opgeslagen als %s in %s; als uw balans of transacties incorrect zijn dient u een backup terug te zetten. + (default: %s) (standaard: %s) @@ -3615,14 +2450,6 @@ Always query for peer addresses via DNS lookup (default: %u) Vind anderen door middel van een DNS-naslag (standaard: %u) - - Error loading wallet.dat - Fout bij laden wallet.dat - - - Generate coins (default: %u) - Genereer munten (standaard: %u) - How many blocks to check at startup (default: %u, 0 = all) Aantal te checken blokken bij het opstarten (standaard: %u, 0 = allemaal) @@ -3707,18 +2534,6 @@ Unknown network specified in -onlynet: '%s' Onbekend netwerk gespecificeerd in -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Kan -bind adres niet herleiden: '%s' - - - Cannot resolve -externalip address: '%s' - Kan -externlip adres niet herleiden: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Ongeldig bedrag voor -paytxfee=<bedrag>: '%s' - Insufficient funds Ontoereikend saldo diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index c5a0b17e8..12151a576 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -25,10 +25,6 @@ C&lose I&sara - - &Copy Address - &Kopyan ing address - Delete the currently selected address from the list Ilako ya ing kasalungsungan makapiling address keng listahan @@ -37,61 +33,6 @@ &Delete &Ilako - - Choose the address to send coins to - Pilinan ing address a magpadalang coins kang - - - Choose the address to receive coins with - Pilinan ing address a tumanggap coins a atin - - - C&hoose - P&ilinan - - - Sending addresses - Address king pamag-Send - - - Receiving addresses - Address king pamag-Tanggap - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Reni reng kekang Bitcoin address king pamagpadalang kabayaran. Lawan mulang masalese reng alaga ampo ing address na ning tumanggap bayu ka magpadalang barya. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Reni reng kekang Bitcoin addresses keng pamananggap bayad. Rerekomenda mi na gumamit kang bayung address keng balang transaksiyon. - - - Copy &Label - Kopyan ing &Label - - - &Edit - &Alilan - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - - AddressTableModel - - Label - Label - - - Address - Address - - - (no label) - (alang label) - AskPassphraseDialog @@ -111,82 +52,6 @@ Repeat new passphrase Pasibayuan ya ing bayung passphrase - - Encrypt wallet - I-encrypt ye ing wallet - - - This operation needs your wallet passphrase to unlock the wallet. - Ing operasyun a ini kailangan ne ing kekayung wallet passphrase, ban a-unlock ya ing wallet - - - Unlock wallet - Unlock ya ing wallet - - - This operation needs your wallet passphrase to decrypt the wallet. - Ing operasyun a ini kailangan ne ing kekang wallet passphrase ban a-decrypt ne ing wallet. - - - Decrypt wallet - I-decrypt ya ing wallet - - - Change passphrase - Alilan ya ing passphrase - - - Confirm wallet encryption - Kumpirman ya ing wallet encryption - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Kapabaluan: Istung in-encrypt me ing kekang wallet at meala ya ing passphrase na, ma-<b>ALA NO NGAN RING KEKANG BITCOINS</b> - - - Are you sure you wish to encrypt your wallet? - Siguradu na kang buri meng i-encrypt ing kekang wallet? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - Mayalaga: Reng milabas a backups a gewa mu gamit ing wallet file mu dapat lamung mialilan bayung gawang encrypted wallet file. Para keng seguridad , reng milabas a backups dareng ali maka encrypt a wallet file ma-ala nala istung inumpisan mu nalang gamitan reng bayu, at me encrypt a wallet. - - - Warning: The Caps Lock key is on! - Kapabaluan: Makabuklat ya ing Caps Lock key! - - - Wallet encrypted - Me-encrypt ne ing wallet - - - Wallet encryption failed - Memali ya ing pamag-encrypt king wallet - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Memali ya ing encryption uli na ning ausan dang internal error. E ya me-encrypt ing wallet yu. - - - The supplied passphrases do not match. - E la mitutugma ring mibieng passphrase - - - Wallet unlock failed - Memali ya ing pamag-unlock king wallet - - - The passphrase entered for the wallet decryption was incorrect. - E ya istu ing passphrase a pepalub da para king wallet decryption - - - Wallet decryption failed - Me-mali ya ing pamag-decrypt king wallet - - - Wallet passphrase was successfully changed. - Mi-alilan ne ing passphrase na ning wallet. - BanTableModel @@ -309,10 +174,6 @@ Tabs toolbar Gamit para king Tabs - - Bitcoin Core - Kapilubluban ning Bitcoin - &Command-line options Pipamilian command-line @@ -362,13 +223,6 @@ Maka-<b>encrypt</b> ya ing wallet at kasalukuyan yang maka-<b>locked</b> - - ClientModel - - Network Alert - Alertu ning Network - - CoinControlDialog @@ -387,22 +241,6 @@ Confirmed Me-kumpirma - - Copy address - Kopyan ing address - - - Copy label - Kopyan ing label - - - Copy amount - Kopyan ing alaga - - - (no label) - (alang label) - EditAddressDialog @@ -418,48 +256,12 @@ &Address &Address - - New receiving address - Bayung address king pamagtanggap - - - New sending address - Bayung address king pamagpadala - - - Edit receiving address - Alilan ya ing address king pamagpadala - - - Edit sending address - Alilan ya ing address king pamagpadala - - - The entered address "%1" is already in the address book. - Ing pepalub yung address "%1" ati na yu king aklat dareng address - - - The entered address "%1" is not a valid Bitcoin address. - Ing pepalub yung address "%1" ali ya katanggap-tanggap a Bitcoin address. - - - Could not unlock wallet. - Ali ya bisang mag-unlock ing wallet - - - New key generation failed. - Memali ya ing pamangaua king key - FreespaceChecker HelpMessageDialog - - Bitcoin Core - Kapilubluban ning Bitcoin - version bersion @@ -483,10 +285,6 @@ Welcome Malaus ka - - Bitcoin Core - Kapilubluban ning Bitcoin - Error Mali @@ -613,9 +411,6 @@ Ing kekang kasalungsungan kabuuang balanse - - PaymentServer - PeerTableModel @@ -630,9 +425,6 @@ N/A - - QRImageWidget - RPCConsole @@ -691,10 +483,6 @@ Totals Kabuuan: - - Build date - Kaaldauan ning pamaglalang - Debug log file Debug log file @@ -718,60 +506,13 @@ &Label: &Label: - - Copy label - Kopyan ing label - - - Copy amount - Kopyan ing alaga - - + ReceiveRequestDialog Copy &Address &Kopyan ing address - - Address - Address - - - Amount - Alaga - - - Label - Label - - - Message - Mensayi - - - - RecentRequestsTableModel - - Date - Kaaldauan - - - Label - Label - - - Message - Mensayi - - - Amount - Alaga - - - (no label) - (alang label) - SendCoinsDialog @@ -815,31 +556,7 @@ S&end Ipadala - - Confirm send coins - Kumpirman ing pamagpadalang barya - - - Copy amount - Kopyan ing alaga - - - The amount to pay must be larger than 0. - Ing alaga na ning bayaran dapat mung mas matas ya king 0. - - - The amount exceeds your balance. - Ing alaga mipasobra ya king kekang balanse. - - - The total exceeds your balance when the %1 transaction fee is included. - Ing kabuuan mipasobra ya king kekang balanse istung inabe ya ing %1 a bayad king transaksion - - - (no label) - (alang label) - - + SendCoinsEntry @@ -850,10 +567,6 @@ Pay &To: Ibayad &kang: - - Enter a label for this address to add it to your address book - Magpalub kang label para king address a ini ban a-iabe me king aklat dareng address - &Label: &Label: @@ -948,65 +661,9 @@ Reset all verify message fields Ibalik king dati reng ngan fields na ning pamag beripikang mensayi - - Click "Sign Message" to generate signature - I-click ing "Pirman ing Mensayi" ban agawa ya ing metung a pirma - - - The entered address is invalid. - Ing milub a address e ya katanggap-tanggap. - - - Please check the address and try again. - Maliaring pakilawe pasibayu ing address at pasibayuan ya iti. - - - The entered address does not refer to a key. - Ing milub a address ali ya mag-refer king metung a key. - - - Wallet unlock was cancelled. - Me-kansela ya ing pamag-unlock king wallet. - - - Private key for the entered address is not available. - Ing private key para king milub a address, ala ya. - - - Message signing failed. - Me-mali ya ing pamag-pirma king mensayi . - - - Message signed. - Me-pirman ne ing mensayi. - - - The signature could not be decoded. - Ing pirma ali ya bisang ma-decode. - - - Please check the signature and try again. - Maliaring pakilawe pasibayu ing pirma kaibat pasibayuan ya iti. - - - The signature did not match the message digest. - Ing pirma ali ya makatugma king message digest. - - - Message verification failed. - Me-mali ya ing pamag-beripika king mensayi. - - - Message verified. - Me-beripika ne ing mensayi. - SplashScreen - - Bitcoin Core - Kapilubluban ning Bitcoin - [testnet] [testnet] @@ -1015,330 +672,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Makabuklat anggang %1 - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/ali me-kumpirma - - - %1 confirmations - %1 kumpirmasion - - - Status - Kabilian - - - Date - Kaaldauan - - - Source - Pikuanan - - - Generated - Megawa - - - From - Menibat - - - To - Para kang - - - own address - sariling address - - - label - label - - - Credit - Credit - - - not accepted - ali metanggap - - - Debit - Debit - - - Transaction fee - Bayad king Transaksion - - - Net amount - Alaga dareng eganagana - - - Message - Mensayi - - - Comment - Komentu - - - Transaction ID - ID - - - Debug information - Impormasion ning Debug - - - Transaction - Transaksion - - - Amount - Alaga - - - true - tutu - - - false - e tutu - - - , has not been successfully broadcast yet - , eya matagumpeng mibalita - - - unknown - e miya balu - - TransactionDescDialog - - Transaction details - Detalye ning Transaksion - This pane shows a detailed description of the transaction Ining pane a ini magpakit yang detalyadung description ning transaksion - - TransactionTableModel - - Date - Kaaldauan - - - Type - Klase - - - Open until %1 - Makabuklat anggang %1 - - - Confirmed (%1 confirmations) - Me-kumpirma(%1 kumpirmasion) - - - This block was not received by any other nodes and will probably not be accepted! - Ing block a ini ali de atanggap deng aliwa pang nodes ania ali ya magsilbing tanggapan - - - Generated but not accepted - Me-generate ya oneng ali ya metanggap - - - Label - Label - - - Received with - Atanggap kayabe ning - - - Received from - Atanggap menibat kang - - - Sent to - Mipadala kang - - - Payment to yourself - Kabayaran keka - - - Mined - Me-mina - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Status ning Transaksion: Itapat me babo na ning field a ini ban ipakit dala reng bilang dareng me-kumpirma na - - - Date and time that the transaction was received. - Aldo at oras nung kapilan me tanggap ya ing transaksion - - - Type of transaction. - Klase ning transaksion - - - Amount removed from or added to balance. - Alagang milako o miragdag king balanse. - - - - TransactionView - - All - Eganagana - - - Today - Aldo iti - - - This week - Paruminggung iti - - - This month - Bulan a iti - - - Last month - Milabas a bulan - - - This year - Banuang iti - - - Range... - Angganan... - - - Received with - Atanggap kayabe ning - - - Sent to - Mipadala kang - - - To yourself - Keng sarili mu - - - Mined - Me-mina - - - Other - Aliwa - - - Enter address or label to search - Magpalub kang address o label para pantunan - - - Min amount - Pekaditak a alaga - - - Copy address - Kopyan ing address - - - Copy label - Kopyan ing label - - - Copy amount - Kopyan ing alaga - - - Edit label - Alilan ing label - - - Show transaction details - Ipakit ing detalye ning transaksion - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Confirmed - Me-kumpirma - - - Date - Kaaldauan - - - Type - Klase - - - Label - Label - - - Address - Address - - - ID - ID - - - Range: - Angga: - - - to - para kang - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Magpadalang Barya - - - - WalletView - bitcoin-core @@ -1369,6 +712,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Tumanggap koneksion menibat king kilwal (default: 1 if no -proxy or -connect) + + Bitcoin Core + Kapilubluban ning Bitcoin + Block creation options: Pipamilian king pamag-gawang block: @@ -1401,26 +748,10 @@ Failed to listen on any port. Use -listen=0 if you want this. Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini. - - Cannot resolve -whitebind address: '%s' - Eya me-resolve ing -whitebind address: '%s' - Information &Impormasion - - Invalid amount for -maxtxfee=<amount>: '%s' - Eya maliari ing alaga keng -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Eya maliari ing alaga keng -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Eya maliari ing alaga keng -mintxfee=<amount>: '%s' - Send trace/debug info to console instead of debug.log file Magpadalang trace/debug info okeng console kesa keng debug.log file @@ -1445,10 +776,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) I-execute ing command istung mialilan ya ing best block (%s in cmd is replaced by block hash) - - This help message - Ining saup a mensayi - Allow DNS lookups for -addnode, -seednode and -connect Payagan ing pamaglawe DNS para king -addnode, -seednode and -connect @@ -1457,14 +784,6 @@ Loading addresses... Lo-load da ne ing address... - - Error loading wallet.dat: Wallet corrupted - Me-mali ya ing pamag-load king wallet.dat: Me-corrupt ya ing wallet - - - Error loading wallet.dat - Me-mali ya ing pamag-load king wallet.dat - Invalid -proxy address: '%s' Ali katanggap-tanggap a -proxy addresss: '%s' @@ -1473,18 +792,6 @@ Unknown network specified in -onlynet: '%s' E kilalang network ing mepili king -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Eya me-resolve ing -bind address: '%s' - - - Cannot resolve -externalip address: '%s' - Eya me-resolve ing -externalip address: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Eya maliari ing alaga keng -paytxfee=<amount>: '%s' - Insufficient funds Kulang a pondo diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index ffbacfd49..6d41cbeef 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Kliknij prawy przycisk aby edytować adres lub etykietę + Kliknij prawy przycisk myszy, aby edytować adres lub etykietę Create a new address @@ -25,10 +25,6 @@ C&lose Z&amknij - - &Copy Address - &Kopiuj adres - Delete the currently selected address from the list Usuń zaznaczony adres z listy @@ -45,73 +41,6 @@ &Delete &Usuń - - Choose the address to send coins to - Wybierz adres, na który chcesz wysłać monety - - - Choose the address to receive coins with - Wybierz adres, na który chcesz otrzymać monety - - - C&hoose - W&ybierz - - - Sending addresses - Adres wysyłania - - - Receiving addresses - Adres odbiorczy - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Tutaj znajdują się adresy Bitcoin na które wysyłasz płatności. Zawsze sprawdzaj ilość i adres odbiorcy przed wysyłką monet. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - To twoje adresy Bitcoin, na które otrzymujesz płatności. Zaleca się używanie nowych adresów odbiorczych dla każdej transakcji. - - - Copy &Label - Kopiuj &Etykietę - - - &Edit - &Modyfikuj - - - Export Address List - Eksportuj listę adresową - - - Comma separated file (*.csv) - Pliki (*.csv) rozdzielone przecinkami - - - Exporting Failed - Błąd przy próbie eksportowania - - - There was an error trying to save the address list to %1. Please try again. - Wystąpił błąd podczas próby zapisu listy adresów %1. Proszę spróbować ponownie. - - - - AddressTableModel - - Label - Etykieta - - - Address - Adres - - - (no label) - (brak etykiety) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Powtórz nowe hasło - - Encrypt wallet - Zaszyfruj portfel - - - This operation needs your wallet passphrase to unlock the wallet. - Operacja wymaga hasła portfela, aby go odblokować. - - - Unlock wallet - Odblokuj portfel - - - This operation needs your wallet passphrase to decrypt the wallet. - Operacja wymaga hasła portfela, aby go odszyfrować. - - - Decrypt wallet - Odszyfruj portfel - - - Change passphrase - Zmień hasło - - - Confirm wallet encryption - Potwierdź szyfrowanie portfela - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Uwaga: jeśli zaszyfrujesz swój portfel i zgubisz hasło <b>STRACISZ WSZYSTKIE SWOJE BITCOINY</b>! - - - Are you sure you wish to encrypt your wallet? - Jesteś pewien, że chcesz zaszyfrować swój portfel? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Program Bitcoin Core zamknie się, aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni twoich bitcoinów przed kradzieżą przez złośliwe oprogramowanie mogące zainfekować twój komputer. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - WAŻNE: Wszystkie wcześniejsze kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela. - - - Warning: The Caps Lock key is on! - Uwaga: klawisz Caps Lock jest włączony! - - - Wallet encrypted - Portfel zaszyfrowany - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Wprowadź nowe hasło do portfela.<br/>Proszę używać hasła złożonego z <b>10 lub więcej losowych znaków</b> albo <b>8 lub więcej słów.</b> - - - Enter the old passphrase and new passphrase to the wallet. - Podaj stare i nowe hasło do portfela. - - - Wallet encryption failed - Szyfrowanie portfela nie powiodło się - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Szyfrowanie portfela nie powiodło się z powodu wewnętrznego błędu. Twój portfel nie został zaszyfrowany. - - - The supplied passphrases do not match. - Podane hasła nie są takie same. - - - Wallet unlock failed - Odblokowanie portfela nie powiodło się - - - The passphrase entered for the wallet decryption was incorrect. - Wprowadzone hasło do odszyfrowania portfela jest niepoprawne. - - - Wallet decryption failed - Odszyfrowanie portfela nie powiodło się - - - Wallet passphrase was successfully changed. - Hasło portfela zostało pomyślnie zmienione. - BanTableModel @@ -269,6 +110,14 @@ Quit application Zamknij program + + &About %1 + &O %1 + + + Show information about %1 + Pokaż informacje o %1 + About &Qt O &Qt @@ -281,6 +130,10 @@ &Options... &Opcje... + + Modify configuration options for %1 + Zmień opcje konfiguracji dla %1 + &Encrypt Wallet... Zaszyfruj Portf&el @@ -305,14 +158,6 @@ Open &URI... Otwórz URI... - - Bitcoin Core client - Klient Rdzenia Bitcoina - - - Importing blocks from disk... - Importowanie bloków z dysku... - Reindexing blocks on disk... Ponowne indeksowanie bloków na dysku... @@ -357,10 +202,6 @@ &Receive Odbie&rz - - Show information about Bitcoin Core - Pokaż informacje o Rdzeniu Bitcoina - &Show / Hide &Pokaż / Ukryj @@ -397,22 +238,10 @@ Tabs toolbar Pasek zakładek - - Bitcoin Core - Rdzeń Bitcoina - Request payments (generates QR codes and bitcoin: URIs) Żądaj płatności (generuje kod QR oraz bitcoinowe URI) - - &About Bitcoin Core - &O Bitcoin Core - - - Modify configuration options for Bitcoin Core - Zmień opcje konfiguracji dla Bitcoin Core - Show the list of used sending addresses and labels Pokaż listę adresów i etykiet użytych do wysyłania @@ -429,14 +258,18 @@ &Command-line options &Opcje linii komend - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Pokaż pomoc Rdzenia Bitcoin, aby zobaczyć listę wszystkich opcji linii poleceń - %n active connection(s) to Bitcoin network %n aktywnych połączeń do sieci Bitcoin%n aktywnych połączeń do sieci Bitcoin%n aktywnych połączeń do sieci Bitcoin + + Indexing blocks on disk... + Indeksowanie bloków na dysku... + + + Processing blocks on disk... + Przetwarzanie blocks on disk... + No block source available... Brak dostępnych źródeł bloków... @@ -493,6 +326,14 @@ Up to date Aktualny + + Show the %1 help message to get a list with possible Bitcoin command-line options + Pokaż pomoc %1 aby zobaczyć listę wszystkich opcji lnii poleceń. + + + %1 client + %1 klient + Catching up... Trwa synchronizacja… @@ -544,13 +385,6 @@ Portfel jest <b>zaszyfrowany</b> i obecnie <b>zablokowany</b> - - ClientModel - - Network Alert - Komunikat Sieci - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Priorytet - - Copy address - Kopiuj adres - - - Copy label - Kopiuj etykietę - - - Copy amount - Kopiuj kwotę - - - Copy transaction ID - Skopiuj ID transakcji - - - Lock unspent - Zablokuj niewydane - - - Unlock unspent - Odblokuj niewydane - - - Copy quantity - Skopiuj ilość - - - Copy fee - Skopiuj opłatę - - - Copy after fee - Skopiuj ilość po opłacie - - - Copy bytes - Skopiuj ilość bajtów - - - Copy priority - Skopiuj priorytet - - - Copy dust - Kopiuj kurz - - - Copy change - Skopiuj resztę - - - highest - najwyższa - - - higher - wyższa - - - high - wysoka - - - medium-high - średnio wysoki - - - medium - średnia - - - low-medium - średnio niski - - - low - niski - - - lower - niższy - - - lowest - najniższy - - - (%1 locked) - (%1 zablokowane) - - - none - żaden - - - This label turns red if the transaction size is greater than 1000 bytes. - Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów. - - - This label turns red if the priority is smaller than "medium". - Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni" - - - This label turns red if any recipient receives an amount smaller than %1. - Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1. - - - Can vary +/- %1 satoshi(s) per input. - Waha się +/- %1 satoshi na wejście. - - - yes - tak - - - no - nie - - - This means a fee of at least %1 per kB is required. - Oznacza to wymaganą opłatę minimum %1 na kB. - - - Can vary +/- 1 byte per input. - Waha się +/- 1 bajt na wejście. - - - Transactions with higher priority are more likely to get included into a block. - Transakcje o wyższym priorytecie zwykle szybciej zostają dołączone do bloku. - - - (no label) - (brak etykiety) - - - change from %1 (%2) - reszta z %1 (%2) - - - (change) - (reszta) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adres - - New receiving address - Nowy adres otrzymywania - - - New sending address - Nowy adres wysyłania - - - Edit receiving address - Zmień adres odbioru - - - Edit sending address - Zmień adres wysyłania - - - The entered address "%1" is already in the address book. - Wprowadzony adres «%1» już istnieje w książce adresowej. - - - The entered address "%1" is not a valid Bitcoin address. - Wprowadzony adres «%1"» nie jest poprawnym adresem bitcoinowym. - - - Could not unlock wallet. - Nie można było odblokować portfela. - - - New key generation failed. - Tworzenie nowego klucza nie powiodło się. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Rdzeń Bitcoina - version wersja @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - O Bitcoin Core + About %1 + Informacje o %1 Command-line options @@ -907,8 +561,8 @@ Wyświetl okno powitalne podczas uruchamiania (domyślnie: %u) - Reset all settings changes made over the GUI - Ustaw jako domyślne wszystkie ustawienia interfejsu + Reset all settings changed in the GUI + Zresetuj wszystkie ustawienia zmienione w GUI @@ -918,16 +572,16 @@ Witaj - Welcome to Bitcoin Core. - Witaj w Bitcoin Core + Welcome to %1. + Witaj w %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Ponieważ jest to pierwsze uruchomienie programu, możesz wybrać gdzie Bitcoin Core będzie przechowywał swoje dane. + As this is the first time the program is launched, you can choose where %1 will store its data. + Ponieważ jest to pierwsze uruchomienie programu, możesz wybrać gdzie %1 będzie przechowywał swoje dane. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Program pobierze i będzie przechowywał kopię łańcucha bloków bitcoinowych. W wybranym katalogu musi być przynajmniej %1 GB miejsca, a z czasem ilość danych będzie rosła. Portfel będzie przechowywany w tym samym katalogu. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 pobierze i będzie przechowywał kopię łańcucha bloków Bitcoin. W wybranym katalogu zostanie zapisanych %2GB danych, a z czasem ta ilość będzie rosła. Portfel będzie przechowywany w tym samym katalogu. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Użyj wybranego folderu dla danych - - Bitcoin Core - Rdzeń Bitcoina - Error: Specified data directory "%1" cannot be created. Błąd: podany folder danych «%1» nie mógł zostać utworzony. @@ -976,10 +626,6 @@ Select payment request file Otwórz żądanie zapłaty z pliku - - Select payment request file to open - Wybierz plik żądania zapłaty do otwarcia - OptionsDialog @@ -991,6 +637,14 @@ &Main Główne + + Automatically start %1 after logging in to the system. + Automatycznie uruchom %1 po zalogowaniu do systemu. + + + &Start %1 on system login + Uruchamiaj %1 wraz z zalogowaniem do &systemu + Size of &database cache Wielkość bufora bazy &danych @@ -1019,10 +673,6 @@ 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. Minimalizuje zamiast zakończyć działanie programu przy zamykaniu okna. Kiedy ta opcja jest włączona, program zakończy działanie po wybieraniu Zamknij w menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin. - 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 |. Zewnętrzne URL podglądu transakcji (np. eksplorator bloków), które będą wyświetlały się w menu kontekstowym, w zakładce transakcji. %s będzie zamieniany w adresie na hash transakcji. Oddziel wiele adresów pionową kreską |. @@ -1047,14 +697,6 @@ &Network &Sieć - - Automatically start Bitcoin Core after logging in to the system. - Automatycznie uruchamia Bitcoin po zalogowaniu do systemu. - - - &Start Bitcoin Core on system login - Uruchamiaj Bitcoin Core wraz z zalogowaniem do &systemu - (0 = auto, <0 = leave that many cores free) (0 = automatycznie, <0 = zostaw tyle wolnych rdzeni) @@ -1139,6 +781,14 @@ &Window &Okno + + &Hide the icon from the system tray. + Ukryj ikonę z zasobnika systemowego. + + + Hide tray icon + Ukryj ikonę zasobnika + Show only a tray icon after minimizing the window. Pokazuj tylko ikonę przy zegarku po zminimalizowaniu okna. @@ -1159,6 +809,10 @@ User Interface &language: Język &użytkownika: + + The user interface language can be set here. This setting will take effect after restarting %1. + Można tu ustawić język interfejsu uzytkownika. Ustawienie przyniesie skutek po ponownym uruchomieniu %1. + &Unit to show amounts in: &Jednostka pokazywana przy kwocie: @@ -1283,97 +937,6 @@ Łączna kwota na podglądanych adresach - - PaymentServer - - URI handling - Obsługa URI - - - Invalid payment address %1 - błędny adres płatności %1 - - - Payment request rejected - Żądanie płatności odrzucone - - - Payment request network doesn't match client network. - Sieć żądania płatności nie odpowiada sieci klienta. - - - Payment request is not initialized. - Żądanie płatności nie jest zainicjowane. - - - Requested payment amount of %1 is too small (considered dust). - Żądana kwota %1 jest za niska (uznano za kurz). - - - Payment request error - Błąd żądania płatności - - - Cannot start bitcoin: click-to-pay handler - Nie można uruchomić protokołu bitcoin: kliknij-by-zapłacić - - - Payment request fetch URL is invalid: %1 - URL pobrania żądania zapłaty jest nieprawidłowe: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI nie może zostać przetworzony! Może to być spowodowane nieprawidłowym adresem Bitcoin lub uszkodzonymi parametrami URI. - - - Payment request file handling - Przechwytywanie plików żądania płatności - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Plików żądania płatności nie może zostać odczytany. Mogło to być spowodowane nieprawidłowym plikiem żądania płatności. - - - Payment request expired. - Żądanie płatności upłynęło. - - - Unverified payment requests to custom payment scripts are unsupported. - Niezweryfikowane żądania płatności do własnych skryptów płatności są niewspierane. - - - Invalid payment request. - Nieprawidłowe żądanie płatności - - - Refund from %1 - Zwrot z %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów). - - - Error communicating with %1: %2 - Błąd komunikacji z %1 : %2 - - - Payment request cannot be parsed! - Żądanie płatności nie może zostać przetworzone. - - - Bad response from server %1 - Błędna odpowiedź z serwera %1 - - - Payment acknowledged - Płatność potwierdzona - - - Network request error - Błąd żądania sieci - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Zapisz obraz... - - - &Copy Image - &Kopiuj obraz - - - Save QR Code - Zapisz kod QR - - - PNG Image (*.png) - Obraz PNG (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Używana wersja BerkeleyDB + + Datadir + Katalog danych + Startup time Czas uruchomienia @@ -1513,10 +1061,6 @@ Memory usage Zużycie pamięci - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach. - Received Otrzymane @@ -1565,6 +1109,18 @@ User Agent Aplikacja kliencka + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Otwórz plik dziennika debugowania %1 z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach. + + + Decrease font size + Zmniejsz rozmiar czcionki + + + Increase font size + Zwiększ rozmiar czcionki + Services Usługi @@ -1629,10 +1185,6 @@ Out: Wyjście: - - Build date - Data kompilacji - Debug log file Plik logowania debugowania @@ -1670,8 +1222,8 @@ Odblokuj węzeł - Welcome to the Bitcoin Core RPC console. - Witaj w konsoli Bitcoin Core RPC. + Welcome to the %1 RPC console. + Witaj w konsoli %1 RPC. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1800,18 +1352,6 @@ Remove Usuń - - Copy label - Kopiuj etykietę - - - Copy message - Kopiuj wiadomość - - - Copy amount - Kopiuj kwotę - ReceiveRequestDialog @@ -1831,73 +1371,6 @@ &Save Image... &Zapisz obraz... - - Request payment to %1 - Zażądaj płatności do %1 - - - Payment information - Informacje o płatności - - - URI - URI - - - Address - Adres - - - Amount - Kwota - - - Label - Etykieta - - - Message - Wiadomość - - - Resulting URI too long, try to reduce the text for label / message. - Wynikowy URI jest zbyt długi, spróbuj zmniejszyć tekst etykiety / wiadomości - - - Error encoding URI into QR Code. - Błąd kodowania URI w Kodzie QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etykieta - - - Message - Wiadomość - - - Amount - Kwota - - - (no label) - (brak etykiety) - - - (no message) - (brak wiadomości) - - - (no amount) - (brak kwoty) - SendCoinsDialog @@ -2017,14 +1490,6 @@ fast szybko - - Send as zero-fee transaction if possible - Wyślij bez opłaty jeżeli to możliwe - - - (confirmation may take longer) - (potwierdzenie może potrwać dłużej) - Send to multiple recipients at once Wyślij do wielu odbiorców na raz @@ -2057,118 +1522,6 @@ S&end Wy&syłka - - Confirm send coins - Potwierdź wysyłanie monet - - - %1 to %2 - %1 do %2 - - - Copy quantity - Skopiuj ilość - - - Copy amount - Kopiuj kwotę - - - Copy fee - Skopiuj opłatę - - - Copy after fee - Skopiuj ilość po opłacie - - - Copy bytes - Skopiuj ilość bajtów - - - Copy priority - Skopiuj priorytet - - - Copy change - Skopiuj resztę - - - Total Amount %1 - Łączna kwota %1 - - - or - lub - - - The amount to pay must be larger than 0. - Kwota do zapłacenia musi być większa od 0. - - - The amount exceeds your balance. - Kwota przekracza twoje saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - Suma przekracza twoje saldo, gdy doliczymy %1 prowizji transakcyjnej. - - - Transaction creation failed! - Utworzenie transakcji nie powiodło się! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transakcja została odrzucona! Może się to zdarzyć jeśli część monet z portfela została już wydana używając kopii pliku wallet.dat i nie zostało to tutaj uwzględnione. - - - A fee higher than %1 is considered an absurdly high fee. - Opłata wyższa niż %1 jest uważana za szalenie wysoką. - - - Payment request expired. - Żądanie płatności upłynęło. - - - Pay only the required fee of %1 - Zapłać tylko wymaganą opłatę %1 - - - Estimated to begin confirmation within %n block(s). - Przybliżony czas zatwierdzenia: %n bloków.Przybliżony czas zatwierdzenia: %n bloków.Przybliżony czas zatwierdzenia: %n bloków. - - - The recipient address is not valid. Please recheck. - Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie. - - - Duplicate address found: addresses should only be used once each. - Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania. - - - Warning: Invalid Bitcoin address - Ostrzeżenie: nieprawidłowy adres Bitcoin - - - (no label) - (brak etykiety) - - - Warning: Unknown change address - Ostrzeżenie: Nieznany adres reszty - - - Copy dust - Kopiuj kurz - - - Are you sure you want to send? - Czy na pewno chcesz wysłać? - - - added as transaction fee - dodano jako opłata transakcyjna - SendCoinsEntry @@ -2180,10 +1533,6 @@ Pay &To: Zapłać &dla: - - Enter a label for this address to add it to your address book - Wprowadź etykietę dla tego adresu by dodać go do książki adresowej - &Label: &Etykieta: @@ -2256,8 +1605,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core się zamyka... + %1 is shutting down... + %1 się zamyka... Do not shut down the computer until this window disappears. @@ -2351,69 +1700,9 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Reset all verify message fields Resetuje wszystkie pola weryfikacji wiadomości - - Click "Sign Message" to generate signature - Kliknij "Podpisz Wiadomość" żeby uzyskać podpis - - - The entered address is invalid. - Podany adres jest nieprawidłowy. - - - Please check the address and try again. - Proszę sprawdzić adres i spróbować ponownie. - - - The entered address does not refer to a key. - Wprowadzony adres nie odnosi się do klucza. - - - Wallet unlock was cancelled. - Odblokowanie portfela zostało anulowane. - - - Private key for the entered address is not available. - Klucz prywatny dla podanego adresu nie jest dostępny. - - - Message signing failed. - Podpisanie wiadomości nie powiodło się. - - - Message signed. - Wiadomość podpisana. - - - The signature could not be decoded. - Podpis nie może zostać zdekodowany. - - - Please check the signature and try again. - Sprawdź podpis i spróbuj ponownie. - - - The signature did not match the message digest. - Podpis nie odpowiada skrótowi wiadomości. - - - Message verification failed. - Weryfikacja wiadomości nie powiodła się. - - - Message verified. - Wiadomość zweryfikowana. - SplashScreen - - Bitcoin Core - Rdzeń Bitcoina - - - The Bitcoin Core developers - Deweloperzy Bitcoin Core - [testnet] [testnet] @@ -2426,422 +1715,13 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw KB/s - - TransactionDesc - - Open until %1 - Otwórz do %1 - - - conflicted - konflikt - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/niezatwierdzone - - - %1 confirmations - %1 potwierdzeń - - - Status - Status - - - , broadcast through %n node(s) - , przekazywany przez %n węzłów, przekazywany przez %n węzłów, przekazywany przez %n węzłów - - - Date - Data - - - Source - Źródło - - - Generated - Wygenerowano - - - From - Od - - - To - Do - - - own address - własny adres - - - watch-only - tylko-obserwowany - - - label - etykieta - - - Credit - Przypisy - - - matures in %n more block(s) - potwierdzona przy %n blokach więcejpotwierdzona przy %n blokach więcejpotwierdzona przy %n blokach więcej - - - not accepted - niezaakceptowane - - - Debit - Debet - - - Total debit - Razem wychodzących - - - Total credit - Razem przychodzących - - - Transaction fee - Opłata transakcyjna - - - Net amount - Kwota netto - - - Message - Wiadomość - - - Comment - Komentarz - - - Transaction ID - ID transakcji - - - Merchant - Kupiec - - - 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. - Wygenerowane monety muszą dojrzeć przez %1 bloków zanim będzie można je wydać. Gdy wygenerowałeś ten blok został on ogłoszony w sieci i dodany do łańcucha bloków. Jeżeli nie uda mu się wejść do łańcucha jego status zostanie zmieniony na "nie zaakceptowano" i nie będzie można go wydać. To czasem zdarza się gdy inny węzeł wygeneruje blok w kilka sekund od twojego. - - - Debug information - Informacje debugowania - - - Transaction - Transakcja - - - Inputs - Wejścia - - - Amount - Kwota - - - true - prawda - - - false - fałsz - - - , has not been successfully broadcast yet - , nie został jeszcze pomyślnie rozesłany - - - Open for %n more block(s) - Otwórz dla %n następnych blokówOtwórz dla %n następnych blokówOtwórz dla %n następnych bloków - - - unknown - nieznany - - TransactionDescDialog - - Transaction details - Szczegóły transakcji - This pane shows a detailed description of the transaction Ten panel pokazuje szczegółowy opis transakcji - - TransactionTableModel - - Date - Data - - - Type - Typ - - - Immature (%1 confirmations, will be available after %2) - Niedojrzała (%1 potwierdzeń, będzie dostępna po %2) - - - Open for %n more block(s) - Otwórz dla %n następnych blokówOtwórz dla %n następnych blokówOtwórz dla %n następnych bloków - - - Open until %1 - Otwórz do %1 - - - Confirmed (%1 confirmations) - Zatwierdzony (%1 potwierdzeń) - - - This block was not received by any other nodes and will probably not be accepted! - Ten blok nie został odebrany przez jakikolwiek inny węzeł i prawdopodobnie nie zostanie zaakceptowany! - - - Generated but not accepted - Wygenerowano ale nie zaakceptowano - - - Offline - Offline - - - Label - Etykieta - - - Unconfirmed - Niepotwierdzone: - - - Confirming (%1 of %2 recommended confirmations) - Potwierdzanie (%1 z %2 rekomendowanych potwierdzeń) - - - Conflicted - Konflikt - - - Received with - Otrzymane przez - - - Received from - Odebrano od - - - Sent to - Wysłano do - - - Payment to yourself - Płatność do siebie - - - Mined - Wydobyto - - - watch-only - tylko-obserwowany - - - (n/a) - (brak) - - - Transaction status. Hover over this field to show number of confirmations. - Status transakcji. Najedź na pole, aby zobaczyć liczbę potwierdzeń. - - - Date and time that the transaction was received. - Data i czas odebrania transakcji. - - - Type of transaction. - Rodzaj transakcji. - - - Whether or not a watch-only address is involved in this transaction. - Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji. - - - User-defined intent/purpose of the transaction. - Zdefiniowana przez użytkownika intencja/cel transakcji. - - - Amount removed from or added to balance. - Kwota usunięta z lub dodana do konta. - - - - TransactionView - - All - Wszystko - - - Today - Dzisiaj - - - This week - W tym tygodniu - - - This month - W tym miesiącu - - - Last month - W zeszłym miesiącu - - - This year - W tym roku - - - Range... - Zakres... - - - Received with - Otrzymane przez - - - Sent to - Wysłano do - - - To yourself - Do siebie - - - Mined - Wydobyto - - - Other - Inne - - - Enter address or label to search - Wprowadź adres albo etykietę żeby wyszukać - - - Min amount - Min suma - - - Copy address - Kopiuj adres - - - Copy label - Kopiuj etykietę - - - Copy amount - Kopiuj kwotę - - - Copy transaction ID - Skopiuj ID transakcji - - - Copy raw transaction - Skopiuj surowe dane transakcji - - - Edit label - Zmień etykietę - - - Show transaction details - Pokaż szczegóły transakcji - - - Export Transaction History - Eksport historii transakcji - - - Watch-only - Tylko obserwowany - - - Exporting Failed - Błąd przy próbie eksportu - - - There was an error trying to save the transaction history to %1. - Wystąpił błąd przy próbie zapisu historii transakcji do %1. - - - Exporting Successful - Eksport powiódł się - - - The transaction history was successfully saved to %1. - Historia transakcji została zapisana do %1. - - - Comma separated file (*.csv) - CSV (rozdzielany przecinkami) - - - Confirmed - Potwierdzony - - - Date - Data - - - Type - Typ - - - Label - Etykieta - - - Address - Adres - - - ID - ID - - - Range: - Zakres: - - - to - do - - UnitDisplayStatusBarControl @@ -2849,55 +1729,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Jednostka w jakiej pokazywane są kwoty. Kliknij aby wybrać inną. - - WalletFrame - - No wallet has been loaded. - Nie załadowano żadnego portfela. - - - - WalletModel - - Send Coins - Wyślij monety - - - - WalletView - - &Export - &Eksportuj - - - Export the data in the current tab to a file - Eksportuj dane z aktywnej karty do pliku - - - Backup Wallet - Kopia zapasowa portfela - - - Wallet Data (*.dat) - Dane portfela (*.dat) - - - Backup Failed - Nie udało się wykonać kopii zapasowej - - - There was an error trying to save the wallet data to %1. - Wystąpił błąd przy próbie zapisu pliku portfela do %1. - - - The wallet data was successfully saved to %1. - Plik portfela został zapisany do %1. - - - Backup Successful - Wykonano kopię zapasową - - bitcoin-core @@ -2924,10 +1755,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw If <category> is not supplied or if <category> = 1, output all debugging information. Jeżeli <category> nie zostanie określona lub <category> = 1, wyświetl wszystkie informacje debugowania. - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo. - Prune configured below the minimum of %d MiB. Please use a higher number. Przycinanie skonfigurowano poniżej minimalnych %d MiB. Proszę użyć wyższej liczby. @@ -2956,6 +1783,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Accept connections from outside (default: 1 if no -proxy or -connect) Akceptuj połączenia z zewnątrz (domyślnie: 1 jeśli nie ustawiono -proxy lub -connect) + + Bitcoin Core + Rdzeń Bitcoina + + + The %s developers + Deweloperzy %s + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee ma ustawioną bardzo dużą wartość! Jest to prowizja za transakcje, którą możesz zapłacić gdy oszacowanie opłaty jest niemożliwe. @@ -2964,6 +1799,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Bind to given address and always listen on it. Use [host]:port notation for IPv6 Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Nie można uzyskać blokady na katalogu z danymi %s. %s najprawdopodobniej jest już uruchomiony. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Usuwa wszystkie transakcje w portfelu i tylko odtwarza te części z łańcucha bloków poprzez -rescan przy starcie @@ -2972,6 +1811,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Rozprowadzane na licencji MIT, zobacz dołączony plik COPYING lub <http://www.opensource.org/licenses/mit-license.php>. + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Błąd odczytu %s! Wszystkie klucze zostały odczytane poprawnie, ale może brakować danych transakcji lub wpisów w książce adresowej, lub mogą one być nieprawidłowe. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID) @@ -2980,6 +1823,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Wymuś przekazywanie transakcji od osób z białej listy, nawet jeśli narusza to lokalną politykę przekazywania (default: %d) + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, %s nie będzie działał prawidłowo. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Ustaw liczbę wątków skryptu weryfikacyjnego (%u do %d, 0 = auto, <0 = zostaw tyle rdzeni wolnych, domyślnie: %d) @@ -2988,17 +1835,9 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw This is a pre-release test build - use at your own risk - do not use for mining or merchant applications To jest testowa wersja - używaj na własne ryzyko - nie używaj do wykopywania oraz przy aplikacjach kupieckich - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Nie można przywiązać z portem %s na tym komputerze. Bitcoin Core prawdopodobnie już działa. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Niewspierany argument -whitelistalwaysrelay zignorowany, użyj -whitelistrelay i/lub -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) - Używaj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje i brak -proxy) + Użyj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje i brak -proxy) WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) @@ -3016,14 +1855,18 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Uwaga: Wygląda na to, że nie ma pełnej zgodności z naszymi peerami! Możliwe, że potrzebujesz aktualizacji bądź inne węzły jej potrzebują - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Ostrzeżenie: Odtworzono dane z uszkodzonego pliku wallet.dat! Oryginalny wallet.dat został zapisany jako wallet.{timestamp}.bak w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Musisz przebudować bazę używając -reindex-chainstate aby zmienić -txindex + + + %s corrupt, salvage failed + %s uszkodzony, odtworzenie się nie powiodło + -maxmempool must be at least %d MB -maxmempool musi być przynajmniej %d MB @@ -3032,6 +1875,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <category> can be: <category> mogą być: + + Attempt to recover private keys from a corrupt wallet on startup + Próbuj odzyskać klucze prywatne z uszkodzonego portfela podczas uruchamiania. + Block creation options: Opcje tworzenia bloku: @@ -3044,6 +1891,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Connection options: Opcje połączenia: + + Copyright (C) %i-%i + Prawa autorskie (C) %i-%i + Corrupted block database detected Wykryto uszkodzoną bazę bloków @@ -3072,6 +1923,18 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Error initializing wallet database environment %s! Błąd inicjowania środowiska bazy portfela %s! + + Error loading %s + Błąd ładowania %s + + + Error loading %s: Wallet corrupted + Błąd ładowania %s: Uszkodzony portfel + + + Error loading %s: Wallet requires newer version of %s + Błąd ładowania %s: Portfel wymaga nowszej wersji %s + Error loading block database Błąd ładowania bazy bloków @@ -3096,10 +1959,18 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Incorrect or no genesis block found. Wrong datadir for network? Nieprawidłowy lub brak bloku genezy. Błędny folder_danych dla sieci? + + Initialization sanity check failed. %s is shutting down. + Wstępna kontrola poprawności nie powiodła się. %s wyłącza się. + Invalid -onion address: '%s' Nieprawidłowy adres -onion: '%s' + + Invalid amount for -%s=<amount>: '%s' + Nieprawidłowa kwota dla -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Nieprawidłowa kwota dla -fallbackfee=<amount>: '%s' @@ -3116,6 +1987,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Only connect to nodes in network <net> (ipv4, ipv6 or onion) Łącz z węzłami tylko w sieci <net> (ipv4, piv6 lub onion) + + Print this help message and exit + Wyświetl ten tekst pomocy i wyjdź + Print version and exit Wyświetl wersję i wyjdź @@ -3128,6 +2003,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Prune mode is incompatible with -txindex. Tryb ograniczony jest niekompatybilny z -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Odbuduj stan lańcucha i indeks bloków z obecnych na dysku plików blk*.dat + + + Rebuild chain state from the currently indexed blocks + Odbuduj stan łańcucha z aktualnie zindeksowanych bloków + Set database cache size in megabytes (%d to %d, default: %d) Ustaw wielkość pamięci podręcznej w megabajtach (%d do %d, domyślnie: %d) @@ -3140,6 +2023,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Specify wallet file (within data directory) Określ plik portfela (w obrębie folderu danych) + + Unable to bind to %s on this computer. %s is probably already running. + Nie można przywiązać do %s na tym komputerze. %s prawdopodobnie jest już uruchomiony. + Unsupported argument -benchmark ignored, use -debug=bench. Niewspierany argument -benchmark zignorowany, użyj -debug=bench. @@ -3173,12 +2060,16 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Portfel %s znajduje się poza folderem danych %s - Wallet options: - Opcje portfela: + Wallet debugging/testing options: + Opcje debugowania/testowania portfela: - You need to rebuild the database using -reindex to change -txindex - Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex + Wallet needed to be rewritten: restart %s to complete + Portfel wymaga przepisania: zrestartuj %s aby ukończyć + + + Wallet options: + Opcje portfela: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3192,10 +2083,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Powiąż się z podanym adresem, aby nasłuchiwać połączenia JSON-RPC. Użyj notacji [host]:port dla IPv6. Ta opcja może być określona kilka razy (domyślnie: powiąż ze wszystkimi interfejsami) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Nie można uzyskać blokady na katalogu z danymi %s. Rdzeń Bitcoin najprawdopodobniej jest już uruchomiony. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela) @@ -3232,10 +2119,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Ustaw maksymalny rozmiar transakcji o wysokim priorytecie/niskiej prowizji w bajtach (domyślnie: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Ustaw liczbę wątków dla generowania monet (-1 = wszystkie rdzenie, domyślnie: %d) - The transaction amount is too small to send after the fee has been deducted Zbyt niska kwota transakcji do wysłania po odjęciu opłaty @@ -3256,34 +2139,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Accept public REST requests (default: %u) Akceptuj publiczne żądania REST (domyślnie: %u) - - Activating best chain... - Aktywuje najlepszy łańcuch - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Próbuj podczas uruchamiania programu odzyskać klucze prywatne z uszkodzonego pliku wallet.dat - Automatically create Tor hidden service (default: %d) Stwórz automatycznie ukrytą usługę Tora (domyślnie: %d) - - Cannot resolve -whitebind address: '%s' - Nie można rozwiązać adresu -whitebind: '%s' - Connect through SOCKS5 proxy Połącz przez SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i The Bitcoin Core Developers - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin Core - Error reading from database, shutting down. Błąd odczytu z bazy danych, wyłączam się. @@ -3296,22 +2159,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Information Informacja - - Initialization sanity check failed. Bitcoin Core is shutting down. - Wstępna kontrola poprawności nie powiodła się. Bitcoin Core wyłącza się. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Nieprawidłowa kwota dla -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Nieprawidłowa kwota dla -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Nieprawidłowa kwota dla -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Nieprawidłowa kwota dla -paytxfee=<amount>: '%s' (musi być co najmniej %s) @@ -3336,14 +2183,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw RPC server options: Opcje serwera RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia - - - Receive and display P2P network alerts (default: %u) - Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Zmniejszanie -maxconnections z %d do %d z powodu ograniczeń systemu. @@ -3412,10 +2251,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Username for JSON-RPC connections Nazwa użytkownika dla połączeń JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Portfel wymaga przepisania: zrestartuj Bitcoina aby ukończyć - Warning Ostrzeżenie @@ -3428,10 +2263,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw ZeroMQ notification options: Opcje powiadomień ZeroMQ: - - wallet.dat corrupt, salvage failed - wallet.dat uszkodzony, odtworzenie się nie powiodło - Password for JSON-RPC connections Hasło do połączeń JSON-RPC @@ -3440,10 +2271,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Execute command when the best block changes (%s in cmd is replaced by block hash) Wykonaj polecenie kiedy najlepszy blok ulegnie zmianie (%s w komendzie zastanie zastąpione przez hash bloku) - - This help message - Ta wiadomość pomocy - Allow DNS lookups for -addnode, -seednode and -connect Zezwól -addnode, -seednode i -connect na łączenie się z serwerem DNS @@ -3452,17 +2279,13 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Loading addresses... Wczytywanie adresów... - - Error loading wallet.dat: Wallet corrupted - Błąd ładowania wallet.dat: Uszkodzony portfel - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane) -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji. + -maxtxfee ma ustawioną badzo dużą wartość! Tak wysokie opłaty mogą być zapłacone w jednej transakcji. -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. @@ -3472,10 +2295,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Do not keep transactions in the mempool longer than <n> hours (default: %u) Nie trzymaj w pamięci transakcji starszych niż <n> godz. (domyślnie: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Opłaty (w %s/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy tworzeniu transakcji (domyślnie: %s) @@ -3506,16 +2325,24 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) - Próbuje utrzymać ruch wychodzący poniżej zadanego (w MiB na dobę), 0 = bez limitu (domyślnie: %d) + Próbuje utrzymać ruch wychodzący poniżej zadanego (w MiB na 24h), 0 = bez limitu (domyślnie: %d) Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Znaleziono niewspierany argument -socks. Wybieranie wersji SOCKS nie jest już możliwe, wsparcie programu obejmuje tylko proxy SOCKS5 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Niewspierany argument -whitelistalwaysrelay zignorowany, użyj -whitelistrelay i/lub -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s) + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Ostrzeżenie: Odtworzono dane z uszkodzonego pliku portfela! Oryginalny %s został zapisany jako %s w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową. + (default: %s) (domyślnie: %s) @@ -3524,14 +2351,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Always query for peer addresses via DNS lookup (default: %u) Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u) - - Error loading wallet.dat - Błąd ładowania wallet.dat - - - Generate coins (default: %u) - Generuj monety (domyślnie: %u) - How many blocks to check at startup (default: %u, 0 = all) Ile bloków sprawdzić przy starcie (domyślnie: %u, 0 = wszystkie) @@ -3616,18 +2435,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Unknown network specified in -onlynet: '%s' Nieznana sieć w -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Nie można uzyskać adresu -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Nie można uzyskać adresu -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Nieprawidłowa kwota dla -paytxfee=<amount>: '%s' - Insufficient funds Niewystarczające środki diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 1b92395c7..fe9dd6626 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Clique com o botão direito para editar o endereço ou rótulo + Clique com o botão direito para editar o endereço ou rótulo Create a new address @@ -25,10 +25,6 @@ C&lose &Fechar - - &Copy Address - &Copiar Endereço - Delete the currently selected address from the list Excluir os endereços selecionados da lista @@ -45,73 +41,6 @@ &Delete &Excluir - - Choose the address to send coins to - Escolha o endereço para enviar moedas - - - Choose the address to receive coins with - Escolha o endereço para receber moedas - - - C&hoose - Escol&ha - - - Sending addresses - Endereços para envios - - - Receiving addresses - Endereços de recebimento - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Esses são seus endereços Bitcoin para enviar pagamentos. Confira sempre a quantia e o destinatário antes de enviar moedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estes são os seus endereços Bitcoin para receber pagamentos. Recomenda-se a utilização de um novo endereço de recebimento para cada transação. - - - Copy &Label - Copiar &Rótulo - - - &Edit - &Editar - - - Export Address List - Exportar lista de endereços - - - Comma separated file (*.csv) - Arquivo separado por vírgulas (*. csv) - - - Exporting Failed - Exportação Falhou - - - There was an error trying to save the address list to %1. Please try again. - Ocorreu um erro ao tentar salvar a lista de endereço em %1.. Por favor tente novamente. - - - - AddressTableModel - - Label - Rótulo - - - Address - Endereço - - - (no label) - (Sem rótulo) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repita a nova frase de segurança - - Encrypt wallet - Criptografar carteira - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operação precisa de sua frase de segurança para desbloquear a carteira. - - - Unlock wallet - Desbloquear carteira - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operação precisa de sua frase de segurança para descriptografar a carteira. - - - Decrypt wallet - Descriptografar carteira - - - Change passphrase - Alterar frase de segurança - - - Confirm wallet encryption - Confirmar criptografia da carteira - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atenção: Se você criptografar sua carteira e perder sua frase, você vai <b>perder todos os seus BITCOINS!</b> - - - Are you sure you wish to encrypt your wallet? - Tem certeza de que deseja criptografar sua carteira? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - O Bitcoin irá fechar agora para terminar o processo de criptografia. Lembre-se que criptografando sua carteira não te protege totalmente de ter seus bitcoins roubados por um malware que infectar seu computador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Qualquer backup prévio que você tenha feito do seu arquivo wallet deve ser substituído pelo novo e encriptado arquivo wallet gerado. Por razões de segurança, qualquer backup do arquivo wallet não criptografado se tornará inútil assim que você começar a usar uma nova carteira criptografada. - - - Warning: The Caps Lock key is on! - Atenção: A tecla Caps Lock está ligada! - - - Wallet encrypted - Carteira criptografada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Digite a nova frase da carteira. <br/>Por favor utilize uma senha com <b>dez ou mais caracteres aleartórios</b>, ou <b>oito ou mais palavras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Insira a frase antiga e a nova da carteira. - - - Wallet encryption failed - A criptografia da carteira falhou - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - A criptografia da carteira falhou devido a um erro interno. Sua carteira não estava criptografada. - - - The supplied passphrases do not match. - A frase de segurança fornecida não confere. - - - Wallet unlock failed - O desbloqueio da carteira falhou - - - The passphrase entered for the wallet decryption was incorrect. - A frase de segurança digitada para a descriptografia da carteira estava incorreta. - - - Wallet decryption failed - A descriptografia da carteira falhou - - - Wallet passphrase was successfully changed. - A frase de segurança da carteira foi alterada com êxito. - BanTableModel @@ -269,6 +110,10 @@ Quit application Sair da aplicação + + &About %1 + &About %1 + About &Qt Sobre &Qt @@ -281,6 +126,10 @@ &Options... &Opções... + + Modify configuration options for %1 + Modificar opções de configuração para o %1 + &Encrypt Wallet... &Criptografar Carteira... @@ -305,14 +154,6 @@ Open &URI... Abrir &URI... - - Bitcoin Core client - Cliente Bitcoin - - - Importing blocks from disk... - Importando blocos do disco... - Reindexing blocks on disk... Reindexando blocos no disco... @@ -357,10 +198,6 @@ &Receive &Receber - - Show information about Bitcoin Core - Mostrar informações sobre Bitcoin - &Show / Hide &Exibir/Ocultar @@ -397,22 +234,10 @@ Tabs toolbar Barra de ferramentas - - Bitcoin Core - Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Solicitações de pagamentos (gera códigos QR e bitcoin: URIs) - - &About Bitcoin Core - &Sobre Bitcoin - - - Modify configuration options for Bitcoin Core - Modificar opções de configuração do Bitcoin - Show the list of used sending addresses and labels Mostrar a lista de endereços de envio e rótulos usados @@ -429,14 +254,18 @@ &Command-line options Opções de linha de &comando - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostra a mensagem de ajuda do Bitcoin para pegar a lista com os comandos possíveis - %n active connection(s) to Bitcoin network %n conexão ativa na rede Bitcoin%n conexões ativas na rede Bitcoin + + Indexing blocks on disk... + Indexando blocos no disco... + + + Processing blocks on disk... + Processando blocos no disco... + No block source available... Nenhum servidor disponível... @@ -493,6 +322,14 @@ Up to date Atualizado + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostrar a mensagem de ajuda do %1 para obter uma lista com possíveis opções de linha de comando Bitcoin + + + %1 client + cliente %1 + Catching up... Recuperando o atraso ... @@ -544,13 +381,6 @@ Carteira está <b>criptografada</b> e atualmente <b>bloqueada</b> - - ClientModel - - Network Alert - Alerta da Rede - - CoinControlDialog @@ -629,150 +459,6 @@ Priority Prioridade - - Copy address - Copiar endereço - - - Copy label - Copiar rótulo - - - Copy amount - Copiar quantia - - - Copy transaction ID - Copiar ID da transação - - - Lock unspent - Travar não gasto - - - Unlock unspent - Destravar não gasto - - - Copy quantity - Copiar quantidade - - - Copy fee - Copiar taxa - - - Copy after fee - Copia pós-taxa - - - Copy bytes - Copiar bytes - - - Copy priority - Copia prioridade - - - Copy dust - Copiar poeira - - - Copy change - Copia alteração - - - highest - mais alta possível - - - higher - muito alta - - - high - alta - - - medium-high - média-alta - - - medium - média - - - low-medium - média-baixa - - - low - baixa - - - lower - muito baixa - - - lowest - a mais baixa possível - - - (%1 locked) - (%1 travado) - - - none - Nenhum - - - This label turns red if the transaction size is greater than 1000 bytes. - Este texto fica vermelho se o tamanho da transação for maior que 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Este texto fica vermelho se a prioridade é menor que "medio". - - - This label turns red if any recipient receives an amount smaller than %1. - Este texto fica vermelho se qualquer destinatário receber uma quantidade menor que %1. - - - Can vary +/- %1 satoshi(s) per input. - Pode variar +/- %1 satoshi(s) por entrada. - - - yes - sim - - - no - não - - - This means a fee of at least %1 per kB is required. - Isso significa que uma taxa de pelo menos %1 por kB é necessária. - - - Can vary +/- 1 byte per input. - Pode variar +/- 1 byte por entrada. - - - Transactions with higher priority are more likely to get included into a block. - Transações de alta prioridade são mais propensas a serem incluídas em um bloco. - - - (no label) - (Sem rótulo) - - - change from %1 (%2) - troco de %1 (%2) - - - (change) - (troco) - EditAddressDialog @@ -796,38 +482,6 @@ &Address &Endereço - - New receiving address - Novo endereço de recebimento - - - New sending address - Novo endereço de envio - - - Edit receiving address - Editar endereço de recebimento - - - Edit sending address - Editar endereço de envio - - - The entered address "%1" is already in the address book. - O endereço digitado "%1" já se encontra no catálogo de endereços. - - - The entered address "%1" is not a valid Bitcoin address. - O endereço digitado "%1" não é um endereço Bitcoin válido. - - - Could not unlock wallet. - Não foi possível desbloquear a carteira. - - - New key generation failed. - A geração de nova chave falhou. - FreespaceChecker @@ -854,10 +508,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin - version versão @@ -867,8 +517,8 @@ (%1-bit) - About Bitcoin Core - Sobre o Bitcoin + About %1 + Sobre %1 Command-line options @@ -907,8 +557,8 @@ Exibir tela de abertura na inicialização (padrão: %u) - Reset all settings changes made over the GUI - Desfazer todas as mudanças de configuração feitas na interface + Reset all settings changed in the GUI + Resetar todas as configuraçãoes do GUI @@ -918,16 +568,8 @@ Bem-vindo - Welcome to Bitcoin Core. - Bem vindo ao Bitcoin. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - A primeira vez que o programa é aberto você pode escolher onde o Bitcoin vai guardar os dados. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - O Bitcoin vai fazer download e salvar uma cópia da cadeia de blocos do Bitcoin: Blockchain. Pelo menos %1 GB de dados serão armazenados nesse diretório e isso aumentará ao longo do tempo. Sua carteira também será armazenada nesse diretório. + Welcome to %1. + Bem vindo ao %1 Use the default data directory @@ -937,10 +579,6 @@ Use a custom data directory: Use um diretório de dados personalizado: - - Bitcoin Core - Bitcoin - Error: Specified data directory "%1" cannot be created. Erro: Diretório de dados "%1" não pode ser criado. @@ -976,10 +614,6 @@ Select payment request file Selecione o arquivo de cobrança - - Select payment request file to open - Selecione o arquivo de cobrança para ser aberto - OptionsDialog @@ -991,6 +625,14 @@ &Main Principal + + Automatically start %1 after logging in to the system. + Executar o %1 automaticamente ao iniciar o sistema. + + + &Start %1 on system login + $Iniciar %1 ao fazer login no sistema + Size of &database cache Tamanho do banco de &dados do cache @@ -1019,10 +661,6 @@ 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. Minimizar em vez de fechar o programa quando a janela for fechada. Quando essa opção estiver ativa, o programa só será fechado somente pela opção Sair no menu Arquivo. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - A linguagem da interface do usuário pode ser alterada aqui. A mudança ocorrerá após o reinício do Bitcoin Core. - 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 |. URLs de terceiros (exemplo: explorador de blocos) que aparecem na aba de transações como itens do menu de contexto. %s na URL é substituido pela hash da transação. Múltiplas URLs são separadas pela barra vertical |. @@ -1047,14 +685,6 @@ &Network Rede - - Automatically start Bitcoin Core after logging in to the system. - Inicar automaticamente o Bitcoin ao logar no sistema. - - - &Start Bitcoin Core on system login - &Iniciar Bitcoin no login do sistema - (0 = auto, <0 = leave that many cores free) (0 = automático, <0 = número de cores deixados livres) @@ -1139,6 +769,14 @@ &Window &Janela + + &Hide the icon from the system tray. + &Ocultar o ícone da bandeja do sistema. + + + Hide tray icon + Ocultar ícone de bandeja + Show only a tray icon after minimizing the window. Mostrar apenas um ícone na bandeja ao minimizar a janela. @@ -1159,6 +797,10 @@ User Interface &language: &Linguagem da interface: + + The user interface language can be set here. This setting will take effect after restarting %1. + O idioma de interface do usuário pode ser definido aqui. Essa configuração terá efeito após reiniciar o %1 + &Unit to show amounts in: &Unidade usada para mostrar quantidades: @@ -1283,97 +925,6 @@ Balanço total em endereços monitorados - - PaymentServer - - URI handling - Manipulação de URI - - - Invalid payment address %1 - Endereço de pagamento inválido %1 - - - Payment request rejected - Solicitação de pagamento rejeitada - - - Payment request network doesn't match client network. - Rede de pedido de pagamento não corresponde rede do cliente. - - - Payment request is not initialized. - Pedido de pagamento não é inicializado. - - - Requested payment amount of %1 is too small (considered dust). - Valor do pagamento solicitado de %1 é muito pequeno (Considerado poeira). - - - Payment request error - Erro no pedido de pagamento - - - Cannot start bitcoin: click-to-pay handler - Não foi possível iniciar bitcoin: manipulador clique-para-pagar - - - Payment request fetch URL is invalid: %1 - URL de cobrança é inválida: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI não pode ser analisado ! Isto pode ser causado por um endereço Bitcoin inválido ou parâmetros URI informados incorretamente. - - - Payment request file handling - Manipulação de arquivo de cobrança - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Arquivo de pedido de pagamento não pode ser lido ! Isto pode ser causado por uma requisição de pagamento inválida. - - - Payment request expired. - Pedido de pagamento expirado. - - - Unverified payment requests to custom payment scripts are unsupported. - Cobrança não verificada para scripts de pagamento personalizados não é suportado. - - - Invalid payment request. - Pedido de pagamento inválido. - - - Refund from %1 - Reembolso de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes). - - - Error communicating with %1: %2 - Erro na comunicação com %1: %2 - - - Payment request cannot be parsed! - Requisição de pagamento não pode ser analisado! - - - Bad response from server %1 - Resposta incorreta do servidor %1 - - - Payment acknowledged - Pagamento reconhecido - - - Network request error - Erro de solicitação de rede - - PeerTableModel @@ -1428,25 +979,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Salvar imagem - - - &Copy Image - &Copiar Imagem - - - Save QR Code - Salvar código QR - - - PNG Image (*.png) - PNG Imagem (*.png) - - RPCConsole @@ -1513,10 +1045,6 @@ Memory usage Uso de memória - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes. - Received Recebido @@ -1565,6 +1093,14 @@ User Agent User Agent + + Decrease font size + Diminuir o tamanho da fonte + + + Increase font size + Aumentar o tamanho da fonte + Services Serviços @@ -1633,10 +1169,6 @@ Out: Saída: - - Build date - Data do 'build' - Debug log file Arquivo de log de Depuração @@ -1674,8 +1206,8 @@ &Desbanir nó - Welcome to the Bitcoin Core RPC console. - Bem vindo ao console de RPC do Bitcoin. + Welcome to the %1 RPC console. + Bem-vindo ao console RPC do %1 Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1336,6 @@ Remove Remover - - Copy label - Copiar rótulo - - - Copy message - Copiar mensagem - - - Copy amount - Copiar quantia - ReceiveRequestDialog @@ -1835,73 +1355,6 @@ &Save Image... &Salvar Imagem... - - Request payment to %1 - Requisitar pagamento para %1 - - - Payment information - Informação de pagamento - - - URI - URI - - - Address - Endereço - - - Amount - Quantidade - - - Label - Rótulo - - - Message - Mensagem - - - Resulting URI too long, try to reduce the text for label / message. - URI resultante muito longa. Tente reduzir o texto do rótulo ou da mensagem. - - - Error encoding URI into QR Code. - Erro ao codigicar o URI em código QR - - - - RecentRequestsTableModel - - Date - Data - - - Label - Rótulo - - - Message - Mensagem - - - Amount - Quantidade - - - (no label) - (Sem rótulo) - - - (no message) - (sem mensagem) - - - (no amount) - (sem quantia especificada) - SendCoinsDialog @@ -2021,14 +1474,6 @@ fast rápido - - Send as zero-fee transaction if possible - Enviar sem taxa de transação se possível - - - (confirmation may take longer) - (confirmação pode demorar) - Send to multiple recipients at once Enviar para vários destinatários de uma só vez @@ -2061,118 +1506,6 @@ S&end Enviar - - Confirm send coins - Confirmar envio de moedas - - - %1 to %2 - %1 para %2 - - - Copy quantity - Copiar quantidade - - - Copy amount - Copiar quantia - - - Copy fee - Copiar taxa - - - Copy after fee - Copia pós-taxa - - - Copy bytes - Copiar bytes - - - Copy priority - Copia prioridade - - - Copy change - Copia alteração - - - Total Amount %1 - Quantia Total %1 - - - or - ou - - - The amount to pay must be larger than 0. - A quantidade a ser paga precisa ser maior que 0. - - - The amount exceeds your balance. - A quantidade excede seu saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - O total excede seu saldo quando uma taxa de transação de %1 é incluída. - - - Transaction creation failed! - A criação de transação falhou! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - A transação foi rejeitada! Isso pode acontecer se alguns bitcoins na sua carteira já foram gastos em outro local, por exemplo se você tiver uma cópia do wallet.dat e os bitcoins tiverem sido gastos na cópia mas não marcados como gastos aqui ainda. - - - A fee higher than %1 is considered an absurdly high fee. - Uma taxa maior que %1 é considerada uma taxa absurdamente alto. - - - Payment request expired. - Pedido de pagamento expirado. - - - Pay only the required fee of %1 - Pagar somente a taxa requerida de %1 - - - Estimated to begin confirmation within %n block(s). - Confirmação estimada em %n bloco.Confirmação estimada em %n blocos. - - - The recipient address is not valid. Please recheck. - O endereço do destinatário é inválido. Favor confirmar. - - - Duplicate address found: addresses should only be used once each. - Endereço duplicado encontrado: Endereços devem ser usados somente uma vez cada. - - - Warning: Invalid Bitcoin address - Atenção: endereço de Bitcoin inválido - - - (no label) - (Sem rótulo) - - - Warning: Unknown change address - Atenção: endereço de troco desconhecido - - - Copy dust - Copiar poeira - - - Are you sure you want to send? - Tem certeza que quer enviar? - - - added as transaction fee - Adicionado como taxa de transação - SendCoinsEntry @@ -2184,10 +1517,6 @@ Pay &To: Pagar &Para: - - Enter a label for this address to add it to your address book - Digite um rótulo para este endereço para adicioná-lo ao catálogo de endereços - &Label: &Rótulo: @@ -2259,10 +1588,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin está sendo encerrado... - Do not shut down the computer until this window disappears. Não desligue o computador até que esta janela desapareça. @@ -2354,69 +1679,9 @@ Reset all verify message fields Limpar todos os campos de assinatura da mensagem - - Click "Sign Message" to generate signature - Clique em "Assinar mensagem" para gerar a assinatura - - - The entered address is invalid. - O endereço fornecido é inválido. - - - Please check the address and try again. - Por favor, verifique o endereço e tente novamente. - - - The entered address does not refer to a key. - O endereço fornecido não se refere a uma chave. - - - Wallet unlock was cancelled. - Desbloqueamento da Carteira foi cancelado. - - - Private key for the entered address is not available. - A chave privada para o endereço fornecido não está disponível. - - - Message signing failed. - Assinatura da mensagem falhou. - - - Message signed. - Mensagem assinada. - - - The signature could not be decoded. - A assinatura não pode ser decodificada. - - - Please check the signature and try again. - Por favor, verifique a assinatura e tente novamente. - - - The signature did not match the message digest. - A assinatura não corresponde ao "resumo da mensagem". - - - Message verification failed. - Verificação da mensagem falhou. - - - Message verified. - Mensagem verificada. - SplashScreen - - Bitcoin Core - Bitcoin - - - The Bitcoin Core developers - Programadores do Bitcoin - [testnet] [testnet] @@ -2429,422 +1694,13 @@ KB/s - - TransactionDesc - - Open until %1 - Aberto até %1 - - - conflicted - em conflito - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/não confirmadas - - - %1 confirmations - %1 confirmações - - - Status - Status - - - , broadcast through %n node(s) - , difundir atráves de %n nó, difundir atráves de %n nós - - - Date - Data - - - Source - Fonte - - - Generated - Gerados - - - From - De - - - To - Para - - - own address - seu próprio endereço - - - watch-only - monitorado - - - label - rótulo - - - Credit - Crédito - - - matures in %n more block(s) - matura em mais %n blocomatura em mais %n blocos - - - not accepted - não aceito - - - Debit - Débito - - - Total debit - Débito total - - - Total credit - Credito total - - - Transaction fee - Taxa de transação - - - Net amount - Valor líquido - - - Message - Mensagem - - - Comment - Comentário - - - Transaction ID - ID da transação - - - Merchant - Mercador - - - 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. - Bitcoins recém minerados precisam aguardar %1 blocos antes de serem gastos. Quando o bloco foi gerado, ele foi disseminado pela rede para ser adicionado à blockchain. Se ele falhar em ser inserido na cadeia, seu estado será modificado para "não aceito" e ele não poderá ser gasto. Isso pode acontecer eventualmente quando blocos são gerados quase que simultaneamente. - - - Debug information - Informação de depuração - - - Transaction - Transação - - - Inputs - Entradas - - - Amount - Quantidade - - - true - verdadeiro - - - false - falso - - - , has not been successfully broadcast yet - , ainda não foi propagada na rede com sucesso. - - - Open for %n more block(s) - Abrir para mais %n blocoAbrir para mais %n blocos - - - unknown - desconhecido - - TransactionDescDialog - - Transaction details - Detalhes da transação - This pane shows a detailed description of the transaction Este painel mostra uma descrição detalhada da transação - - TransactionTableModel - - Date - Data - - - Type - Tipo - - - Immature (%1 confirmations, will be available after %2) - Recém-criado (%1 confirmações, disponível somente após %2) - - - Open for %n more block(s) - Abrir para mais %n blocoAbrir para mais %n blocos - - - Open until %1 - Aberto até %1 - - - Confirmed (%1 confirmations) - Confirmado (%1 confirmações) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloco não foi recebido por nenhum outro participante da rede e provavelmente não será aceito! - - - Generated but not accepted - Gerado mas não aceito - - - Offline - Offline - - - Label - Rótulo - - - Unconfirmed - Não confirmado - - - Confirming (%1 of %2 recommended confirmations) - Confirmando (%1 de %2 confirmações recomendadas) - - - Conflicted - Conflitou - - - Received with - Recebido - - - Received from - Recebido - - - Sent to - Enviado - - - Payment to yourself - Pagamento para você mesmo - - - Mined - Minerado - - - watch-only - monitorado - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Status da transação. Passe o mouse sobre este campo para mostrar o número de confirmações. - - - Date and time that the transaction was received. - Data e hora em que a transação foi recebida. - - - Type of transaction. - Tipo de transação. - - - Whether or not a watch-only address is involved in this transaction. - Mostrar ou não endereços Bitcoin na lista de transações. - - - User-defined intent/purpose of the transaction. - Intenção/Propósito definido pelo usuário para a transação - - - Amount removed from or added to balance. - Quantidade debitada ou creditada ao saldo. - - - - TransactionView - - All - Todos - - - Today - Hoje - - - This week - Esta semana - - - This month - Este mês - - - Last month - Mês passado - - - This year - Este ano - - - Range... - Intervalo... - - - Received with - Recebido - - - Sent to - Enviado - - - To yourself - Para você mesmo - - - Mined - Minerado - - - Other - Outro - - - Enter address or label to search - Procure um endereço ou rótulo - - - Min amount - Quantidade mínima - - - Copy address - Copiar endereço - - - Copy label - Copiar rótulo - - - Copy amount - Copiar quantia - - - Copy transaction ID - Copiar ID da transação - - - Copy raw transaction - Copia os dados brutos da transação - - - Edit label - Editar rótulo - - - Show transaction details - Mostrar detalhes da transação - - - Export Transaction History - Exportar Histórico de Transação - - - Watch-only - Monitorado - - - Exporting Failed - Exportação Falhou - - - There was an error trying to save the transaction history to %1. - Ocorreu um erro ao tentar salvar o histórico de transação em %1. - - - Exporting Successful - Exportação feita com sucesso - - - The transaction history was successfully saved to %1. - O histórico de transação foi gravado com sucesso em %1. - - - Comma separated file (*.csv) - Arquivo separado por vírgulas (*. csv) - - - Confirmed - Confirmado - - - Date - Data - - - Type - Tipo - - - Label - Rótulo - - - Address - Endereço - - - ID - ID - - - Range: - Intervalo: - - - to - para - - UnitDisplayStatusBarControl @@ -2852,55 +1708,6 @@ Unidade para mostrar. Clique para selecionar outra unidade. - - WalletFrame - - No wallet has been loaded. - Nenhuma carteira foi carregada. - - - - WalletModel - - Send Coins - Send Coins - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar os dados na aba atual para um arquivo - - - Backup Wallet - Fazer cópia de segurança da Carteira - - - Wallet Data (*.dat) - Dados da Carteira (*.dat) - - - Backup Failed - Cópia de segurança Falhou - - - There was an error trying to save the wallet data to %1. - Ocorreu um erro ao tentar salvar os dados da carteira em %1. - - - The wallet data was successfully saved to %1. - Os dados da carteira foram salvos com sucesso em %1. - - - Backup Successful - Backup feito com sucesso - - bitcoin-core @@ -2927,14 +1734,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Se <category> não for suprida ou se <category> = 1, mostrar toda informação de depuração. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Total máximo de comissão (em %s) que será usado em uma única transação; um valor muito baixo pode cancelar uma transação grande (padrão: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Por favor verifique se a data e horário estão corretos no seu computador! Se o seu relógio estiver incorreto, a Carteira Bitcoin não irá funcionar corretamente. - Prune configured below the minimum of %d MiB. Please use a higher number. Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto. @@ -2975,6 +1774,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceitar conexões externas (padrão: 1 se opções -proxy ou -connect não estiverem presentes) + + Bitcoin Core + Bitcoin + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee está muito alta! Essa é a taxa de transação que você vai pagar quando a taxa estimada não estiver disponível. @@ -3019,14 +1822,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Este pode ser um build de teste pré-lançamento - use por sua conta e risco - não use para mineração ou aplicações de comércio. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Impossível ouvir em %s neste computador. Provavelmente o Bitcoin já está sendo executado. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Argumento não suportado -whitelistalwaysrelay foi ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy) @@ -3043,18 +1838,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atenção: A rede não parecem concordar plenamente! Alguns mineiros parecem estar enfrentando problemas. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Aviso: Versões de bloco desconhecidas sendo mineradas! É possível que regras estranhas estejam ativas - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atenção: Nós não parecemos concordar plenamente com nossos colegas! Você pode precisar atualizar ou outros nós podem precisar atualizar. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Atenção: wallet.dat corrompido, dados recuperados! Arquivo wallet.dat original salvo como wallet.{timestamp}.bak em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes. @@ -3239,10 +2026,6 @@ Wallet options: Opções da carteira: - - You need to rebuild the database using -reindex to change -txindex - Você precisa reconstruir o banco de dados utilizando -reindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permitir conexões JSON-RPC de uma fonte específica. Válido para um único ip (ex. 1.2.3.4), até uma rede/máscara (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser usada múltiplas vezes @@ -3255,10 +2038,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Conecte ao endereço dado para receber conecções JSON-RPC. Use a notação [destino]:porta para IPv6. Essa opção pode ser especificada várias vezes (padrão: conecte a todas as interfaces) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Criar novos arquivos com permissões padrão do sistema, em vez de umask 077 (apenas efetivo com funcionalidade de carteira desabilitada) @@ -3303,10 +2082,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Define o tamanho máximo de alta-prioridade por taxa baixa nas transações em bytes (padrão: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Determina o número de núcleos para a geração de moedas se ativado (-1 = todos os núcleos, padrão: %d) - The transaction amount is too small to send after the fee has been deducted A quantia da transação é muito pequena para mandar @@ -3331,34 +2106,14 @@ Accept public REST requests (default: %u) Aceitar pedidos restantes públicas (padrão: %u) - - Activating best chain... - Ativando a melhor sequência... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Tentar recuperar na inicialização chaves privadas de um arquivo wallet.dat corrompido - Automatically create Tor hidden service (default: %d) Criar automaticamente serviços ocultos do Tor (padrão: %d) - - Cannot resolve -whitebind address: '%s' - Impossível resolver endereço -whitebind: '%s' - Connect through SOCKS5 proxy Connecte-se através de um proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Desenvolvedores Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Erro ao carregar wallet.dat: A carteira requer a nova versão do Bitcoin - Error reading from database, shutting down. Erro ao ler o banco de dados. Finalizando. @@ -3371,22 +2126,6 @@ Information Informação - - Initialization sanity check failed. Bitcoin Core is shutting down. - O teste de integridade da inicialização falhou. O Core do Bitcoin está sendo desligado. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Quantidade inválida para -maxtxfee=<quantidade>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Quantidade inválida para -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Valor inválido para -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Valor inválido para -paytxfee=<amount>: '%s' (precisa ser no mínimo %s) @@ -3411,14 +2150,6 @@ RPC server options: Opções do servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstruir índice de cadeia de bloco a partir dos arquivos blk000??.dat atuais durante a inicialização - - - Receive and display P2P network alerts (default: %u) - Receba e mostre P2P alerta de rede (padrão: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reduzindo -maxconnections de %d para %d, devido a limitações do sistema @@ -3491,10 +2222,6 @@ Username for JSON-RPC connections Nome de usuário para conexões JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Sua carteira precisou ser reescrita: favor reiniciar o Bitcoin para completar - Warning Atenção @@ -3515,10 +2242,6 @@ ZeroMQ notification options: Opções de notificação ZeroMQ: - - wallet.dat corrupt, salvage failed - wallet.dat corrompido, recuperação falhou - Password for JSON-RPC connections Senha para conexões JSON-RPC @@ -3527,10 +2250,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco) - - This help message - Exibe esta mensagem de ajuda - Allow DNS lookups for -addnode, -seednode and -connect Permitir consultas DNS para -addnode, -seednode e -connect @@ -3539,10 +2258,6 @@ Loading addresses... Carregando endereços... - - Error loading wallet.dat: Wallet corrupted - Erro ao carregar wallet.dat: Carteira corrompida - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = manter metadados tx e.g. informação do dono da conta e requisição de pagamente, 2 = descartar metadados tx) @@ -3559,10 +2274,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Não manter transações na mempool por mais que <n> horas (padrão: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Erro ao ler o arquivo wallet.dat! Todas as chaves foram lidas corretamente, mas os dados de transações ou o livro de endereços podem estar faltando ou ser incorretos. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Comissões (em %s/kB) menores serão consideradas como zero para criação de transação (padrão %s) @@ -3599,6 +2310,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Argumento inválido -socks encontrado. Definir a versão do SOCKS não é mais possível, somente proxys SOCK5 são suportados. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumento não suportado -whitelistalwaysrelay foi ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor (padrão: %s) @@ -3607,6 +2322,10 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Nome de usuário e senha hash para conexões JSON-RPC. O campo <userpw> vem com o formato: <USERNAME>:<SALT>$<HASH>. Um script python canônico é incluído em share/rpcuser. Essa opção pode ser especificada múltiplas vezes. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Aviso: Versões de bloco desconhecidas sendo mineradas! É possível que regras estranhas estejam ativas + (default: %s) (padrão: %s) @@ -3615,14 +2334,6 @@ Always query for peer addresses via DNS lookup (default: %u) Sempre pergunte pelo endereço de peer via pesquisa DNS (padrão: %u) - - Error loading wallet.dat - Erro ao carregar wallet.dat - - - Generate coins (default: %u) - Gerar moedas (padrão: %u) - How many blocks to check at startup (default: %u, 0 = all) Quantos blocos devem ser checados ao iniciar (padrão: %u, 0 = todos) @@ -3707,18 +2418,6 @@ Unknown network specified in -onlynet: '%s' Rede desconhecida especificada em -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Impossível encontrar o endereço -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Impossível encontrar endereço -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Quantidade inválida para -paytxfee=<quantidade>: '%s' - Insufficient funds Saldo insuficiente diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 362769138..16b912dfd 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -25,10 +25,6 @@ C&lose F&echar - - &Copy Address - &Copiar Endereço - Delete the currently selected address from the list Eliminar o endereço selecionado da lista @@ -45,73 +41,6 @@ &Delete &Eliminar - - Choose the address to send coins to - Escolha o endereço para enviar as moedas - - - Choose the address to receive coins with - Escolha o endereço para receber as moedas com - - - C&hoose - Escol&her - - - Sending addresses - Endereços de envio - - - Receiving addresses - Endereços de a receber - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Estes são os seus endereços Bitcoin para enviar pagamentos. Verifique sempre o valor e o endereço de envio antes de enviar moedas. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Estes são os seus endereços do Bitcoin para receber pagamentos. É recomendado que utilize um novo endereço para cada transação. - - - Copy &Label - Copiar &Rótulo - - - &Edit - &Editar - - - Export Address List - Exportar Lista de Endereços - - - Comma separated file (*.csv) - Ficheiro separado por vírgulas (*.csv) - - - Exporting Failed - Exportação Falhou - - - There was an error trying to save the address list to %1. Please try again. - Houve um erro ao tentar a guardar a lista de endereços em %1. Por favor tente novamente. - - - - AddressTableModel - - Label - Etiqueta - - - Address - Endereço - - - (no label) - (sem etiqueta) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repita a nova frase de palavra-passe - - Encrypt wallet - Encriptar carteira - - - This operation needs your wallet passphrase to unlock the wallet. - Esta operação precisa da sua frase de palavra-passe da carteira para desbloquear a mesma. - - - Unlock wallet - Desbloquear carteira - - - This operation needs your wallet passphrase to decrypt the wallet. - Esta operação precisa da sua frase de palavra-passe da carteira para desencriptar a mesma. - - - Decrypt wallet - Desencriptar carteira - - - Change passphrase - Alterar frase de palavra-passe - - - Confirm wallet encryption - Confirmar encriptação da carteira - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Aviso: se encriptar a sua carteira e perder a sua frase de de palavra-passe, irá <b>PERDER TODOS OS SEUS BITCOINS</b>! - - - Are you sure you wish to encrypt your wallet? - Tem a certeza que deseja encriptar a carteira? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - O cliente Bitcoin Core irá agora ser fechado para terminar o processo de encriptação. Recorde que a encriptação da sua carteira não protegerá totalmente os seus bitcoins de serem roubados por programas maliciosos que infectem o seu computador. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANTE: Qualquer cópia de segurança da carteira anterior deverá ser substituída com o novo ficheiro de carteira, agora encriptado. Por razões de segurança, cópias de segurança não encriptadas tornar-se-ão inúteis assim que começar a usar a nova carteira encriptada. - - - Warning: The Caps Lock key is on! - Atenção: a tecla Caps Lock está ativada! - - - Wallet encrypted - Carteira encriptada - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Insira a nova frase de palavra-passe da sua carteira. <br/> Por favor, utilize uma frase de palavra-passe com <b>mais de 10 ou mais carateres aleatórios,</b> ou <b>oito ou mais palavras</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Insira a frase de palavra-passe antiga e a nova frase de palavra-passe para carteira. - - - Wallet encryption failed - A encriptação da carteira falhou - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - A encriptação da carteira falhou devido a um erro interno. A carteira não foi encriptada. - - - The supplied passphrases do not match. - As frases de palavra-passe inseridas não coincidem. - - - Wallet unlock failed - O desbloqueio da carteira falhou - - - The passphrase entered for the wallet decryption was incorrect. - A frase de palavra-passe inserida para a desencriptação da carteira estava incorreta. - - - Wallet decryption failed - A desencriptação da carteira falhou - - - Wallet passphrase was successfully changed. - A frase de palavra-passe da carteira foi alterada com sucesso. - BanTableModel @@ -269,6 +110,14 @@ Quit application Sair da aplicação + + &About %1 + &Acerca de %1 + + + Show information about %1 + Mostrar informação sobre %1 + About &Qt Sobre &Qt @@ -281,6 +130,10 @@ &Options... &Opções... + + Modify configuration options for %1 + Modificar opções de configuração para %1 + &Encrypt Wallet... E&ncriptar Carteira... @@ -305,14 +158,6 @@ Open &URI... Abrir &URI... - - Bitcoin Core client - Cliente do Bitcoin Core - - - Importing blocks from disk... - A importar os blocos do disco... - Reindexing blocks on disk... A reindexar os blocos no disco... @@ -357,10 +202,6 @@ &Receive &Receber - - Show information about Bitcoin Core - Mostrar informação sobre o Bitcoin Core - &Show / Hide Mo&strar / Ocultar @@ -397,22 +238,10 @@ Tabs toolbar Barra de ferramentas dos separadores - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Solicitar pagamentos (gera códigos QR e bitcoin: URIs) - - &About Bitcoin Core - &Sobre o Bitcoin Core - - - Modify configuration options for Bitcoin Core - Modificar as opções de configuração do Bitcoin Core - Show the list of used sending addresses and labels Mostrar a lista de rótulos e endereços de envio usados @@ -429,14 +258,18 @@ &Command-line options &Opções da linha de &comando - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Mostrar a mensagem de ajuda do Bitcoin Core para obter uma lista com possíveis opções de linha de comando do Bitcoin - %n active connection(s) to Bitcoin network %n ligação ativa à rede Bitcoin%n ligações ativas à rede Bitcoin + + Indexing blocks on disk... + A indexar blocos no disco... + + + Processing blocks on disk... + A processar blocos no disco... + No block source available... Nenhuma fonte de blocos disponível... @@ -544,13 +377,6 @@ A carteira está <b>encriptada</b> e atualmente <b>bloqueada</b> - - ClientModel - - Network Alert - Alerta da Rede - - CoinControlDialog @@ -629,150 +455,6 @@ Priority Prioridade - - Copy address - Copiar endereço - - - Copy label - Copiar etiqueta - - - Copy amount - Copiar valor - - - Copy transaction ID - Copiar id. da transação - - - Lock unspent - Bloquear não gastas - - - Unlock unspent - Desbloquear não gastas - - - Copy quantity - Copiar quantidade - - - Copy fee - Copiar taxa - - - Copy after fee - Copiar depois da taxa - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridade - - - Copy dust - Copiar lixo - - - Copy change - Copiar alteração - - - highest - muito alta - - - higher - mais alta - - - high - alta - - - medium-high - média alta - - - medium - média - - - low-medium - média baixa - - - low - baixa - - - lower - mais baixa - - - lowest - muito baixa - - - (%1 locked) - (%1 bloqueados) - - - none - nenhum - - - This label turns red if the transaction size is greater than 1000 bytes. - Esta etiqueta fica vermelha se o tamanho da transação exceder os 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Esta etiqueta fica vermelha se a prioridade for menor que "média". - - - This label turns red if any recipient receives an amount smaller than %1. - Esta etiqueta fica vermelha se qualquer recipiente receber uma quantia menor que %1. - - - Can vary +/- %1 satoshi(s) per input. - Pode variar +/- %1 satoshi(s) por entrada - - - yes - sim - - - no - não - - - This means a fee of at least %1 per kB is required. - Isto significa que uma taxa de pelo menos %1 por kB é necessária. - - - Can vary +/- 1 byte per input. - Pode variar +/- 1 byte por input. - - - Transactions with higher priority are more likely to get included into a block. - Transacções com uma prioridade mais alta têm uma maior probabilidade de serem incluídas num bloco. - - - (no label) - (sem etiqueta) - - - change from %1 (%2) - troco de %1 (%2) - - - (change) - (troco) - EditAddressDialog @@ -796,38 +478,6 @@ &Address E&ndereço - - New receiving address - Novo endereço de entrada - - - New sending address - Novo endereço de saída - - - Edit receiving address - Editar endereço de entrada - - - Edit sending address - Editar endereço de saída - - - The entered address "%1" is already in the address book. - O endereço introduzido "%1" já se encontra no livro de endereços. - - - The entered address "%1" is not a valid Bitcoin address. - O endereço introduzido "%1" não é um endereço bitcoin válido. - - - Could not unlock wallet. - Impossível desbloquear carteira. - - - New key generation failed. - Falha ao gerar nova chave. - FreespaceChecker @@ -854,10 +504,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version versão @@ -867,8 +513,8 @@ (%1-bit) - About Bitcoin Core - Sobre o Bitcoin Core + About %1 + Sobre %1 Command-line options @@ -906,11 +552,7 @@ Show splash screen on startup (default: %u) Mostrar o ecrã de abertura no arranque (predefinição: %u) - - Reset all settings changes made over the GUI - Reiniciar as alterações das configurações efetuadas na GUI - - + Intro @@ -918,16 +560,8 @@ Bem-vindo - Welcome to Bitcoin Core. - Bem-vindo ao Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Como esta é a primeira vez que o programa é iniciado, pode escolher onde guardar os seus dados do Bitcoin Core. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - O Bitcoin Core irá transferir e guardar uma cópia da cadeia de bloco do Bitcoin. Pelo menos %1GB de dados serão guardados nesta diretoria, e estes irão crescer ao longo do tempo. A sua carteira também será guardada nesta diretoria. + Welcome to %1. + Bem-vindo a %1. Use the default data directory @@ -937,10 +571,6 @@ Use a custom data directory: Utilizar uma diretoria de dados personalizada: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Erro: não pode ser criada a diretoria de dados especificada como "%1. @@ -976,10 +606,6 @@ Select payment request file Seleccione o ficheiro de pedido de pagamento - - Select payment request file to open - Seleccione o ficheiro de pedido de pagamento a abrir - OptionsDialog @@ -991,6 +617,10 @@ &Main &Principal + + &Start %1 on system login + &Iniciar o %1 no início de sessão do sistema + Size of &database cache Tamanho da cache da base de &dados @@ -1019,10 +649,6 @@ 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. Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada quando escolher Sair da aplicação no menú. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - O idioma da da interface do utilizador pode ser definida aqui. Esta definição será aplicada depois de reiniciar o Bitcoin Core. - 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 |. URLs de outrem (ex. um explorador de blocos) que aparece no separador de transações como itens do menu de contexto. @@ -1048,14 +674,6 @@ &Network &Rede - - Automatically start Bitcoin Core after logging in to the system. - Iniciar automaticamente o Bitcoin Core depois de iniciar a sessão no sistema. - - - &Start Bitcoin Core on system login - &Iniciar o Bitcoin Core ao iniciar a sessão no sistema - (0 = auto, <0 = leave that many cores free) (0 = automático, <0 = deixar essa quantidade de núcleos livre) @@ -1140,6 +758,10 @@ &Window &Janela + + Hide tray icon + Ocultar ícone da bandeja + Show only a tray icon after minimizing the window. Apenas mostrar o ícone da bandeja de sistema após minimizar a janela. @@ -1284,97 +906,6 @@ Saldo disponivél em enderços modo-verificação - - PaymentServer - - URI handling - Manuseamento de URI - - - Invalid payment address %1 - Endereço de pagamento inválido %1 - - - Payment request rejected - Pedido de pagamento rejeitado - - - Payment request network doesn't match client network. - Rede de requisição de pagamento não corresponde com a rede do cliente. - - - Payment request is not initialized. - Requisição de pagamento não iniciou. - - - Requested payment amount of %1 is too small (considered dust). - Quantia solicitada para pagamento de %1 é muito pequena (considerada "pó"). - - - Payment request error - Erro de pedido de pagamento - - - Cannot start bitcoin: click-to-pay handler - Não é possível iniciar o Bitcoin: utilizador clique-para-pagar - - - Payment request fetch URL is invalid: %1 - O URL de pedido de pagamento é inválido: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI não foi lido correctamente! Isto pode ser causado por um endereço Bitcoin inválido ou por parâmetros URI malformados. - - - Payment request file handling - Controlo de pedidos de pagamento. - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - O ficheiro de pedido de pagamento não pôde ser lido! Isto pode ter sido causado por um ficheiro de pedido de pagamento inválido. - - - Payment request expired. - Pedido de pagamento expirou. - - - Unverified payment requests to custom payment scripts are unsupported. - Pedidos de pagamento não-verificados para scripts de pagamento personalizados não são suportados. - - - Invalid payment request. - Pedido de pagamento inválido. - - - Refund from %1 - Reembolsar de %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Pedido de pagamento %1 excede o tamanho (%2 bytes, permitido %3 bytes). - - - Error communicating with %1: %2 - Erro ao comunicar com %1: %2 - - - Payment request cannot be parsed! - O pedido de pagamento não pode ser lido ou processado! - - - Bad response from server %1 - Má resposta do servidor %1 - - - Payment acknowledged - Pagamento confirmado - - - Network request error - Erro de pedido de rede - - PeerTableModel @@ -1429,25 +960,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Salvar Imagem... - - - &Copy Image - &Copiar Imagem - - - Save QR Code - Guardar Código QR - - - PNG Image (*.png) - Imagem PNG (*.png) - - RPCConsole @@ -1514,10 +1026,6 @@ Memory usage Utilização de memória - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Abrir o ficheiro de registo de depuração da pasta de dados actual. Isto pode demorar alguns segundos para ficheiros de registo grandes. - Received Recebido @@ -1566,6 +1074,14 @@ User Agent Agente Usuário + + Decrease font size + Diminuir tamanho da letra + + + Increase font size + Aumentar tamanho da letra + Services Serviços @@ -1634,10 +1150,6 @@ Out: Saída: - - Build date - Data de compilação - Debug log file Ficheiro de registo de depuração @@ -1675,8 +1187,8 @@ &Desbloquear Nó - Welcome to the Bitcoin Core RPC console. - Bem-vindo à consola RPC do Bitcoin Core. + Welcome to the %1 RPC console. + Bem-vindo à consola RPC da %1. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1805,18 +1317,6 @@ Remove Remover - - Copy label - Copiar rótulo - - - Copy message - Copiar mensagem - - - Copy amount - Copiar quantia - ReceiveRequestDialog @@ -1836,73 +1336,6 @@ &Save Image... &Salvar Imagem... - - Request payment to %1 - Requisitar Pagamento para %1 - - - Payment information - Informação de Pagamento - - - URI - URI - - - Address - Endereço - - - Amount - Quantia - - - Label - Rótulo - - - Message - Mensagem - - - Resulting URI too long, try to reduce the text for label / message. - URI resultante muito longo. Tente reduzir o texto do rótulo / mensagem. - - - Error encoding URI into QR Code. - Erro ao codificar URI em Código QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Rótulo - - - Message - Mensagem - - - Amount - Quantia - - - (no label) - (sem rótulo) - - - (no message) - (sem mensagem) - - - (no amount) - (sem quantia) - SendCoinsDialog @@ -2022,14 +1455,6 @@ fast rapido - - Send as zero-fee transaction if possible - Enviar como uma transação a custo zero se possivél - - - (confirmation may take longer) - (confirmação poderá demorar mais) - Send to multiple recipients at once Enviar para múltiplos destinatários de uma vez @@ -2062,114 +1487,6 @@ S&end E&nviar - - Confirm send coins - Confirme envio de moedas - - - %1 to %2 - %1 para %2 - - - Copy quantity - Copiar quantidade - - - Copy amount - Copiar quantia - - - Copy fee - Copiar taxa - - - Copy after fee - Copiar valor após taxa - - - Copy bytes - Copiar bytes - - - Copy priority - Copiar prioridade - - - Copy change - Copiar alteração - - - Total Amount %1 - Quantia Total %1 - - - or - ou - - - The amount to pay must be larger than 0. - A quantia a pagar deverá ser maior que 0. - - - The amount exceeds your balance. - A quantia excede o seu saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - O total excede o seu saldo quando a taxa de transação de %1 for incluída. - - - Transaction creation failed! - Erro: A criação da transação falhou! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - A transação foi rejeitada! Isto poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas tiverem sido gastas na cópia mas não tiverem sido marcadas como gastas aqui. - - - A fee higher than %1 is considered an absurdly high fee. - Uma taxa superior a %1 é considerada muito alta. - - - Payment request expired. - Pedido de pagamento expirou. - - - Pay only the required fee of %1 - Pagar somente a taxa mínima de %1 - - - The recipient address is not valid. Please recheck. - O endereço de destino não é válido. Por favor, verifique novamente. - - - Duplicate address found: addresses should only be used once each. - Endereço duplicado encontrado: cada endereço só poderá ser usado uma vez. - - - Warning: Invalid Bitcoin address - Aviso: Endereço Bitcoin inválido - - - (no label) - (sem rótulo) - - - Warning: Unknown change address - Aviso: Endereço de troco desconhecido - - - Copy dust - Copiar lixo - - - Are you sure you want to send? - Tem a certeza que deseja enviar? - - - added as transaction fee - adicionados como taxa de transação - SendCoinsEntry @@ -2181,10 +1498,6 @@ Pay &To: &Pagar A: - - Enter a label for this address to add it to your address book - Escreva um rótulo para este endereço para o adicionar ao seu livro de endereços - &Label: Rótu&lo: @@ -2257,8 +1570,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - O Bitcoin Core está a encerrar... + %1 is shutting down... + %1 está a encerrar... Do not shut down the computer until this window disappears. @@ -2351,69 +1664,9 @@ Reset all verify message fields Repor todos os campos de verificação de mensagem - - Click "Sign Message" to generate signature - Clique "Assinar mensagem" para gerar a assinatura - - - The entered address is invalid. - O endereço introduzido é inválido. - - - Please check the address and try again. - Por favor verifique o endereço e tente de novo. - - - The entered address does not refer to a key. - O endereço introduzido não refere a nenhuma chave. - - - Wallet unlock was cancelled. - O desbloqueio da carteira foi cancelado. - - - Private key for the entered address is not available. - A chave privada para o endereço introduzido não está disponível. - - - Message signing failed. - Assinatura de mensagem falhou. - - - Message signed. - Mensagem assinada. - - - The signature could not be decoded. - A assinatura não pôde ser descodificada. - - - Please check the signature and try again. - Por favor verifique a assinatura e tente de novo. - - - The signature did not match the message digest. - A assinatura não condiz com o conteúdo da mensagem. - - - Message verification failed. - Verificação da mensagem falhou. - - - Message verified. - Mensagem verificada. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Os programadores do Bitcoin Core - [testnet] [rede de testes] @@ -2426,422 +1679,13 @@ KB/s - - TransactionDesc - - Open until %1 - Aberto até %1 - - - conflicted - em conflito: - - - %1/offline - %1/desligado - - - %1/unconfirmed - %1/não confirmada - - - %1 confirmations - %1 confirmações - - - Status - Estado - - - , broadcast through %n node(s) - , transmitida através de %n nó, transmitida através de %n nós - - - Date - Data - - - Source - Origem - - - Generated - Gerado - - - From - De - - - To - Para - - - own address - endereço próprio - - - watch-only - modo-verificação - - - label - rótulo - - - Credit - Crédito - - - matures in %n more block(s) - matura em %n blocomatura em %n blocos - - - not accepted - não aceite - - - Debit - Débito - - - Total debit - Total a debitar - - - Total credit - Total a creditar - - - Transaction fee - Taxa de transação - - - Net amount - Valor líquido - - - Message - Mensagem - - - Comment - Comentário - - - Transaction ID - ID da Transação - - - Merchant - Comerciante - - - 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. - Moedas geradas deverão maturar por %1 blocos antes de poderem ser gastas. Quando gerou este bloco, ele foi transmitido para a rede para ser incluído na cadeia de blocos. Se a inclusão na cadeia de blocos falhar, o seu estado irá ser alterado para "não aceite" e as moedas não poderão ser gastas. Isto poderá acontecer ocasionalmente se outro nó da rede gerar um bloco a poucos segundos de diferença do seu. - - - Debug information - Informação de depuração - - - Transaction - Transação - - - Inputs - Entradas - - - Amount - Quantia - - - true - verdadeiro - - - false - falso - - - , has not been successfully broadcast yet - , ainda não foi transmitida com sucesso - - - Open for %n more block(s) - Aberta por mais %n blocoAberta por mais %n blocos - - - unknown - desconhecido - - TransactionDescDialog - - Transaction details - Detalhes da transação - This pane shows a detailed description of the transaction Esta janela mostra uma descrição detalhada da transação - - TransactionTableModel - - Date - Data - - - Type - Tipo - - - Immature (%1 confirmations, will be available after %2) - Imaturo (%1 confirmações, estará disponível após %2) - - - Open for %n more block(s) - Aberta por mais %n blocoAberta por mais %n blocos - - - Open until %1 - Aberto até %1 - - - Confirmed (%1 confirmations) - Confirmada (%1 confirmações) - - - This block was not received by any other nodes and will probably not be accepted! - Este bloco não foi recebido por outros nós e provavelmente não será aceite pela rede! - - - Generated but not accepted - Gerado mas não aceite - - - Offline - Offline - - - Label - Rótulo - - - Unconfirmed - Não confirmado: - - - Confirming (%1 of %2 recommended confirmations) - A confirmar (%1 de %2 confirmações recomendadas) - - - Conflicted - Em Conflito: - - - Received with - Recebido com - - - Received from - Recebido de - - - Sent to - Enviado para - - - Payment to yourself - Pagamento a si mesmo - - - Mined - Minadas - - - watch-only - modo-verificação - - - (n/a) - (n/d) - - - Transaction status. Hover over this field to show number of confirmations. - Estado da transação. Passar o cursor por cima deste campo para mostrar o número de confirmações. - - - Date and time that the transaction was received. - Data e hora em que a transação foi recebida. - - - Type of transaction. - Tipo de transação. - - - Whether or not a watch-only address is involved in this transaction. - Desde que um endereço de modo-verificação faça parte ou não desta transação - - - User-defined intent/purpose of the transaction. - Motivo da transacção definido pelo utilizador. - - - Amount removed from or added to balance. - Quantia retirada ou adicionada ao saldo. - - - - TransactionView - - All - Todas - - - Today - Hoje - - - This week - Esta semana - - - This month - Este mês - - - Last month - Mês passado - - - This year - Este ano - - - Range... - Período... - - - Received with - Recebida com - - - Sent to - Enviada para - - - To yourself - Para si mesmo - - - Mined - Minadas - - - Other - Outras - - - Enter address or label to search - Escreva endereço ou rótulo a procurar - - - Min amount - Quantia mínima - - - Copy address - Copiar endereço - - - Copy label - Copiar rótulo - - - Copy amount - Copiar quantia - - - Copy transaction ID - Copiar ID da Transação - - - Copy raw transaction - Copiar dados brutos da transacção - - - Edit label - Editar rótulo - - - Show transaction details - Mostrar detalhes da transação - - - Export Transaction History - Exportar Histórico de Transacções - - - Watch-only - Modo-verificação - - - Exporting Failed - A Exportação Falhou - - - There was an error trying to save the transaction history to %1. - Ocorreu um erro ao tentar guardar o histórico de transações em %1. - - - Exporting Successful - Exportação Bem Sucedida - - - The transaction history was successfully saved to %1. - O histórico de transacções foi com guardado com sucesso em %1. - - - Comma separated file (*.csv) - Ficheiro separado por vírgulas (*.csv) - - - Confirmed - Confirmada - - - Date - Data - - - Type - Tipo - - - Label - Rótulo - - - Address - Endereço - - - ID - ID - - - Range: - Período: - - - to - até - - UnitDisplayStatusBarControl @@ -2849,55 +1693,6 @@ Unidade de valores recebidos. Clique para selecionar outra unidade. - - WalletFrame - - No wallet has been loaded. - Não foi carregada nenhuma carteira. - - - - WalletModel - - Send Coins - Enviar Moedas - - - - WalletView - - &Export - &Exportar - - - Export the data in the current tab to a file - Exportar os dados no separador actual para um ficheiro - - - Backup Wallet - Cópia de Segurança da Carteira - - - Wallet Data (*.dat) - Dados da Carteira (*.dat) - - - Backup Failed - Cópia de Segurança Falhou - - - There was an error trying to save the wallet data to %1. - Ocorreu um erro ao tentar guardar os dados da carteira em %1. - - - The wallet data was successfully saved to %1. - Os dados da carteira foram guardados com sucesso em %1. - - - Backup Successful - Cópia de Segurança Bem Sucedida - - bitcoin-core @@ -2924,14 +1719,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Se <category> não é fornecida ou <category> = 1, imprimir toda a informação de depuração. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Total máximo de taxas (em %s) a utilizar numa única transacção; definir este valor demasiado baixo pode abortar transacções grandes (padrão: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Por favor verifique que a data e hora do seu computador estão correctas! Se o seu relógio não estiver certo o Bitcoin Core não irá funcionar correctamente. - Prune configured below the minimum of %d MiB. Please use a higher number. Poda configurada abaixo do mínimo de %d MiB. Por favor, utilize um valor mais elevado. @@ -2972,6 +1759,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Aceitar ligações externas (padrão: 1 sem -proxy ou -connect) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee está definida muito elevada! Esta é a taxa de transação pode poderá pagar quando as estimativas de taxas não estão disponíveis. @@ -3016,14 +1807,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta é uma versão de testes pré-lançamento - use à sua responsabilidade - não usar para minar ou aplicações comerciais - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Incapaz de vincular à porta %s neste computador. O Bitcoin Core provavelmente já está a correr. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Argumento não suportado -whitelistalwaysrelay ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizar UPnP para mapear a porta de escuta (predefinição: 1 quando escutar e sem -proxy) @@ -3040,18 +1823,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Aviso: A rede não parece estar completamente de acordo! Parece que alguns mineiros estão com dificuldades técnicas. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Atenção: Versões desconhecidas de blocos estão a ser mineradas! É possível que regras desconhecias estão a ser efetuadas - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atenção: Parecemos não estar de acordo com os nossos pares! Poderá ter que atualizar o seu cliente, ou outros nós poderão ter que atualizar os seus clientes. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Atenção: wallet.dat corrompido, dados recuperados! wallet.dat original salvo como wallet.{timestamp}.bak em %s; se o seu saldo ou transações estiverem incorrectos deverá recuperar uma cópia de segurança. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Ligações na lista branca conectam desde a seguinte netmask ou endereço IP. Posse ser especificado varias vezes. @@ -3124,6 +1899,18 @@ Error initializing wallet database environment %s! Erro ao inicializar o ambiente %s da base de dados da carteira + + Error loading %s + Erro ao carregar %s + + + Error loading %s: Wallet corrupted + Erro ao carregar %s: carteira corrompida + + + Error loading %s: Wallet requires newer version of %s + Erro ao carregar %s: a carteira requer a nova versão de %s + Error loading block database Erro ao carregar base de dados de blocos @@ -3152,6 +1939,10 @@ Invalid -onion address: '%s' Endereço -onion inválido: '%s' + + Invalid amount for -%s=<amount>: '%s' + Valor inválido para -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Valor inválido para -fallbackfee=<amount>: '%s' @@ -3176,6 +1967,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Somente conectar aos nodes na rede <net> (ipv4, ipv6 ou onion) + + Print this help message and exit + Imprimir esta mensagem de ajuda e sair + Print version and exit Imprimir versão e sair @@ -3236,10 +2031,6 @@ Wallet options: Opções da carteira: - - You need to rebuild the database using -reindex to change -txindex - É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permitir conexções JSON-RPC de fontes especificas. Valido para <ip> um unico IP (ex. 1.2.3.4), uma rede/netmask (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser especificada varias vezes @@ -3252,10 +2043,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Vinculado para dar o endereço para atender as ligações JSON-RPC. Use [host]: Notação de porta para IPv6. Esta opção pode ser especificada várias vezes (padrão: ligam-se a todas as interfaces) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin Core já está a ser executado. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Crie ficheiros novos com as permisões predefinidas do sistema, em vez de umask 077 (apenas eficaz caso a funcionalidade carteira esteja desactivada) @@ -3300,10 +2087,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Definir o número threads para a geração de moedas, caso activo (-1 = todos os cores, padrão: %d) - The transaction amount is too small to send after the fee has been deducted O montante da transacção é demasiado baixo após a dedução da taxa @@ -3328,34 +2111,14 @@ Accept public REST requests (default: %u) Aceitar pedidos REST públicos (predefinição: %u) - - Activating best chain... - A activar a melhor cadeia... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Tentar recuperar chaves privadas de um wallet.dat corrompido ao iniciar - Automatically create Tor hidden service (default: %d) Criar automaticamente o serviço Tor oculto (predefinição: %d) - - Cannot resolve -whitebind address: '%s' - Não foi possível resolver o endereço -whitebind: '%s' - Connect through SOCKS5 proxy Ligar através de um proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Os Programadores do Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Erro ao carregar wallet.dat: A carteira requer uma versão mais recente do Bitcoin Core - Error reading from database, shutting down. Erro ao ler da base de dados, encerrando. @@ -3368,22 +2131,6 @@ Information Informação - - Initialization sanity check failed. Bitcoin Core is shutting down. - Falha na prova real inicial. Bitcoin Core está a desligar. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Quantia inválida para -maxtxfee=<quantidade>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Quantia inválida para -minrelaytxfee=<quantidade>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Quantia inválida para -mintxfee=<quantidade>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Montante inválido para -paytxfee=<amount>: '%s' (deverá ser no mínimo %s) @@ -3408,14 +2155,6 @@ RPC server options: Opções do servidor RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Reconstruir a cadeia de blocos a partir dos ficheiros blk000??.dat actuais ao iniciar - - - Receive and display P2P network alerts (default: %u) - Receber e mostrar alertas da rede P2P (padrão: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Reduzindo -maxconnections de %d para %d, devido a limitações no sistema. @@ -3488,10 +2227,6 @@ Username for JSON-RPC connections Nome de utilizador para ligações JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - A Carteira precisou de ser reescrita: reinicie o Bitcoin Core para completar o processo - Warning Aviso @@ -3512,10 +2247,6 @@ ZeroMQ notification options: Opções de notificação ZeroMQ: - - wallet.dat corrupt, salvage failed - wallet.dat corrompido, recuperação falhou - Password for JSON-RPC connections Palavra-passe para ligações JSON-RPC @@ -3524,10 +2255,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Executar comando quando o melhor bloco mudar (no comando, %s é substituído pela hash do bloco) - - This help message - Esta mensagem de ajuda - Allow DNS lookups for -addnode, -seednode and -connect Permitir procuras DNS para -addnode, -seednode e -connect @@ -3536,10 +2263,6 @@ Loading addresses... A carregar os endereços... - - Error loading wallet.dat: Wallet corrupted - Erro ao carregar wallet.dat: Carteira danificada - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = guardar metadados da transacção ex: proprietário da conta e informação do pedido de pagamento, 2 = descartar metadados da transacção) @@ -3556,10 +2279,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Não guardar transações no banco de memória por mais de <n> horas (predefinição: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Erro ao ler wallet.dat! Todas as chaves foram lidas correctamente, mas os dados das transacções ou do livro de endereços podem estar em falta ou incorrectos. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Taxas (em %s/kB) abaixo deste valor são consideradas nulas para a criação de transacções (padrão: %s) @@ -3596,6 +2315,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Encontrado um argumento não suportado -socks. Definir a versão do SOCKS já não é possível, apenas proxies SOCKS5 são suportados. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumento não suportado -whitelistalwaysrelay ignorado, utilize -whitelistrelay e/ou -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use um proxy SOCKS5 separado para alcançar pares via serviços ocultos do Tor (padrão: %s) @@ -3604,6 +2327,10 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Username e hash da password para ligações JSON-RPC. O campo <userpw> está no formato: <USERNAME>:<SALT>$<HASH>. Um script python está incluido em share/rpcuser. Esta opção pode ser especificada múltiplas vezes. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Atenção: Versões desconhecidas de blocos estão a ser mineradas! É possível que regras desconhecias estão a ser efetuadas + (default: %s) (predefinição: %s) @@ -3612,14 +2339,6 @@ Always query for peer addresses via DNS lookup (default: %u) Utilizar sempre a consulta de DNS para endereços de pares (predefinição: %u) - - Error loading wallet.dat - Erro ao carregar wallet.dat - - - Generate coins (default: %u) - Gerar moedas (predefinição: %u) - How many blocks to check at startup (default: %u, 0 = all) Quantos blocos para verificar no arranque (predefinição: %u, 0 = todos) @@ -3704,18 +2423,6 @@ Unknown network specified in -onlynet: '%s' Rede desconhecida especificada em -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Não foi possível resolver o endereço -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Não foi possível resolver o endereço -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Quantia inválida para -paytxfee=<amount>: '%s' - Insufficient funds Fundos insuficientes diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index 11ac69f0f..270a4ba06 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -11,7 +11,7 @@ &New - &Nou + Nou Copy the currently selected address to the system clipboard @@ -19,15 +19,11 @@ &Copy - &Copiază + Copiază C&lose - Î&nchide - - - &Copy Address - &Copiază Adresa + Închide Delete the currently selected address from the list @@ -39,32 +35,38 @@ &Export - &Exportă + Exportă - Choose the address to send coins to - Indică adresa de expediere a monedelor + &Delete + Șterge - - Choose the address to receive coins with - Indică adresa de a primi monedele - - - - AddressTableModel - + AskPassphraseDialog - + + Passphrase Dialog + Secventa de cuvinte a parolei + + + Enter passphrase + Introduceti parola + + + New passphrase + Noua parolă + + + Repeat new passphrase + Repetati noua parolă + + BanTableModel BitcoinGUI - - ClientModel - CoinControlDialog @@ -89,18 +91,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -110,9 +106,6 @@ ReceiveRequestDialog - - RecentRequestsTableModel - SendCoinsDialog @@ -131,38 +124,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - - TransactionView - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Exportă - - - Export the data in the current tab to a file - Exportă datele din tabul curent in fisier - - bitcoin-core diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 502052dff..e6f591aa9 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -25,10 +25,6 @@ C&lose Închide - - &Copy Address - &Copiază Adresa - Delete the currently selected address from the list Şterge adresele curent selectate din listă @@ -45,73 +41,6 @@ &Delete &Şterge - - Choose the address to send coins to - Alegeţi adresa unde vreţi să trimiteţi monedele - - - Choose the address to receive coins with - Alegeţi adresa unde vreţi să primiţi monedele - - - C&hoose - &Alegeţi - - - Sending addresses - Adresa destinatarului - - - Receiving addresses - Adresa de primire - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Acestea sînt adresele dumneavoastră Bitcoin pentru efectuarea plăţilor. Verificaţi întotdeauna cantitatea şi adresa de primire înainte de a trimite monede. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Acestea sînt adresele dumneavoastră Bitcoin folosite pentru a primi plati. Este recomandat să folosiţi o adresă nouă de primire pentru fiecare tranzacţie în parte. - - - Copy &Label - Copiază &eticheta - - - &Edit - &Editare - - - Export Address List - Exportă listă de adrese - - - Comma separated file (*.csv) - Fişier text cu valori separate prin virgulă (*.csv) - - - Exporting Failed - Export nereuşit - - - There was an error trying to save the address list to %1. Please try again. - A apărut o eroare la salvarea listei de adrese la %1. Vă rugăm să încercaţi din nou. - - - - AddressTableModel - - Label - Etichetă - - - Address - Adresă - - - (no label) - (fără etichetă) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Repetaţi noua frază de acces - - Encrypt wallet - Criptare portofel - - - This operation needs your wallet passphrase to unlock the wallet. - Această acţiune necesită fraza dvs. de acces pentru deblocarea portofelului. - - - Unlock wallet - Deblocare portofel - - - This operation needs your wallet passphrase to decrypt the wallet. - Această acţiune necesită fraza dvs. de acces pentru decriptarea portofelului. - - - Decrypt wallet - Decriptare portofel - - - Change passphrase - Schimbare frază de acces - - - Confirm wallet encryption - Confirmaţi criptarea portofelului - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atenţie: Dacă pierdeţi parola portofelului electronic după criptare, <b>VEŢI PIERDE ÎNTREAGA SUMĂ DE BITCOIN ACUMULATĂ</b>! - - - Are you sure you wish to encrypt your wallet? - Sigur doriţi să criptaţi portofelul dvs.? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin se va închide acum pentru a termina procesul de criptare. Ţineţi minte că criptarea portofelului nu vă poate proteja în totalitate de furtul monedelor de către programe dăunătoare care vă infectează calculatorul. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT: Orice copie de siguranţă făcută anterior portofelului dumneavoastră ar trebui înlocuită cu cea generată cel mai recent, fişier criptat al portofelului. Pentru siguranţă, copiile de siguranţă vechi ale portofelului ne-criptat vor deveni inutile imediat ce veţi începe folosirea noului fişier criptat al portofelului. - - - Warning: The Caps Lock key is on! - Atenţie! Caps Lock este pornit! - - - Wallet encrypted - Portofel criptat - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduceţi noua parolă a portofelului electronic.<br/>Vă rugăm să folosiţi o parolă de<b>minimum 10 caractere aleatoare</b>, sau <b>minimum 8 cuvinte</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Introduceţi vechea şi noua parolă pentru portofel. - - - Wallet encryption failed - Criptarea portofelului nu a reuşit - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Criptarea portofelului nu a reuşit din cauza unei erori interne. Portofelul dvs. nu a fost criptat. - - - The supplied passphrases do not match. - Frazele de acces introduse nu se potrivesc. - - - Wallet unlock failed - Deblocarea portofelului nu a reuşit - - - The passphrase entered for the wallet decryption was incorrect. - Fraza de acces introdusă pentru decriptarea portofelului a fost incorectă. - - - Wallet decryption failed - Decriptarea portofelului nu a reuşit - - - Wallet passphrase was successfully changed. - Parola portofelului electronic a fost schimbată. - BanTableModel @@ -305,14 +146,6 @@ Open &URI... Deschide &URI... - - Bitcoin Core client - Clientul Bitcoin Core - - - Importing blocks from disk... - Import blocuri de pe disk... - Reindexing blocks on disk... Se reindexează blocurile pe disc... @@ -357,10 +190,6 @@ &Receive P&rimeşte - - Show information about Bitcoin Core - Arată informaţii despre Bitcoin Core - &Show / Hide Arată/Ascunde @@ -397,22 +226,10 @@ Tabs toolbar Bara de unelte - - Bitcoin Core - Nucleul Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Cereţi plăţi (generează coduri QR şi bitcoin-uri: URls) - - &About Bitcoin Core - &Despre Nucleul Bitcoin - - - Modify configuration options for Bitcoin Core - Modifică opţiunile de configurare pentru Bitcoin - Show the list of used sending addresses and labels Arată lista de adrese trimise şi etichetele folosite. @@ -429,10 +246,6 @@ &Command-line options Opţiuni linie de &comandă - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Arată mesajul de ajutor Bitcoin Core pentru a obţine o listă cu opţiunile posibile de linii de comandă Bitcoin - %n active connection(s) to Bitcoin network %n conexiune activă către reţeaua Bitcoin%n conexiuni active către reţeaua Bitcoin%n de conexiuni active către reţeaua Bitcoin @@ -544,13 +357,6 @@ Portofelul este <b>criptat</b> iar în momentul de faţă este <b>blocat</b> - - ClientModel - - Network Alert - Alertă reţea - - CoinControlDialog @@ -629,150 +435,6 @@ Priority Prioritate - - Copy address - Copiază adresa - - - Copy label - Copiază eticheta - - - Copy amount - Copiază suma - - - Copy transaction ID - Copiază ID tranzacţie - - - Lock unspent - Blocare necheltuiţi - - - Unlock unspent - Deblocare necheltuiţi - - - Copy quantity - Copiază cantitea - - - Copy fee - Copiază taxa - - - Copy after fee - Copiază după taxă - - - Copy bytes - Copiază octeţi - - - Copy priority - Copiază prioritatea - - - Copy dust - Copiază praf - - - Copy change - Copiază rest - - - highest - cea mai mare - - - higher - mai mare - - - high - mare - - - medium-high - medie-mare - - - medium - medie - - - low-medium - medie-scăzută - - - low - scazută - - - lower - mai scăzută - - - lowest - cea mai scăzută - - - (%1 locked) - (%1 blocat) - - - none - nimic - - - This label turns red if the transaction size is greater than 1000 bytes. - Această etichetă devine roşie în cazul în care dimensiunea tranzacţiei este mai mare de 1000 de octeţi. - - - This label turns red if the priority is smaller than "medium". - Această etichetă devine roşie dacă prioritatea e mai mică decît "medie". - - - This label turns red if any recipient receives an amount smaller than %1. - Această etichetă devine roşie, dacă orice beneficiar primeşte o sumă mai mică decât %1. - - - Can vary +/- %1 satoshi(s) per input. - Poate varia +/- %1 satoshi pentru fiecare intrare. - - - yes - da - - - no - nu - - - This means a fee of at least %1 per kB is required. - Aceasta înseamnă o taxă de cel puţin %1 pe kB necesar. - - - Can vary +/- 1 byte per input. - Poate varia +/- 1 octet pentru fiecare intrare. - - - Transactions with higher priority are more likely to get included into a block. - Tranzacţiile cu prioritate mai mare sînt mai susceptibile de fi incluse într-un bloc. - - - (no label) - (fără etichetă) - - - change from %1 (%2) - restul de la %1 (%2) - - - (change) - (rest) - EditAddressDialog @@ -796,38 +458,6 @@ &Address &Adresă - - New receiving address - Noua adresă de primire - - - New sending address - Noua adresă de trimitere - - - Edit receiving address - Editează adresa de primire - - - Edit sending address - Editează adresa de trimitere - - - The entered address "%1" is already in the address book. - Adresa introdusă "%1" se află deja în lista de adrese. - - - The entered address "%1" is not a valid Bitcoin address. - Adresa introdusă "%1" nu este o adresă bitcoin validă. - - - Could not unlock wallet. - Portofelul nu a putut fi deblocat. - - - New key generation failed. - Generarea noii chei nu a reuşit. - FreespaceChecker @@ -854,10 +484,6 @@ HelpMessageDialog - - Bitcoin Core - Nucleul Bitcoin - version versiunea @@ -867,8 +493,8 @@ (%1-bit) - About Bitcoin Core - Despre Nucleul Bitcoin + About %1 + Despre %1 Command-line options @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Afişează ecran splash la pornire (implicit: %u) - - Reset all settings changes made over the GUI - Resetează toate schimbările făcute în GUI - - + Intro Welcome Bun venit - - Welcome to Bitcoin Core. - Bine aţi venit la Nucleul Bitcoin. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Dacă aceasta este prima dată cînd programul este lansat, puteţi alege unde Nucleul Bitcoin va stoca datele. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Nucleul Bitcoin se va descărca şi va stoca o copie a lanţului blocului Bitcoin. Cel puţin %1GB de date vor fi stocate în acest dosar şi se va mări în timp. Portofelul va fi, de asemenea, stocat în acest dosar. - Use the default data directory Foloseşte dosarul de date implicit @@ -937,10 +547,6 @@ Use a custom data directory: Foloseşte un dosar de date personalizat: - - Bitcoin Core - Nucleul Bitcoin - Error: Specified data directory "%1" cannot be created. Eroare: Directorul datelor specificate "%1" nu poate fi creat. @@ -976,10 +582,6 @@ Select payment request file Selectaţi fişierul cerere de plată - - Select payment request file to open - Selectaţi fişierul cerere de plată pentru deschidere - OptionsDialog @@ -1019,10 +621,6 @@ 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. Minimizează fereastra în locul părăsirii programului în momentul închiderii ferestrei. Cînd acestă opţiune e activă, aplicaţia se va opri doar în momentul selectării comenzii 'Închide aplicaţia' din menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Limba interfeţei utilizatorului poate fi setată aici. Această setare va avea efect după repornirea Nucleului Bitcoin. - 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 |. URL-uri terţe părţi (de exemplu, un explorator de bloc), care apar în tab-ul tranzacţiilor ca elemente de meniu contextual. %s în URL este înlocuit cu hash de tranzacţie. URL-urile multiple sînt separate prin bară verticală |. @@ -1047,14 +645,6 @@ &Network Reţea - - Automatically start Bitcoin Core after logging in to the system. - Porneşte automat Bitcoin Core după logarea în sistem. - - - &Start Bitcoin Core on system login - Porneşte Nucleul Bitcoin la pornirea sistemului - (0 = auto, <0 = leave that many cores free) (0 = automat, <0 = lasă atîtea nuclee libere) @@ -1267,97 +857,6 @@ Soldul dvs. total în adresele doar-supraveghere - - PaymentServer - - URI handling - Gestionare URI - - - Invalid payment address %1 - Adresă pentru plată nevalidă %1 - - - Payment request rejected - Cerere de plată refuzată - - - Payment request network doesn't match client network. - Cererea de plată din reţea nu se potriveşte cu clientul din reţea - - - Payment request is not initialized. - Cererea de plată nu este iniţializată. - - - Requested payment amount of %1 is too small (considered dust). - Suma cerută de plată de %1 este prea mică (considerată praf). - - - Payment request error - Eroare la cererea de plată - - - Cannot start bitcoin: click-to-pay handler - Nu poate porni bitcoin: manipulator clic-pentru-plată - - - Payment request fetch URL is invalid: %1 - URL-ul cererii de plată preluat nu este valid: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI nu poate fi analizat! Acest lucru poate fi cauzat de o adresă Bitcoin nevalidă sau parametri URI deformaţi. - - - Payment request file handling - Manipulare fişier cerere de plată - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Fişierul cerere de plată nu poate fi citit! Cauza poate fi un fişier cerere de plată nevalid. - - - Payment request expired. - Cererea de plată a expirat. - - - Unverified payment requests to custom payment scripts are unsupported. - Cererile de plată neverificate prin script-uri personalizate de plată nu sînt suportate. - - - Invalid payment request. - Cerere de plată nevalidă. - - - Refund from %1 - Rambursare de la %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Cererea de plată %1 este prea mare (%2 octeţi, permis %3 octeţi). - - - Error communicating with %1: %2 - Eroare la comunicarea cu %1: %2 - - - Payment request cannot be parsed! - Cererea de plată nu poate fi analizată! - - - Bad response from server %1 - Răspuns greşit de la server %1 - - - Payment acknowledged - Plată acceptată - - - Network request error - Eroare în cererea de reţea - - PeerTableModel @@ -1412,25 +911,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Salvează imagine... - - - &Copy Image - &Copiază imaginea - - - Save QR Code - Salvează codul QR - - - PNG Image (*.png) - Imagine de tip PNG (*.png) - - RPCConsole @@ -1589,10 +1069,6 @@ Out: Ieşire: - - Build date - Construit la data - Debug log file Fişier jurnal depanare @@ -1621,10 +1097,6 @@ 1 &year 1 &an - - Welcome to the Bitcoin Core RPC console. - Bun venit la consola Nucleului Bitcoin RPC. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Folosiţi săgetile sus şi jos pentru a naviga în istoric şi <b>Ctrl-L</b> pentru a curăţa. @@ -1748,18 +1220,6 @@ Remove Înlătură - - Copy label - Copiază eticheta - - - Copy message - Copiază mesajul - - - Copy amount - Copiază suma - ReceiveRequestDialog @@ -1779,73 +1239,6 @@ &Save Image... &Salvează imaginea... - - Request payment to %1 - Cere plata pentru %1 - - - Payment information - Informaţiile plăţii - - - URI - URI - - - Address - Adresă - - - Amount - Sumă - - - Label - Etichetă - - - Message - Mesaj - - - Resulting URI too long, try to reduce the text for label / message. - URI rezultat este prea lung, încearcaţi să reduceţi textul pentru etichetă / mesaj. - - - Error encoding URI into QR Code. - Eroare la codarea URl-ului în cod QR. - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etichetă - - - Message - Mesaj - - - Amount - Sumă - - - (no label) - (fără etichetă) - - - (no message) - (nici un mesaj) - - - (no amount) - (sumă nulă) - SendCoinsDialog @@ -1945,14 +1338,6 @@ fast rapid - - Send as zero-fee transaction if possible - Trimite ca taxă zero dacă este posibil - - - (confirmation may take longer) - (confirmarea poate dura mai mult) - Send to multiple recipients at once Trimite simultan către mai mulţi destinatari @@ -1985,106 +1370,6 @@ S&end Trimit&e - - Confirm send coins - Confirmă trimiterea de monede - - - %1 to %2 - %1 la %2 - - - Copy quantity - Copiază cantitea - - - Copy amount - Copiază suma - - - Copy fee - Copiază taxa - - - Copy after fee - Copiază după taxă - - - Copy bytes - Copiază octeţi - - - Copy priority - Copiază prioritatea - - - Copy change - Copiază rest - - - Total Amount %1 - Suma totală %1 - - - or - sau - - - The amount to pay must be larger than 0. - Suma de plată trebuie să fie mai mare decît 0. - - - The amount exceeds your balance. - Suma depăşeşte soldul contului. - - - The total exceeds your balance when the %1 transaction fee is included. - Totalul depăşeşte soldul contului dacă se include şi plata taxei de %1. - - - Transaction creation failed! - Creare tranzacţie nereuşită! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Tranzacţia a fost respinsă! Acest lucru se poate întîmpla dacă o parte din monedele tale din portofel au fost deja cheltuite, la fel ca şi cum aţi fi folosit o copie a wallet.dat şi monedele au fost cheltuite în copie, dar nu au fost marcate ca şi cheltuite şi aici. - - - Payment request expired. - Cererea de plată a expirat. - - - The recipient address is not valid. Please recheck. - Adresa destinatarului nu este validă, vă rugăm să o verificaţi. - - - Duplicate address found: addresses should only be used once each. - Adresă duplicat găsită: fiecare adresă ar trebui folosită o singură dată. - - - Warning: Invalid Bitcoin address - Atenţie: Adresa bitcoin nevalidă! - - - (no label) - (fără etichetă) - - - Warning: Unknown change address - Atenţie: Adresă de rest necunoscută - - - Copy dust - Copiază praf - - - Are you sure you want to send? - Sigur doriţi să trimiteţi? - - - added as transaction fee - adăugat ca taxă de tranzacţie - SendCoinsEntry @@ -2096,10 +1381,6 @@ Pay &To: Plăteşte că&tre: - - Enter a label for this address to add it to your address book - Introduceţi o etichetă pentru această adresă pentru a fi adăugată în lista dvs. de adrese - &Label: &Etichetă: @@ -2156,8 +1437,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Nucleul Bitcoin se închide... + %1 is shutting down... + %1 se închide Do not shut down the computer until this window disappears. @@ -2242,69 +1523,9 @@ Reset all verify message fields Resetează toate cîmpurile mesajelor semnate - - Click "Sign Message" to generate signature - Faceţi clic pe "Semneaza msaj" pentru a genera semnătura - - - The entered address is invalid. - Adresa introdusă nu este validă - - - Please check the address and try again. - Vă rugăm verificaţi adresa şi încercaţi din nou. - - - The entered address does not refer to a key. - Adresa introdusă nu se referă la o cheie. - - - Wallet unlock was cancelled. - Blocarea portofelului a fost întreruptă. - - - Private key for the entered address is not available. - Cheia privată pentru adresa introdusă nu este validă. - - - Message signing failed. - Semnarea mesajului nu a reuşit. - - - Message signed. - Mesaj semnat. - - - The signature could not be decoded. - Această semnatură nu a putut fi decodată. - - - Please check the signature and try again. - Vă rugăm verificaţi semnătura şi încercaţi din nou. - - - The signature did not match the message digest. - Semnatura nu se potriveşte cu mesajul. - - - Message verification failed. - Verificarea mesajului nu a reuşit. - - - Message verified. - Mesaj verificat. - SplashScreen - - Bitcoin Core - Nucleul Bitcoin - - - The Bitcoin Core developers - Dezvoltatorii Nucleului Bitcoin - [testnet] [testnet] @@ -2317,414 +1538,13 @@ KB/s - - TransactionDesc - - Open until %1 - Deschis pînă la %1 - - - conflicted - în conflict - - - %1/offline - %1/deconectat - - - %1/unconfirmed - %1/neconfirmat - - - %1 confirmations - %1 confirmări - - - Status - Stare - - - , broadcast through %n node(s) - , distribuit prin %n nod, distribuit prin %n noduri, distribuit prin %n de noduri - - - Date - Data - - - Source - Sursa - - - Generated - Generat - - - From - De la - - - To - Către - - - own address - adresa proprie - - - watch-only - doar-supraveghere - - - label - etichetă - - - Credit - Credit - - - matures in %n more block(s) - se maturizează în încă %n blocse maturizează în încă %n blocurise maturizează în încă %n de blocuri - - - not accepted - neacceptat - - - Debit - Debit - - - Total debit - Total debit - - - Total credit - Total credit - - - Transaction fee - Taxă tranzacţie - - - Net amount - Suma netă - - - Message - Mesaj - - - Comment - Comentariu - - - Transaction ID - ID-ul tranzacţie - - - Merchant - Comerciant - - - 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. - Monedele generate trebuie să crească %1 blocuri înainte să poată fi cheltuite. Cînd aţi generat acest bloc, a fost transmis reţelei pentru a fi adaugat la lanţul de blocuri. Aceasta se poate întîmpla ocazional dacă alt nod generează un bloc la numai cîteva secunde de al dvs. - - - Debug information - Informaţii pentru depanare - - - Transaction - Tranzacţie - - - Inputs - Intrări - - - Amount - Sumă - - - true - adevărat - - - false - fals - - - , has not been successfully broadcast yet - , nu s-a propagat încă - - - Open for %n more block(s) - Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri - - - unknown - necunoscut - - TransactionDescDialog - - Transaction details - Detaliile tranzacţiei - This pane shows a detailed description of the transaction Acest panou arată o descriere detaliată a tranzacţiei - - TransactionTableModel - - Date - Data - - - Type - Tip - - - Immature (%1 confirmations, will be available after %2) - Imatur (%1 confirmări, va fi disponibil după %2) - - - Open for %n more block(s) - Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri - - - Open until %1 - Deschis până la %1 - - - Confirmed (%1 confirmations) - Confirmat (%1 confirmări) - - - This block was not received by any other nodes and will probably not be accepted! - Acest bloc nu a fost recepţionat de nici un alt nod şi probabil nu va fi acceptat! - - - Generated but not accepted - Generat dar neacceptat - - - Offline - Deconectat - - - Label - Etichetă - - - Unconfirmed - Neconfirmat - - - Confirming (%1 of %2 recommended confirmations) - Confirmare (%1 din %2 confirmări recomandate) - - - Conflicted - În conflict - - - Received with - Recepţionat cu - - - Received from - Primit de la - - - Sent to - Trimis către - - - Payment to yourself - Plată către dvs. - - - Mined - Minerit - - - watch-only - doar-supraveghere - - - (n/a) - indisponibil - - - Transaction status. Hover over this field to show number of confirmations. - Starea tranzacţiei. Treceţi cu mouse-ul peste acest cîmp pentru afişarea numărului de confirmări. - - - Date and time that the transaction was received. - Data şi ora la care a fost recepţionată tranzacţia. - - - Type of transaction. - Tipul tranzacţiei. - - - Whether or not a watch-only address is involved in this transaction. - Indiferent dacă sau nu o adresă doar-suăpraveghere este implicată în această tranzacţie. - - - Amount removed from or added to balance. - Suma extrasă sau adăugată la sold. - - - - TransactionView - - All - Toate - - - Today - Astăzi - - - This week - Săptămîna aceasta - - - This month - Luna aceasta - - - Last month - Luna trecută - - - This year - Anul acesta - - - Range... - Interval... - - - Received with - Recepţionat cu - - - Sent to - Trimis către - - - To yourself - Către dvs. - - - Mined - Minerit - - - Other - Altele - - - Enter address or label to search - Introduceţi adresa sau eticheta pentru căutare - - - Min amount - Suma minimă - - - Copy address - Copiază adresa - - - Copy label - Copiază eticheta - - - Copy amount - Copiază suma - - - Copy transaction ID - Copiază ID tranzacţie - - - Edit label - Editează eticheta - - - Show transaction details - Arată detaliile tranzacţiei - - - Export Transaction History - Export istoric tranzacţii - - - Watch-only - Doar-supraveghere - - - Exporting Failed - Export nereuşit - - - There was an error trying to save the transaction history to %1. - S-a produs o eroare la salvarea istoricului tranzacţiilor la %1. - - - Exporting Successful - Export reuşit - - - The transaction history was successfully saved to %1. - Istoricul tranzacţiilor a fost salvat cu succes la %1. - - - Comma separated file (*.csv) - Fişier text cu valori separate prin virgulă (*.csv) - - - Confirmed - Confirmat - - - Date - Data - - - Type - Tip - - - Label - Etichetă - - - Address - Adresă - - - ID - ID - - - Range: - Interval: - - - to - către - - UnitDisplayStatusBarControl @@ -2732,55 +1552,6 @@ Unitatea în care sînt arătate sumele. Faceţi clic pentru a selecta o altă unitate. - - WalletFrame - - No wallet has been loaded. - Nu a fost încărcat nici un portofel. - - - - WalletModel - - Send Coins - Trimitere bitcoin - - - - WalletView - - &Export - &Export - - - Export the data in the current tab to a file - Exportă datele din tab-ul curent într-un fişier - - - Backup Wallet - Copie de siguranţă portofel - - - Wallet Data (*.dat) - Date portofel (*.dat) - - - Backup Failed - Copierea de siguranţă nu a reuşit - - - There was an error trying to save the wallet data to %1. - S-a produs o eroare la salvarea datelor portofelului la %1. - - - The wallet data was successfully saved to %1. - Datele portofelului s-au salvat cu succes la %1. - - - Backup Successful - Copie de siguranţă efectuată cu succes - - bitcoin-core @@ -2811,6 +1582,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Acceptă conexiuni din afară (implicit: 1 dacă nu se foloseşte -proxy sau -connect) + + Bitcoin Core + Nucleul Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Ataşaţi adresei date şi ascultaţi totdeauna pe ea. Folosiţi notaţia [host]:port pentru IPv6 @@ -2831,10 +1606,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Aceasta este o versiune de test preliminară - vă asumaţi riscul folosind-o - nu folosiţi pentru minerit sau aplicaţiile comercianţilor - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Nu se poate lega la %s pe acest calculator. Nucleul Bitcoin probabil deja rulează. - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atenţie: Reţeaua nu pare să fie de acord în totalitate! Aparent nişte mineri au probleme. @@ -2843,10 +1614,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Atenţie: Aparent, nu sîntem de acord cu toţi partenerii noştri! Va trebui să faceţi o actualizare, sau alte noduri necesită actualizare. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Atenţie: fişierul wallet.dat este corupt, date salvate! Fişierul original wallet.dat a fost salvat ca wallet.{timestamp}.bak in %s; dacă balansul sau tranzactiile sînt incorecte ar trebui să restauraţi dintr-o copie de siguranţă. - <category> can be: <category> poate fi: @@ -2955,18 +1722,10 @@ Wallet options: Opţiuni portofel: - - You need to rebuild the database using -reindex to change -txindex - Trebuie să reconstruiţi baza de date folosind -reindex pentru a schimba -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Permite conexiunile JSON-RPC din sursa specificată. Valid pentru <ip> sînt IP singulare (ex. 1.2.3.4), o reţea/mască-reţea (ex. 1.2.3.4/255.255.255.0) sau o reţea/CIDR (ex. 1.2.3.4/24). Această opţiune poate fi specificată de mai multe ori - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Nu se poate obţine blocarea folderului cu date %s. Nucleul Bitcoin probabil deja rulează. - Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Execută comanda cînd o alertă relevantă este primită sau vedem o bifurcaţie foarte lungă (%s în cmd este înlocuit de mesaj) @@ -2988,17 +1747,13 @@ Acceptă cererile publice REST (implicit: %u) - Cannot resolve -whitebind address: '%s' - Nu se poate rezolva adresa -whitebind: '%s' + Automatically create Tor hidden service (default: %d) + Crează automat un serviciu Tor ascuns (implicit: %d) Connect through SOCKS5 proxy Conectare prin proxy SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Dezvoltatorii Bitcoin - Error reading from database, shutting down. Eroare la citirea bazei de date. Oprire. @@ -3007,22 +1762,6 @@ Information Informaţie - - Initialization sanity check failed. Bitcoin Core is shutting down. - Nu s-a reuşit iniţierea verificării sănătăţii. Nucleul Bitcoin se opreşte. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Sumă nevalidă pentru -maxtxfee=<suma>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Sumă nevalidă pentru -minrelaytxfee=<suma>:'%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Sumă nevalidă pentru -mintxfee=<suma>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Sumă nevalidă pentru -paytxfee=<suma>: '%s' (trebuie să fie cel puţin %s) @@ -3087,10 +1826,6 @@ Username for JSON-RPC connections Utilizator pentru conexiunile JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Portofelul necesită rescrierea: reporniţi Nucleul Bitcoin pentru completare - Warning Avertisment @@ -3099,10 +1834,6 @@ Zapping all transactions from wallet... Şterge toate tranzacţiile din portofel... - - wallet.dat corrupt, salvage failed - wallet.dat corupt, salvare nereuşită - Password for JSON-RPC connections Parola pentru conexiunile JSON-RPC @@ -3111,10 +1842,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Execută comanda cînd cel mai bun bloc se modifică (%s în cmd este înlocuit cu hash-ul blocului) - - This help message - Acest mesaj de ajutor - Allow DNS lookups for -addnode, -seednode and -connect Permite căutări DNS pentru -addnode, -seednode şi -connect @@ -3123,10 +1850,6 @@ Loading addresses... Încărcare adrese... - - Error loading wallet.dat: Wallet corrupted - Eroare la încărcarea wallet.dat: Portofel corupt - Output debugging information (default: %u, supplying <category> is optional) Produce toate informaţiile de depanare (implicit: %u <category> furnizată este opţională) @@ -3135,14 +1858,6 @@ (default: %s) (implicit: %s) - - Error loading wallet.dat - Eroare la încărcarea wallet.dat - - - Generate coins (default: %u) - Generează monede (implicit: %u) - How many blocks to check at startup (default: %u, 0 = all) Cîte blocuri verifică la pornire (implicit: %u, 0 = toate) @@ -3167,18 +1882,6 @@ Unknown network specified in -onlynet: '%s' Reţeaua specificată în -onlynet este necunoscută: '%s' - - Cannot resolve -bind address: '%s' - Nu se poate rezolva adresa -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Nu se poate rezolva adresa -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Suma nevalidă pentru -paytxfee=<amount>: '%s' - Insufficient funds Fonduri insuficiente diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index b4546a215..e2949a948 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -25,10 +25,6 @@ C&lose &Закрыть - - &Copy Address - &Копировать адрес - Delete the currently selected address from the list Удалить выбранный адрес из списка @@ -45,73 +41,6 @@ &Delete &Удалить - - Choose the address to send coins to - Выберите адрес для отправки на него монет - - - Choose the address to receive coins with - Выберите адрес для получения монет - - - C&hoose - &Выбрать - - - Sending addresses - Адреса отправки - - - Receiving addresses - Адреса получения - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте количество и адрес получателя перед отправкой перевода. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Это ваши адреса Bitcoin для приёма платежей. Рекомендуется использовать новый адрес получения для каждой транзакции. - - - Copy &Label - Копировать &метку - - - &Edit - &Правка - - - Export Address List - Экспортировать список адресов - - - Comma separated file (*.csv) - Текст, разделённый запятыми (*.csv) - - - Exporting Failed - Экспорт не удался - - - There was an error trying to save the address list to %1. Please try again. - Произошла ошибка при попытке сохранить список адресов, %1. Пожалуйста, попробуйте еще раз. - - - - AddressTableModel - - Label - Метка - - - Address - Адрес - - - (no label) - [нет метки] - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Повторите новый пароль - - Encrypt wallet - Зашифровать бумажник - - - This operation needs your wallet passphrase to unlock the wallet. - Для выполнения операции требуется пароль вашего бумажника. - - - Unlock wallet - Разблокировать бумажник - - - This operation needs your wallet passphrase to decrypt the wallet. - Для выполнения операции требуется пароль вашего бумажника. - - - Decrypt wallet - Расшифровать бумажник - - - Change passphrase - Сменить пароль - - - Confirm wallet encryption - Подтвердите шифрование бумажника - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Внимание: если вы зашифруете бумажник и потеряете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОЙНЫ</b>! - - - Are you sure you wish to encrypt your wallet? - Вы уверены, что хотите зашифровать ваш бумажник? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник. - - - Warning: The Caps Lock key is on! - Внимание: Caps Lock включен! - - - Wallet encrypted - Бумажник зашифрован - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Введите новый пароль бумажника.<br/>Используйте пароль, состоящий из <b>десяти или более случайных символов</b>, или <b>восьми или более слов</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Введите старый и новый пароль для кошелька. - - - Wallet encryption failed - Не удалось зашифровать бумажник - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Шифрование бумажника не удалось из-за внутренней ошибки. Ваш бумажник не был зашифрован. - - - The supplied passphrases do not match. - Введённые пароли не совпадают. - - - Wallet unlock failed - Разблокировка бумажника не удалась - - - The passphrase entered for the wallet decryption was incorrect. - Указанный пароль не подходит. - - - Wallet decryption failed - Расшифрование бумажника не удалось - - - Wallet passphrase was successfully changed. - Пароль бумажника успешно изменён. - BanTableModel @@ -269,6 +110,14 @@ Quit application Закрыть приложение + + &About %1 + &О %1 + + + Show information about %1 + Показать информацию о %1 + About &Qt О &Qt @@ -305,14 +154,6 @@ Open &URI... Открыть &URI... - - Bitcoin Core client - Bitcoin Core клиент - - - Importing blocks from disk... - Импортируются блоки с диска... - Reindexing blocks on disk... Идёт переиндексация блоков на диске... @@ -357,10 +198,6 @@ &Receive &Получить - - Show information about Bitcoin Core - Показать информацию о Bitcoin Core - &Show / Hide &Показать / Скрыть @@ -397,22 +234,10 @@ Tabs toolbar Панель вкладок - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Запросить платежи (создаёт QR-коды и bitcoin: ссылки) - - &About Bitcoin Core - &О Bitcoin Core - - - Modify configuration options for Bitcoin Core - Изменить опции конфигурации Bitcoin Core - Show the list of used sending addresses and labels Показать список использованных адресов и меток отправки @@ -429,14 +254,18 @@ &Command-line options &Параметры командной строки - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Показать помощь по Bitcoin Core и получить список доступных параметров командной строки. - %n active connection(s) to Bitcoin network %n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin + + Indexing blocks on disk... + Индексация блоков на диске... + + + Processing blocks on disk... + Обработка блоков на диске... + No block source available... Источник блоков недоступен... @@ -493,6 +322,10 @@ Up to date Синхронизировано + + %1 client + %1 клиент + Catching up... Синхронизируется... @@ -544,13 +377,6 @@ Бумажник <b>зашифрован</b> и в настоящее время <b>заблокирован</b> - - ClientModel - - Network Alert - Сетевая Тревога - - CoinControlDialog @@ -629,150 +455,6 @@ Priority Приоритет - - Copy address - Копировать адрес - - - Copy label - Копировать метку - - - Copy amount - Скопировать сумму - - - Copy transaction ID - Скопировать ID транзакции - - - Lock unspent - Заблокировать непотраченное - - - Unlock unspent - Разблокировать непотраченное - - - Copy quantity - Копировать количество - - - Copy fee - Копировать комиссию - - - Copy after fee - Копировать после комиссии - - - Copy bytes - Копировать байты - - - Copy priority - Копировать приоритет - - - Copy dust - Копировать пыль - - - Copy change - Копировать сдачу - - - highest - самый высокий - - - higher - выше - - - high - высокий - - - medium-high - выше среднего - - - medium - средний - - - low-medium - ниже среднего - - - low - низкий - - - lower - ниже - - - lowest - самый низкий - - - (%1 locked) - (%1 заблокировано) - - - none - ничего - - - This label turns red if the transaction size is greater than 1000 bytes. - Эта метка становится красной, если размер транзакции будет больше, чем 1000 байт. - - - This label turns red if the priority is smaller than "medium". - Эта метка становится красной, если приоритет меньше, чем "среднее". - - - This label turns red if any recipient receives an amount smaller than %1. - Эта метка становится красной, если любой из получателей принимает количество меньше, чем %1. - - - Can vary +/- %1 satoshi(s) per input. - Может отличаться на +/- %1 сатоши на вход. - - - yes - да - - - no - нет - - - This means a fee of at least %1 per kB is required. - Это значит, что требуется комиссия как минимум %1 на КБ. - - - Can vary +/- 1 byte per input. - Может отличаться на +/- 1 байт на вход. - - - Transactions with higher priority are more likely to get included into a block. - Транзакции с более высоким приоритетом будут вероятнее других включены в блок. - - - (no label) - [нет метки] - - - change from %1 (%2) - сдача с %1 (%2) - - - (change) - (размен) - EditAddressDialog @@ -796,38 +478,6 @@ &Address &Адрес - - New receiving address - Новый адрес для получения - - - New sending address - Новый адрес для отправки - - - Edit receiving address - Изменение адреса для получения - - - Edit sending address - Изменение адреса для отправки - - - The entered address "%1" is already in the address book. - Введённый адрес «%1» уже находится в адресной книге. - - - The entered address "%1" is not a valid Bitcoin address. - Введённый адрес "%1" не является правильным Bitcoin-адресом. - - - Could not unlock wallet. - Не удается разблокировать бумажник. - - - New key generation failed. - Генерация нового ключа не удалась. - FreespaceChecker @@ -854,10 +504,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version версия @@ -867,8 +513,8 @@ (%1-бит) - About Bitcoin Core - О Bitcoin Core + About %1 + О %1 Command-line options @@ -906,11 +552,7 @@ Show splash screen on startup (default: %u) Показывать экран-заставку при запуске (по умолчанию: %u) - - Reset all settings changes made over the GUI - Сбросить все настройки сделанные через графический интерфейс - - + Intro @@ -918,16 +560,8 @@ Добро пожаловать - Welcome to Bitcoin Core. - Добро пожаловать в Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Так как вы впервые запустили программу, вы можете выбрать, где Bitcoin Core будет хранить данные. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core скачает и сохранит копию цепи блоков. Как минимум, %1ГБ данных будет храниться в этом каталоге, и со временем он будет расти. Бумажник будет также сохранён в этом каталоге. + Welcome to %1. + Добро пожаловать в %1 Use the default data directory @@ -937,10 +571,6 @@ Use a custom data directory: Использовать другой каталог данных: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Ошибка: не удалось создать указанный каталог данных "%1". @@ -976,10 +606,6 @@ Select payment request file Выбрать файл запроса платежа - - Select payment request file to open - Выберите файл запроса платежа - OptionsDialog @@ -1019,10 +645,6 @@ 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. Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin Core. - 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 |. Сторонние URL (например, block explorer), которые отображаются на вкладке транзакций как пункты контекстного меню. %s в URL заменяется хэшем транзакции. URL отделяются друг от друга вертикальной чертой |. @@ -1047,14 +669,6 @@ &Network &Сеть - - Automatically start Bitcoin Core after logging in to the system. - Автоматически запускать Bitcoin Core после входа в систему - - - &Start Bitcoin Core on system login - &Запускать Bitcoin Core при входе в систему - (0 = auto, <0 = leave that many cores free) (0 = автоматически, <0 = оставить столько незагруженных ядер) @@ -1139,6 +753,10 @@ &Window &Окно + + Hide tray icon + Скрыть иконку в трее + Show only a tray icon after minimizing the window. Показывать только иконку в системном лотке после сворачивания окна. @@ -1283,97 +901,6 @@ Текущий общий баланс на адресах наблюдения - - PaymentServer - - URI handling - Обработка URI - - - Invalid payment address %1 - Неверный адрес платежа %1 - - - Payment request rejected - Запрос платежа отклонён - - - Payment request network doesn't match client network. - Сеть запроса платежа не совпадает с сетью клиента. - - - Payment request is not initialized. - Запрос платежа не инициализирован. - - - Requested payment amount of %1 is too small (considered dust). - Запрошенная сумма платежа %1 слишком мала (считается пылью). - - - Payment request error - Ошибка запроса платежа - - - Cannot start bitcoin: click-to-pay handler - Не удаётся запустить bitcoin: обработчик click-to-pay - - - Payment request fetch URL is invalid: %1 - Неверный URL запроса платежа: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - Не удалось обработать URI! Это может быть связано с неверным адресом Bitcoin или неправильными параметрами URI. - - - Payment request file handling - Обработка файла запроса платежа - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа. - - - Payment request expired. - Запрос платежа просрочен. - - - Unverified payment requests to custom payment scripts are unsupported. - Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются. - - - Invalid payment request. - Неверный запрос платежа. - - - Refund from %1 - Возврат от %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Запрос платежа %1 слишком большой (%2 байтов, разрешено %3 байтов). - - - Error communicating with %1: %2 - Ошибка связи с %1: %2 - - - Payment request cannot be parsed! - Запрос платежа не может быть разобран! - - - Bad response from server %1 - Плохой ответ от сервера %1 - - - Payment acknowledged - Платёж принят - - - Network request error - Ошибка сетевого запроса - - PeerTableModel @@ -1428,25 +955,6 @@ %1 мс - - QRImageWidget - - &Save Image... - &Сохранить изображение... - - - &Copy Image - &Копировать изображение - - - Save QR Code - Сохранить QR-код - - - PNG Image (*.png) - Изображение PNG (*.png) - - RPCConsole @@ -1513,10 +1021,6 @@ Memory usage Использование памяти - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. - Received Получено @@ -1633,10 +1137,6 @@ Out: Выход: - - Build date - Дата сборки - Debug log file Отладочный лог-файл @@ -1673,10 +1173,6 @@ &Unban Node &Разблокировать узел - - Welcome to the Bitcoin Core RPC console. - Добро пожаловать в RPC-консоль Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Используйте стрелки вверх и вниз для просмотра истории и <b>Ctrl-L</b> для очистки экрана. @@ -1804,18 +1300,6 @@ Remove Удалить - - Copy label - Копировать метку - - - Copy message - Копировать сообщение - - - Copy amount - Скопировать сумму - ReceiveRequestDialog @@ -1835,73 +1319,6 @@ &Save Image... &Сохранить изображение... - - Request payment to %1 - Запросить платёж на %1 - - - Payment information - Информация платежа - - - URI - URI - - - Address - Адрес - - - Amount - Сумма - - - Label - Метка - - - Message - Сообщение - - - Resulting URI too long, try to reduce the text for label / message. - Получившийся URI слишком длинный, попробуйте сократить текст метки / сообщения. - - - Error encoding URI into QR Code. - Ошибка кодирования URI в QR-код - - - - RecentRequestsTableModel - - Date - Дата - - - Label - Метка - - - Message - Сообщение - - - Amount - Сумма - - - (no label) - [нет метки] - - - (no message) - (нет сообщения) - - - (no amount) - (нет суммы) - SendCoinsDialog @@ -2021,14 +1438,6 @@ fast ускоренный - - Send as zero-fee transaction if possible - Осуществить транзакцию бесплатно, если возможно - - - (confirmation may take longer) - (подтверждение может занять больше времени) - Send to multiple recipients at once Отправить нескольким получателям одновременно @@ -2061,118 +1470,6 @@ S&end &Отправить - - Confirm send coins - Подтвердите отправку монет - - - %1 to %2 - С %1 на %2 - - - Copy quantity - Копировать количество - - - Copy amount - Скопировать сумму - - - Copy fee - Копировать комиссию - - - Copy after fee - Копировать после комиссии - - - Copy bytes - Копировать байты - - - Copy priority - Копировать приоритет - - - Copy change - Копировать размен - - - Total Amount %1 - Общая сумма %1 - - - or - или - - - The amount to pay must be larger than 0. - Сумма для отправки должно быть больше 0. - - - The amount exceeds your balance. - Сумма превышает Ваш баланс - - - The total exceeds your balance when the %1 transaction fee is included. - Сумма превысит Ваш баланс, если комиссия в размере %1 будет добавлена к транзакции - - - Transaction creation failed! - Не удалось создать транзакцию! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. - - - A fee higher than %1 is considered an absurdly high fee. - Комиссия больше, чем %1, считается невероятно большой. - - - Payment request expired. - Запрос платежа просрочен. - - - Pay only the required fee of %1 - Заплатить только обязательную комиссию %1 - - - Estimated to begin confirmation within %n block(s). - Подтверждение ожидается через %n блок.Подтверждение ожидается через %n блока.Подтверждение ожидается через %n блоков.Подтверждение ожидается через %n блоков. - - - The recipient address is not valid. Please recheck. - Адрес получателя неверный. Пожалуйста, перепроверьте. - - - Duplicate address found: addresses should only be used once each. - Обнаружен дублирующийся адрес: используйте каждый адрес только один раз. - - - Warning: Invalid Bitcoin address - Внимание: неверный адрес Bitcoin - - - (no label) - [нет метки] - - - Warning: Unknown change address - Внимание: неизвестный адрес для сдачи - - - Copy dust - Копировать пыль - - - Are you sure you want to send? - Вы уверены, что хотите отправить? - - - added as transaction fee - добавлено как комиссия - SendCoinsEntry @@ -2184,10 +1481,6 @@ Pay &To: Полу&чатель: - - Enter a label for this address to add it to your address book - Введите метку для данного адреса (для добавления в адресную книгу) - &Label: &Метка: @@ -2259,10 +1552,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core выключается... - Do not shut down the computer until this window disappears. Не выключайте компьютер, пока это окно не исчезнет. @@ -2354,69 +1643,9 @@ Reset all verify message fields Сбросить все поля проверки сообщения - - Click "Sign Message" to generate signature - Нажмите "Подписать сообщение" для создания подписи - - - The entered address is invalid. - Введённый адрес неверен - - - Please check the address and try again. - Пожалуйста, проверьте адрес и попробуйте ещё раз. - - - The entered address does not refer to a key. - Введённый адрес не связан с ключом - - - Wallet unlock was cancelled. - Разблокировка бумажника была отменена. - - - Private key for the entered address is not available. - Для введённого адреса недоступен закрытый ключ - - - Message signing failed. - Не удалось подписать сообщение - - - Message signed. - Сообщение подписано - - - The signature could not be decoded. - Подпись не может быть раскодирована. - - - Please check the signature and try again. - Пожалуйста, проверьте подпись и попробуйте ещё раз. - - - The signature did not match the message digest. - Подпись не соответствует отпечатку сообщения. - - - Message verification failed. - Проверка сообщения не удалась. - - - Message verified. - Сообщение проверено. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Разработчики Bitcoin Core - [testnet] [тестовая сеть] @@ -2429,422 +1658,13 @@ КБ/сек - - TransactionDesc - - Open until %1 - Открыто до %1 - - - conflicted - в противоречии - - - %1/offline - %1/отключен - - - %1/unconfirmed - %1/не подтверждено - - - %1 confirmations - %1 подтверждений - - - Status - Статус - - - , broadcast through %n node(s) - , разослано через %n узел, разослано через %n узла, разослано через %n узлов, разослано через %n узлов - - - Date - Дата - - - Source - Источник - - - Generated - Сгенерированно - - - From - От - - - To - Для - - - own address - свой адрес - - - watch-only - только наблюдение - - - label - метка - - - Credit - Кредит - - - matures in %n more block(s) - будет доступно через %n блокбудет доступно через %n блокабудет доступно через %n блоковбудет доступно через %n блоков - - - not accepted - не принято - - - Debit - Дебет - - - Total debit - Всего дебет - - - Total credit - Всего кредит - - - Transaction fee - Комиссия - - - Net amount - Чистая сумма - - - Message - Сообщение - - - Comment - Комментарий: - - - Transaction ID - ID транзакции - - - Merchant - Продавец - - - 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. - Сгенерированные монеты должны подождать %1 блоков, прежде чем они могут быть потрачены. Когда Вы сгенерировали этот блок, он был отправлен в сеть для добавления в цепочку блоков. Если он не попадёт в цепь, его статус изменится на "не принят", и монеты будут недействительны. Это иногда происходит в случае, если другой узел сгенерирует блок на несколько секунд раньше вас. - - - Debug information - Отладочная информация - - - Transaction - Транзакция - - - Inputs - Входы - - - Amount - Сумма - - - true - истина - - - false - ложь - - - , has not been successfully broadcast yet - , ещё не было успешно разослано - - - Open for %n more block(s) - Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков - - - unknown - неизвестно - - TransactionDescDialog - - Transaction details - Детали транзакции - This pane shows a detailed description of the transaction Эта панель отображает детальное описание транзакции. - - TransactionTableModel - - Date - Дата - - - Type - Тип - - - Immature (%1 confirmations, will be available after %2) - Незрелый (%1 подтверждений, будет доступен после %2) - - - Open for %n more block(s) - Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков - - - Open until %1 - Открыто до %1 - - - Confirmed (%1 confirmations) - Подтверждено (%1 подтверждений) - - - This block was not received by any other nodes and will probably not be accepted! - Этот блок не был получен другими узлами и, возможно, не будет принят! - - - Generated but not accepted - Сгенерированно, но не подтверждено - - - Offline - Нет активных соединений с сетью - - - Label - Метка - - - Unconfirmed - Неподтверждено - - - Confirming (%1 of %2 recommended confirmations) - Подтверждено(%1 подтверждений, рекомендуется %2 подтверждений) - - - Conflicted - В противоречии - - - Received with - Получено - - - Received from - Получено от - - - Sent to - Отправлено - - - Payment to yourself - Отправлено себе - - - Mined - Добыто - - - watch-only - только наблюдение - - - (n/a) - [не доступно] - - - Transaction status. Hover over this field to show number of confirmations. - Статус транзакции. Подведите курсор к нужному полю для того, чтобы увидеть количество подтверждений. - - - Date and time that the transaction was received. - Дата и время, когда транзакция была получена. - - - Type of transaction. - Тип транзакции. - - - Whether or not a watch-only address is involved in this transaction. - Использовался ли в транзакции адрес для наблюдения. - - - User-defined intent/purpose of the transaction. - Определяемое пользователем намерение/цель транзакции. - - - Amount removed from or added to balance. - Сумма, добавленная, или снятая с баланса. - - - - TransactionView - - All - Все - - - Today - Сегодня - - - This week - На этой неделе - - - This month - В этом месяце - - - Last month - В прошлом месяце - - - This year - В этом году - - - Range... - Промежуток... - - - Received with - Получено на - - - Sent to - Отправлено на - - - To yourself - Отправленные себе - - - Mined - Добытые - - - Other - Другое - - - Enter address or label to search - Введите адрес или метку для поиска - - - Min amount - Мин. сумма - - - Copy address - Копировать адрес - - - Copy label - Копировать метку - - - Copy amount - Скопировать сумму - - - Copy transaction ID - Скопировать ID транзакции - - - Copy raw transaction - Скопировать исходную транзакции - - - Edit label - Изменить метку - - - Show transaction details - Показать подробности транзакции - - - Export Transaction History - Экспортировать историю транзакций - - - Watch-only - Для наблюдения - - - Exporting Failed - Экспорт не удался - - - There was an error trying to save the transaction history to %1. - Произошла ошибка при сохранении истории транзакций в %1. - - - Exporting Successful - Экспорт успешно завершён - - - The transaction history was successfully saved to %1. - История транзакций была успешно сохранена в %1. - - - Comma separated file (*.csv) - Текст, разделённый запятыми (*.csv) - - - Confirmed - Подтверждено - - - Date - Дата - - - Type - Тип - - - Label - Метка - - - Address - Адрес - - - ID - ID - - - Range: - Промежуток от: - - - to - до - - UnitDisplayStatusBarControl @@ -2852,55 +1672,6 @@ Единица измерения количества монет. Щёлкните для выбора другой единицы. - - WalletFrame - - No wallet has been loaded. - Не был загружен ни один бумажник. - - - - WalletModel - - Send Coins - Отправка - - - - WalletView - - &Export - &Экспорт - - - Export the data in the current tab to a file - Экспортировать данные из вкладки в файл - - - Backup Wallet - Сделать резервную копию бумажника - - - Wallet Data (*.dat) - Данные бумажника (*.dat) - - - Backup Failed - Резервное копирование не удалось - - - There was an error trying to save the wallet data to %1. - Произошла ошибка при сохранении данных бумажника в %1. - - - The wallet data was successfully saved to %1. - Данные бумажника были успешно сохранены в %1. - - - Backup Successful - Резервное копирование успешно завершено - - bitcoin-core @@ -2927,14 +1698,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Если <category> не предоставлена или равна 1, выводить всю отладочную информацию. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Максимальная сумма комиссий (%s) для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно! Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно. - Prune configured below the minimum of %d MiB. Please use a higher number. Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение. @@ -2975,6 +1738,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Принимать подключения извне (по умолчанию: 1, если не используется -proxy или -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6 @@ -3007,10 +1774,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy) @@ -3027,18 +1790,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Внимание: похоже, в сети нет полного согласия! Некоторый майнеры, возможно, испытывают проблемы. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Внимание: Получена неизвестная версия блока! Возможно неизвестные правила вступили в силу. - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Внимание: мы не полностью согласны с подключенными участниками! Вам или другим участникам, возможно, следует обновиться. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Внимание: wallet.dat повреждён, данные спасены! Оригинальный wallet.dat сохранён как wallet.{timestamp}.bak в %s; если ваш баланс или транзакции некорректны, вы должны восстановить файл из резервной копии. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно. @@ -3107,6 +1862,10 @@ Error initializing wallet database environment %s! Ошибка инициализации окружения БД бумажника %s! + + Error loading %s + Ошибка загрузки %s + Error loading block database Ошибка чтения базы данных блоков @@ -3211,10 +1970,6 @@ Wallet options: Настройки бумажника: - - You need to rebuild the database using -reindex to change -txindex - Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Разрешить подключения JSON-RPC с указанного источника. Разрешённые значения для <ip> — отдельный IP (например, 1.2.3.4), сеть/маска сети (например, 1.2.3.4/255.255.255.0) или сеть/CIDR (например, 1.2.3.4/24). Эту опцию можно использовать многократно @@ -3227,10 +1982,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Привязаться к указанному адресу для прослушивания JSON-RPC подключений. Используйте запись [хост]:порт для IPv6. Эту опцию можно использовать многократно (по умолчанию: привязываться ко всем интерфейсам) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Не удалось установить блокировку на каталог данных %s. Возможно, Bitcoin Core уже запущен. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Создавать новые файлы с системными правами по умолчанию вместо umask 077 (эффективно только при отключенном бумажнике) @@ -3275,10 +2026,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d) - The transaction amount is too small to send after the fee has been deducted Сумма транзакции за вычетом комиссии слишком мала @@ -3303,34 +2050,14 @@ Accept public REST requests (default: %u) Принимать публичные REST-запросы (по умолчанию: %u) - - Activating best chain... - Активируется лучшая цепь... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Попытаться восстановить приватные ключи из повреждённого wallet.dat при запуске - Automatically create Tor hidden service (default: %d) Автоматически создавать скрытый Tor сервис (по умолчанию: %d) - - Cannot resolve -whitebind address: '%s' - Не удаётся разрешить адрес в параметре -whitebind: '%s' - Connect through SOCKS5 proxy Подключаться через SOCKS5 прокси - - Copyright (C) 2009-%i The Bitcoin Core Developers - Все права защищены © 2009-%i Разработчики Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Ошибка загрузки wallet.dat: бумажник требует более новую версию Bitcoin Core - Error reading from database, shutting down. Ошибка чтения базы данных, работа завершается. @@ -3343,22 +2070,6 @@ Information Информация - - Initialization sanity check failed. Bitcoin Core is shutting down. - Не удалось проверить чистоту. Bitcoin Core выключается. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Неверное значение -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Неверная сумма в параметре -minrelaytxfee=<кол-во>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Неверная сумма в параметре -mintxfee=<кол-во>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Неверное количество в параметре -paytxfee=<кол-во>: '%s' (должно быть как минимум %s) @@ -3383,14 +2094,6 @@ RPC server options: Параметры сервера RPC: - - Rebuild block chain index from current blk000??.dat files on startup - Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat - - - Receive and display P2P network alerts (default: %u) - Получать и отображать P2P сетевые тревоги (по умолчанию: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Уменьшите -maxconnections с %d до %d, из-за ограничений системы. @@ -3463,10 +2166,6 @@ Username for JSON-RPC connections Имя для подключений JSON-RPC - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Необходимо перезаписать бумажник, перезапустите Bitcoin Core для завершения операции. - Warning Внимание @@ -3487,10 +2186,6 @@ ZeroMQ notification options: ZeroMQ параметры оповещения: - - wallet.dat corrupt, salvage failed - wallet.dat повреждён, спасение данных не удалось - Password for JSON-RPC connections Пароль для подключений JSON-RPC @@ -3499,10 +2194,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Выполнить команду, когда появляется новый блок (%s в команде заменяется на хэш блока) - - This help message - Эта справка - Allow DNS lookups for -addnode, -seednode and -connect Разрешить поиск в DNS для -addnode, -seednode и -connect @@ -3511,10 +2202,6 @@ Loading addresses... Загрузка адресов... - - Error loading wallet.dat: Wallet corrupted - Ошибка загрузки wallet.dat: Бумажник поврежден - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные) @@ -3531,10 +2218,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Не хранить транзакции в памяти дольше, чем <n> часов (по умолчанию %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Ошибка чтения wallet.dat! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми при создании транзакций (по умолчанию: %s) @@ -3579,6 +2262,10 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Имя пользователя и хэш пароля для JSON-RPC соединений. Поле <userpw> использует формат: <USERNAME>:<SALT>$<HASH>. Каноничный пример скрипта на питоне включен в "share/rpcuser". Эта опция может быть указана несколько раз + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Внимание: Получена неизвестная версия блока! Возможно неизвестные правила вступили в силу. + (default: %s) (по умолчанию: %s) @@ -3587,14 +2274,6 @@ Always query for peer addresses via DNS lookup (default: %u) Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u) - - Error loading wallet.dat - Ошибка при загрузке wallet.dat - - - Generate coins (default: %u) - Включить добычу монет (по умолчанию: %u) - How many blocks to check at startup (default: %u, 0 = all) Сколько блоков проверять при запуске (по умолчанию: %u, 0 = все) @@ -3679,18 +2358,6 @@ Unknown network specified in -onlynet: '%s' В параметре -onlynet указана неизвестная сеть: '%s' - - Cannot resolve -bind address: '%s' - Не удаётся разрешить адрес в параметре -bind: '%s' - - - Cannot resolve -externalip address: '%s' - Не удаётся разрешить адрес в параметре -externalip: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Неверная сумма в параметре -paytxfee=<кол-во>: '%s' - Insufficient funds Недостаточно монет diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 41e467e49..a6f9ffccb 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -21,10 +21,6 @@ C&lose Закрыть - - &Copy Address - Копировать адрес - Delete the currently selected address from the list Удалить выбранный адрес из списка @@ -41,14 +37,7 @@ &Delete Удалить - - C&hoose - Выбрать - - - - AddressTableModel - + AskPassphraseDialog @@ -57,14 +46,6 @@ BitcoinGUI - - Bitcoin Core - Bitcoin Core - - - &About Bitcoin Core - О Bitcoin Core - &Command-line options Опции командной строки @@ -82,9 +63,6 @@ Информация - - ClientModel - CoinControlDialog @@ -99,18 +77,6 @@ Confirmed Подтвержденные - - Copy address - Копировать адрес - - - yes - Да - - - no - Нет - EditAddressDialog @@ -124,18 +90,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version версия - - About Bitcoin Core - О Bitcoin Core - Command-line options Опции командной строки @@ -147,10 +105,6 @@ Intro - - Bitcoin Core - Bitcoin Core - Error Ошибка @@ -173,18 +127,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -198,13 +146,6 @@ ReceiveRequestDialog - - RecentRequestsTableModel - - Date - Дата - - SendCoinsDialog @@ -219,68 +160,22 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - TrafficGraphWidget - - TransactionDesc - - Date - Дата - - TransactionDescDialog - - TransactionTableModel - - Date - Дата - - - - TransactionView - - Copy address - Копировать адрес - - - Confirmed - Подтвержденные - - - Date - Дата - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - Экспорт - - - Export the data in the current tab to a file - Экспортировать данные текущей вкладки в файл - - bitcoin-core + + Bitcoin Core + Bitcoin Core + Information Информация diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 9addbdaa8..e2b8a0201 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -25,10 +25,6 @@ C&lose Zatvoriť - - &Copy Address - &Kopírovať adresu - Delete the currently selected address from the list Vymaž vybranú adresu zo zoznamu @@ -45,73 +41,6 @@ &Delete &Zmazať - - Choose the address to send coins to - Zvoľte adresu kam poslať coins - - - Choose the address to receive coins with - Zvoľte adresu na ktorú prijať coins - - - C&hoose - Vybrať - - - Sending addresses - Adresa odoslania - - - Receiving addresses - Prijímacia adresa - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Toto sú Vaše Bitcoin adresy pre posielanie platieb. Vždy skontrolujte množstvo a prijímaciu adresu pred poslaním coins. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Toto sú vaše Bitcoin adresy pre prijímanie platieb. Odporúča sa použiť novú prijímaciu adresu pre každú transakciu. - - - Copy &Label - Kopírovať &popis - - - &Edit - &Upraviť - - - Export Address List - Exportovať zoznam adries - - - Comma separated file (*.csv) - Čiarkou oddelovaný súbor (*.csv) - - - Exporting Failed - Export zlyhal - - - There was an error trying to save the address list to %1. Please try again. - Nastala chyba pri pokuse uložiť zoznam adries do %1. Skúste znovu. - - - - AddressTableModel - - Label - Popis - - - Address - Adresa - - - (no label) - (bez popisu) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Zopakujte nové heslo - - Encrypt wallet - Zašifrovať peňaženku - - - This operation needs your wallet passphrase to unlock the wallet. - Táto operácia potrebuje heslo k vašej peňaženke aby ju mohla dešifrovať. - - - Unlock wallet - Odomknúť peňaženku - - - This operation needs your wallet passphrase to decrypt the wallet. - Táto operácia potrebuje heslo k vašej peňaženke na dešifrovanie peňaženky. - - - Decrypt wallet - Dešifrovať peňaženku - - - Change passphrase - Zmena hesla - - - Confirm wallet encryption - Potvrďte šifrovanie peňaženky - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Varovanie: Ak zašifrujete peňaženku a stratíte heslo, <b>STRATÍTE VŠETKY VAŠE BITCOINY</b>!⏎ - - - Are you sure you wish to encrypt your wallet? - Ste si istí, že si želáte zašifrovať peňaženku? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Jadro Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj, že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred krádežou bitcoinov pomocou škodlivého software. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - DÔLEŽITÉ: Všetky doterajšie záložné kópie peňaženky ktoré ste zhotovili by mali byť nahradené novým zašifrovaným súborom s peňaženkou. Z bezpečnostných dôvodov sa predchádzajúce kópie nezašifrovanej peňaženky stanú neužitočné keď začnete používať novú zašifrovanú peňaženku. - - - Warning: The Caps Lock key is on! - Varovanie: Caps Lock je zapnutý - - - Wallet encrypted - Peňaženka zašifrovaná - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Zadajte nové heslo k peňaženke.<br/>Prosím použite heslo s dĺžkou aspoň <b>10 alebo viac náhodných znakov</b>, alebo <b>8 alebo viac slov</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Zadajte staré a nové heslo k peňaženke. - - - Wallet encryption failed - Šifrovanie peňaženky zlyhalo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Šifrovanie peňaženky zlyhalo kôli internej chybe. Vaša peňaženka nebola zašifrovaná. - - - The supplied passphrases do not match. - Zadané heslá nesúhlasia. - - - Wallet unlock failed - Odomykanie peňaženky zlyhalo - - - The passphrase entered for the wallet decryption was incorrect. - Zadané heslo pre dešifrovanie peňaženky bolo nesprávne. - - - Wallet decryption failed - Zlyhalo šifrovanie peňaženky. - - - Wallet passphrase was successfully changed. - Heslo k peňaženke bolo úspešne zmenené. - BanTableModel @@ -269,6 +110,10 @@ Quit application Ukončiť program + + &About %1 + &O %1 + About &Qt O &Qt @@ -305,14 +150,6 @@ Open &URI... Otvoriť &URI... - - Bitcoin Core client - Bitcoin Core klient - - - Importing blocks from disk... - Importujem bloky z disku... - Reindexing blocks on disk... Preindexúvam bloky na disku... @@ -357,10 +194,6 @@ &Receive &Prijať - - Show information about Bitcoin Core - Zobraziť informácie o Bitcoin Core - &Show / Hide Zobraziť / skryť @@ -397,22 +230,10 @@ Tabs toolbar Lišta záložiek - - Bitcoin Core - Jadro Bitcoin - Request payments (generates QR codes and bitcoin: URIs) Vyžiadať platby (vygeneruje QR kódy a bitcoin: URI) - - &About Bitcoin Core - O jadre Bitcoin - - - Modify configuration options for Bitcoin Core - Upraviť možnosti nastavenia pre Jadro Bitcoin - Show the list of used sending addresses and labels Zobraziť zoznam použitých adries odosielateľa a ich popisy @@ -429,10 +250,6 @@ &Command-line options Možnosti príkazového riadku - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku - %n active connection(s) to Bitcoin network %n aktívne pripojenie do siete Bitcoin%n aktívne pripojenia do siete Bitcoin%n aktívnych pripojení do siete Bitcoin @@ -544,13 +361,6 @@ Peňaženka je <b>zašifrovaná</b> a momentálne <b>zamknutá</b> - - ClientModel - - Network Alert - Výstraha siete - - CoinControlDialog @@ -629,150 +439,6 @@ Priority Priorita - - Copy address - Kopírovať adresu - - - Copy label - Kopírovať popis - - - Copy amount - Kopírovať sumu - - - Copy transaction ID - Kopírovať ID transakcie - - - Lock unspent - Uzamknúť neminuté - - - Unlock unspent - Odomknúť neminuté - - - Copy quantity - Kopírovať množstvo - - - Copy fee - Kopírovať poplatok - - - Copy after fee - Kopírovať za poplatok - - - Copy bytes - Kopírovať bajty - - - Copy priority - Kopírovať prioritu - - - Copy dust - Kopírovať prach - - - Copy change - Kopírovať zmenu - - - highest - najvyššie - - - higher - vyššie - - - high - vysoké - - - medium-high - stredne vysoké - - - medium - stredné - - - low-medium - stredne nízke - - - low - nízke - - - lower - nižšie - - - lowest - najnižšie - - - (%1 locked) - (%1 zamknutých) - - - none - žiadne - - - This label turns red if the transaction size is greater than 1000 bytes. - Tento popis sčervenie ak veľkosť transakcie presiahne 1000 bajtov. - - - This label turns red if the priority is smaller than "medium". - Tento popis sčervenie ak je priorita nižšia ako "stredná". - - - This label turns red if any recipient receives an amount smaller than %1. - Tento popis sčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1. - - - Can vary +/- %1 satoshi(s) per input. - Môže sa líšiť o +/- %1 satoshi pre každý vstup - - - yes - áno - - - no - nie - - - This means a fee of at least %1 per kB is required. - To znamená že požadovaný poplatok je aspoň %1 za kB. - - - Can vary +/- 1 byte per input. - Môže sa pohybovať +/- 1 bajt pre vstup. - - - Transactions with higher priority are more likely to get included into a block. - Transakcie s vysokou prioritou sa pravdepodobnejsie dostanú do bloku. - - - (no label) - (bez popisu) - - - change from %1 (%2) - zmena od %1 (%2) - - - (change) - (zmena) - EditAddressDialog @@ -796,38 +462,6 @@ &Address &Adresa - - New receiving address - Nová adresa pre prijímanie - - - New sending address - Nová adresa pre odoslanie - - - Edit receiving address - Upraviť prijímacie adresy - - - Edit sending address - Upraviť odosielaciu adresu - - - The entered address "%1" is already in the address book. - Vložená adresa "%1" sa už nachádza v adresári. - - - The entered address "%1" is not a valid Bitcoin address. - Vložená adresa "%1" nieje platnou adresou bitcoin. - - - Could not unlock wallet. - Nepodarilo sa odomknúť peňaženku. - - - New key generation failed. - Generovanie nového kľúča zlyhalo. - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - Jadro Bitcoin - version verzia @@ -866,10 +496,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - O jadre Bitcoin - Command-line options Voľby príkazového riadku @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Zobraziť uvítaciu obrazovku pri štarte (predvolené: %u) - - Reset all settings changes made over the GUI - Reštartovať všetky nastavenia urobené v používateľskom rozhraní. - - + Intro Welcome Vitajte - - Welcome to Bitcoin Core. - Vitajte v jadre Bitcoin. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Keďže spúštate program prvý krát, môžte si vybrať kde bude Bitcoin Jadro ukladať svoje dáta. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Jadro Bitcoin stiahne zo siete a uloží kópiu Bitcoin blockchain. Aspoň %1GB dát bude uložených v tomto priečinku a časom porastie. Peňaženka bude tiež uložená v tomto priečinku. - Use the default data directory Použiť predvolený dátový adresár @@ -937,10 +547,6 @@ Use a custom data directory: Použiť vlastný dátový adresár: - - Bitcoin Core - Jadro Bitcoin - Error: Specified data directory "%1" cannot be created. Chyba: Zadaný priečinok pre dáta "%1" nemôže byť vytvorený. @@ -976,10 +582,6 @@ Select payment request file Vyberte súbor s výzvou k platbe - - Select payment request file to open - Vyberte ktorý súbor s výzvou k platbe otvoriť - OptionsDialog @@ -1019,10 +621,6 @@ 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. Minimalizovať namiesto ukončenia aplikácie keď sa okno zavrie. Keď je zvolená táto možnosť, aplikácia sa zavrie len po zvolení Ukončiť v menu. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Jadra Bitcoin. - 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 |. URL tretích strán (napr. prehliadač blockchain) ktoré sa zobrazujú v záložke transakcií ako položky kontextového menu. %s v URL je nahradené hash-om transakcie. Viaceré URL sú oddelené zvislou čiarou |. @@ -1047,14 +645,6 @@ &Network &Sieť - - Automatically start Bitcoin Core after logging in to the system. - Automaticky spustiť Jadro Bitcoin po prihlásení do systému - - - &Start Bitcoin Core on system login - &Spustiť Bitcoin pri spustení systému správy okien - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = nechať toľko jadier voľných) @@ -1283,97 +873,6 @@ Aktuálny celkový zostatok pre adries ktoré sa iba sledujú - - PaymentServer - - URI handling - Spracovanie URI - - - Invalid payment address %1 - Neplatná adresa platby %1 - - - Payment request rejected - Požiadavka na platbu zamietnutá - - - Payment request network doesn't match client network. - Sieť požiadavky na platbu nie je zhodná so sieťou klienta. - - - Payment request is not initialized. - Požiadavka na platbu nie je inicializovaná - - - Requested payment amount of %1 is too small (considered dust). - Požadovaná platba sumy %1 je príliš malá (považovaná za prach). - - - Payment request error - Chyba pri vyžiadaní platby - - - Cannot start bitcoin: click-to-pay handler - Nedá sa spustiť obslužný program bitcoin: click-to-pay zaplatiť kliknutím - - - Payment request fetch URL is invalid: %1 - URL pre stiahnutie výzvy na zaplatenie je neplatné: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI sa nedá analyzovať! To môže byť spôsobené neplatnou Bitcoin adresou alebo zle upravenými vlastnosťami URI. - - - Payment request file handling - Obsluha súboru s požiadavkou na platbu - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Súbor s výzvou na zaplatenie sa nedá čítať alebo spracovať! To môže byť spôsobené aj neplatným súborom s výzvou. - - - Payment request expired. - Vypršala platnosť požiadavky na platbu. - - - Unverified payment requests to custom payment scripts are unsupported. - Program nepodporuje neoverené platobné výzvy na vlastná skripty. - - - Invalid payment request. - Chybná požiadavka na platbu. - - - Refund from %1 - Vrátenie z %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov). - - - Error communicating with %1: %2 - Chyba komunikácie s %1: %2 - - - Payment request cannot be parsed! - Požiadavka na platbu nemôže byť analyzovaná! - - - Bad response from server %1 - Zlá odpoveď zo servera %1 - - - Payment acknowledged - Platba potvrdená - - - Network request error - Chyba požiadavky siete - - PeerTableModel @@ -1428,25 +927,6 @@ %1 ms - - QRImageWidget - - &Save Image... - Uložiť obrázok... - - - &Copy Image - Kopírovať obrázok - - - Save QR Code - Ukladanie QR kódu - - - PNG Image (*.png) - PNG obrázok (*.png) - - RPCConsole @@ -1513,10 +993,6 @@ Memory usage Využitie pamäte - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Otvoriť Bitcoin log súbor pre ladenie z aktuálneho dátového adresára. Toto môže trvať niekoľko sekúnd pre veľké súbory. - Received Prijaté @@ -1630,10 +1106,6 @@ Out: Von: - - Build date - Dátum zostavenia - Debug log file Súbor záznamu ladenia @@ -1670,10 +1142,6 @@ &Unban Node &odblokovať uzol - - Welcome to the Bitcoin Core RPC console. - Vitajte v RPC konzole pre Jadro Bitcoin. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Použi šípky hore a dolu pre navigáciu históriou a <b>Ctrl-L</b> pre vyčistenie obrazovky. @@ -1801,18 +1269,6 @@ Remove Odstrániť - - Copy label - Kopírovať popis - - - Copy message - Kopírovať správu - - - Copy amount - Kopírovať sumu - ReceiveRequestDialog @@ -1832,73 +1288,6 @@ &Save Image... Uložiť obrázok... - - Request payment to %1 - Vyžiadať platbu pre %1 - - - Payment information - Informácia o platbe - - - URI - URI - - - Address - Adresa - - - Amount - Suma - - - Label - Popis - - - Message - Správa - - - Resulting URI too long, try to reduce the text for label / message. - Výsledné URI príliš dlhé, skráť text pre názov / správu. - - - Error encoding URI into QR Code. - Chyba v zakódovaní URI do QR kódu - - - - RecentRequestsTableModel - - Date - Dátum - - - Label - Popis - - - Message - Správa - - - Amount - Suma - - - (no label) - (bez popisu) - - - (no message) - (žiadna správa) - - - (no amount) - (žiadna suma) - SendCoinsDialog @@ -2018,14 +1407,6 @@ fast rýchle - - Send as zero-fee transaction if possible - Poslať ako transakciu bez poplatku, ak je to možné - - - (confirmation may take longer) - (potvrdenie môže trvať dlhšie) - Send to multiple recipients at once Poslať viacerým príjemcom naraz @@ -2058,114 +1439,6 @@ S&end &Odoslať - - Confirm send coins - Potvrdiť odoslanie bitcoins - - - %1 to %2 - %1 do %2 - - - Copy quantity - Kopírovať množstvo - - - Copy amount - Kopírovať sumu - - - Copy fee - Kopírovať poplatok - - - Copy after fee - Kopírovať za poplatok - - - Copy bytes - Kopírovať bajty - - - Copy priority - Kopírovať prioritu - - - Copy change - Kopírovať zmenu - - - Total Amount %1 - Celkové množstvo %1 - - - or - alebo - - - The amount to pay must be larger than 0. - Suma na úhradu musí byť väčšia ako 0. - - - The amount exceeds your balance. - Suma je vyššia ako Váš zostatok. - - - The total exceeds your balance when the %1 transaction fee is included. - Suma celkom prevyšuje Váš zostatok ak sú započítané %1 transakčné poplatky. - - - Transaction creation failed! - Vytvorenie transakcie zlyhalo! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transakcia bola zamietnutá! Toto sa môže stať ak niektoré coins vo vašej peňaženke už boli minuté, ako keď použijete kópiu wallet.dat a coins boli minuté z kópie ale neoznačené ako minuté tu. - - - A fee higher than %1 is considered an absurdly high fee. - Poplatok vyšší ako %1 je považovaný za šialene vysoký. - - - Payment request expired. - Vypršala platnosť požiadavky na platbu. - - - Pay only the required fee of %1 - Zaplatiť len vyžadovaný poplatok z %1 - - - The recipient address is not valid. Please recheck. - Adresa príjemcu je neplatná. Prosím, overte ju. - - - Duplicate address found: addresses should only be used once each. - Našla sa duplicitná adresa: každú adresu je možné použiť len raz. - - - Warning: Invalid Bitcoin address - Varovanie: Nesprávna Bitcoin adresa - - - (no label) - (bez popisu) - - - Warning: Unknown change address - Varovanie: Neznáma adresa pre výdavok - - - Copy dust - Kopírovať prach - - - Are you sure you want to send? - Určite to chcete odoslať? - - - added as transaction fee - pridané ako transakčný poplatok - SendCoinsEntry @@ -2177,10 +1450,6 @@ Pay &To: Zapla&tiť: - - Enter a label for this address to add it to your address book - Vložte popis pre túto adresu aby sa pridala do adresára - &Label: &Popis: @@ -2252,10 +1521,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Jadro Bitcoin sa ukončuje... - Do not shut down the computer until this window disappears. Nevypínajte počítač kým toto okno nezmizne. @@ -2339,69 +1604,9 @@ Reset all verify message fields Obnoviť všetky polia v overiť správu - - Click "Sign Message" to generate signature - Kliknite "Podpísať Správu" na získanie podpisu - - - The entered address is invalid. - Zadaná adresa je neplatná. - - - Please check the address and try again. - Prosím skontrolujte adresu a skúste znova. - - - The entered address does not refer to a key. - Vložená adresa nezodpovedá žiadnemu kľúcu. - - - Wallet unlock was cancelled. - Odomknutie peňaženky bolo zrušené. - - - Private key for the entered address is not available. - Súkromný kľúč pre vložená adresu nieje k dispozícii. - - - Message signing failed. - Podpísanie správy zlyhalo. - - - Message signed. - Správa podpísaná. - - - The signature could not be decoded. - Podpis nie je možné dekódovať. - - - Please check the signature and try again. - Prosím skontrolujte podpis a skúste znova. - - - The signature did not match the message digest. - Podpis sa nezhoduje so zhrnutím správy - - - Message verification failed. - Overenie správy zlyhalo. - - - Message verified. - Správa overená. - SplashScreen - - Bitcoin Core - Jadro Bitcoin - - - The Bitcoin Core developers - Vývojári jadra Bitcoin - [testnet] [testovacia sieť] @@ -2414,414 +1619,13 @@ KB/s - - TransactionDesc - - Open until %1 - Otvorené do %1 - - - conflicted - sporné - - - %1/offline - %1/offline - - - %1/unconfirmed - %1/nepotvrdené - - - %1 confirmations - %1 potvrdení - - - Status - Stav - - - , broadcast through %n node(s) - , vysielať cez %n uzol, vysielať cez %n uzle, vysielať cez %n uzolov - - - Date - Dátum - - - Source - Zdroj - - - Generated - Vygenerované - - - From - od - - - To - Pre - - - own address - vlastná adresa - - - watch-only - Iba sledovanie - - - label - popis - - - Credit - Kredit - - - not accepted - neprijaté - - - Debit - Debet - - - Total debit - Debit spolu - - - Total credit - Kredit spolu - - - Transaction fee - Transakčný poplatok - - - Net amount - Suma netto - - - Message - Správa - - - Comment - Komentár - - - Transaction ID - ID transakcie - - - Merchant - Kupec - - - 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. - Vygenerované mince musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane do reťazca, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iný uzol vytvorí blok približne v rovnakom čase. - - - Debug information - Ladiace informácie - - - Transaction - Transakcie - - - Inputs - Vstupy - - - Amount - Suma - - - true - pravda - - - false - nepravda - - - , has not been successfully broadcast yet - , ešte nebola úspešne odoslaná - - - Open for %n more block(s) - Otvorené pre %n ďalší blokOtvorené pre %n ďalšie blokyOtvorené pre %n ďalších blokov - - - unknown - neznámy - - TransactionDescDialog - - Transaction details - Detaily transakcie - This pane shows a detailed description of the transaction Táto časť obrazovky zobrazuje detailný popis transakcie - - TransactionTableModel - - Date - Dátum - - - Type - Typ - - - Immature (%1 confirmations, will be available after %2) - Nezrelé (%1 potvrdení, bude k dispozícii po %2) - - - Open for %n more block(s) - Otvorené pre %n ďalší blokOtvorené pre %n ďalšie blokyOtvorené pre %n ďalších blokov - - - Open until %1 - Otvorené do %1 - - - Confirmed (%1 confirmations) - Potvrdené (%1 potvrdení) - - - This block was not received by any other nodes and will probably not be accepted! - Ten blok nebol prijatý žiadnou inou nódou a pravdepodobne nebude akceptovaný! - - - Generated but not accepted - Vygenerované ale neakceptované - - - Offline - Offline - - - Label - Popis - - - Unconfirmed - Nepotvrdené - - - Confirming (%1 of %2 recommended confirmations) - Potvrdzuje sa ( %1 z %2 odporúčaných potvrdení) - - - Conflicted - V rozpore - - - Received with - Prijaté s - - - Received from - Prijaté od: - - - Sent to - Odoslané na - - - Payment to yourself - Platba sebe samému - - - Mined - Vyťažené - - - watch-only - Iba sledovanie - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Status transakcie. Pohybujte myšou nad týmto poľom a zjaví sa počet potvrdení. - - - Date and time that the transaction was received. - Dátum a čas prijatia transakcie. - - - Type of transaction. - Typ transakcie. - - - Whether or not a watch-only address is involved in this transaction. - Či sú ale nie sú, adresy iba na sledovanie zahrnuté v tejto transakcii. - - - Amount removed from or added to balance. - Suma pridaná alebo odobraná k zostatku. - - - - TransactionView - - All - Všetko - - - Today - Dnes - - - This week - Tento týždeň - - - This month - Tento mesiac - - - Last month - Minulý mesiac - - - This year - Tento rok - - - Range... - Rozsah... - - - Received with - Prijaté s - - - Sent to - Odoslané na - - - To yourself - Samému sebe - - - Mined - Vyťažené - - - Other - Iné - - - Enter address or label to search - Vložte adresu alebo popis pre vyhľadávanie - - - Min amount - Min množstvo - - - Copy address - Kopírovať adresu - - - Copy label - Kopírovať popis - - - Copy amount - Kopírovať sumu - - - Copy transaction ID - Kopírovať ID transakcie - - - Copy raw transaction - Kopírovať celú tranzakciu - - - Edit label - Editovať popis - - - Show transaction details - Zobraziť podrobnosti transakcie - - - Export Transaction History - Exportovať históriu transakcií - - - Watch-only - Iba sledovanie - - - Exporting Failed - Export zlyhal - - - There was an error trying to save the transaction history to %1. - Vyskytla sa chyba pri pokuse o uloženie histórie transakcií do %1. - - - Exporting Successful - Export úspešný - - - The transaction history was successfully saved to %1. - História transakciá bola úspešne uložená do %1. - - - Comma separated file (*.csv) - Čiarkou oddelovaný súbor (*.csv) - - - Confirmed - Potvrdené - - - Date - Dátum - - - Type - Typ - - - Label - Popis - - - Address - Adresa - - - ID - ID - - - Range: - Rozsah: - - - to - do - - UnitDisplayStatusBarControl @@ -2829,55 +1633,6 @@ Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky. - - WalletFrame - - No wallet has been loaded. - Nie je načítaná peňaženka. - - - - WalletModel - - Send Coins - Poslať Bitcoins - - - - WalletView - - &Export - &Exportovať... - - - Export the data in the current tab to a file - Exportovať tento náhľad do súboru - - - Backup Wallet - Zálohovať peňaženku - - - Wallet Data (*.dat) - Údaje peňaženky (*.dat) - - - Backup Failed - Záloha zlyhala - - - There was an error trying to save the wallet data to %1. - Vyskytla sa chyba pri pokuse o uloženie dát peňaženky do %1. - - - The wallet data was successfully saved to %1. - Dáta peňaženky boli úspešne uložené do %1. - - - Backup Successful - Záloha úspešná - - bitcoin-core @@ -2900,10 +1655,6 @@ Accept command line and JSON-RPC commands Prijímať príkazy z príkazového riadku a JSON-RPC - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Skontrolujte správnosť nastavenia dátumu a času na vašom počítači! Ak je čas nesprávny Jadro Bitcoin nebude správne fungovať. - Error: A fatal internal error occurred, see debug.log for details Chyba: Vyskytla sa interná chyba, pre viac informácií zobrazte debug.log @@ -2928,6 +1679,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Prijať spojenia zvonku (predvolené: 1 ak žiadne -proxy alebo -connect) + + Bitcoin Core + Jadro Bitcoin + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6 @@ -2952,10 +1707,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Nepodarilo sa pripojiť na %s na tomto počítači. Bitcoin Jadro je už pravdepodobne spustené. - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) VAROVANIE: príliš veľa vygenerovaných blokov; %d prijatých blokov v posledných %d hodinách (očakávaných %d) @@ -2974,10 +1725,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Varovanie: Zjavne sa úplne nezhodujeme s našimi peer-mi! Možno potrebujete prejsť na novšiu verziu alebo ostatné uzly potrebujú vyššiu verziu. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Varovanie: wallet.dat je poškodený, údaje úspešne získané! Pôvodný wallet.dat uložený ako wallet.{timestamp}.bak v %s; ak váš zostatok alebo transakcie niesu správne, mali by ste súbor obnoviť zo zálohy. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát. @@ -3038,6 +1785,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Error initializing wallet database environment %s! Chyba spustenia databázového prostredia peňaženky %s! + + Error loading %s + Chyba načítania %s + + + Error loading %s: Wallet corrupted + Chyba načítania %s: Peňaženka je poškodená + + + Error loading %s: Wallet requires newer version of %s + Chyba načítania %s: Peňaženka vyžaduje novšiu verziu %s + Error loading block database Chyba načítania databázy blokov @@ -3066,10 +1825,18 @@ The network does not appear to fully agree! Some miners appear to be experiencin Invalid -onion address: '%s' Neplatná -onion adresa: '%s' + + Invalid amount for -%s=<amount>: '%s' + Neplatná suma pre -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Neplatná suma pre -fallbackfee=<amount>: '%s' + + Loading banlist... + Načítavam banlist... + Not enough file descriptors available. Nedostatok kľúčových slov súboru. @@ -3130,10 +1897,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Wallet options: Voľby peňaženky: - - You need to rebuild the database using -reindex to change -txindex - Potrebujete prebudovať databázu použitím -reindex zmeniť -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Povoliť JSON-RPC pripojenia zo zadaného zdroja. Pre <ip> sú platné jednoduché IP (napr. 1.2.3.4), sieť/netmask (napr. 1.2.3.4/255.255.255.0) alebo sieť/CIDR (napr. 1.2.3.4/24). Táto možnosť môže byť zadaná niekoľko krát @@ -3146,10 +1909,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Spojiť s danou adresou pre počúvanie JSON-RPC spojení. Použite zápis [host]:port pre IPv6. Táto možnosť môže byt zadaná niekoľko krát (predvolené: spojiť so všetkými rozhraniami) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Neviem uzamknúť data adresár %s. Jadro Bitcoin je pravdepodobne už spustené. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky) @@ -3186,10 +1945,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Nastaviť najväčšiu veľkosť vysoká-dôležitosť/nízke-poplatky transakcií v bajtoch (prednastavené: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d) - The transaction amount is too small to send after the fee has been deducted Suma je príliš malá pre odoslanie tranzakcie @@ -3210,34 +1965,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Accept public REST requests (default: %u) Akceptovať verejné REST žiadosti (predvolené: %u) - - Activating best chain... - Aktivácia najlepšej reťaze... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Pokus o obnovenie privátnych kľúčov z poškodenej wallet.dat pri spustení - Automatically create Tor hidden service (default: %d) Automaticky vytvoriť skrytú službu Tor (predvolené: %d) - - Cannot resolve -whitebind address: '%s' - Nedá sa vyriešiť -whitebind adresa: '%s' - Connect through SOCKS5 proxy Pripojiť cez proxy server SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Autorské práva (C) 2009-%i Vývojári jadra Bitcoin - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin - Error reading from database, shutting down. Chyba pri načítaní z databázy, ukončuje sa. @@ -3250,22 +1985,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Information Informácia - - Initialization sanity check failed. Bitcoin Core is shutting down. - Inicializačná kontrola zlyhala. Jadro Bitcoin sa ukončuje. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Neplatná suma pre -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Neplatná suma pre -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Neplatná suma pre -mintxfee=<amount>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Neplatná suma pre -paytxfee=<amount>: '%s' (musí byť aspoň %s) @@ -3290,10 +2009,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin RPC server options: Možnosti servra RPC: - - Receive and display P2P network alerts (default: %u) - Obdržať a zobraziť sieťové P2P varovania (predvolené: %u) - Send trace/debug info to console instead of debug.log file Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu @@ -3354,10 +2069,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Username for JSON-RPC connections Užívateľské meno pre JSON-RPC spojenia - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Peňaženka musí byť prepísaná: pre dokončenie reštartujte Jadro Bitcoin - Warning Upozornenie @@ -3366,10 +2077,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Zapping all transactions from wallet... Zmazať všetky transakcie z peňaženky... - - wallet.dat corrupt, salvage failed - wallet.dat je poškodený, záchrana zlyhala - Password for JSON-RPC connections Heslo pre JSON-rPC spojenia @@ -3378,10 +2085,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Execute command when the best block changes (%s in cmd is replaced by block hash) Vykonaj príkaz, ak zmeny v najlepšom bloku (%s v príkaze nahradí blok hash) - - This help message - Táto pomocná správa - Allow DNS lookups for -addnode, -seednode and -connect Povoliť vyhľadávanie DNS pre pridanie nódy a spojenie @@ -3390,10 +2093,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Loading addresses... Načítavanie adries... - - Error loading wallet.dat: Wallet corrupted - Chyba načítania wallet.dat: Peňaženka je poškodená - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = zachovať metaúdaje tx napr. vlastníka účtu a informácie o platobných príkazoch, 2 = zahodiť metaúdaje tx) @@ -3426,14 +2125,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Always query for peer addresses via DNS lookup (default: %u) Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u) - - Error loading wallet.dat - Chyba načítania wallet.dat - - - Generate coins (default: %u) - Generovať mince (predvolené: %u) - How many blocks to check at startup (default: %u, 0 = all) Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky) @@ -3514,18 +2205,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Unknown network specified in -onlynet: '%s' Neznáma sieť upresnená v -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Nemožno rozriešiť -bind adress: '%s' - - - Cannot resolve -externalip address: '%s' - Nemožno rozriešiť -externalip address: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Neplatná suma pre -paytxfee=<amount>: '%s' - Insufficient funds Nedostatok prostriedkov diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 1b540a731..155be7bb2 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -25,10 +25,6 @@ C&lose &Zapri - - &Copy Address - &Kopiraj naslov - Delete the currently selected address from the list Izbriši trenutno označeni naslov iz seznama @@ -45,73 +41,6 @@ &Delete I&zbriši - - Choose the address to send coins to - Izbira naslova, na katerega pošiljate plačilo - - - Choose the address to receive coins with - Izbira naslova za prejem plačila - - - C&hoose - &Izberi - - - Sending addresses - Imenik naslovov za pošiljanje - - - Receiving addresses - Imenik naslovov za prejemanje - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - To je vaš imenik shranjenih naslovov Bitcoin, na katere lahko pošiljate plačila. Pred vsakim odlivom vedno preverite, če sta znesek in prejemnikov naslov pravilna. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - To je imenik vaših ustvarjenih naslovov Bitcoin, na katere lahko prejemate plačila. Priporočljivo je, da za vsak nov priliv ustvarite nov prejemni naslov. - - - Copy &Label - Kopiraj &oznako - - - &Edit - &Uredi - - - Export Address List - Izvozi seznam naslovov - - - Comma separated file (*.csv) - Datoteka s podatki, ločenimi z vejico (*.csv) - - - Exporting Failed - Seznama naslovov ni bilo mogoče izvoziti. - - - There was an error trying to save the address list to %1. Please try again. - Napaka pri shranjevanju seznama naslovov v datoteko %1. Prosimo, poskusite znova. - - - - AddressTableModel - - Label - Oznaka - - - Address - Naslov - - - (no label) - (brez oznake) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Ponovite novo geslo - - Encrypt wallet - Šifriraj denarnico - - - This operation needs your wallet passphrase to unlock the wallet. - To dejanje zahteva geslo za odklepanje vaše denarnice. - - - Unlock wallet - Odkleni denarnico - - - This operation needs your wallet passphrase to decrypt the wallet. - To dejanje zahteva geslo za dešifriranje vaše denarnice. - - - Decrypt wallet - Dešifriraj denarnico - - - Change passphrase - Zamenjaj geslo - - - Confirm wallet encryption - Potrditev šifriranja denarnice - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Opozorilo: V primeru izgube gesla šifrirane denarnice, boste <b>IZGUBILI VSE BITCOINE V DENARNICI</b>! - - - Are you sure you wish to encrypt your wallet? - Ali ste prepričani, da želite šifrirati vašo denarnico? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Program se bo zaprl, da dokonča proces šifriranja. Zapomnite si, da šifriranje ne more popolnoma zaščititi vaše denarnice pred krajami in zlonamernimi programi, ki bi lahko bili nameščeni na vašem računalniku. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - POMEMBNO: Vse starejše obstoječe varnostne kopije denarnice je potrebno zamenjati s to novo, šifrirano varnostno kopijo. Iz varnostnih razlogov bodo stare varnostne kopije postale neuporabne takoj, ko začnete uporabljati novo, šifrirano denarnico. - - - Warning: The Caps Lock key is on! - Opozorilo: imate vklopljene velike črke (Caps Lock) - - - Wallet encrypted - Denarnica je šifrirana - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Vnesite novo geslo. Prosimo, da uporabite geslo sestavljeno iz <b>deset ali več</b> naključnih znakov, ali <b>osem ali več</b> besed. - - - Enter the old passphrase and new passphrase to the wallet. - Vnesite staro in novo geslo denarnice. - - - Wallet encryption failed - Denarnice ni bilo mogoče šifrirati. - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Prišlo je do napake. Denarnice ni bilo mogoče šifrirati. - - - The supplied passphrases do not match. - Vnešeni gesli se ne ujemata - - - Wallet unlock failed - Denarnice ni bilo mogoče odkleniti. - - - The passphrase entered for the wallet decryption was incorrect. - Vnesli ste napačno geslo za dešifriranje denarnice. - - - Wallet decryption failed - Denarnice ni bilo mogoče dešifrirati. - - - Wallet passphrase was successfully changed. - Geslo za dostop do denarnice je bilo uspešno zamenjano. - BanTableModel @@ -297,14 +138,6 @@ Open &URI... Odpri &URI ... - - Bitcoin Core client - Odjemalec Bitcoin Core - - - Importing blocks from disk... - Uvažam bloke z diska ... - Reindexing blocks on disk... Poustvarjam kazalo blokov na disku ... @@ -349,10 +182,6 @@ &Receive P&rejmi - - Show information about Bitcoin Core - Oglejte si informacije o programu - &Show / Hide &Prikaži / Skrij @@ -389,22 +218,10 @@ Tabs toolbar Orodna vrstica zavihkov - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Zahtevajte plačilo (ustvarite zahtevek s kodo QR in URI tipa bitcoin:) - - &About Bitcoin Core - &O programu - - - Modify configuration options for Bitcoin Core - Spremenite programske nastavitve - Show the list of used sending addresses and labels Preglejte in uredite seznam naslovov, na katere ste kdaj poslali plačila @@ -421,10 +238,6 @@ &Command-line options Opcije &ukazne vrstice - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Oglejte si seznam in kratek opis vseh opcij pri zagonu programa iz ukazne vrstice - %n active connection(s) to Bitcoin network %n aktivna povezava v omrežje Bitcoin%n aktivni povezavi v omrežje Bitcoin%n aktivne povezave v omrežje Bitcoin%n aktivnih povezav v omrežje Bitcoin @@ -439,7 +252,7 @@ %n hour(s) - %n ura%n uri%n ure%n ur + %n uro%n uri%n ure%n ur %n day(s) @@ -536,13 +349,6 @@ Denarnica je <b>šifrirana</b> in trenutno <b>zaklenjena</b> - - ClientModel - - Network Alert - Omrežno opozorilo - - CoinControlDialog @@ -621,150 +427,6 @@ Priority Prioriteta - - Copy address - Kopiraj naslov - - - Copy label - Kopiraj oznako - - - Copy amount - Kopiraj znesek - - - Copy transaction ID - Kopiraj ID transakcije - - - Lock unspent - Zakleni neporabljeno - - - Unlock unspent - Odkleni neporabljeno - - - Copy quantity - Kopiraj število vhodov - - - Copy fee - Kopiraj znesek provizije - - - Copy after fee - Kopiraj končni znesek - - - Copy bytes - Kopiraj število bajtov - - - Copy priority - Kopiraj prioriteto - - - Copy dust - Kopiraj prah - - - Copy change - Kopiraj znesek vračila - - - highest - najvišja - - - higher - višja - - - high - visoka - - - medium-high - srednje visoka - - - medium - srednja - - - low-medium - srednje nizka - - - low - nizka - - - lower - nižja - - - lowest - najnižja - - - (%1 locked) - (%1 zaklenjeno) - - - none - nič - - - This label turns red if the transaction size is greater than 1000 bytes. - Oznaka postane rdeča, če je transakcije večja od 1000 bajtov. - - - This label turns red if the priority is smaller than "medium". - Oznaka postane rdeča, če je prioriteta transakcije manjša kot "srednja". - - - This label turns red if any recipient receives an amount smaller than %1. - Oznaka postane rdeča, če je znesek manjši od %1. - - - Can vary +/- %1 satoshi(s) per input. - Lahko variira +/- %1 satoshijev na vhod. - - - yes - da - - - no - ne - - - This means a fee of at least %1 per kB is required. - To pomeni, da je zahtevana provizija v višini vsaj %1 na KiB. - - - Can vary +/- 1 byte per input. - Lahko variira +/-1 bajt na vhod. - - - Transactions with higher priority are more likely to get included into a block. - Transakcije z višjo prioriteto imajo boljše možnosti za vključitev v blok. - - - (no label) - (brez oznake) - - - change from %1 (%2) - vračilo od %1 (%2) - - - (change) - (vračilo) - EditAddressDialog @@ -788,38 +450,6 @@ &Address &Naslov - - New receiving address - Nov naslov za prilive - - - New sending address - Nov naslov za odlive - - - Edit receiving address - Uredi naslov za prilive - - - Edit sending address - Uredi naslov za odlive - - - The entered address "%1" is already in the address book. - Vnešeni naslov %1 je že v imeniku. - - - The entered address "%1" is not a valid Bitcoin address. - Vnešeni naslov %1 ni veljaven naslov Bitcoin. - - - Could not unlock wallet. - Denarnice ni bilo mogoče odkleniti. - - - New key generation failed. - Novega ključa ni bilo mogoče ustvariti. - FreespaceChecker @@ -846,10 +476,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version različica @@ -858,10 +484,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - O programu Bitcoin Core - Command-line options Možnosti ukazne vrstice @@ -881,18 +503,6 @@ Welcome Dobrodošli - - Welcome to Bitcoin Core. - Dobrodošli v programu Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - To je prvi zagon programa, zato lahko izberete mapo, v katero bo program shranjeval podatke. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Program bo prenesel in shranil kopijo verige blokov. V izbrani podatkovni mapi bo shranjenih vsaj %1 GiB podatkov, ta količina pa bo sčasoma še naraščala. V tej mapi bo shranjena tudi denarnica. - Use the default data directory Uporabi privzeto podatkovno mapo @@ -901,10 +511,6 @@ Use a custom data directory: Uporabi to podatkovno mapo: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Napaka: Ni mogoče ustvariti mape "%1". @@ -940,10 +546,6 @@ Select payment request file Izbiranje datoteke z zahtevkom za plačilo - - Select payment request file to open - Izberite datoteko, ki vsebuje zahtevek za plačilo - OptionsDialog @@ -983,10 +585,6 @@ 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. Ko zaprete glavno okno programa, bo program tekel še naprej, okno pa bo zgolj minimirano. Program v tem primeru ustavite tako, da v meniju izberete ukaz Izhod. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Nastavitev jezika uporabniškega vmesnika programa. Nova nastavitev jezika bo uporabljena šele, ko boste znova zagnali program. - 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 |. Naslovi URL tretjih oseb (npr. raziskovalec blokov), ki bodo navedeni v kontekstnem meniju seznama transakcij. Niz %s iz naslova URL je nadomeščen s hash vrednostjo transakcije. Več zaporednih naslovov URL je med seboj ločenih z znakom |. @@ -1011,14 +609,6 @@ &Network &Omrežje - - Automatically start Bitcoin Core after logging in to the system. - Ob uporabnikovi prijavi v sistem se bo program samodejno zagnal - - - &Start Bitcoin Core on system login - &Zaženi program ob prijavi v sistem - (0 = auto, <0 = leave that many cores free) (0 = samodejno, <0 = toliko procesorskih jeder naj ostane prostih) @@ -1223,97 +813,6 @@ Trenutno skupno stanje sredstev na opazovanih naslovih - - PaymentServer - - URI handling - Rokovanje z URI - - - Invalid payment address %1 - Neveljaven naslov plačila %1 - - - Payment request rejected - Zahtevek za plačilo je bil zavrnjen. - - - Payment request network doesn't match client network. - Zahtevek za plačilo in vaš odjemalec se nahajata na dveh različnih omrežjih. - - - Payment request is not initialized. - Zahtevek za plačilo ni inicializiran. - - - Requested payment amount of %1 is too small (considered dust). - Znesek %1 v zahtevku za plačilo je prenizek (smatran za prah.) - - - Payment request error - Napaka pri zahtevku za plačilo - - - Cannot start bitcoin: click-to-pay handler - Ni mogoče zagnati rokovalca plačilnih povezav tipa bitcoin:. - - - Payment request fetch URL is invalid: %1 - Naslov URL za pridobitev zahtevka za plačilo ni veljaven: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI je neprepoznaven! Možno je, da je naslov Bitcoin neveljaven, ali da so parametri v URI napačno oblikovani. - - - Payment request file handling - Rokovanje z datoteko z zahtevkom za plačilo - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Datoteke z zahtevkom za plačilo ni mogoče prebrati! Možno je, da datoteka ni veljavna. - - - Payment request expired. - Zahtevek za plačilo je potekel. - - - Unverified payment requests to custom payment scripts are unsupported. - Nepreverjeni zahtevki za plačilo, namenjeni plačilni skripti po meri, niso podprti. - - - Invalid payment request. - Neveljaven zahtevek za plačilo. - - - Refund from %1 - Povračilo od %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.) - - - Error communicating with %1: %2 - Napaka pri povezavi z %1: %2 - - - Payment request cannot be parsed! - Zahtevek za plačilo je neprepoznaven! - - - Bad response from server %1 - Napačen odziv strežnika %1 - - - Payment acknowledged - Plačilo priznano - - - Network request error - Napaka omrežne zahteve - - PeerTableModel @@ -1368,25 +867,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &Shrani sliko ... - - - &Copy Image - &Kopiraj sliko - - - Save QR Code - Shrani kodo QR - - - PNG Image (*.png) - PNG slika (*.png) - - RPCConsole @@ -1441,10 +921,6 @@ Current number of blocks Trenutno število blokov - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Odpre razhroščevalni dnevnik debug.log, ki se nahaja v trenutni podatkovni mapi. Če je datoteka velika, lahko postopek traja nekaj sekund. - Received Prejeto @@ -1533,10 +1009,6 @@ Out: Odhodnih: - - Build date - Datum izgradnje - Debug log file Razhroščevalni dnevnik @@ -1545,10 +1017,6 @@ Clear console Počisti konzolo - - Welcome to the Bitcoin Core RPC console. - Dobrodošli v konzoli RPC programa Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Uporabite tipki gor in dol za navigacijo po zgodovini ukazov. Uporabite <b>Ctrl-L</b> za izbris zaslona in zgodovine ukazov. @@ -1672,18 +1140,6 @@ Remove Odstrani - - Copy label - Kopiraj oznako - - - Copy message - Kopiraj sporočilo - - - Copy amount - Kopiraj znesek - ReceiveRequestDialog @@ -1703,73 +1159,6 @@ &Save Image... &Shrani sliko ... - - Request payment to %1 - Zahtevek za plačilo z oznako: %1 - - - Payment information - Informacije o plačilu - - - URI - URI - - - Address - Naslov - - - Amount - Znesek - - - Label - Oznaka - - - Message - Sporočilo - - - Resulting URI too long, try to reduce the text for label / message. - Nastali URI je predolg. Skušajte skrajšati besedilo v oznaki/sporočilu. - - - Error encoding URI into QR Code. - Napaka pri pretvorbi URI v kodo QR. - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Oznaka - - - Message - Sporočilo - - - Amount - Znesek - - - (no label) - (brez oznake) - - - (no message) - (brez sporočila) - - - (no amount) - (brez zneska) - SendCoinsDialog @@ -1889,14 +1278,6 @@ fast hitro - - Send as zero-fee transaction if possible - Pošlji brez provizije, če je mogoče - - - (confirmation may take longer) - (čas do potrditve je lahko daljši) - Send to multiple recipients at once Pošlji več prejemnikom hkrati @@ -1929,110 +1310,6 @@ S&end &Pošlji - - Confirm send coins - Potrdi pošiljanje - - - %1 to %2 - %1 na %2 - - - Copy quantity - Kopiraj število vhodov - - - Copy amount - Kopiraj znesek - - - Copy fee - Kopiraj provizijo - - - Copy after fee - Kopiraj Po proviziji - - - Copy bytes - Kopiraj bajte - - - Copy priority - Kopiraj prioriteto - - - Copy change - Kopiraj vračilo - - - or - ali - - - The amount to pay must be larger than 0. - Znesek za plačilo mora biti večji od 0. - - - The amount exceeds your balance. - Znesek je večji od stanja sredstev, s katerimi razpolagate. - - - The total exceeds your balance when the %1 transaction fee is included. - Celotni znesek z vključeno provizijo %1 je večji od stanja sredstev, s katerimi razpolagate. - - - Transaction creation failed! - Transakcije ni bilo mogoče ustvariti! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transakcija je bila zavrnjena! To se lahko zgodi, če so bili kateri od kovancev iz denarnice že porabljeni, kot v primeru, da ste kje uporabili kopijo datoteke wallet.dat in kovance tam že porabili, lokalno pa ti še niso bili označeni kot porabljeni. - - - A fee higher than %1 is considered an absurdly high fee. - Provizija, višja od %1, velja za nesmiselno visoko. - - - Payment request expired. - Zahtevek za plačilo je potekel. - - - Estimated to begin confirmation within %n block(s). - Predviden začetek potrditev po %n najdenem bloku.Predviden začetek potrditev po %n najdenih blokih.Predviden začetek potrditev po %n najdenih blokih.Predviden začetek potrditev po %n najdenih blokih. - - - The recipient address is not valid. Please recheck. - Naslov prejemnika je neveljaven. Prosimo, preverite. - - - Duplicate address found: addresses should only be used once each. - Naslov je že bil uporabljen. Vsak naslov naj bi se uporabil samo enkrat. - - - Warning: Invalid Bitcoin address - Opozorilo: Neveljaven bitcoin naslov - - - (no label) - (brez oznake) - - - Warning: Unknown change address - Opozorilo: Neznan naslov za vračilo drobiža - - - Copy dust - Kopiraj prah - - - Are you sure you want to send? - Ali ste prepričani, da želite izvesti plačilo? - - - added as transaction fee - dodano kot provizija transakcije - SendCoinsEntry @@ -2044,10 +1321,6 @@ Pay &To: Prejemnik &plačila: - - Enter a label for this address to add it to your address book - Vnesite oznako, pod katero bo zgornji naslov shranjen v imenik - &Label: &Oznaka: @@ -2119,10 +1392,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Program se ustavlja ... - Do not shut down the computer until this window disappears. Dokler to okno ne izgine, ne zaustavljajte računalnika. @@ -2214,69 +1483,9 @@ Reset all verify message fields Počisti vsa polja za vnos v oknu za preverjanje - - Click "Sign Message" to generate signature - Kliknite "Podpiši sporočilo" da ustvarite podpis - - - The entered address is invalid. - Vnešeni naslov ni veljaven. - - - Please check the address and try again. - Prosimo preverite naslov in poskusite znova. - - - The entered address does not refer to a key. - Vnešeni naslov se ne nanaša na noben ključ. - - - Wallet unlock was cancelled. - Odklepanje denarnice je bilo preklicano. - - - Private key for the entered address is not available. - Zasebni ključ vnešenega naslova ni na voljo. - - - Message signing failed. - Podpisa ni bilo mogoče ustvariti. - - - Message signed. - Podpis je bil ustvarjen. - - - The signature could not be decoded. - Podpisa ni bilo mogoče razbrati. - - - Please check the signature and try again. - Prosimo preverite podpis in poskusite znova. - - - The signature did not match the message digest. - Podpis se ne ujema z rezultatom funkcije preverjanja. - - - Message verification failed. - Podpis ni veljaven za to sporočilo. - - - Message verified. - Podpis sporočila je veljaven. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core razvijalci - [testnet] [testnet] @@ -2289,418 +1498,13 @@ KiB/s - - TransactionDesc - - Open until %1 - Odprto do %1 - - - conflicted - v konfliktu - - - %1/offline - %1/brez povezave - - - %1/unconfirmed - %1/nepotrjeno - - - %1 confirmations - %1 potrdil - - - Status - Status - - - , broadcast through %n node(s) - , posredovano %n vozlišču, posredovano %n vozliščema, posredovano %n vozliščem, posredovano %n vozliščem - - - Date - Datum - - - Source - Izvor - - - Generated - Generirano - - - From - Pošiljatelj - - - To - Prejemnik - - - own address - lasten naslov - - - watch-only - opazovano - - - label - oznaka - - - Credit - V dobro - - - matures in %n more block(s) - dozori po %n najdenem blokudozori po %n najdenih blokihdozori po %n najdenih blokihdozori po %n najdenih blokih - - - not accepted - ni bilo sprejeto - - - Debit - Debit - - - Total debit - Skupaj v breme - - - Total credit - Skupaj v dobro - - - Transaction fee - Provizija transakcije - - - Net amount - Neto znesek - - - Message - Sporočilo - - - Comment - Opomba - - - Transaction ID - ID transakcije - - - Merchant - Trgovec - - - 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. - Ustvarjeni kovanci morajo zoreti %1 blokov, preden jih lahko porabite. Ko ste ta blok zgenerirali, je bil posredovan v omrežje, da bo dodan v verigo. Če se bloku ni uspelo uvrstiti v verigo, se bo njegovo stanje spremenilo v "ni bilo sprejeto" in kovancev ne bo mogoče porabiti. To se včasih zgodi, če kak drug rudar v roku nekaj sekund hkrati z vami odkrije drug blok. - - - Debug information - Razhroščevalne informacije - - - Transaction - Transakcija - - - Inputs - Vhodi - - - Amount - Znesek - - - true - pravilno - - - false - nepravilno - - - , has not been successfully broadcast yet - , še ni bila uspešno raznešena - - - Open for %n more block(s) - Še %n blok do potrditveŠe %n bloka do potrditveŠe %n bloki do potrditveŠe %n blokov do potrditve - - - unknown - neznano - - TransactionDescDialog - - Transaction details - Podrobnosti transakcije - This pane shows a detailed description of the transaction V tem podoknu so prikazane podrobnosti o transakciji - - TransactionTableModel - - Date - Datum - - - Type - Vrsta - - - Immature (%1 confirmations, will be available after %2) - Nedozorelo (št. potrditev: %1, na voljo šele po: %2) - - - Open for %n more block(s) - Še %n blok do potrditveŠe %n bloka do potrditveŠe %n bloki do potrditveŠe %n blokov do potrditve - - - Open until %1 - Odprto do %1 - - - Confirmed (%1 confirmations) - Potrjeno (%1 potrdil) - - - This block was not received by any other nodes and will probably not be accepted! - Ta blok ni prejelo še nobeno vozlišče. Najverjetneje ne bo sprejet! - - - Generated but not accepted - Generirano, toda ne sprejeto - - - Offline - Brez povezave - - - Label - Oznaka - - - Unconfirmed - Nepotrjeno - - - Confirming (%1 of %2 recommended confirmations) - V potrjevanju (št. potrditev: %1 od priporočenih %2) - - - Conflicted - V konfliktu - - - Received with - Prejemek - - - Received from - Prejemek - - - Sent to - Izdatek - - - Payment to yourself - Nakazilo sebi - - - Mined - Narudarjeno - - - watch-only - opazovano - - - (n/a) - (ni na voljo) - - - Transaction status. Hover over this field to show number of confirmations. - Stanje transakcije. Zapeljite z miško čez to polje za prikaz števila potrdil. - - - Date and time that the transaction was received. - Datum in čas, ko je transakcija bila prejeta. - - - Type of transaction. - Vrsta transakcije. - - - Whether or not a watch-only address is involved in this transaction. - Ali je v transakciji udeležen kateri od opazovanih naslovov. - - - User-defined intent/purpose of the transaction. - Uporabniško določen namen transakcije. - - - Amount removed from or added to balance. - Znesek spremembe stanja sredstev. - - - - TransactionView - - All - Vse - - - Today - Danes - - - This week - Ta teden - - - This month - Ta mesec - - - Last month - Prejšnji mesec - - - This year - To leto - - - Range... - Območje ... - - - Received with - Prejemek - - - Sent to - Izdatek - - - To yourself - Nakazilo sebi - - - Mined - Narudarjeno - - - Other - Drugo - - - Enter address or label to search - Iščite po naslovu ali oznaki - - - Min amount - Minimalni znesek - - - Copy address - Kopiraj naslov - - - Copy label - Kopiraj oznako - - - Copy amount - Kopiraj znesek - - - Copy transaction ID - Kopiraj ID transakcije - - - Edit label - Uredi oznako - - - Show transaction details - Prikaži podrobnosti transakcije - - - Export Transaction History - Izvoz zgodovine transakcij - - - Watch-only - Opazovano - - - Exporting Failed - Seznama transakcij ni bilo mogoče izvoziti. - - - There was an error trying to save the transaction history to %1. - Prišlo je do napake med shranjevanjem zgodovine transakcij v datoteko %1. - - - Exporting Successful - Uspešen izvoz - - - The transaction history was successfully saved to %1. - Zgodovina poteklih transakcij je bila uspešno shranjena v datoteko %1. - - - Comma separated file (*.csv) - Datoteka s podatki, ločenimi z vejico (*.csv) - - - Confirmed - Potrjeno - - - Date - Datum - - - Type - Vrsta - - - Label - Oznaka - - - Address - Naslov - - - ID - ID - - - Range: - Območje: - - - to - za - - UnitDisplayStatusBarControl @@ -2708,55 +1512,6 @@ Merska enota za prikaz zneskov. Kliknite za izbiro druge enote. - - WalletFrame - - No wallet has been loaded. - Denarnica ni bila naložena. - - - - WalletModel - - Send Coins - Pošlji - - - - WalletView - - &Export - &Izvozi - - - Export the data in the current tab to a file - Izvozi podatke iz trenutnega zavihka v datoteko - - - Backup Wallet - Izdelava varnostne kopije denarnice - - - Wallet Data (*.dat) - Podatki denarnice (*.dat) - - - Backup Failed - Varnostne kopije ni bilo mogoče izdelati. - - - There was an error trying to save the wallet data to %1. - Prišlo je do napake pri shranjevanju podatkov denarnice v datoteko %1. - - - The wallet data was successfully saved to %1. - Podatki iz denarnice so bili uspešno shranjeni v datoteko %1. - - - Backup Successful - Varnostna kopija je bila uspešno izdelana - - bitcoin-core @@ -2787,6 +1542,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Veži dani naslov in tam vedno poslušaj. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata. @@ -2807,10 +1566,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije. - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Na tem računalniku ni bilo mogoče vezati naslova %s. Odjemalec Bitcoin Core je verjetno že zagnan. - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov) @@ -2827,10 +1582,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Opozorilo: Datoteka wallet.dat je bila okvarjena, podatki pa so bili kljub temu rešeni! Originalna datoteka je bila shranjena kot wallet.{čas.oznaka}.bak v mapo %s. Če sta skupno stanje ali seznam transakcij napačna, morate datoteko restavrirati iz varnostne kopije. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat. @@ -2951,10 +1702,6 @@ Wallet options: Izbire denarnice: - - You need to rebuild the database using -reindex to change -txindex - Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Iz navedenega vira dovoli povezave na JSON-RPC. Veljavne oblike vrednosti parametra <ip> so: edinstven naslov IP (npr.: 1.2.3.4), kombinacija omrežje/netmask (npr.: 1.2.3.4/255.255.255.0), ali pa kombinacija omrežje/CIDR (1.2.3.4/24). To opcijo lahko navedete večkrat. @@ -2967,10 +1714,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Veži dani naslov in sprejemaj povezave na JSON-RPC. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata. To opcijo lahko navedete večkrat. (privzeto: veži vse omrežne vmesnike) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Ne morem zakleniti podatkovne mape %s. Bitcoin Core je verjetno že zagnan. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Ustvarjaj nove datoteke s privzetimi sistemskimi dovoljenji, namesto z umask 077. (To pride v poštev samo, kadar imate izklopljeno funkcijo denarnice.) @@ -2999,38 +1742,14 @@ (default: %u) (privzeto: %u) - - Activating best chain... - Prehajam na najboljšo verigo ... - - - Cannot resolve -whitebind address: '%s' - Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti. - Connect through SOCKS5 proxy Poveži se preko posredniškega strežnika SOCKS5 - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i The Bitcoin Core Developers - Information Informacije - - Invalid amount for -maxtxfee=<amount>: '%s' - Neveljavna količina za -maxtxfee=<amount>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Neveljavna količina za -minrelaytxfee=<amount>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Neveljavna količina za -mintxfee=<amount>: '%s' - Need to specify a port with -whitebind: '%s' Pri opciji -whitebind morate navesti vrata: %s @@ -3079,10 +1798,6 @@ Zapping all transactions from wallet... Brišem vse transakcije iz denarnice ... - - wallet.dat corrupt, salvage failed - Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti. - Password for JSON-RPC connections Geslo za povezave na JSON-RPC @@ -3091,10 +1806,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka) - - This help message - To sporočilo pomoči - Allow DNS lookups for -addnode, -seednode and -connect Omogoči poizvedbe DNS za opcije -addnode, -seednode in -connect. @@ -3103,10 +1814,6 @@ Loading addresses... Nalagam naslove ... - - Error loading wallet.dat: Wallet corrupted - Napaka pri nalaganju wallet.dat: denarnica pokvarjena - Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5 (privzeto: %s) @@ -3115,10 +1822,6 @@ (default: %s) (privzeto: %s) - - Error loading wallet.dat - Napaka pri nalaganju wallet.dat - Invalid -proxy address: '%s' Neveljaven naslov -proxy: '%s' @@ -3151,18 +1854,6 @@ Unknown network specified in -onlynet: '%s' Neznano omrežje določeno v -onlynet: '%s'. - - Cannot resolve -bind address: '%s' - Naslova %s, podanega pri opciji -bind ni mogoče razrešiti. - - - Cannot resolve -externalip address: '%s' - Naslova "%s", podanega pri opciji -externalip ni mogoče razrešiti. - - - Invalid amount for -paytxfee=<amount>: '%s' - Neveljavna količina za -paytxfee=<amount>: '%s' - Insufficient funds Premalo sredstev diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index d87bd9db5..6c86b7d9f 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -21,10 +21,6 @@ &Copy &Kopjo - - &Copy Address - &Kopjo adresen - Delete the currently selected address from the list Fshi adresen e selektuar nga lista @@ -37,65 +33,6 @@ &Delete &Fshi - - Choose the address to send coins to - Zgjidh adresen ku do te dergoni monedhat - - - Sending addresses - Duke derguar adresen - - - Receiving addresses - Duke marr adresen - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Këto janë Bitcoin adresat e juaja për të dërguar pagesa. Gjithmon kontrolloni shumën dhe adresën pranuese para se të dërgoni monedha. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Këto janë Bitcoin adresat e juaja për të pranuar pagesa. Rekomandohet që gjithmon të përdorni një adresë të re për çdo transaksion. - - - Copy &Label - Kopjo &Etiketë - - - &Edit - &Ndrysho - - - Export Address List - Eksporto listën e adresave - - - Comma separated file (*.csv) - Skedar i ndarë me pikëpresje(*.csv) - - - Exporting Failed - Eksportimi dështoj - - - There was an error trying to save the address list to %1. Please try again. - Gabim gjatë ruajtjes së listës së adresave në %1. Ju lutem provoni prapë. - - - - AddressTableModel - - Label - Etiketë - - - Address - Adresë - - - (no label) - (pa etiketë) - AskPassphraseDialog @@ -111,67 +48,7 @@ Repeat new passphrase Përsërisni frazkalimin e ri - - Encrypt wallet - Kripto portofolin - - - This operation needs your wallet passphrase to unlock the wallet. - Ky veprim ka nevojë per frazkalimin e portofolit tuaj që të ç'kyç portofolin. - - - Unlock wallet - ç'kyç portofolin. - - - This operation needs your wallet passphrase to decrypt the wallet. - Ky veprim kërkon frazkalimin e portofolit tuaj që të dekriptoj portofolin. - - - Decrypt wallet - Dekripto portofolin - - - Change passphrase - Ndrysho frazkalimin - - - Confirm wallet encryption - Konfirmoni enkriptimin e portofolit - - - Are you sure you wish to encrypt your wallet? - Jeni te sigurt te enkriptoni portofolin tuaj? - - - Wallet encrypted - Portofoli u enkriptua - - - Wallet encryption failed - Enkriptimi i portofolit dështoi - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Enkriptimi i portofolit dështoi për shkak të një gabimi të brëndshëm. portofoli juaj nuk u enkriptua. - - - The supplied passphrases do not match. - Frazkalimet e plotësuara nuk përputhen. - - - Wallet unlock failed - ç'kyçja e portofolit dështoi - - - The passphrase entered for the wallet decryption was incorrect. - Frazkalimi i futur për dekriptimin e portofolit nuk ishte i saktë. - - - Wallet decryption failed - Dekriptimi i portofolit dështoi - - + BanTableModel @@ -249,14 +126,6 @@ Tabs toolbar Shiriti i mjeteve - - Bitcoin Core - Berthama Bitcoin - - - &About Bitcoin Core - Rreth Berthames Bitkoin - %1 and %2 %1 dhe %2 @@ -298,9 +167,6 @@ Portofoli po <b> enkriptohet</b> dhe është <b> i kyçur</b> - - ClientModel - CoinControlDialog @@ -319,22 +185,6 @@ Date Data - - Copy address - Kopjo adresën - - - yes - po - - - no - jo - - - (no label) - (pa etiketë) - EditAddressDialog @@ -350,34 +200,6 @@ &Address &Adresa - - New receiving address - Adresë e re pritëse - - - New sending address - Adresë e re dërgimi - - - Edit receiving address - Ndrysho adresën pritëse - - - Edit sending address - ndrysho adresën dërguese - - - The entered address "%1" is already in the address book. - Adresa e dhënë "%1" është e zënë në librin e adresave. - - - Could not unlock wallet. - Nuk mund të ç'kyçet portofoli. - - - New key generation failed. - Krijimi i çelësit të ri dështoi. - FreespaceChecker @@ -388,18 +210,10 @@ HelpMessageDialog - - Bitcoin Core - Berthama Bitcoin - version versioni - - About Bitcoin Core - Rreth Berthames Bitkoin - Intro @@ -407,14 +221,6 @@ Welcome Miresevini - - Welcome to Bitcoin Core. - Miresevini ne Berthamen Bitcoin - - - Bitcoin Core - Berthama Bitcoin - Error Problem @@ -441,9 +247,6 @@ Formilarë - - PaymentServer - PeerTableModel @@ -454,9 +257,6 @@ Sasia - - QRImageWidget - RPCConsole @@ -501,37 +301,6 @@ Copy &Address &Kopjo adresen - - Address - Adresë - - - Amount - Sasia - - - Label - Etiketë - - - - RecentRequestsTableModel - - Date - Data - - - Label - Etiketë - - - Amount - Sasia - - - (no label) - (pa etiketë) - SendCoinsDialog @@ -559,18 +328,6 @@ Confirm the send action Konfirmo veprimin e dërgimit - - Confirm send coins - konfirmo dërgimin e monedhave - - - The amount to pay must be larger than 0. - Shuma e paguar duhet të jetë më e madhe se 0. - - - (no label) - (pa etiketë) - SendCoinsEntry @@ -582,10 +339,6 @@ Pay &To: Paguaj &drejt: - - Enter a label for this address to add it to your address book - Krijoni një etiketë për këtë adresë që t'ja shtoni librit të adresave - &Label: &Etiketë: @@ -627,10 +380,6 @@ SplashScreen - - Bitcoin Core - Berthama Bitcoin - [testnet] [testo rrjetin] @@ -639,172 +388,26 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Hapur deri më %1 - - - %1/unconfirmed - %1/I pakonfirmuar - - - %1 confirmations - %1 konfirmimet - - - Date - Data - - - Transaction - transaksionit - - - Amount - Sasia - - - , has not been successfully broadcast yet - , nuk është transmetuar me sukses deri tani - - - unknown - i/e panjohur - - TransactionDescDialog - - Transaction details - Detajet e transaksionit - This pane shows a detailed description of the transaction Ky panel tregon një përshkrim të detajuar të transaksionit - - TransactionTableModel - - Date - Data - - - Type - Lloji - - - Open until %1 - Hapur deri më %1 - - - Confirmed (%1 confirmations) - I/E konfirmuar(%1 konfirmime) - - - This block was not received by any other nodes and will probably not be accepted! - Ky bllok është marrë nga ndonjë nyje dhe ka shumë mundësi të mos pranohet! - - - Generated but not accepted - I krijuar por i papranuar - - - Label - Etiketë - - - Received with - Marrë me - - - Sent to - Dërguar drejt - - - Payment to yourself - Pagesë ndaj vetvetes - - - Mined - Minuar - - - (n/a) - (p/a) - - - - TransactionView - - Received with - Marrë me - - - Sent to - Dërguar drejt - - - Mined - Minuar - - - Copy address - Kopjo adresën - - - Exporting Failed - Eksportimi dështoj - - - Comma separated file (*.csv) - Skedar i ndarë me pikëpresje(*.csv) - - - Date - Data - - - Type - Lloji - - - Label - Etiketë - - - Address - Adresë - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Dërgo Monedha - - - - WalletView - - Export the data in the current tab to a file - Eksporto të dhënat e skedës korrente në një skedar - - bitcoin-core Options: Opsionet: + + Bitcoin Core + Berthama Bitcoin + Information Informacion diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index b6ba896b3..6b6f1af6f 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -17,10 +17,6 @@ &Copy Kopirajte - - &Copy Address - Kopirajte adresu - Delete the currently selected address from the list Izbrisite trenutno izabranu adresu sa liste @@ -29,25 +25,6 @@ &Delete &Избриши - - Comma separated file (*.csv) - Зарезом одвојене вредности (*.csv) - - - - AddressTableModel - - Label - Етикета - - - Address - Адреса - - - (no label) - (без етикете) - AskPassphraseDialog @@ -63,74 +40,6 @@ Repeat new passphrase Поновите нову лозинку - - Encrypt wallet - Шифровање новчаника - - - This operation needs your wallet passphrase to unlock the wallet. - Ова акција захтева лозинку Вашег новчаника да би га откључала. - - - Unlock wallet - Откључавање новчаника - - - This operation needs your wallet passphrase to decrypt the wallet. - Ова акција захтева да унесете лозинку да би дешифловала новчаник. - - - Decrypt wallet - Дешифровање новчаника - - - Change passphrase - Промена лозинке - - - Confirm wallet encryption - Одобрите шифровање новчаника - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Упозорење: Ако се ваш новчаник шифрује а потом изгубите лозинкзу, ви ћете <b>ИЗГУБИТИ СВЕ BITCOIN-Е</b>! - - - Are you sure you wish to encrypt your wallet? - Да ли сте сигурни да желите да се новчаник шифује? - - - Wallet encrypted - Новчаник је шифрован - - - Wallet encryption failed - Неуспело шифровање новчаника - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Настала је унутрашња грешка током шифровања новчаника. Ваш новчаник није шифрован. - - - The supplied passphrases do not match. - Лозинке које сте унели се не подударају. - - - Wallet unlock failed - Неуспело откључавање новчаника - - - The passphrase entered for the wallet decryption was incorrect. - Лозинка коју сте унели за откључавање новчаника је нетачна. - - - Wallet decryption failed - Неуспело дешифровање новчаника - - - Wallet passphrase was successfully changed. - Лозинка за приступ новчанику је успешно промењена. - BanTableModel @@ -221,10 +130,6 @@ Tabs toolbar Трака са картицама - - &About Bitcoin Core - O Bitcoin Coru - Up to date Ажурно @@ -250,9 +155,6 @@ Новчаник јс <b>шифрован</b> и тренутно <b>закључан</b> - - ClientModel - CoinControlDialog @@ -271,22 +173,6 @@ Confirmed Potvrdjen - - Copy address - kopiraj adresu - - - Copy label - kopiraj naziv - - - Copy amount - kopiraj iznos - - - (no label) - (без етикете) - EditAddressDialog @@ -302,15 +188,7 @@ &Address &Адреса - - The entered address "%1" is already in the address book. - Унешена адреса "%1" се већ налази у адресару. - - - Could not unlock wallet. - Немогуће откључати новчаник. - - + FreespaceChecker @@ -320,10 +198,6 @@ version верзија - - About Bitcoin Core - O Bitcoin Coru - Usage: Korišćenje: @@ -361,9 +235,6 @@ Форма - - PaymentServer - PeerTableModel @@ -374,9 +245,6 @@ iznos - - QRImageWidget - RPCConsole @@ -394,60 +262,13 @@ &Message: Poruka: - - Copy label - kopiraj naziv - - - Copy amount - kopiraj iznos - - + ReceiveRequestDialog Copy &Address Kopirajte adresu - - Address - Адреса - - - Amount - iznos - - - Label - Етикета - - - Message - Poruka - - - - RecentRequestsTableModel - - Date - datum - - - Label - Етикета - - - Message - Poruka - - - Amount - iznos - - - (no label) - (без етикете) - SendCoinsDialog @@ -467,15 +288,7 @@ S&end &Пошаљи - - Copy amount - kopiraj iznos - - - (no label) - (без етикете) - - + SendCoinsEntry @@ -523,258 +336,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - Otvoreno do %1 - - - %1/unconfirmed - %1/nepotvrdjeno - - - %1 confirmations - %1 potvrde - - - Date - datum - - - label - етикета - - - Message - Poruka - - - Transaction - transakcije - - - Amount - iznos - - - , has not been successfully broadcast yet - , nije još uvek uspešno emitovan - - - unknown - nepoznato - - TransactionDescDialog - - Transaction details - detalji transakcije - This pane shows a detailed description of the transaction Ovaj odeljak pokazuje detaljan opis transakcije - - TransactionTableModel - - Date - datum - - - Type - tip - - - Open until %1 - Otvoreno do %1 - - - Confirmed (%1 confirmations) - Potvrdjena (%1 potvrdjenih) - - - This block was not received by any other nodes and will probably not be accepted! - Ovaj blok nije primljen od ostalih čvorova (nodova) i verovatno neće biti prihvaćen! - - - Generated but not accepted - Generisan ali nije prihvaćen - - - Label - Етикета - - - Received with - Primljen sa - - - Received from - Primljeno od - - - Sent to - Poslat ka - - - Payment to yourself - Isplata samom sebi - - - Mined - Minirano - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Status vaše transakcije. Predjite mišem preko ovog polja da bi ste videli broj konfirmacija - - - Date and time that the transaction was received. - Datum i vreme primljene transakcije. - - - Type of transaction. - Tip transakcije - - - Amount removed from or added to balance. - Iznos odbijen ili dodat balansu. - - - - TransactionView - - All - Sve - - - Today - Danas - - - This week - ove nedelje - - - This month - Ovog meseca - - - Last month - Prošlog meseca - - - This year - Ove godine - - - Range... - Opseg... - - - Received with - Primljen sa - - - Sent to - Poslat ka - - - To yourself - Vama - samom sebi - - - Mined - Minirano - - - Other - Drugi - - - Enter address or label to search - Navedite adresu ili naziv koji bi ste potražili - - - Min amount - Min iznos - - - Copy address - kopiraj adresu - - - Copy label - kopiraj naziv - - - Copy amount - kopiraj iznos - - - Edit label - promeni naziv - - - Comma separated file (*.csv) - Зарезом одвојене вредности (*.csv) - - - Confirmed - Potvrdjen - - - Date - datum - - - Type - tip - - - Label - Етикета - - - Address - Адреса - - - Range: - Opseg: - - - to - do - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - Слање новца - - - - WalletView - - Backup Wallet - Backup новчаника - - bitcoin-core @@ -801,22 +372,10 @@ Password for JSON-RPC connections Lozinka za JSON-RPC konekcije - - This help message - Ova poruka Pomoći - Loading addresses... učitavam adrese.... - - Error loading wallet.dat: Wallet corrupted - Грешка током учитавања wallet.dat: Новчаник је покварен - - - Error loading wallet.dat - Грешка током учитавања wallet.dat - Loading block index... Učitavam blok indeksa... diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts index c836c8ddb..86243bc14 100644 --- a/src/qt/locale/bitcoin_sr@latin.ts +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -25,10 +25,6 @@ C&lose Zatvori - - &Copy Address - Kopiraj adresu - Delete the currently selected address from the list Briše trenutno izabranu adresu sa liste @@ -45,69 +41,6 @@ &Delete &Izbrisati - - Choose the address to send coins to - Izaberi adresu za slanje bitkoina - - - Choose the address to receive coins with - Izaberi adresu za primanje bitkoina - - - C&hoose - I&zaberi - - - Sending addresses - Adrese za slanje - - - Receiving addresses - Adrese za primanje - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Ovo su vase Bitkoin adrese za slanje bitkoina. Uvek proverite unetu kolicinu bitkoina i adresu za slanje bitkoin pre slanja. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Ovo su vase Bitkoin adrese za primanje bitkoina. Preporuceno je da koristite drugaciju adresu za primanje kod svake transakcije. - - - &Edit - &Izmeni - - - Export Address List - Izvezi listu adresa - - - Comma separated file (*.csv) - Zapetom odvojene ('.csv) datoteke - - - Exporting Failed - Izvoz nije uspeo - - - There was an error trying to save the address list to %1. Please try again. - Dogodila se greska prilikom cuvanja adrese u %1. Molimo pokusajte ponovo. - - - - AddressTableModel - - Label - Etiketa - - - Address - Adresa - - - (no label) - (bez etikete) - AskPassphraseDialog @@ -127,94 +60,6 @@ Repeat new passphrase Ponovo unesite pristupnu frazu - - Encrypt wallet - Enkriptuj/Sifruj novcanik - - - This operation needs your wallet passphrase to unlock the wallet. - Da bi ste otkljucali novcanik potrebno je da unesete pristupnu frazu - - - Unlock wallet - Otkljucaj novcanik - - - This operation needs your wallet passphrase to decrypt the wallet. - Da bi ste dekriptovali/desifrovali novcanik potrebno je da unesete pristupnu frazu - - - Decrypt wallet - Dekriptuj/Desifruj novcanik - - - Change passphrase - Izmeni pristupnu frazu - - - Confirm wallet encryption - Potvrdite enkripciju/sifrovanje novcanika - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Upozorenje: Ako ekriptujete/sifrujete novcanik, a izgubite pristupnu frazu <b>IZGUBICETE SVE VASE BITKOINE</b>! - - - Are you sure you wish to encrypt your wallet? - Da li ste sigurni da zelite da enkriptujete/sifrujete novcanik? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core ce se sada zatvoriti radi zavrsavanje procesa enkripcije/sifrovanja novcanika. Zapamtite da enkriptovanje/sifrovanje novcanika ne moze u potpunosti da zastiti vase bitkoine od kradje od strane virusa koji su zarazili vas racunar. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - VAZNO : Bilo koja prethodne rezervne kopije koje ste nacinili od svoje datoteke novcanika treba da se zamene sa novogenerisanom, sifrovanom datotekom novcanika. Iz bezbednosnih razloga, prethodne rezervne kopije su nezasifrovanih datoteka novcanika ce postati beskorisne cim pocnete da koristite novi, sifrovani novčanik. - - - Warning: The Caps Lock key is on! - Upozorenje: Dugme Caps Lock je upaljeno - - - Wallet encrypted - Novcanik je enkriptovan/sifrovan - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Unesite novu pristupnu frazu u novcanik.<br/>Molimo koristite pristupnu frazu od <br/>deset ili vise nasumicnih karaktera <br/>, ili <b>osm ili vise reci </b>. - - - Enter the old passphrase and new passphrase to the wallet. - Unesite staru pristupnu frazu i novu pristupnu frazu u novcanik. - - - Wallet encryption failed - Ekripcija/Sifrovanje novcanika nije uspelo - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Enkriptovanje/Sifrovanje novcanika nije uspelo zbog greske. Vas novcanik nije enkriptovan/sifrovan. - - - The supplied passphrases do not match. - Uneta pristupne fraze se ne podudaraju - - - Wallet unlock failed - Otkljucavanje novcanika nije uspelo - - - The passphrase entered for the wallet decryption was incorrect. - Pristupna fraza za dekriptovanje/desifrovanje novcanika nije tacna. - - - Wallet decryption failed - Dekriptovanje/desifrovanje novcanika nije uspelo - - - Wallet passphrase was successfully changed. - Pristupna fraza novcanika je uspesno promenjena. - BanTableModel @@ -229,18 +74,11 @@ BitcoinGUI - - Bitcoin Core - Bitcoin Core - Error Greska - - ClientModel - CoinControlDialog @@ -251,10 +89,6 @@ Date Datum - - (no label) - (bez etikete) - EditAddressDialog @@ -264,17 +98,9 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - Intro - - Bitcoin Core - Bitcoin Core - Error Greska @@ -289,9 +115,6 @@ OverviewPage - - PaymentServer - PeerTableModel @@ -302,9 +125,6 @@ Kolicina - - QRImageWidget - RPCConsole @@ -313,52 +133,9 @@ ReceiveRequestDialog - - Address - Adresa - - - Amount - Kolicina - - - Label - Etiketa - - - Message - Poruka - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Etiketa - - - Message - Poruka - - - Amount - Kolicina - - - (no label) - (bez etikete) - SendCoinsDialog - - (no label) - (bez etikete) - SendCoinsEntry @@ -371,252 +148,22 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Razvojni tim Bitcoin Core - TrafficGraphWidget - - TransactionDesc - - %1/offline - %1/van mreze - - - %1/unconfirmed - %1/nepotvrdjeno - - - %1 confirmations - %1 potvrdjeno/ih - - - Status - Stanje/Status - - - Date - Datum - - - Source - Izvor - - - Generated - Generisano - - - From - Od - - - To - Kome - - - own address - sopstvena adresa - - - watch-only - samo za gledanje - - - label - etiketa - - - Credit - Kredit - - - not accepted - nije prihvaceno - - - Debit - Zaduzenje - - - Total debit - Ukupno zaduzenje - - - Total credit - Totalni kredit - - - Transaction fee - Taksa transakcije - - - Net amount - Neto iznos - - - Message - Poruka - - - Comment - Komentar - - - Transaction ID - ID Transakcije - - - Merchant - Trgovac - - - Debug information - Informacije debugovanja - - - Transaction - Transakcije - - - Inputs - Unosi - - - Amount - Kolicina - - - true - tacno - - - false - netacno - - - , has not been successfully broadcast yet - , nisu uspesno jos emitovano - - - unknown - nepoznato - - TransactionDescDialog - - Transaction details - Detalji transakcije - - - - TransactionTableModel - - Date - Datum - - - Type - Tip - - - Label - Etiketa - - - Received with - Primljeno uz - - - Received from - Primljeno od - - - Sent to - Poslat - - - Payment to yourself - Placanje samom sebi - - - Mined - Iskopano - - - watch-only - samo za gledanje - - - - TransactionView - - Received with - Primljeno uz - - - Sent to - Poslat - - - Mined - Iskopano - - - Exporting Failed - Izvoz nije uspeo - - - Comma separated file (*.csv) - Zarezom odvojene ('.csv) datoteke - - - Date - Datum - - - Type - Tip - - - Label - Etiketa - - - Address - Adresa - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Izvoz - - - Export the data in the current tab to a file - Izvoz podataka iz trenutne kartice u datoteku - - bitcoin-core + + Bitcoin Core + Bitcoin Core + Insufficient funds Nedovoljno sredstava diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index acf37bd1d..a637cebe2 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -25,10 +25,6 @@ C&lose S&täng - - &Copy Address - &Kopiera adress - Delete the currently selected address from the list Ta bort den valda adressen från listan @@ -45,74 +41,6 @@ &Delete &Radera - - Choose the address to send coins to - Välj en adress att sända betalning till - - - Choose the address to receive coins with - Välj en adress att ta emot betalning till - - - C&hoose - V&älj - - - Sending addresses - Avsändaradresser - - - Receiving addresses - Mottagaradresser - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Detta är dina Bitcoin-adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Detta är dina Bitcoin-adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion. - - - Copy &Label - Kopiera &etikett - - - &Edit - &Ändra - - - Export Address List - Exportera adresslistan - - - Comma separated file (*.csv) - Kommaseparerad fil (*.csv) - - - Exporting Failed - Exporteringen misslyckades - - - There was an error trying to save the address list to %1. Please try again. - Det inträffade ett fel när adresslistan skulle sparas till %1. -Var vänlig och försök igen. - - - - AddressTableModel - - Label - Etikett - - - Address - Adress - - - (no label) - (ingen etikett) - AskPassphraseDialog @@ -132,94 +60,6 @@ Var vänlig och försök igen. Repeat new passphrase Upprepa nytt lösenord - - Encrypt wallet - Kryptera plånbok - - - This operation needs your wallet passphrase to unlock the wallet. - Denna operation behöver din plånboks lösenord för att låsa upp plånboken. - - - Unlock wallet - Lås upp plånbok - - - This operation needs your wallet passphrase to decrypt the wallet. - Denna operation behöver din plånboks lösenord för att dekryptera plånboken. - - - Decrypt wallet - Dekryptera plånbok - - - Change passphrase - Ändra lösenord - - - Confirm wallet encryption - Bekräfta kryptering av plånbok - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - VARNING: Om du krypterar din plånbok och glömmer ditt lösenord, kommer du att <b>FÖRLORA ALLA DINA TILLGÅNGAR</b>! - - - Are you sure you wish to encrypt your wallet? - Är du säker på att du vill kryptera din plånbok? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core kommer att stängas för att slutföra krypteringsprocessen. Kom ihåg att plånbokskryptering inte garanterar fullt skydd mot skadlig kod på din dator. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - VIKTIGT: Alla tidigare säkerhetskopior du har gjort av plånbokens fil ska ersättas med den nya genererade, krypterade plånboks filen. Av säkerhetsskäl kommer tidigare säkerhetskopior av den okrypterade plånboks filen blir oanvändbara när du börjar använda en ny, krypterad plånbok. - - - Warning: The Caps Lock key is on! - Varning: Caps Lock är påslaget! - - - Wallet encrypted - Plånboken är krypterad - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Ange plånbokens nya lösenord. <br/> Använd ett lösenord på <b>tio eller fler slumpmässiga tecken,</b> eller <b>åtta eller fler ord.</b>. - - - Enter the old passphrase and new passphrase to the wallet. - Ge det gamla lösenordet och det nya lösenordet för plånboken. - - - Wallet encryption failed - Kryptering av plånbok misslyckades - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Kryptering av plånbok misslyckades på grund av ett internt fel. Din plånbok blev inte krypterad. - - - The supplied passphrases do not match. - De angivna lösenorden överensstämmer inte. - - - Wallet unlock failed - Upplåsning av plånbok misslyckades - - - The passphrase entered for the wallet decryption was incorrect. - Lösenordet för dekryptering av plånbok var felaktig. - - - Wallet decryption failed - Dekryptering av plånbok misslyckades - - - Wallet passphrase was successfully changed. - Plånbokens lösenord har ändrats. - BanTableModel @@ -270,6 +110,14 @@ Var vänlig och försök igen. Quit application Avsluta programmet + + &About %1 + &Om %1 + + + Show information about %1 + Visa information om %1 + About &Qt Om &Qt @@ -282,6 +130,10 @@ Var vänlig och försök igen. &Options... &Alternativ... + + Modify configuration options for %1 + Ändra konfigurationsalternativ för %1 + &Encrypt Wallet... &Kryptera plånbok... @@ -306,14 +158,6 @@ Var vänlig och försök igen. Open &URI... Öppna &URI... - - Bitcoin Core client - Bitcoin Core-klient - - - Importing blocks from disk... - Importerar block från disk... - Reindexing blocks on disk... Återindexerar block på disken... @@ -358,10 +202,6 @@ Var vänlig och försök igen. &Receive &Ta emot - - Show information about Bitcoin Core - Visa information om Bitcoin Core - &Show / Hide &Visa / Göm @@ -398,22 +238,10 @@ Var vänlig och försök igen. Tabs toolbar Verktygsfält för tabbar - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Begär betalning (genererar QR-koder och bitcoin-URI) - - &About Bitcoin Core - &Om Bitcoin Core - - - Modify configuration options for Bitcoin Core - Ändra konfigurationsalternativ för Bitcoin Core - Show the list of used sending addresses and labels Visa listan av använda avsändaradresser och etiketter @@ -430,14 +258,18 @@ Var vänlig och försök igen. &Command-line options &Kommandoradsalternativ - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Visa Bitcoin Cores hjälpmeddelande för att få en lista med möjliga Bitcoin-kommandoradsalternativ. - %n active connection(s) to Bitcoin network %n aktiva anslutningar till Bitcoin-nätverket.%n aktiva anslutningar till Bitcoin-nätverket. + + Indexing blocks on disk... + Indexerar block på disken... + + + Processing blocks on disk... + Bearbetar block på disken... + No block source available... Ingen block-källa tillgänglig... @@ -494,6 +326,14 @@ Var vänlig och försök igen. Up to date Uppdaterad + + Show the %1 help message to get a list with possible Bitcoin command-line options + Visa %1 hjälpmeddelande för att få en lista med möjliga Bitcoin kommandoradsalternativ. + + + %1 client + %1-klient + Catching up... Hämtar senaste... @@ -545,13 +385,6 @@ Var vänlig och försök igen. Denna plånbok är <b>krypterad</b> och för närvarande <b>låst</b> - - ClientModel - - Network Alert - Nätverkslarm - - CoinControlDialog @@ -630,150 +463,6 @@ Var vänlig och försök igen. Priority Prioritet - - Copy address - Kopiera adress - - - Copy label - Kopiera etikett - - - Copy amount - Kopiera belopp - - - Copy transaction ID - Kopiera transaktions ID - - - Lock unspent - Lås ospenderat - - - Unlock unspent - Lås upp ospenderat - - - Copy quantity - Kopiera kvantitet - - - Copy fee - Kopiera avgift - - - Copy after fee - Kopiera efter avgift - - - Copy bytes - Kopiera byte - - - Copy priority - Kopiera prioritet - - - Copy dust - Kopiera damm - - - Copy change - Kopiera växel - - - highest - högst - - - higher - högre - - - high - hög - - - medium-high - medelhög - - - medium - medel - - - low-medium - lågmedel - - - low - låg - - - lower - lägre - - - lowest - lägst - - - (%1 locked) - (%1 låst) - - - none - ingen - - - This label turns red if the transaction size is greater than 1000 bytes. - Denna etikett blir röd om transaktionens storlek är större än 1000 bytes. - - - This label turns red if the priority is smaller than "medium". - Denna etikett blir röd om prioriteten är lägre än "medium". - - - This label turns red if any recipient receives an amount smaller than %1. - Denna etikett blir röd om någon mottagare får ett belopp mindre än %1. - - - Can vary +/- %1 satoshi(s) per input. - Kan variera +/- %1 satoshi per inmatning. - - - yes - ja - - - no - nej - - - This means a fee of at least %1 per kB is required. - Detta betyder att en avgift på minst %1 per kB behövs. - - - Can vary +/- 1 byte per input. - Kan variera +/- 1 byte per inmatning. - - - Transactions with higher priority are more likely to get included into a block. - Transaktioner med högre prioritet har större sannolikhet att inkluderas i ett block. - - - (no label) - (Ingen etikett) - - - change from %1 (%2) - växel från %1 (%2) - - - (change) - (växel) - EditAddressDialog @@ -797,38 +486,6 @@ Var vänlig och försök igen. &Address &Adress - - New receiving address - Ny mottagaradress - - - New sending address - Ny avsändaradress - - - Edit receiving address - Redigera mottagaradress - - - Edit sending address - Redigera avsändaradress - - - The entered address "%1" is already in the address book. - Den angivna adressen "%1" finns redan i adressboken. - - - The entered address "%1" is not a valid Bitcoin address. - Den angivna adressen "%1" är inte en giltig Bitcoin-adress. - - - Could not unlock wallet. - Plånboken kunde inte låsas upp. - - - New key generation failed. - Misslyckades med generering av ny nyckel. - FreespaceChecker @@ -855,10 +512,6 @@ Var vänlig och försök igen. HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version @@ -868,8 +521,8 @@ Var vänlig och försök igen. (%1-bit) - About Bitcoin Core - Om Bitcoin Core + About %1 + Om %1 Command-line options @@ -908,8 +561,8 @@ Var vänlig och försök igen. Visa startbild vid uppstart (standard: %u) - Reset all settings changes made over the GUI - Återställ alla inställningar som gjorts över GUI + Reset all settings changed in the GUI + Återställ alla inställningar som gjorts i GUI @@ -919,16 +572,16 @@ Var vänlig och försök igen. Välkommen - Welcome to Bitcoin Core. - Välkommen till Bitcoin Core. + Welcome to %1. + Välkommen till %1. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sina data. + As this is the first time the program is launched, you can choose where %1 will store its data. + Eftersom detta är första gången programmet startas får du välja var %1 skall lagra sitt data. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin-blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 kommer att ladda ner och spara en kopia av Bitcoin blockkedjan. Åtminstone %2GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog. Use the default data directory @@ -938,10 +591,6 @@ Var vänlig och försök igen. Use a custom data directory: Använd en anpassad datakatalog: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Fel: Den angivna datakatalogen "%1" kan inte skapas. @@ -977,10 +626,6 @@ Var vänlig och försök igen. Select payment request file Välj betalningsbegäransfil - - Select payment request file to open - Välj betalningsbegäransfil att öppna - OptionsDialog @@ -992,6 +637,14 @@ Var vänlig och försök igen. &Main &Allmänt + + Automatically start %1 after logging in to the system. + Starta %1 automatiskt efter inloggningen. + + + &Start %1 on system login + &Starta %1 vid systemlogin + Size of &database cache Storleken på &databascache @@ -1020,10 +673,6 @@ Var vänlig och försök igen. 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. Minimera istället för att stänga programmet när fönstret stängs. När detta alternativ är aktiverat stängs programmet endast genom att välja Stäng i menyn. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Gränssnittets språk kan väljas här. Denna inställning träder i kraft efter omstart av Bitcoin Core. - 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 |. Tredjeparts URL:er (t.ex. en blockutforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |. @@ -1048,14 +697,6 @@ Var vänlig och försök igen. &Network &Nätverk - - Automatically start Bitcoin Core after logging in to the system. - Kör Bitcoin Core automatiskt vid systeminloggning. - - - &Start Bitcoin Core on system login - &Kör Bitcoin Core vid systeminloggning - (0 = auto, <0 = leave that many cores free) (0 = auto, <0 = lämna så många kärnor lediga) @@ -1140,6 +781,14 @@ Var vänlig och försök igen. &Window &Fönster + + &Hide the icon from the system tray. + &Göm ikonen från systemfältet. + + + Hide tray icon + Göm systemfältsikonen + Show only a tray icon after minimizing the window. Visa endast en systemfältsikon vid minimering. @@ -1160,6 +809,10 @@ Var vänlig och försök igen. User Interface &language: Användargränssnittets &språk: + + The user interface language can be set here. This setting will take effect after restarting %1. + Användargränssnittets språk kan ställas in här. Denna inställning träder i kraft efter en omstart av %1. + &Unit to show amounts in: &Måttenhet att visa belopp i: @@ -1284,97 +937,6 @@ Var vänlig och försök igen. Nuvarande total balans i granska-bara adresser - - PaymentServer - - URI handling - URI hantering - - - Invalid payment address %1 - Felaktig betalningsadress %1 - - - Payment request rejected - Betalningsbegäran avslogs - - - Payment request network doesn't match client network. - Betalningsbegärans nätverk matchar inte klientens nätverk. - - - Payment request is not initialized. - Betalningsbegäran är inte initierad. - - - Requested payment amount of %1 is too small (considered dust). - Begärd betalning av %1 är för liten (betraktas som damm). - - - Payment request error - Fel vid betalningsbegäran - - - Cannot start bitcoin: click-to-pay handler - Kan inte starta bitcoin: klicka-och-betala handhavare - - - Payment request fetch URL is invalid: %1 - Betalningsbegärans hämta URL är felaktig: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI går inte att tolkas! Detta kan orsakas av en ogiltig Bitcoin-adress eller felaktiga URI parametrar. - - - Payment request file handling - Hantering av betalningsbegäransfil - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Betalningsbegäransfilen kan inte läsas! Detta kan orsakas av en felaktig betalningsbegäransfil. - - - Payment request expired. - Betalningsbegäran löpte ut. - - - Unverified payment requests to custom payment scripts are unsupported. - Overifierade betalningsbegärningar till specialbetalningsskript stöds inte. - - - Invalid payment request. - Ogiltig betalningsbegäran. - - - Refund from %1 - Återbetalning från %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Betalningsbegäran %1 är för stor (%2 bytes, tillåten %3 bytes) - - - Error communicating with %1: %2 - Kommunikationsfel med %1: %2 - - - Payment request cannot be parsed! - Betalningsbegäran kan inte behandlas! - - - Bad response from server %1 - Dåligt svar från server %1 - - - Payment acknowledged - Betalningen bekräftad - - - Network request error - Fel vid närverksbegäran - - PeerTableModel @@ -1429,25 +991,6 @@ Var vänlig och försök igen. %1 ms - - QRImageWidget - - &Save Image... - &Spara Bild... - - - &Copy Image - &Kopiera Bild - - - Save QR Code - Spara QR-kod - - - PNG Image (*.png) - PNG-bild (*.png) - - RPCConsole @@ -1478,6 +1021,10 @@ Var vänlig och försök igen. Using BerkeleyDB version Använder BerkeleyDB versionen + + Datadir + Datakatalog + Startup time Uppstartstid @@ -1514,10 +1061,6 @@ Var vänlig och försök igen. Memory usage Minnesåtgång - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor. - Received Mottagen @@ -1566,6 +1109,18 @@ Var vänlig och försök igen. User Agent Användaragent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Öppna %1 debug-loggfilen från aktuell datakatalog. Detta kan ta några sekunder för stora loggfiler. + + + Decrease font size + Minska fontstorleken + + + Increase font size + Öka fontstorleken + Services Tjänster @@ -1634,10 +1189,6 @@ Var vänlig och försök igen. Out: Ut: - - Build date - Kompileringsdatum - Debug log file Debugloggfil @@ -1675,8 +1226,8 @@ Var vänlig och försök igen. &Ta bort ban från nod - Welcome to the Bitcoin Core RPC console. - Välkommen till RPC-konsolen för Bitcoin Core. + Welcome to the %1 RPC console. + Välkommen till %1 RPC-konsolen. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1805,18 +1356,6 @@ Var vänlig och försök igen. Remove Ta bort - - Copy label - Kopiera etikett - - - Copy message - Kopiera meddelande - - - Copy amount - Kopiera belopp - ReceiveRequestDialog @@ -1836,73 +1375,6 @@ Var vänlig och försök igen. &Save Image... &Spara Bild... - - Request payment to %1 - Begär betalning till %1 - - - Payment information - Betalningsinformation - - - URI - URI - - - Address - Adress - - - Amount - Mängd - - - Label - Etikett - - - Message - Meddelande - - - Resulting URI too long, try to reduce the text for label / message. - URI:n är för lång, försöka minska texten för etikett / meddelande. - - - Error encoding URI into QR Code. - Fel vid skapande av QR-kod från URI. - - - - RecentRequestsTableModel - - Date - Datum - - - Label - Etikett - - - Message - Meddelande - - - Amount - Mängd - - - (no label) - (Ingen etikett) - - - (no message) - (inget meddelande) - - - (no amount) - (ingen summa) - SendCoinsDialog @@ -2022,14 +1494,6 @@ Var vänlig och försök igen. fast snabb - - Send as zero-fee transaction if possible - Sänd som nollavgiftstransaktion om möjligt - - - (confirmation may take longer) - (bekräftelse kan ta längre tid) - Send to multiple recipients at once Skicka till flera mottagare samtidigt @@ -2062,118 +1526,6 @@ Var vänlig och försök igen. S&end &Skicka - - Confirm send coins - Bekräfta skickade mynt - - - %1 to %2 - %1 till %2 - - - Copy quantity - Kopiera kvantitet - - - Copy amount - Kopiera belopp - - - Copy fee - Kopiera avgift - - - Copy after fee - Kopiera efter avgift - - - Copy bytes - Kopiera byte - - - Copy priority - Kopiera prioritet - - - Copy change - Kopiera växel - - - Total Amount %1 - Total summa %1 - - - or - eller - - - The amount to pay must be larger than 0. - Det betalade beloppet måste vara större än 0. - - - The amount exceeds your balance. - Värdet överstiger ditt saldo. - - - The total exceeds your balance when the %1 transaction fee is included. - Totalvärdet överstiger ditt saldo när transaktionsavgiften %1 är pålagd. - - - Transaction creation failed! - Transaktionen gick inte att skapa! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Transaktionen avslogs! Detta kan hända om några av mynten i plånboken redan spenderats, t.ex om du använt en kopia av wallet.dat och mynt spenderades i kopian men inte markerats som spenderade här. - - - A fee higher than %1 is considered an absurdly high fee. - En avgift som är högre än %1 anses vara en orimligt hög avgift. - - - Payment request expired. - Betalningsbegäran löpte ut. - - - Pay only the required fee of %1 - Betala endast den nödvändiga avgiften på %1 - - - Estimated to begin confirmation within %n block(s). - Uppskattas till att påbörja bekräftelse inom %n block.Uppskattas till att påbörja bekräftelse inom %n block. - - - The recipient address is not valid. Please recheck. - Mottagarens adress är ogiltig. Kontrollera igen. - - - Duplicate address found: addresses should only be used once each. - Duplicerad adress upptäckt: adresser skall endast användas en gång var. - - - Warning: Invalid Bitcoin address - Varning: Felaktig Bitcoinadress - - - (no label) - (Ingen etikett) - - - Warning: Unknown change address - Varning: Okänd växeladress - - - Copy dust - Kopiera damm - - - Are you sure you want to send? - Är du säker på att du vill skicka? - - - added as transaction fee - adderad som transaktionsavgift - SendCoinsEntry @@ -2185,10 +1537,6 @@ Var vänlig och försök igen. Pay &To: Betala &Till: - - Enter a label for this address to add it to your address book - Ange ett namn för den här adressen och lägg till den i din adressbok - &Label: &Etikett: @@ -2261,8 +1609,8 @@ Var vänlig och försök igen. ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Core stängs av... + %1 is shutting down... + %1 stängs av... Do not shut down the computer until this window disappears. @@ -2355,69 +1703,9 @@ Var vänlig och försök igen. Reset all verify message fields Rensa alla fält - - Click "Sign Message" to generate signature - Klicka "Signera Meddelande" för att få en signatur - - - The entered address is invalid. - Den angivna adressen är ogiltig. - - - Please check the address and try again. - Vad god kontrollera adressen och försök igen. - - - The entered address does not refer to a key. - Den angivna adressen refererar inte till en nyckel. - - - Wallet unlock was cancelled. - Upplåsningen av plånboken avbröts. - - - Private key for the entered address is not available. - Privata nyckel för den angivna adressen är inte tillgänglig. - - - Message signing failed. - Signeringen av meddelandet misslyckades. - - - Message signed. - Meddelandet är signerat. - - - The signature could not be decoded. - Signaturen kunde inte avkodas. - - - Please check the signature and try again. - Kontrollera signaturen och försök igen. - - - The signature did not match the message digest. - Signaturen matchade inte meddelandesammanfattningen. - - - Message verification failed. - Meddelandet verifikation misslyckades. - - - Message verified. - Meddelandet är verifierad. - SplashScreen - - Bitcoin Core - Bitcoin Kärna - - - The Bitcoin Core developers - Bitcoin Core-utvecklarna - [testnet] [testnet] @@ -2430,422 +1718,13 @@ Var vänlig och försök igen. KB/s - - TransactionDesc - - Open until %1 - Öppet till %1 - - - conflicted - konflikterade - - - %1/offline - %1/nerkopplad - - - %1/unconfirmed - %1/obekräftade - - - %1 confirmations - %1 bekräftelser - - - Status - Status - - - , broadcast through %n node(s) - , sänd genom %n nod, sänd genom %n noder - - - Date - Datum - - - Source - Källa - - - Generated - Genererad - - - From - Från - - - To - Till - - - own address - egen adress - - - watch-only - granska-bara - - - label - etikett - - - Credit - Kredit - - - matures in %n more block(s) - mognar om %n fler blockmognar om %n fler block - - - not accepted - inte accepterad - - - Debit - Belasta - - - Total debit - Total skuld - - - Total credit - Total kredit - - - Transaction fee - Transaktionsavgift - - - Net amount - Nettobelopp - - - Message - Meddelande - - - Comment - Kommentar - - - Transaction ID - Transaktions-ID - - - Merchant - Handlare - - - 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. - Genererade mynt måste vänta %1 block innan de kan användas. När du skapade detta block sändes det till nätverket för att läggas till i blockkedjan. Om blocket inte kommer in i kedjan kommer dess status att ändras till "accepteras inte" och kommer ej att gå att spendera. Detta kan ibland hända om en annan nod genererar ett block nästan samtidigt som dig. - - - Debug information - Debug information - - - Transaction - Transaktion - - - Inputs - Inputs - - - Amount - Mängd - - - true - sant - - - false - falsk - - - , has not been successfully broadcast yet - , har inte lyckats skickas ännu - - - Open for %n more block(s) - Öppet för %n mer blockÖppet för %n mer block - - - unknown - okänd - - TransactionDescDialog - - Transaction details - Transaktionsdetaljer - This pane shows a detailed description of the transaction Den här panelen visar en detaljerad beskrivning av transaktionen - - TransactionTableModel - - Date - Datum - - - Type - Typ - - - Immature (%1 confirmations, will be available after %2) - Omogen (%1 konfirmeringar, blir tillgänglig efter %2) - - - Open for %n more block(s) - Öppet för %n mer blockÖppet för %n mer block - - - Open until %1 - Öppet till %1 - - - Confirmed (%1 confirmations) - Bekräftad (%1 bekräftelser) - - - This block was not received by any other nodes and will probably not be accepted! - Det här blocket togs inte emot av några andra noder och kommer antagligen inte att bli godkänt. - - - Generated but not accepted - Genererad men inte accepterad - - - Offline - Nerkopplad - - - Label - Etikett - - - Unconfirmed - Okonfirmerade - - - Confirming (%1 of %2 recommended confirmations) - Konfirmerar (%1 of %2 konfirmeringar) - - - Conflicted - Konflikterade - - - Received with - Mottagen med - - - Received from - Mottaget från - - - Sent to - Skickad till - - - Payment to yourself - Betalning till dig själv - - - Mined - Genererade - - - watch-only - granska-bara - - - (n/a) - (n/a) - - - Transaction status. Hover over this field to show number of confirmations. - Transaktionsstatus. Håll muspekaren över för att se antal bekräftelser. - - - Date and time that the transaction was received. - Tidpunkt då transaktionen mottogs. - - - Type of transaction. - Transaktionstyp. - - - Whether or not a watch-only address is involved in this transaction. - Anger om granska-bara--adresser är involverade i denna transaktion. - - - User-defined intent/purpose of the transaction. - Användardefinierat syfte/ändamål för transaktionen. - - - Amount removed from or added to balance. - Belopp draget eller tillagt till balans. - - - - TransactionView - - All - Alla - - - Today - Idag - - - This week - Denna vecka - - - This month - Denna månad - - - Last month - Föregående månad - - - This year - Det här året - - - Range... - Period... - - - Received with - Mottagen med - - - Sent to - Skickad till - - - To yourself - Till dig själv - - - Mined - Genererade - - - Other - Övriga - - - Enter address or label to search - Sök efter adress eller etikett - - - Min amount - Minsta mängd - - - Copy address - Kopiera adress - - - Copy label - Kopiera etikett - - - Copy amount - Kopiera belopp - - - Copy transaction ID - Kopiera transaktions ID - - - Copy raw transaction - Kopiera rå transaktion - - - Edit label - Ändra etikett - - - Show transaction details - Visa transaktionsdetaljer - - - Export Transaction History - Exportera Transaktionshistoriken - - - Watch-only - Granska-bara - - - Exporting Failed - Exporteringen misslyckades - - - There was an error trying to save the transaction history to %1. - Det inträffade ett fel när transaktionshistoriken skulle sparas till %1. - - - Exporting Successful - Exporteringen lyckades - - - The transaction history was successfully saved to %1. - Transaktionshistoriken sparades utan problem till %1. - - - Comma separated file (*.csv) - Kommaseparerad fil (*.csv) - - - Confirmed - Bekräftad - - - Date - Datum - - - Type - Typ - - - Label - Etikett - - - Address - Adress - - - ID - ID - - - Range: - Intervall: - - - to - till - - UnitDisplayStatusBarControl @@ -2853,55 +1732,6 @@ Var vänlig och försök igen. &Enhet att visa belopp i. Klicka för att välja annan enhet. - - WalletFrame - - No wallet has been loaded. - Ingen plånbok har laddats in. - - - - WalletModel - - Send Coins - Skicka pengar - - - - WalletView - - &Export - &Exportera - - - Export the data in the current tab to a file - Exportera informationen i den nuvarande fliken till en fil - - - Backup Wallet - Säkerhetskopiera Plånbok - - - Wallet Data (*.dat) - Plånboks-data (*.dat) - - - Backup Failed - Säkerhetskopiering misslyckades - - - There was an error trying to save the wallet data to %1. - Det inträffade ett fel när plånbokens data skulle sparas till %1. - - - The wallet data was successfully saved to %1. - Plånbokens data sparades utan problem till %1. - - - Backup Successful - Säkerhetskopiering lyckades - - bitcoin-core @@ -2928,14 +1758,6 @@ Var vänlig och försök igen. If <category> is not supplied or if <category> = 1, output all debugging information. Om <kategori> inte anges eller om <category> = 1, visa all avlusningsinformation. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Maximal total avgift (i %s) att använda i en plånbokstransaktion. Sätts denna för lågtkan stora transaktioner komma att avbrytas (förvalt: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Vänligen kontrollera att din dators datum och tid är korrekt! Om din klocka går fel kommer Bitcoin Core inte att fungera ordentligt. - Prune configured below the minimum of %d MiB. Please use a higher number. Beskärning konfigurerad under miniminivån %d MiB. Vänligen använd ett högre värde. @@ -2976,6 +1798,10 @@ Var vänlig och försök igen. Accept connections from outside (default: 1 if no -proxy or -connect) Acceptera anslutningar utifrån (förvalt: 1 om ingen -proxy eller -connect) + + Bitcoin Core + Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee är satt väldigt högt! Detta är avgiften du kan komma att betala om uppskattad avgift inte finns tillgänglig. @@ -2992,6 +1818,10 @@ Var vänlig och försök igen. Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Kan inte låsa data-mappen %s. %s körs förmodligen redan. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart @@ -3000,6 +1830,14 @@ Var vänlig och försök igen. Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Fel vid laddning av %s: Du kan inte aktivera HD på en existerande icke-HD plånbok + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Fel vid läsning av %s! Alla nycklar lästes korrekt, men transaktionsdatat eller adressbokens poster kanske saknas eller är felaktiga. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID) @@ -3008,6 +1846,22 @@ Var vänlig och försök igen. Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Vidarebefodra alltid transaktioner från vitlistade noder även om de bryter mot lokala reläpolicyn (förvalt: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Maximalt tillåten median-peer tidsoffset justering. Lokalt perspektiv av tiden kan bli påverkad av partners, framåt eller bakåt denna tidsrymd. (förvalt: %u sekunder) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maximal total avgift (i %s) att använda i en plånbokstransaktion eller råa transaktioner. Sätts denna för lågt kan stora transaktioner avbrytas (förvalt: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Vänligen kolla så att din dators datum och tid är korrekt! Om din klocka går fel kommer %s inte att fungera korrekt. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Var snäll och bidra om du finner %s användbar. Besök %s för mer information om mjukvaran. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Ange antalet skriptkontrolltrådar (%u till %d, 0 = auto, <0 = lämna så många kärnor lediga, förval: %d) @@ -3020,14 +1874,6 @@ Var vänlig och försök igen. This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Detta är ett förhands testbygge - använd på egen risk - använd inte för mining eller handels applikationer - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Det går inte att binda till %s på den här datorn. Bitcoin Core är förmodligen redan igång. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Argumentet -whitelistalwaysrelay stöds inte utan ignoreras, använd -whitelistrelay och/eller -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Använd UPnP för att mappa den lyssnande porten (förvalt: 1 när lyssning aktiverat och utan -proxy) @@ -3044,22 +1890,22 @@ Var vänlig och försök igen. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varning: Nätverket verkar inte vara helt överens! Några miners verkar ha problem. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - Varning: Okända blockversioner bryts! Det är möjligt att okända regler används - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Varning: Vi verkar inte helt överens med våra peers! Du kan behöva uppgradera, eller andra noder kan behöva uppgradera. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Varning: wallet.dat korrupt, datan har räddats! Den ursprungliga wallet.dat har sparas som wallet.{timestamp}.bak i %s; om ditt saldo eller transaktioner är felaktiga ska du återställa från en säkerhetskopia. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Du måste återskapa databasen med -reindex-chainstate för att ändra -txindex + + + %s corrupt, salvage failed + %s är korrupt, räddning misslyckades + -maxmempool must be at least %d MB -maxmempool måste vara minst %d MB @@ -3072,10 +1918,22 @@ Var vänlig och försök igen. Append comment to the user agent string Lägg till kommentar till user-agent-strängen + + Attempt to recover private keys from a corrupt wallet on startup + Försök att rädda privata nycklar från en korrupt plånbok vid uppstart + Block creation options: Block skapande inställningar: + + Cannot resolve -%s address: '%s' + Kan inte matcha -%s adress: '%s' + + + Change index out of range + Förändringsindexet utom räckhåll + Connect only to the specified node(s) Koppla enbart upp till den/de specificerade noden/noder @@ -3084,6 +1942,10 @@ Var vänlig och försök igen. Connection options: Anslutningsalternativ: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Korrupt blockdatabas har upptäckts @@ -3128,6 +1990,22 @@ Var vänlig och försök igen. Error initializing wallet database environment %s! Fel vid initiering av plånbokens databasmiljö %s! + + Error loading %s + Fel vid inläsning av %s + + + Error loading %s: Wallet corrupted + Fel vid inläsningen av %s: Plånboken är koruppt + + + Error loading %s: Wallet requires newer version of %s + Fel vid inläsningen av %s: Plånboken kräver en senare version av %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Fel vid laddning av %s: Du kan inte avaktivera HD på en redan existerande HD plånbok + Error loading block database Fel vid inläsning av blockdatabasen @@ -3152,10 +2030,18 @@ Var vänlig och försök igen. Incorrect or no genesis block found. Wrong datadir for network? Felaktig eller inget genesisblock hittades. Fel datadir för nätverket? + + Initialization sanity check failed. %s is shutting down. + Initieringschecken fallerade. %s stängs av. + Invalid -onion address: '%s' Ogiltig -onion adress:'%s' + + Invalid amount for -%s=<amount>: '%s' + Ogiltigt belopp för -%s=<belopp>:'%s' + Invalid amount for -fallbackfee=<amount>: '%s' Ogiltigt belopp för -fallbackfee=<belopp>: '%s' @@ -3164,6 +2050,10 @@ Var vänlig och försök igen. Keep the transaction memory pool below <n> megabytes (default: %u) Håll minnespoolen över transaktioner under <n> megabyte (förvalt: %u) + + Loading banlist... + Laddar svarta listan... + Location of the auth cookie (default: data dir) Plats för authcookie (förvalt: datamapp) @@ -3180,6 +2070,10 @@ Var vänlig och försök igen. Only connect to nodes in network <net> (ipv4, ipv6 or onion) Anslut enbart till noder i nätverket <net> (IPv4, IPv6 eller onion) + + Print this help message and exit + Visa denna hjälptext och avsluta + Print version and exit Visa version och avsluta @@ -3192,6 +2086,14 @@ Var vänlig och försök igen. Prune mode is incompatible with -txindex. Beskärningsläge är inkompatibel med -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Återskapa blockkedjans status och index från blk*.dat filer på disken + + + Rebuild chain state from the currently indexed blocks + Återskapa blockkedjans status från aktuella indexerade block + Set database cache size in megabytes (%d to %d, default: %d) Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d) @@ -3204,6 +2106,14 @@ Var vänlig och försök igen. Specify wallet file (within data directory) Ange plånboksfil (inom datakatalogen) + + The source code is available from %s. + Källkoden är tillgänglig från %s. + + + Unable to bind to %s on this computer. %s is probably already running. + Det går inte att binda till %s på den här datorn. %s är förmodligen redan igång. + Unsupported argument -benchmark ignored, use -debug=bench. Argumentet -benchmark stöds inte och ignoreras, använd -debug=bench. @@ -3237,12 +2147,16 @@ Var vänlig och försök igen. Plånbok %s ligger utanför datakatalogen %s - Wallet options: - Plånboksinställningar: + Wallet debugging/testing options: + Plånbokens Avlusnings/Testnings optioner: - You need to rebuild the database using -reindex to change -txindex - Du måste återskapa databasen med -reindex för att ändra -txindex + Wallet needed to be rewritten: restart %s to complete + Plånboken behöver sparas om: Starta om %s för att fullfölja + + + Wallet options: + Plånboksinställningar: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3256,10 +2170,6 @@ Var vänlig och försök igen. Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Bind till angiven adress för att lyssna på JSON-RPC-anslutningar. Använd [värd]:port-format for IPv6. Detta alternativ kan anges flera gånger (förvalt: bind till alla gränssnitt) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Kan inte låsa data-mappen %s. Bitcoin Core körs förmodligen redan. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Skapa nya filer med systemets förvalda rättigheter, istället för umask 077 (bara effektivt med avaktiverad plånboks funktionalitet) @@ -3304,10 +2214,6 @@ Var vänlig och försök igen. Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Ange antalet trådar för myntgenerering om påslagen (-1= alla kärnor, förval: %d) - The transaction amount is too small to send after the fee has been deducted Transaktionen är för liten att skicka efter det att avgiften har dragits @@ -3316,6 +2222,10 @@ Var vänlig och försök igen. This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Denna produkten innehåller mjukvara utvecklad av OpenSSL Project för användning i OpenSSL Toolkit <https://www.openssl.org/> och kryptografisk mjukvara utvecklad av Eric Young samt UPnP-mjukvara skriven av Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Använd hierarkisk deterministisk nyckel generering (HD) efter BIP32. Har bara effekt under plånbokens skapande/första användning. + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Vitlistade klienter kan inte bli DoS-bannade och deras transaktioner reläas alltid, även om dom redan är i mempoolen, användbart för t.ex en gateway @@ -3332,34 +2242,14 @@ Var vänlig och försök igen. Accept public REST requests (default: %u) Acceptera publika REST förfrågningar (förvalt: %u) - - Activating best chain... - Aktiverar bästa kedjan... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Försök att rädda privata nycklar från en korrupt wallet.dat vid uppstart - Automatically create Tor hidden service (default: %d) Skapa automatiskt dold tjänst i Tor (förval: %d) - - Cannot resolve -whitebind address: '%s' - Kan inte matcha -whitebind adress: '%s' - Connect through SOCKS5 proxy Anslut genom SOCKS5 proxy - - Copyright (C) 2009-%i The Bitcoin Core Developers - Copyright (C) 2009-%i Bitcoin Core Utvecklarna - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Fel vid inläsningen av wallet.dat: Kontofilen kräver en senare version av Bitcoin Core - Error reading from database, shutting down. Fel vid läsning från databas, avslutar. @@ -3372,22 +2262,6 @@ Var vänlig och försök igen. Information Information - - Initialization sanity check failed. Bitcoin Core is shutting down. - Initieringschecken fallerade. Bitcoin Core stängs av... - - - Invalid amount for -maxtxfee=<amount>: '%s' - Otillåtet belopp för -maxtxfee=<belopp>: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Ogiltigt belopp för -minrelaytxfee=<belopp>: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - Ogiltigt belopp för -mintxfee=<belopp>: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Ogiltigt belopp för -paytxfee=<belopp>:'%s' (måste vara minst %s) @@ -3412,14 +2286,6 @@ Var vänlig och försök igen. RPC server options: RPC-serveralternativ: - - Rebuild block chain index from current blk000??.dat files on startup - Återskapa blockkedjans index från nuvarande blk000??.dat filer under uppstarten - - - Receive and display P2P network alerts (default: %u) - Mottag och visa P2P nätverksvarningar (förvalt: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Minskar -maxconnections från %d till %d, på grund av systembegränsningar. @@ -3492,10 +2358,6 @@ Var vänlig och försök igen. Username for JSON-RPC connections Användarnamn för JSON-RPC-anslutningar - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Kontot behöver sparas om: Starta om Bitcoin Core för att fullfölja - Warning Varning @@ -3516,10 +2378,6 @@ Var vänlig och försök igen. ZeroMQ notification options: ZeroMQ-alternativ för notiser: - - wallet.dat corrupt, salvage failed - wallet.dat korrupt, räddning misslyckades - Password for JSON-RPC connections Lösenord för JSON-RPC-anslutningar @@ -3528,10 +2386,6 @@ Var vänlig och försök igen. Execute command when the best block changes (%s in cmd is replaced by block hash) Exekvera kommando när det bästa blocket ändras (%s i cmd är utbytt av blockhash) - - This help message - Det här hjälp medelandet - Allow DNS lookups for -addnode, -seednode and -connect Tillåt DNS-sökningar för -addnode, -seednode och -connect @@ -3540,10 +2394,6 @@ Var vänlig och försök igen. Loading addresses... Laddar adresser... - - Error loading wallet.dat: Wallet corrupted - Fel vid inläsningen av wallet.dat: Plånboken är skadad - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata) @@ -3560,10 +2410,6 @@ Var vänlig och försök igen. Do not keep transactions in the mempool longer than <n> hours (default: %u) Håll inte transaktioner i minnespoolen längre än <n> timmar (förvalt: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdata eller adressbokens poster kanske saknas eller är felaktiga. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Avgifter (i %s/kB) mindre än detta anses vara nollavgifter vid skapande av transaktion (standard: %s) @@ -3600,6 +2446,10 @@ Var vänlig och försök igen. Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Argumentet -socks hittades och stöds inte. Det är inte längre möjligt att sätta SOCKS-version längre, bara SOCKS5-proxy stöds. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argumentet -whitelistalwaysrelay stöds inte utan ignoreras, använd -whitelistrelay och/eller -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s) @@ -3608,6 +2458,14 @@ Var vänlig och försök igen. Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Användarnamn och hashat lösenord för JSON-RPC-anslutningar. Fältet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Ett kanoniskt pythonskript finns inkluderat i share/rpcuser. Detta alternativ kan anges flera gånger + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Varning: Okända blockversioner bryts! Det är möjligt att okända regler används + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Varning: Plånboksfilen var korrupt, datat har räddats! Den ursprungliga %s har sparas som %s i %s. Om ditt saldo eller transaktioner är felaktiga bör du återställa från en säkerhetskopia. + (default: %s) (förvalt: %s) @@ -3616,14 +2474,6 @@ Var vänlig och försök igen. Always query for peer addresses via DNS lookup (default: %u) Sök alltid efter klientadresser med DNS sökningen (förvalt: %u) - - Error loading wallet.dat - Fel vid inläsning av plånboksfilen wallet.dat - - - Generate coins (default: %u) - Generera mynt (förvalt: %u) - How many blocks to check at startup (default: %u, 0 = all) Hur många block att kontrollera vid uppstart (förvalt: %u, 0 = alla) @@ -3708,18 +2558,6 @@ Var vänlig och försök igen. Unknown network specified in -onlynet: '%s' Okänt nätverk som anges i -onlynet: '%s' - - Cannot resolve -bind address: '%s' - Kan inte matcha -bind adress: '%s' - - - Cannot resolve -externalip address: '%s' - Kan inte matcha -externalip adress: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - Ogiltigt belopp för -paytxfee=<belopp>:'%s' - Insufficient funds Otillräckligt med bitcoins diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index c93524cda..6878d23fe 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -17,10 +17,6 @@ C&lose &மூடு - - &Copy Address - &முகவரியை நகலெடு - &Export &ஏற்றுமதி @@ -29,44 +25,9 @@ &Delete &அழி - - C&hoose - &தேர்ந்தெடு - - - Sending addresses - அனுப்பும் முகவரிகள் - - - Receiving addresses - பெறும் முகவரிகள் - - - &Edit - &தொகு - - - - AddressTableModel - - Label - லேபிள் - - - Address - விலாசம் - - + AskPassphraseDialog - - Encrypt wallet - என்க்ரிப்ட் பணப்பை - - - Decrypt wallet - டிக்ரிப்ட் பணப்பை - BanTableModel @@ -145,10 +106,6 @@ &Help &உதவி - - Bitcoin Core - Bitcoin மையம் - %n hour(s) %n மணி%n மணி @@ -202,13 +159,6 @@ அனுப்பிய பரிவர்த்தனை - - ClientModel - - Network Alert - பிணைய எச்சரிக்கை - - CoinControlDialog @@ -255,27 +205,7 @@ Priority முன்னுரிமை - - Copy address - பிரதியை முகவரியை - - - Copy amount - நகலை தொகை - - - none - none - - - yes - ஆம் - - - no - இல்லை - - + EditAddressDialog @@ -288,14 +218,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin மையம் - - - About Bitcoin Core - Bitcoin மையம் பற்றி - Intro @@ -303,10 +225,6 @@ Welcome நல்வரவு - - Bitcoin Core - Bitcoin மையம் - Error தவறு @@ -413,9 +331,6 @@ மொத்தம்: - - PaymentServer - PeerTableModel @@ -454,25 +369,6 @@ %1 ms - - QRImageWidget - - &Save Image... - &படத்தை சேமி... - - - &Copy Image - &படத்தை - - - Save QR Code - QR குறியீடு காப்பாற்ற - - - PNG Image (*.png) - PNG படத்தை (*.png) - - RPCConsole @@ -638,14 +534,6 @@ Remove நீக்கு - - Copy message - நகலை செய்தி - - - Copy amount - நகலை தொகை - ReceiveRequestDialog @@ -665,46 +553,7 @@ &Save Image... &படத்தை சேமி... - - URI - URI - - - Address - விலாசம் - - - Amount - விலை - - - Label - லேபிள் - - - Message - செய்தி - - - - RecentRequestsTableModel - - Date - தேதி - - - Label - லேபிள் - - - Message - செய்தி - - - Amount - விலை - - + SendCoinsDialog @@ -755,19 +604,7 @@ S&end &அனுப்பு - - %1 to %2 - %1 to %2 - - - Copy amount - நகலை தொகை - - - or - அல்லது - - + SendCoinsEntry @@ -811,10 +648,6 @@ SplashScreen - - Bitcoin Core - Bitcoin மையம் - TrafficGraphWidget @@ -823,188 +656,18 @@ KB/s - - TransactionDesc - - Status - நிலை - - - Date - தேதி - - - Source - மூலம் - - - Credit - கடன் - - - Debit - பற்று - - - Total debit - மொத்த பற்று - - - Total credit - மொத்த கடன் - - - Net amount - நிகர தொகை - - - Message - செய்தி - - - Comment - கருத்து - - - Transaction ID - பரிவர்த்தனை ID - - - Merchant - வணிகர் - - - Debug information - சரிசெய்வதற்கான தகவல் - - - Transaction - பரிவர்த்தனை - - - Inputs - உள்ளீடுகள் - - - Amount - விலை - - - true - உண்மை - - - false - தவறான - - TransactionDescDialog - - TransactionTableModel - - Date - தேதி - - - Offline - ஆஃப்லைன் - - - Label - லேபிள் - - - (n/a) - (n/a) - - - - TransactionView - - All - முழுவதும் - - - Today - இன்று - - - This week - இந்த வாரம் - - - This month - இந்த மாதம் - - - Last month - கடந்த மாதம் - - - This year - இந்த வருடம் - - - Range... - எல்லை... - - - Other - வேறு - - - Copy address - பிரதியை முகவரியை - - - Copy amount - நகலை தொகை - - - Confirmed - உறுதியாக - - - Date - தேதி - - - Label - லேபிள் - - - Address - விலாசம் - - - ID - ID - - - Range: - எல்லை: - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &ஏற்றுமதி - - bitcoin-core + + Bitcoin Core + Bitcoin மையம் + (default: %u) (default: %u) diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index ba3b1e874..263093914 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -25,10 +25,6 @@ C&lose &ปิด - - &Copy Address - &คัดลอกที่อยู่ - Delete the currently selected address from the list ลบที่อยู่ที่เลือกไว้ในขณะนี้จากรายการ @@ -45,72 +41,13 @@ &Delete &ลบ - - Choose the address to send coins to - เลือกที่อยู่เพื่อส่งเหรียญไปไว้ - - - Choose the address to receive coins with - เลือกที่อยู่เพื่อรับเหรียญไว้ - - - C&hoose - &เลือก - - - Sending addresses - ส่งที่อยู่ - - - Receiving addresses - กำลังรับที่อยู่ - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - ที่อยู่เหล่านี้เป็นที่อยู่ Bitcoin ของคุณ สำหรับใช้เพื่อส่งเงิน กรุณาตรวจสอบจำนวนเงินและที่อยู่สำหรับรับเงินก่อนส่งเหรียญไป - - - Copy &Label - คัดลอก &ป้ายชื่อ - - - &Edit - &แก้ไข - - - Export Address List - ส่งออกรายการที่อยู่ - - - Comma separated file (*.csv) - คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv) - - - Exporting Failed - ส่งออกข้อมูลล้มเหลว - - - There was an error trying to save the address list to %1. Please try again. - พบข้อผิดพลาดบางกระการในการพยายามบันทึกรายชื่อที่อยู่ไปยัง %1. กรุณาลองใหม่อีกครั้ง - - - - AddressTableModel - - Label - ชื่อ - - - Address - ที่อยู่ - - - (no label) - (ไม่มีชื่อ) - AskPassphraseDialog + + Passphrase Dialog + ช่องสำหรับ รหัสผ่าน + Enter passphrase ใส่รหัสผ่าน @@ -123,72 +60,24 @@ Repeat new passphrase กรุณากรอกรหัสผ่านใหม่อีกครั้งหนึ่ง - - Encrypt wallet - กระเป๋าสตางค์ที่เข้ารหัส - - - This operation needs your wallet passphrase to unlock the wallet. - การดำเนินการนี้ต้องมีรหัสผ่านกระเป๋าเงินของคุณเพื่อปลดล็อคกระเป๋าเงิน - - - Unlock wallet - เปิดกระเป๋าสตางค์ - - - This operation needs your wallet passphrase to decrypt the wallet. - การดำเนินการนี้ต้องมีรหัสผ่านกระเป๋าเงินของคุณในการถอดรหัสกระเป๋าเงิน - - - Decrypt wallet - ถอดรหัสกระเป๋าสตางค์ - - - Change passphrase - เปลี่ยนรหัสผ่าน - - - Confirm wallet encryption - ยืนยันการเข้ารหัสกระเป๋าสตางค์ - - - Are you sure you wish to encrypt your wallet? - คุณแน่ใจแล้วหรือว่าต้องการเข้ารหัสกระเป๋าสตางค์ของคุณ? - - - Wallet encrypted - กระเป๋าสตางค์ถูกเข้ารหัสเรียบร้อยแล้ว - - - Wallet encryption failed - การเข้ารหัสกระเป๋าสตางค์ผิดพลาด - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - กระเป๋าเงินเข้ารหัสล้มเหลวเนื่องจากข้อผิดพลาดภายใน กระเป๋าเงินของคุณไม่ได้เข้ารหัส - - - The supplied passphrases do not match. - รหัสผ่านที่คุณกรอกไม่ตรงกัน - - - Wallet unlock failed - ปลดล็อคกระเป๋าเงินล้มเหลว - - - The passphrase entered for the wallet decryption was incorrect. - ป้อนรหัสผ่านสำหรับการถอดรหัสกระเป๋าเงินไม่ถูกต้อง - - - Wallet decryption failed - ถอดรหัสกระเป๋าเงินล้มเหลว - - + BanTableModel - + + IP/Netmask + IP/Netmask (ตัวกรอง IP) + + + Banned Until + ห้าม จนถึง + + BitcoinGUI + + Sign &message... + เซ็นต์ชื่อด้วย &ข้อความ... + Synchronizing with network... กำลังทำข้อมูลให้ตรงกันกับเครือข่าย ... @@ -197,6 +86,10 @@ &Overview &ภาพรวม + + Node + Node/โหนด + Show general overview of wallet แสดงภาพรวมทั่วไปของกระเป๋าเงิน @@ -211,27 +104,83 @@ E&xit - E&ออก + &ออก Quit application ออกจากโปรแกรม + + &About %1 + &เกี่ยวกับ %1 + + + Show information about %1 + แสดงข้อมูล เกี่ยวกับ %1 + About &Qt เกี่ยวกับ &Qt + + Show information about Qt + แสดงข้อมูล เกี่ยวกับ Qt + &Options... &ตัวเลือก... + + Modify configuration options for %1 + ปรับปรุง ข้อมูลการตั้งค่าตัวเลือก สำหรับ %1 + + + &Encrypt Wallet... + &กระเป๋าเงินเข้ารหัส + + + &Backup Wallet... + &สำรองกระเป๋าเงิน... + + + &Change Passphrase... + &เปลี่ยนรหัสผ่าน... + + + &Sending addresses... + &ที่เก็บเงิน ที่จะส่ง bitcoin + + + &Receiving addresses... + &ที่เก็บเงิน ที่จะรับ bitcoin + + + Open &URI... + เปิด &URI + + + Reindexing blocks on disk... + กำลังทำดัชนี ที่เก็บบล็อก ใหม่ ในดิสก์... + + + Send coins to a Bitcoin address + ส่ง coins ไปยัง ที่เก็บ Bitcoin + + + Backup wallet to another location + สำรอง กระเป๋าเงินไปยัง ที่เก็บอื่น + Change the passphrase used for wallet encryption เปลี่ยนรหัสผ่านที่ใช้สำหรับการเข้ารหัสกระเป๋าเงิน &Debug window - &หน้าต่างตรวจสอบข้อผิดพลาด + &หน้าต่าง Debug + + + Open debugging and diagnostic console + เปิด แผลงควบคุม debugging และ diagnostic &Verify message... @@ -243,7 +192,7 @@ Wallet - กระเป๋าสตางค์ + กระเป๋าเงิน &Send @@ -253,6 +202,26 @@ &Receive &รับ + + &Show / Hide + &แสดง / ซ่อน + + + Show or hide the main Window + แสดง หรือ ซ่อน หน้าหลัก + + + Encrypt the private keys that belong to your wallet + เข้ารหัส private keys/ รหัสส่วนตัว สำหรับกระเป๋าเงินของท่าน + + + Sign messages with your Bitcoin addresses to prove you own them + เซ็นชื่อด้วยข้อความ ที่เก็บ Bitcoin เพื่อแสดงว่าท่านเป็นเจ้าของ bitcoin นี้จริง + + + Verify messages to ensure they were signed with specified Bitcoin addresses + ตรวจสอบ ข้อความ เพื่อให้แน่ใจว่า การเซ็นต์ชื่อ ด้วยที่เก็บ Bitcoin แล้ว + &File &ไฟล์ @@ -269,17 +238,135 @@ Tabs toolbar แถบเครื่องมือ + + Request payments (generates QR codes and bitcoin: URIs) + เรียกเก็บ การชำระเงิน (สร้าง QR codes และ bitcoin: URIs) + + + Show the list of used sending addresses and labels + แสดงรายการ ที่เก็บเงินที่จะส่ง bitcoin ออก และป้ายชื่อ ที่ใช้ไปแล้ว + + + Show the list of used receiving addresses and labels + แสดงรายการ ที่เก็บเงินที่จะรับ bitcoin เข้า และป้ายชื่อ ที่ใช้ไปแล้ว + + + Open a bitcoin: URI or payment request + เปิด bitcoin: URI หรือ การเรียกเก็บเงิน (การเรียกให้ชำระเงิน) + + + &Command-line options + &ตัวเลือก Command-line + %n active connection(s) to Bitcoin network - %n ที่ใช้งานการเชื่อมต่อกับเครือข่าย Bitcoin + %n ช่องการเชื่อมต่อที่ใช้งานได้ เพื่อเชื่อมกับเครือข่าย Bitcoin + + + Indexing blocks on disk... + การกำลังสร้างดัชนีของบล็อก ในดิสก์... + + + Processing blocks on disk... + กำลังดำเนินการกับบล็อกในดิสก์... + + + No block source available... + ไม่มีบล็อกเริ่มต้น ให้ใช้ได้... + + + Processed %n block(s) of transaction history. + %n บล็อกในประวัติรายการ ได้รับการดำเนินการเรียบร้อยแล้ว + + + %n hour(s) + %n ชั่วโมง + + + %n day(s) + %n วัน + + + %n week(s) + %n สัปดาห์ + + + %1 and %2 + %1 และ %2 + + + %n year(s) + %n ปี + + + %1 behind + %1 ตามหลัง + + + Last received block was generated %1 ago. + บล็อกสุดท้ายที่ได้รับ สร้างขึ้นเมื่อ %1 มาแล้ว + + + Transactions after this will not yet be visible. + รายการหลังจากนี้ จะไม่แสดงให้เห็น + + + Error + ข้อผิดพลาด + + + Warning + คำเตือน + + + Information + ข้อมูล Up to date ทันสมัย + + Show the %1 help message to get a list with possible Bitcoin command-line options + แสดง %1 ข้อความช่วยเหลือ เพื่อแสดงรายการ ตัวเลือกที่เป็นไปได้สำหรับ Bitcoin command-line + + + %1 client + %1 ลูกค้า + Catching up... - จับได้... + กำลังตามให้ทัน... + + + Date: %1 + + วันที่: %1 + + + + Amount: %1 + + จำนวน: %1 + + + + Type: %1 + + ชนิด: %1 + + + + Label: %1 + + ป้ายชื่อ: %1 + + + + Address: %1 + + ที่อยู่: %1 + Sent transaction @@ -298,15 +385,68 @@ กระเป๋าเงินถูก <b>เข้ารหัส</b> และในปัจจุบัน <b>ล็อค </b> - - ClientModel - CoinControlDialog + + Coin Selection + การเลือก Coin + + + Quantity: + จำนวน: + + + Bytes: + ไบต์: + + + Amount: + จำนวน: + + + Priority: + ความเร่งด่วน: + + + Fee: + ค่าธรรมเนียม: + + + Dust: + เศษ: + + + After Fee: + ส่วนที่เหลือจากค่าธรรมเนียม: + + + Change: + เงินทอน: + + + (un)select all + (ไม่)เลือกทั้งหมด + + + Tree mode + โหมดแบบต้นไม้ + + + List mode + โหมดแบบรายการ + Amount จำนวน + + Received with label + รับโดยป้ายชื่อ (label) + + + Received with address + รับโดยที่เก็บ + Date วันที่ @@ -323,11 +463,7 @@ Priority ระดับความสำคัญ - - (no label) - (ไม่มีชื่อ) - - + EditAddressDialog @@ -336,59 +472,299 @@ &Label - &ชื่อ + &ป้ายชื่อ + + + The label associated with this address list entry + รายการแสดง ป้ายชื่อที่เกี่ยวข้องกับที่เก็บนี้ + + + The address associated with this address list entry. This can only be modified for sending addresses. + ที่เก็บที่เกี่ยวข้องกับ ที่เก็บที่แสดงรายการนี้ การปรับปรุงนี้ทำได้สำหรับ ที่เก็บเงินที่จะใช่ส่งเงิน เท่านั้น &Address - &ที่อยู่ - - - New receiving address - ที่อยู่ผู้รับใหม่ - - - New sending address - ที่อยู่ผู้ส่งใหม่ - - - Edit receiving address - แก้ไขที่อยู่ผู้รับ - - - Edit sending address - แก้ไขที่อยู่ผู้ส่ง - - - The entered address "%1" is already in the address book. - ป้อนที่อยู่ "%1" ที่มีอยู่แล้วในสมุดที่อยู่ - - - Could not unlock wallet. - ไม่สามารถปลดล็อคกระเป๋าเงิน - - - New key generation failed. - สร้างกุญแจใหม่ล้มเหลว + &ที่เก็บ FreespaceChecker - + + A new data directory will be created. + ไดเร็กทอรี่ใหม่ที่ใช้เก็บข้อมูลจะถูกสร้างขึ้นมา + + + name + ชื่อ + + + Path already exists, and is not a directory. + พาธ มีอยู่แล้ว พาธนี่ไม่ใช่ไดเร็กทอรี่ + + + Cannot create data directory here. + ไม่สามารถสร้างไดเร็กทอรี่ข้อมูลที่นี่ + + HelpMessageDialog - + + version + เวอร์ชั่น + + + (%1-bit) + (%1-บิท) + + + About %1 + เกี่ยวกับ %1 + + + Command-line options + ตัวเลือก Command-line + + + Usage: + วิธีใช้งาน: + + + command-line options + ตัวเลือก command-line + + + UI Options: + ตัวเลือก UI: + + + Choose data directory on startup (default: %u) + เลือกไดเร็กทอรี่ข้อมูลตั้งแต่เริ่มต้นสตาร์ทอัพ (ค่าเริ่มต้น: %u) + + + Set language, for example "de_DE" (default: system locale) + ตั้งค่าภาษา ยกตัวอย่าง "de_DE" (ค่าเริ่มต้น: ภาษาท้องถิ่นของระบบ) + + + Start minimized + เริ่มต้นมินิไมซ์ + + + Set SSL root certificates for payment request (default: -system-) + ตั้งค่า SSL root certificates สำหรับเรียกการชำระเงิน (ค่าเริ่มต้น: -system-) + + + Show splash screen on startup (default: %u) + แสดง splash screen ตอนเริ่มต้น (ค่าเริ่มต้น: %u) + + + Reset all settings changed in the GUI + รีเซตการเปลี่ยนการตั้งค่าทั้งหมดใน GUI + + Intro - + + Welcome + ยินดีต้อนรับ + + + Welcome to %1. + ยินดีต้องรับสู่ %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + นี่เป็นการรันโปรแกรมครั้งแรก ท่านสามารถเลือก ว่าจะเก็บข้อมูลไว้ที่ %1 + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 จะดาวน์โหลดและเก็บกอปปี้ชุดหนึ่งของ บล็อกเชน Bitcoin ไว้ ข้อมูลขนานอย่างน้อย %2GB จะเก็บไว้ในไดเร็กทอรี่นี้ และข้อมูลจะมีขนาดใหญ่ขึ้นเรื่อยๆ กระเป๋าเงิน จะเก็บไว้ในไดเร็กทอรี่นี้ด้วย + + + Use the default data directory + ใช้ไดเร็กทอรี่ข้อมูล ที่เป็นค่าเริ่มต้น + + + Use a custom data directory: + ใช้ไดเร็กทอรี่ข้อมูลที่ตั้งค่าเอง: + + + Error: Specified data directory "%1" cannot be created. + ข้อผิดพลาด: ไดเร็กทอรี่ข้อมูลที่ต้องการ "%1" ไม่สามารถสร้างได้ + + + Error + ข้อผิดพลาด + + + %n GB of free space available + %n GB พื้นที่ว่างบนดิสก์ที่ใช้ได้ + + + (of %n GB needed) + (ต้องการพื้นที่ %n GB) + + OpenURIDialog - + + Open URI + เปิด URI + + + Open payment request from URI or file + เปิด การเรียกการชำระเงิน จาก URI หรือ ไฟล์ + + + URI: + URI: + + + Select payment request file + เลือก ไฟล์การเรียกการชำระเงิน + + OptionsDialog Options ตัวเลือก + + &Main + &หลัก + + + Automatically start %1 after logging in to the system. + เริ่มต้นอัตโนมัติ %1 หลังจาก ล็อกอิน เข้าสู่ระบบแล้ว + + + &Start %1 on system login + &เริ่ม %1 ในการล็อกอินระบบ + + + Size of &database cache + ขนาดของ &database cache + + + MB + MB + + + Number of script &verification threads + จำนวนของสคริปท์ &verification threads + + + Accept connections from outside + ยอมรับ การเชื่อมต่อจากภายนอก + + + Allow incoming connections + ยอมให้เชื่อมต่อจากภายนอกได้ + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + IP แอดเดส ของ proxy (เช่น IPv4: 127.0.0.1 / IPv6: ::1) + + + 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. + มินิไมซ์แอพ แทนการออกจากแอพพลิเคชั่น เมื่อวินโดว์ได้รับการปิด เมื่อเลือกตัวเลือกนี้ แอพพลิเคชั่น จะถูกปิด ก็ต่อเมื่อ มีการเลือกเมนู Exit/ออกจากระบบ เท่านั้น + + + 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 |. + URL แบบอื่น (ยกตัวอย่าง เอ็กพลอเลอร์บล็อก) ที่อยู่ใน เมนูรายการ ลำดับ %s ใน URL จะถูกเปลี่ยนด้วย รายการแฮช URL ที่เป็นแบบหลายๆอัน จะถูกแยก โดย เครื่องหมายเส้นบาร์ตั้ง | + + + Third party transaction URLs + URI รายการ แบบของเจ้าอื่นๆ + + + Active command-line options that override above options: + ตัวเลือก command-line แอกทีฟอยู่นี้ จะแทนที่ ตัวเลือกด้านบนนี้: + + + Reset all client options to default. + รีเซต ไคลเอ็นออพชั่น กลับไปเป็นค่าเริ่มต้น + + + &Reset Options + &รีเซต ออพชั่น + + + &Network + &เน็ตเวิร์ก + + + (0 = auto, <0 = leave that many cores free) + (0 = อัตโนมัติ, <0 = ปล่อย คอร์ อิสระ) + + + W&allet + กระเ&ป๋าเงิน + + + Expert + ผู้เชี่ยวชาญ + + + Enable coin &control features + เปิดใช้ coin & รูปแบบการควบคุม + + + 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. + หากท่านไม่เปิดใช้ การใช้เงินทอนที่ยังไม่ยืนยัน เงินทอนจากการทำรายการจะไม่สามารถใช้ได้ จนกว่ารายการที่ทำการ จะได้รับการยืนยันหนึ่งครั้ง และจะกระทบการคำนวณยอดคงเหลือของท่านด้วย + + + &Spend unconfirmed change + &ใช้เงินทอนที่ยังไม่ยืนยัน + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + เปิด Bitcoin ไคล์เอ็นท์พอร์ต/client port บน router โดยอัตโนมัติ วิธีนี้ใช้ได้เมื่อ router สนับสนุน UPnP และสถานะเปิดใช้งาน + + + Map port using &UPnP + จองพอร์ต โดยใช้ &UPnP + + + Connect to the Bitcoin network through a SOCKS5 proxy. + เชื่อมต่อกับ Bitcoin เน็ตเวิร์ก ผ่านพร็อกซี่แบบ SOCKS5 + + + &Connect through SOCKS5 proxy (default proxy): + &เชื่อมต่อผ่าน พร็อกซี่ SOCKS5 (พร็อกซี่เริ่มต้น): + + + Proxy &IP: + พร็อกซี่ &IP: + + + &Port: + &พอร์ต + + + Port of the proxy (e.g. 9050) + พอร์ตของพร็อกซี่ (ตัวอย่าง 9050) + + + Used for reaching peers via: + ใช้ในการเข้าถึงอีกฝ่ายหนึ่ง peer โดย: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + แสดง หากใช้พร็อกซี่ SOCKS5 ที่เป็นค่าเริ่มต้น เพื่อเข้าถึง peer อีกฝ่าย ผ่านทางเน็ตเวิร์กชนิดนี้ + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + OverviewPage @@ -397,9 +773,6 @@ รูป - - PaymentServer - PeerTableModel @@ -410,9 +783,6 @@ จำนวน - - QRImageWidget - RPCConsole @@ -425,37 +795,6 @@ ReceiveRequestDialog - - Address - ที่อยู่ - - - Amount - จำนวน - - - Label - ชื่อ - - - - RecentRequestsTableModel - - Date - วันที่ - - - Label - ชื่อ - - - Amount - จำนวน - - - (no label) - (ไม่มีชื่อ) - SendCoinsDialog @@ -464,8 +803,36 @@ ส่งเหรียญ - (no label) - (ไม่มีชื่อ) + Quantity: + จำนวน: + + + Bytes: + ไบต์: + + + Amount: + จำนวน: + + + Priority: + ความเร่งด่วน + + + Fee: + ค่าธรรมเนียม: + + + After Fee: + ส่วนที่เหลือจากค่าธรรมเนียม: + + + Change: + เงินทอน: + + + Dust: + เศษ: @@ -491,91 +858,29 @@ TrafficGraphWidget - - TransactionDesc - - Date - วันที่ - - - Amount - จำนวน - - TransactionDescDialog - - TransactionTableModel - - Date - วันที่ - - - Label - ชื่อ - - - - TransactionView - - Today - วันนี้ - - - Exporting Failed - ส่งออกข้อมูลล้มเหลว - - - Comma separated file (*.csv) - คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv) - - - Confirmed - ยืนยันแล้ว - - - Date - วันที่ - - - Label - ชื่อ - - - Address - ที่อยู่ - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - Send Coins - ส่งเหรียญ - - - - WalletView - - &Export - &ส่งออก - - - Export the data in the current tab to a file - ส่งออกข้อมูลที่อยู่ในแท็บไปที่ไฟล์ - - bitcoin-core Options: ตัวเลือก: - + + Information + ข้อมูล + + + Warning + คำเตือน + + + Error + ข้อผิดพลาด + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 240677677..f6ab2ca18 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -25,10 +25,6 @@ C&lose K&apat - - &Copy Address - &Adresi Kopyala - Delete the currently selected address from the list Seçili adresi listeden sil @@ -45,73 +41,6 @@ &Delete &Sil - - Choose the address to send coins to - Bitcoin yollanacak adresi seç - - - Choose the address to receive coins with - Bitcoin alınacak adresi seç - - - C&hoose - S&eç - - - Sending addresses - &Gönderme adresleri... - - - Receiving addresses - Alım adresleri - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce miktarı ve alıcının alım adresini daima kontrol ediniz. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir. - - - Copy &Label - &Etiketi kopyala - - - &Edit - &Düzenle - - - Export Address List - Adres listesini dışa aktar - - - Comma separated file (*.csv) - Virgülle ayrılmış değerler dosyası (*.csv) - - - Exporting Failed - Dışa aktarım başarısız oldu - - - There was an error trying to save the address list to %1. Please try again. - Adres listesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. Lütfen tekrar deneyin. - - - - AddressTableModel - - Label - Etiket - - - Address - Adres - - - (no label) - (etiket yok) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Yeni parolayı tekrarlayınız - - Encrypt wallet - Cüzdanı şifrele - - - This operation needs your wallet passphrase to unlock the wallet. - Bu işlem cüzdan kilidini açmak için cüzdan parolanızı gerektirir. - - - Unlock wallet - Cüzdan kilidini aç - - - This operation needs your wallet passphrase to decrypt the wallet. - Bu işlem cüzdanın şifrelemesini açmak için cüzdan parolasını gerektirir. - - - Decrypt wallet - Cüzdanın şifrelemesini aç - - - Change passphrase - Parolayı değiştir - - - Confirm wallet encryption - Cüzdanın şifrelemesini teyit eder - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Uyarı: Eğer cüzdanınızı şifrelerseniz ve parolanızı kaybederseniz, <b>TÜM BİTCOİNLERİNİZİ KAYBEDERSİNİZ</b>! - - - Are you sure you wish to encrypt your wallet? - Cüzdanınızı şifrelemek istediğinizden emin misiniz? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Şifreleme işlemini tamamlamak için Bitcoin Çekirdeği şimdi kapanacaktır. Cüzdanınızı şifrelemenin, Bitcoinlerinizin bilgisayara bulaşan kötücül bir yazılım tarafından çalınmaya karşı tamamen koruyamayacağını unutmayınız. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ÖNEMLİ: Önceden yapmış olduğunuz cüzdan dosyası yedeklemelerinin yeni oluşturulan şifrelenmiş cüzdan dosyası ile değiştirilmeleri gerekir. Güvenlik nedenleriyle yeni, şifrelenmiş cüzdanı kullanmaya başladığınızda eski şifrelenmemiş cüzdan dosyaları işe yaramaz hale gelecektir. - - - Warning: The Caps Lock key is on! - Uyarı: Caps Lock tuşu faal durumda! - - - Wallet encrypted - Cüzdan şifrelendi - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Cüzdan için yeni parolayı giriniz.<br/>Lütfen <b>on ya da daha fazla rastgele karakter</b> veya <b>sekiz ya da daha fazla kelime</b> içeren bir parola kullanınız. - - - Enter the old passphrase and new passphrase to the wallet. - Cüzdan için eski parolayı ve yeni parolayı giriniz. - - - Wallet encryption failed - Cüzdan şifrelemesi başarısız oldu - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Dahili bir hata sebebiyle cüzdan şifrelemesi başarısız oldu. Cüzdanınız şifrelenmedi. - - - The supplied passphrases do not match. - Girilen parolalar birbirleriyle uyumlu değil. - - - Wallet unlock failed - Cüzdan kilidinin açılması başarısız oldu - - - The passphrase entered for the wallet decryption was incorrect. - Cüzdan şifresinin açılması için girilen parola yanlıştı. - - - Wallet decryption failed - Cüzdan şifresinin açılması başarısız oldu - - - Wallet passphrase was successfully changed. - Cüzdan parolası başarılı bir şekilde değiştirildi. - BanTableModel @@ -269,6 +110,14 @@ Quit application Uygulamadan çık + + &About %1 + %1 &hakkında + + + Show information about %1 + %1 hakkında bilgi göster + About &Qt &Qt hakkında @@ -281,6 +130,10 @@ &Options... &Seçenekler... + + Modify configuration options for %1 + %1 için yapılandırma ayarlarını değiştir + &Encrypt Wallet... Cüzdanı &şifrele... @@ -305,14 +158,6 @@ Open &URI... &URI aç... - - Bitcoin Core client - Bitcoin Çekirdeği istemcisi - - - Importing blocks from disk... - Bloklar diskten içe aktarılıyor... - Reindexing blocks on disk... Diskteki bloklar yeniden endeksleniyor... @@ -357,10 +202,6 @@ &Receive &Al - - Show information about Bitcoin Core - Bitcoin Çekirdeği hakkında bilgi göster - &Show / Hide &Göster / Sakla @@ -397,22 +238,10 @@ Tabs toolbar Sekme araç çubuğu - - Bitcoin Core - Bitcoin Çekirdeği - Request payments (generates QR codes and bitcoin: URIs) Ödeme talep et (QR kodu ve bitcoin URI'si oluşturur) - - &About Bitcoin Core - Bitcoin Çekirdeği &hakkında - - - Modify configuration options for Bitcoin Core - Bitcoin Çekirdeği yapılandırma seçeneklerini değiştir - Show the list of used sending addresses and labels Kullanılmış gönderme adresleri ve etiketlerin listesini göster @@ -429,14 +258,18 @@ &Command-line options &Komut satırı seçenekleri - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Bitcoin komut satırı seçeneklerinin listesini elde etmek için Bitcoin Çekirdeği yardım mesajını göster - %n active connection(s) to Bitcoin network Bitcoin şebekesine %n faal bağlantıBitcoin şebekesine %n faal bağlantı + + Indexing blocks on disk... + Bloklar diske indeksleniyor... + + + Processing blocks on disk... + Bloklar diske yazıdırılıyor... + No block source available... Hiçbir blok kaynağı mevcut değil... @@ -493,6 +326,14 @@ Up to date Güncel + + Show the %1 help message to get a list with possible Bitcoin command-line options + Olası Bitcoin komut satırı seçeneklerinin listesini görmek için %1 yardım mesajını göster + + + %1 client + %1 istemcisi + Catching up... Aralık kapatılıyor... @@ -544,13 +385,6 @@ Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilitlidir</b> - - ClientModel - - Network Alert - Şebeke hakkında uyarı - - CoinControlDialog @@ -629,150 +463,6 @@ Priority Öncelik - - Copy address - Adresi kopyala - - - Copy label - Etiketi kopyala - - - Copy amount - Meblağı kopyala - - - Copy transaction ID - Muamele kimliğini kopyala - - - Lock unspent - Harcanmamışı kilitle - - - Unlock unspent - Harcanmamışın kilidini aç - - - Copy quantity - Miktarı kopyala - - - Copy fee - Ücreti kopyala - - - Copy after fee - Ücretten sonrakini kopyala - - - Copy bytes - Baytları kopyala - - - Copy priority - Önceliği kopyala - - - Copy dust - Tozu kopyala - - - Copy change - Para üstünü kopyala - - - highest - azami - - - higher - daha yüksek - - - high - yüksek - - - medium-high - orta-yüksek - - - medium - orta - - - low-medium - düşük-orta - - - low - düşük - - - lower - daha düşük - - - lowest - asgari - - - (%1 locked) - (%1 kilitlendi) - - - none - boş - - - This label turns red if the transaction size is greater than 1000 bytes. - Eğer muamele boyutu 1000 bayttan yüksek ise bu etiket kırmızı hale gelir. - - - This label turns red if the priority is smaller than "medium". - Eğer öncelik "ortadan" düşükse bu etiket kırmızı olur. - - - This label turns red if any recipient receives an amount smaller than %1. - Eğer herhangi bir alıcı %1'den düşük bir meblağ alırsa bu etiket kırmızı olur. - - - Can vary +/- %1 satoshi(s) per input. - Giriş başına +/- %1 satoshi olarak değişebilir. - - - yes - evet - - - no - hayır - - - This means a fee of at least %1 per kB is required. - Bu, kB başına en az %1 ücret gerektiği anlamnına gelir. - - - Can vary +/- 1 byte per input. - Girdi başına +/- 1 bayt değişebilir. - - - Transactions with higher priority are more likely to get included into a block. - Yüksek öncelikli muamelelerin bir bloğa dahil olmaları daha olasıdır. - - - (no label) - (boş etiket) - - - change from %1 (%2) - %1 unsurundan para üstü (%2) - - - (change) - (para üstü) - EditAddressDialog @@ -796,38 +486,6 @@ &Address &Adres - - New receiving address - Yeni alım adresi - - - New sending address - Yeni gönderi adresi - - - Edit receiving address - Alım adresini düzenle - - - Edit sending address - Gönderi adresini düzenle - - - The entered address "%1" is already in the address book. - Girilen "%1" adresi hâlihazırda adres defterinde mevcuttur. - - - The entered address "%1" is not a valid Bitcoin address. - Girilen "%1" adresi geçerli bir Bitcoin adresi değildir. - - - Could not unlock wallet. - Cüzdan kilidi açılamadı. - - - New key generation failed. - Yeni anahtar oluşturulması başarısız oldu. - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Çekirdeği - version sürüm @@ -867,8 +521,8 @@ (%1-bit) - About Bitcoin Core - Bitcoin Çekirdeği hakkında + About %1 + %1 Hakkında Command-line options @@ -907,8 +561,8 @@ Başlatıldığında başlangıç ekranını göster (varsayılan: %u) - Reset all settings changes made over the GUI - Arayüzde yapılan tüm seçenek değişikliklerini sıfırla + Reset all settings changed in the GUI + Grafik arayüzde yapılan tüm seçenek değişikliklerini sıfırla @@ -918,16 +572,16 @@ Hoş geldiniz - Welcome to Bitcoin Core. - Bitcoin Çekirdeğine hoş geldiniz. + Welcome to %1. + %1'a hoş geldiniz. - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Bu programı ilk kez başlattığınızdan dolayı Bitcoin Çekirdeğinin verilerini nereye saklayacağını seçebilirsiniz. + As this is the first time the program is launched, you can choose where %1 will store its data. + Bu programın ilk kez başlatılmasından dolayı %1 yazılımının verilerini nerede saklayacağını seçebilirsiniz. - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin çekirdeği Bitcoin blok zincirinin bir kopyasını indirip saklayacaktır. Asgari %1GB bouyutunda veri bu klasörde saklanacak ve zamanla bu boyut artacaktır. Cüzdan da bu klasörde saklanacaktır. + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1, Bitcoin blok zincirinin bir kopyasını indirecek ve saklayacaktır. Bu klasörde en az %2GB veri saklanacak ve bu zamanla artacaktır. Cüzdan da bu klasörde saklanacaktır. Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: Özel bir veri klasörü kullan: - - Bitcoin Core - Bitcoin Çekirdeği - Error: Specified data directory "%1" cannot be created. Hata: belirtilen "%1" veri klasörü oluşturulamaz. @@ -976,10 +626,6 @@ Select payment request file Ödeme talebi dosyasını seç - - Select payment request file to open - Açılacak ödeme talebi dosyasını seç - OptionsDialog @@ -991,6 +637,14 @@ &Main &Esas ayarlar + + Automatically start %1 after logging in to the system. + Sistemde oturum açıldığında %1 programını otomatik olarak başlat. + + + &Start %1 on system login + &Açılışta %1 açılsın + Size of &database cache &Veritabanı tamponunun boyutu @@ -1019,10 +673,6 @@ 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. Pencere kapatıldığında uygulamadan çıkmak yerine uygulamayı küçültür. Bu seçenek etkinleştirildiğinde, uygulama sadece menüden çıkış seçildiğinde kapanacaktır. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar Bitcoin Çekirdeği tekrar başlatıldığında etkinleşecektir. - 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 |. Muameleler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, muamele hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır. @@ -1047,14 +697,6 @@ &Network &Şebeke - - Automatically start Bitcoin Core after logging in to the system. - Sistemde oturum açıldığında Bitcoin Çekirdeğini otomatik olarak başlat. - - - &Start Bitcoin Core on system login - Bitcoin Çekirdeğini sistem oturumuyla &başlat - (0 = auto, <0 = leave that many cores free) (0 = otomatik, <0 = bu kadar çekirdeği kullanma) @@ -1139,6 +781,14 @@ &Window &Pencere + + &Hide the icon from the system tray. + İkonu sistem çekmecesinden &sakla + + + Hide tray icon + Sistem çekmecesi ikonunu sakla + Show only a tray icon after minimizing the window. Küçültüldükten sonra sadece çekmece ikonu göster. @@ -1159,6 +809,10 @@ User Interface &language: Kullanıcı arayüzü &lisanı: + + The user interface language can be set here. This setting will take effect after restarting %1. + Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar %1 tekrar başlatıldığında etkinleşecektir. + &Unit to show amounts in: Meblağları göstermek için &birim: @@ -1283,97 +937,6 @@ Sadece izlenen adreslerdeki güncel toplam bakiye - - PaymentServer - - URI handling - URI yönetimi - - - Invalid payment address %1 - Geçersiz ödeme adresi %1 - - - Payment request rejected - Ödeme talebi reddedildi - - - Payment request network doesn't match client network. - Ödeme talebi şebekesi istemci şebekesine denk gelmiyor. - - - Payment request is not initialized. - Ödeme talebi başlatılmamış. - - - Requested payment amount of %1 is too small (considered dust). - Talep edilen %1 meblağında ödeme çok düşüktür (toz olarak kabul edilir). - - - Payment request error - Ödeme talebi hatası - - - Cannot start bitcoin: click-to-pay handler - Bitcoin başlatılamadı: tıkla-ve-öde yöneticisi - - - Payment request fetch URL is invalid: %1 - Ödeme talebini alma URL'i geçersiz: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI okunamadı! Sebebi geçersiz bir Bitcoin adresi veya hatalı URI parametreleri olabilir. - - - Payment request file handling - Ödeme talebi dosyası yönetimi - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Ödeme talebi okunamaz ya da işlenemez! Bunun sebebi geçersiz bir ödeme talebi dosyası olabilir. - - - Payment request expired. - Ödeme talebinin ömrü doldu. - - - Unverified payment requests to custom payment scripts are unsupported. - Özel ödeme betiklerine teyit edilmemiş ödeme talepleri desteklenmez. - - - Invalid payment request. - Geçersiz ödeme talebi. - - - Refund from %1 - %1 öğesinden iade - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - %1 ödeme talebi çok büyük (%2 bayt, müsaade edilen %3 bayt). - - - Error communicating with %1: %2 - %1 ile iletişimde hata: %2 - - - Payment request cannot be parsed! - Ödeme talebi ayrıştırılamaz! - - - Bad response from server %1 - %1 sunucusundan hatalı cevap - - - Payment acknowledged - Ödeme teyit edildi - - - Network request error - Şebeke talebi hatası - - PeerTableModel @@ -1428,25 +991,6 @@ %1 ms - - QRImageWidget - - &Save Image... - Resmi k&aydet... - - - &Copy Image - Resmi &kopyala - - - Save QR Code - QR kodu kaydet - - - PNG Image (*.png) - PNG resim (*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version Kullanılan BerkeleyDB sürümü + + Datadir + Veri konumu + Startup time Başlama zamanı @@ -1513,10 +1061,6 @@ Memory usage Bellek kullanımı - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Güncel veri klasöründen Bitcoin Çekirdeği hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir. - Received Alınan @@ -1565,6 +1109,18 @@ User Agent Kullanıcı Yazılımı + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Güncel veri klasöründen %1 hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir. + + + Decrease font size + Font boyutunu küçült + + + Increase font size + Yazıtipi boyutunu büyült + Services Servisler @@ -1633,10 +1189,6 @@ Out: Dışarı: - - Build date - Derleme tarihi - Debug log file Hata ayıklama kütük dosyası @@ -1674,8 +1226,8 @@ Düğümün Yasağını Kald&ır - Welcome to the Bitcoin Core RPC console. - Bitcoin Çekirdeği RPC konsoluna hoş geldiniz. + Welcome to the %1 RPC console. + %1 RPC konsoluna hoş geldiniz. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove Kaldır - - Copy label - Etiketi kopyala - - - Copy message - Mesajı kopyala - - - Copy amount - Meblağı kopyala - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... Resmi ka&ydet... - - Request payment to %1 - %1 unsuruna ödeme talep et - - - Payment information - Ödeme bilgisi - - - URI - URI - - - Address - Adres - - - Amount - Meblağ - - - Label - Etiket - - - Message - Mesaj - - - Resulting URI too long, try to reduce the text for label / message. - Sonuç URI çok uzun, etiket ya da mesaj metnini kısaltmayı deneyiniz. - - - Error encoding URI into QR Code. - URI'nin QR koduna kodlanmasında hata oluştu. - - - - RecentRequestsTableModel - - Date - Tarih - - - Label - Etiket - - - Message - Mesaj - - - Amount - Meblağ - - - (no label) - (boş etiket) - - - (no message) - (boş mesaj) - - - (no amount) - (boş meblağ) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast çabuk - - Send as zero-fee transaction if possible - Mümkünse ücretsiz muamele olarak gönder - - - (confirmation may take longer) - (teyit daha uzun süre alabilir) - Send to multiple recipients at once Birçok alıcıya aynı anda gönder @@ -2061,118 +1526,6 @@ S&end G&önder - - Confirm send coins - Gönderiyi teyit ediniz - - - %1 to %2 - %1 öğesinden %2 unsuruna - - - Copy quantity - Miktarı kopyala - - - Copy amount - Meblağı kopyala - - - Copy fee - Ücreti kopyala - - - Copy after fee - Ücretten sonrakini kopyala - - - Copy bytes - Baytları kopyala - - - Copy priority - Önceliği kopyala - - - Copy change - Para üstünü kopyala - - - Total Amount %1 - Toplam Meblağ %1 - - - or - veya - - - The amount to pay must be larger than 0. - Ödeyeceğiniz tutarın sıfırdan yüksek olması gerekir. - - - The amount exceeds your balance. - Tutar bakiyenizden yüksektir. - - - The total exceeds your balance when the %1 transaction fee is included. - Toplam, %1 muamele ücreti ilâve edildiğinde bakiyenizi geçmektedir. - - - Transaction creation failed! - Muamelenin oluşturulması başarısız oldu! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Muamele reddedildi! Cüzdanınızdaki madenî paraların bazıları zaten harcanmış olduğunda bu meydana gelebilir. Örneğin wallet.dat dosyasının bir kopyasını kullandıysanız ve kopyada para harcandığında ancak burada harcandığı işaretlenmediğinde. - - - A fee higher than %1 is considered an absurdly high fee. - %1 tutarından yüksek ücret saçma derecede yüksek bir ücret olarak kabul edilir. - - - Payment request expired. - Ödeme talebinin ömrü doldu. - - - Pay only the required fee of %1 - Sadece gerekli ücret olan %1 tutarını öde - - - Estimated to begin confirmation within %n block(s). - Tahmini olarak %n blok içinde teyide başlanacaktır.Tahmini olarak %n blok içinde teyide başlanacaktır. - - - The recipient address is not valid. Please recheck. - Alıcı adresi geçerli değildir. Lütfen denetleyiniz. - - - Duplicate address found: addresses should only be used once each. - Çift adres bulundu: adresler herbiri için sadece bir kez kullanılmalıdır. - - - Warning: Invalid Bitcoin address - Uyarı: geçersiz Bitcoin adresi - - - (no label) - (boş etiket) - - - Warning: Unknown change address - Uyarı: geçersiz para üstü adresi - - - Copy dust - Tozu kopyala - - - Are you sure you want to send? - Göndermek istediğinizden emin misiniz? - - - added as transaction fee - muamele ücreti olarak eklendi - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: &Şu adrese öde: - - Enter a label for this address to add it to your address book - Adres defterinize eklemek için bu adrese ilişik bir etiket giriniz - &Label: &Etiket: @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - Bitcoin Çekirdeği kapanıyor... + %1 is shutting down... + %1 kapanıyor... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields Tüm mesaj kontrolü alanlarını sıfırla - - Click "Sign Message" to generate signature - İmzayı oluşturmak için "Mesaj İmzala" unsurunu tıklayın - - - The entered address is invalid. - Girilen adres geçersizdir. - - - Please check the address and try again. - Adresi kontrol edip tekrar deneyiniz. - - - The entered address does not refer to a key. - Girilen adres herhangi bir anahtara işaret etmemektedir. - - - Wallet unlock was cancelled. - Cüzdan kilidinin açılması iptal edildi. - - - Private key for the entered address is not available. - Girilen adres için özel anahtar mevcut değildir. - - - Message signing failed. - Mesajın imzalanması başarısız oldu. - - - Message signed. - Mesaj imzalandı. - - - The signature could not be decoded. - İmzanın kodu çözülemedi. - - - Please check the signature and try again. - İmzayı kontrol edip tekrar deneyiniz. - - - The signature did not match the message digest. - İmza mesajın hash değeri ile eşleşmedi. - - - Message verification failed. - Mesaj doğrulaması başarısız oldu. - - - Message verified. - Mesaj doğrulandı. - SplashScreen - - Bitcoin Core - Bitcoin Çekirdeği - - - The Bitcoin Core developers - Bitcoin Çekirdeği geliştiricileri - [testnet] [testnet] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - %1 değerine dek açık - - - conflicted - çakışma - - - %1/offline - %1/çevrim dışı - - - %1/unconfirmed - %1/doğrulanmadı - - - %1 confirmations - %1 teyit - - - Status - Durum - - - , broadcast through %n node(s) - , %n düğüm vasıtasıyla yayınlandı, %n düğüm vasıtasıyla yayınlandı - - - Date - Tarih - - - Source - Kaynak - - - Generated - Oluşturuldu - - - From - Gönderen - - - To - Alıcı - - - own address - kendi adresiniz - - - watch-only - sadece-izlenen - - - label - etiket - - - Credit - Gider - - - matures in %n more block(s) - %n ek blok sonrasında olgunlaşacak%n ek blok sonrasında olgunlaşacak - - - not accepted - kabul edilmedi - - - Debit - Gelir - - - Total debit - Toplam gider - - - Total credit - Toplam gelir - - - Transaction fee - Muamele ücreti - - - Net amount - Net meblağ - - - Message - Mesaj - - - Comment - Yorum - - - Transaction ID - Muamele tanımlayıcı - - - Merchant - Tüccar - - - 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. - Oluşturulan bitcoin'lerin harcanabilmelerinden önce %1 blok beklemeleri gerekmektedir. Bu blok, oluşturduğunuzda, blok zincirine eklenmesi için ağda yayınlandı. Zincire eklenmesi başarısız olursa, durumu "kabul edilmedi" olarak değiştirilecek ve harcanamayacaktır. Bu, bazen başka bir düğüm sizden birkaç saniye önce ya da sonra blok oluşturursa meydana gelebilir. - - - Debug information - Hata ayıklama verileri - - - Transaction - Muamele - - - Inputs - Girdiler - - - Amount - Meblağ - - - true - doğru - - - false - yanlış - - - , has not been successfully broadcast yet - , henüz başarılı bir şekilde yayınlanmadı - - - Open for %n more block(s) - %n ilâve blok için açık%n ilâve blok için açık - - - unknown - bilinmiyor - - TransactionDescDialog - - Transaction details - Muamele detayları - This pane shows a detailed description of the transaction Bu pano muamelenin ayrıntılı açıklamasını gösterir - - TransactionTableModel - - Date - Tarih - - - Type - Tür - - - Immature (%1 confirmations, will be available after %2) - Olgunlaşmamış (%1 teyit, %2 teyit ardından kullanılabilir olacaktır) - - - Open for %n more block(s) - %n ilâve blok için açık%n ilâve blok için açık - - - Open until %1 - %1 değerine dek açık - - - Confirmed (%1 confirmations) - Doğrulandı (%1 teyit) - - - This block was not received by any other nodes and will probably not be accepted! - Bu blok başka hiçbir düğüm tarafından alınmamıştır ve muhtemelen kabul edilmeyecektir! - - - Generated but not accepted - Oluşturuldu ama kabul edilmedi - - - Offline - Çevrim dışı - - - Label - Etiket - - - Unconfirmed - Teyit edilmemiş - - - Confirming (%1 of %2 recommended confirmations) - Teyit ediliyor (tavsiye edilen %2 teyit üzerinden %1 doğrulama) - - - Conflicted - Çakışma - - - Received with - Şununla alındı - - - Received from - Alındığı kişi - - - Sent to - Gönderildiği adres - - - Payment to yourself - Kendinize ödeme - - - Mined - Madenden çıkarılan - - - watch-only - sadece-izlenen - - - (n/a) - (mevcut değil) - - - Transaction status. Hover over this field to show number of confirmations. - Muamele durumu. Doğrulama sayısını görüntülemek için imleci bu alanda tutunuz. - - - Date and time that the transaction was received. - Muamelenin alındığı tarih ve zaman. - - - Type of transaction. - Muamele türü. - - - Whether or not a watch-only address is involved in this transaction. - Bu muamelede sadece izlenen bir adresin bulunup bulunmadığı. - - - User-defined intent/purpose of the transaction. - Muamelenin kullanıcı tanımlı niyeti/amacı. - - - Amount removed from or added to balance. - Bakiyeden alınan ya da bakiyeye eklenen meblağ. - - - - TransactionView - - All - Hepsi - - - Today - Bugün - - - This week - Bu hafta - - - This month - Bu ay - - - Last month - Geçen ay - - - This year - Bu sene - - - Range... - Aralık... - - - Received with - Şununla alınan - - - Sent to - Gönderildiği adres - - - To yourself - Kendinize - - - Mined - Oluşturulan - - - Other - Diğer - - - Enter address or label to search - Aranacak adres ya da etiket giriniz - - - Min amount - Asgari meblağ - - - Copy address - Adresi kopyala - - - Copy label - Etiketi kopyala - - - Copy amount - Meblağı kopyala - - - Copy transaction ID - Muamele kimliğini kopyala - - - Copy raw transaction - Ham muameleyi kopyala - - - Edit label - Etiketi düzenle - - - Show transaction details - Muamele detaylarını göster - - - Export Transaction History - Muamele tarihçesini dışa aktar - - - Watch-only - Sadece izlenen - - - Exporting Failed - Dışa aktarım başarısız oldu - - - There was an error trying to save the transaction history to %1. - Muamele tarihçesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. - - - Exporting Successful - Dışa aktarım başarılı oldu - - - The transaction history was successfully saved to %1. - Muamele tarihçesi başarılı bir şekilde %1 konumuna kaydedildi. - - - Comma separated file (*.csv) - Virgülle ayrılmış değerler dosyası (*.csv) - - - Confirmed - Doğrulandı - - - Date - Tarih - - - Type - Tür - - - Label - Etiket - - - Address - Adres - - - ID - Tanımlayıcı - - - Range: - Aralık: - - - to - ilâ - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ Meblağları göstermek için birim. Başka bir birim seçmek için tıklayınız. - - WalletFrame - - No wallet has been loaded. - Hiçbir cüzdan yüklenmemiştir. - - - - WalletModel - - Send Coins - Bitcoin yolla - - - - WalletView - - &Export - &Dışa aktar - - - Export the data in the current tab to a file - Güncel sekmedeki verileri bir dosyaya aktar - - - Backup Wallet - Cüzdanı Yedekle - - - Wallet Data (*.dat) - Cüzdan verileri (*.dat) - - - Backup Failed - Yedekleme başarısız oldu - - - There was an error trying to save the wallet data to %1. - Cüzdan verilerinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. - - - The wallet data was successfully saved to %1. - Cüzdan verileri %1 konumuna başarıyla kaydedildi. - - - Backup Successful - Yedekleme başarılı - - bitcoin-core @@ -2927,14 +1758,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Tek cüzdan muamelesinde kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontol ediniz! Saatinizde gecikme varsa Bitcoin Çekirdeği doğru şekilde çalışamaz. - Prune configured below the minimum of %d MiB. Please use a higher number. Budama, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. @@ -2975,6 +1798,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Dışarıdan gelen bağlantıları kabul et (varsayılan: -proxy veya -connect yoksa 1) + + Bitcoin Core + Bitcoin Çekirdeği + + + The %s developers + %s geliştiricileri + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee çok yüksek bir değere ayarlanmış! Ücret tahminleri mevcut değilken ödeyebileceğiniz muamele ücretidir bu. @@ -2991,6 +1822,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız + + Cannot obtain a lock on data directory %s. %s is probably already running. + %s veri dizininde kilit elde edilemedi. %s muhtemelen hâlihazırda çalışmaktadır. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir @@ -2999,6 +1834,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız. + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + %s dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir) @@ -3007,6 +1846,18 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Yerel aktarma politikasını ihlal ettiklerinde bile beyaz listedeki eşlerden gelen muamelelerin aktarılmasını zorla (varsayılan: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Müsaade edilen azami medyan eş zamanı değişiklik sınırının ayarlaması. Zamanın yerel perspektifi bu miktar kadar ileri ya da geri eşler tarafından etkilenebilir. (Varsayılan %u saniye) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Tek cüzdan muamelesinde ya da ham muamelede kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontrol ediniz! Saatinizde gecikme varsa %s doğru şekilde çalışamaz. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) @@ -3019,14 +1870,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır. - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - Desteklenmeyen argüman -whitelistalwaysrelay görmezden gelindi, -whitelistrelay ve/veya -whitelistforcerelay kullanın. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) @@ -3043,22 +1886,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Uyarı: şebeke tamamen mutabık değil gibi görünüyor! Bazı madenciler sorun yaşıyor gibi görünüyor. - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - İkaz: bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür. - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Uyarı: eşlerimizle tamamen mutabık değiliz gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün wallet.dat, wallet.{zamandamgası}.bak olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir. + + You need to rebuild the database using -reindex-chainstate to change -txindex + -txindex'i değiştirmek için veritabanını -reindex-chainstate kullanarak tekrar inşa etmeniz gerekmektedir + + + %s corrupt, salvage failed + %s bozuk, geri kazanım başarısız oldu + -maxmempool must be at least %d MB -maxmempool asgari %d MB olmalıdır @@ -3071,10 +1914,22 @@ Append comment to the user agent string Kullanıcı aracı zincirine yorumu ekle + + Attempt to recover private keys from a corrupt wallet on startup + Başlangıçta bozuk bir cüzdandan özel anahtarları geri kazanmayı dene + Block creation options: Blok oluşturma seçenekleri: + + Cannot resolve -%s address: '%s' + Çözümlenemedi - %s adres: '%s' + + + Change index out of range + Aralık dışında değişiklik endeksi + Connect only to the specified node(s) Sadece belirtilen düğüme veya düğümlere bağlan @@ -3083,6 +1938,10 @@ Connection options: Bağlantı seçenekleri: + + Copyright (C) %i-%i + Telif hakkı (C) %i-%i + Corrupted block database detected Bozuk blok veritabanı tespit edildi @@ -3127,6 +1986,18 @@ Error initializing wallet database environment %s! %s cüzdan veritabanı ortamının başlatılmasında hata meydana geldi! + + Error loading %s + %s unsurunun yüklenmesinde hata oluştu + + + Error loading %s: Wallet corrupted + %s unsurunun yüklenmesinde hata oluştu: bozuk cüzdan + + + Error loading %s: Wallet requires newer version of %s + %s unsurunun yüklenmesinde hata oluştu: cüzdan %s programının yeni bir sürümüne ihtiyaç duyuyor + Error loading block database Blok veritabanının yüklenmesinde hata @@ -3151,10 +2022,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Yanlış ya da bulunamamış doğuş bloku. Şebeke için yanlış veri klasörü mü? + + Initialization sanity check failed. %s is shutting down. + Başlatma sınaması başarısız oldu. %s kapatılıyor. + Invalid -onion address: '%s' Geçersiz -onion adresi: '%s' + + Invalid amount for -%s=<amount>: '%s' + -%s=<meblağ> için geçersiz meblağ: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' -fallbackfee=<meblağ> için geçersiz meblağ: '%s' @@ -3163,6 +2042,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u) + + Loading banlist... + Yasaklama listesi yükleniyor... + Location of the auth cookie (default: data dir) auth çerezinin konumu (varsayılan: veri klasörü) @@ -3179,6 +2062,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Sadece <net> şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion) + + Print this help message and exit + Bu yardım mesajını yaz ve çık + Print version and exit Sürümü yaz ve çık @@ -3191,6 +2078,14 @@ Prune mode is incompatible with -txindex. Budama kipi -txindex ile uyumsuzdur. + + Rebuild chain state and block index from the blk*.dat files on disk + Zincir durumu ve blok endeksini diskteki blk*.dat dosyalarından yeniden derle + + + Rebuild chain state from the currently indexed blocks + Zincir durumunu güncel olarak endekslenen bloklardan yeniden derle + Set database cache size in megabytes (%d to %d, default: %d) Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d) @@ -3203,6 +2098,10 @@ Specify wallet file (within data directory) Cüzdan dosyası belirtiniz (veri klasörünün içinde) + + Unable to bind to %s on this computer. %s is probably already running. + Bu bilgisayarda %s unsuruna bağlanılamadı. %s muhtemelen hâlihazırda çalışmaktadır. + Unsupported argument -benchmark ignored, use -debug=bench. Desteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız. @@ -3236,12 +2135,16 @@ %s cüzdan %s veri klasörünün dışında bulunuyor - Wallet options: - Cüzdan seçenekleri: + Wallet debugging/testing options: + Cüzdan hata ayıklama/test etme seçenekleri: - You need to rebuild the database using -reindex to change -txindex - -txindex'i değiştirmek için veritabanını -reindex kullanarak tekrar inşa etmeniz gerekmektedir + Wallet needed to be rewritten: restart %s to complete + Cüzdanın tekrar yazılması gerekiyordu: işlemi tamamlamak için %s programını yeniden başlatınız + + + Wallet options: + Cüzdan seçenekleri: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3255,10 +2158,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Belirtilen adrese bağlan ve JSON RPC bağlantıları için dinlemeye geç. IPv6 için [makine]:port imlasını kullanınız. Bu seçenek birden çok kez belirtilebilir (varsayılan: tüm arayüzlere bağlan) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - %s veri dizininde kilit elde edilemedi. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Yeni dosyaları umask 077 yerine varsayılan izinlerle oluştur (sadece devre dışı cüzdan işlevselliği ile etkilidir) @@ -3303,10 +2202,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Etkinse bitcoin oluşuturulmasına atanan iş parçacığı sayısını ayarla (-1 = tüm çekirdekler, varsayılan: %d) - The transaction amount is too small to send after the fee has been deducted Bu muamele, ücret düşüldükten sonra göndermek için çok düşük @@ -3331,34 +2226,14 @@ Accept public REST requests (default: %u) Herkese açık REST taleplerini kabul et (varsayılan: %u) - - Activating best chain... - En iyi zincir etkinleştiriliyor... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Başlangıçta bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene - Automatically create Tor hidden service (default: %d) Otomatik olarak gizli Tor servisi oluştur (varsayılan: %d) - - Cannot resolve -whitebind address: '%s' - -whitebind adresi çözümlenemedi: '%s' - Connect through SOCKS5 proxy SOCKS5 vekil sunucusu vasıtasıyla bağlan - - Copyright (C) 2009-%i The Bitcoin Core Developers - Telif hakkı 2009-%i Bitcoin Çekirdeği Geliştiricileri - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - wallet.dat dosyasının yüklenmesinde hata: Cüzdan Bitcoin Çekirdeğinin daha yeni bir sürümünü gerektirmektedir - Error reading from database, shutting down. Veritabanından okumada hata, kapatılıyor. @@ -3371,22 +2246,6 @@ Information Bilgi - - Initialization sanity check failed. Bitcoin Core is shutting down. - Başlatma sınaması başarısız oldu. Bitcoin Çekirdeği kapatılıyor. - - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<tutar> için geçersiz tutar: '%s' - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - -minrelaytxfee=<amount> için geçersiz meblağ: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - -mintxfee=<amount> için geçersiz meblağ: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) -paytxfee=<tutar>:'%s' unsurunda geçersiz tutar (asgari %s olması lazımdır) @@ -3411,14 +2270,6 @@ RPC server options: RPC sunucu seçenekleri: - - Rebuild block chain index from current blk000??.dat files on startup - Başlangıçta blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et - - - Receive and display P2P network alerts (default: %u) - P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Sistem sınırlamaları sebebiyle -maxconnections %d değerinden %d değerine düşürülmüştür. @@ -3491,10 +2342,6 @@ Username for JSON-RPC connections JSON-RPC bağlantıları için kullanıcı ismi - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Cüzdanın tekrar yazılması gerekmektedir: tamamlamak için Bitcoin Çekirdeğini yeniden başlatın - Warning Uyarı @@ -3515,10 +2362,6 @@ ZeroMQ notification options: ZeroMQ bildirim seçenekleri: - - wallet.dat corrupt, salvage failed - wallet.dat bozuk, geri kazanım başarısız oldu - Password for JSON-RPC connections JSON-RPC bağlantıları için parola @@ -3527,10 +2370,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) En iyi blok değiştiğinde komutu çalıştır (komut için %s parametresi blok hash değeri ile değiştirilecektir) - - This help message - Bu yardım mesajı - Allow DNS lookups for -addnode, -seednode and -connect -addnode, -seednode ve -connect için DNS aramalarına izin ver @@ -3539,10 +2378,6 @@ Loading addresses... Adresler yükleniyor... - - Error loading wallet.dat: Wallet corrupted - wallet.dat dosyasının yüklenmesinde hata oluştu: bozuk cüzdan - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at) @@ -3559,10 +2394,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) @@ -3599,6 +2430,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Desteklenmeyen -socks argümanı bulundu. SOCKS sürümünün ayarlanması artık mümkün değildir, sadece SOCKS5 vekilleri desteklenmektedir. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Desteklenmeyen argüman -whitelistalwaysrelay görmezden gelindi, -whitelistrelay ve/veya -whitelistforcerelay kullanın. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s) @@ -3607,6 +2442,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times JSON-RPC bağlantıları için kullanıcı ismi ve karmalanmış parola. <userpw> alanı şu biçimdedir: <USERNAME>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Bu seçenek birden çok kez belirtilebilir. + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + İkaz: bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür. + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün %s, %s olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir. + (default: %s) (varsayılan: %s) @@ -3615,14 +2458,6 @@ Always query for peer addresses via DNS lookup (default: %u) Eş adresleri sorgulaması için daima DNS aramasını kullan (varsayılan: %u) - - Error loading wallet.dat - wallet.dat dosyasının yüklenmesinde hata oluştu - - - Generate coins (default: %u) - Bitcoin oluştur (varsayılan: %u) - How many blocks to check at startup (default: %u, 0 = all) Başlangıçta kontrol edilecek blok sayısı (varsayılan: %u, 0 = hepsi) @@ -3707,18 +2542,6 @@ Unknown network specified in -onlynet: '%s' -onlynet için bilinmeyen bir şebeke belirtildi: '%s' - - Cannot resolve -bind address: '%s' - -bind adresi çözümlenemedi: '%s' - - - Cannot resolve -externalip address: '%s' - -externalip adresi çözümlenemedi: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - -paytxfee=<meblağ> için geçersiz meblağ: '%s' - Insufficient funds Yetersiz bakiye diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index 979aeea03..344309c25 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -25,10 +25,6 @@ C&lose K&apat - - &Copy Address - &Adresi Kopyala - Delete the currently selected address from the list Seçili adresi listeden sil @@ -45,73 +41,6 @@ &Delete &Sil - - Choose the address to send coins to - Para göndereceğiniz adresi seçin - - - Choose the address to receive coins with - Parayı alacağınız adresi seçin - - - C&hoose - S&eç - - - Sending addresses - Gönderim adresleri - - - Receiving addresses - Alış adresleri - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Bunlar ödeme gönderebileceğiniz Bitcoin adreslerinizdir. Para göndermeden önce mutlaka alıcı adresini ve tutarı kontrol edin. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Bunlar ödeme alabileceğiniz Bitcoin adreslerinizdir. Her işlem için yeni bir adres kullanmanız önerilir. - - - Copy &Label - Kopyala &Etiketle - - - &Edit - &Düzenle - - - Export Address List - Adres Listesini Dışa Aktar - - - Comma separated file (*.csv) - Virgül ile ayrılmış dosya (*.csv) - - - Exporting Failed - Dışa Aktarma Başarısız Oldu - - - There was an error trying to save the address list to %1. Please try again. - Adres listesini %1'e kaydederken bir hata oluştu. Lütfen tekrar deneyin. - - - - AddressTableModel - - Label - Etiket - - - Address - Adres - - - (no label) - (etiket yok) - AskPassphraseDialog @@ -126,15 +55,8 @@ Alış adresleri - - ClientModel - CoinControlDialog - - (no label) - (etiket yok) - EditAddressDialog @@ -146,7 +68,7 @@ &Address Adres - + FreespaceChecker @@ -165,18 +87,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -189,32 +105,9 @@ Copy &Address &Adresi Kopyala - - Address - Adres - - - Label - Etiket - - - - RecentRequestsTableModel - - Label - Etiket - - - (no label) - (etiket yok) - SendCoinsDialog - - (no label) - (etiket yok) - SendCoinsEntry @@ -231,58 +124,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - Etiket - - - - TransactionView - - Exporting Failed - Dışa Aktarma Başarısız Oldu - - - Comma separated file (*.csv) - Virgül ile ayrılmış dosya (*.csv) - - - Label - Etiket - - - Address - Adres - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - &Dışa Aktar - - - Export the data in the current tab to a file - Seçili sekmedeki veriyi dosya olarak dışa aktar - - bitcoin-core diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 64df7b5ba..668e787a6 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -25,10 +25,6 @@ C&lose З&акрити - - &Copy Address - &Скопіювати адресу - Delete the currently selected address from the list Вилучити вибрані адреси з переліку @@ -45,73 +41,6 @@ &Delete &Видалити - - Choose the address to send coins to - Виберіть адресу для відправлення монет - - - Choose the address to receive coins with - Виберіть адресу для отримання монет - - - C&hoose - &Обрати - - - Sending addresses - Адреси для відправлення - - - Receiving addresses - Адреси для отримання - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Це ваші Bitcoin-адреси для відправлення платежів. Перед відправленням монет завжди перевіряйте суму та адресу прийому. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Це ваша нова Bitcoin адреса для отримання платежів. Рекомендовано використовувати нову адресу для кожної транзакції. - - - Copy &Label - Скопіювати &мітку - - - &Edit - &Редагувати - - - Export Address List - Експортувати список адрес - - - Comma separated file (*.csv) - Значення, розділені комою (*.csv) - - - Exporting Failed - Помилка експорту - - - There was an error trying to save the address list to %1. Please try again. - Виникла помилка при спробі зберігання адрес до %1. Будь ласка спробуйте ще. - - - - AddressTableModel - - Label - Назва - - - Address - Адреса - - - (no label) - (немає назви) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase Повторіть пароль - - Encrypt wallet - Зашифрувати гаманець - - - This operation needs your wallet passphrase to unlock the wallet. - Ця операція потребує пароль для розблокування гаманця. - - - Unlock wallet - Розблокувати гаманець - - - This operation needs your wallet passphrase to decrypt the wallet. - Ця операція потребує пароль для дешифрування гаманця. - - - Decrypt wallet - Дешифрувати гаманець - - - Change passphrase - Змінити пароль - - - Confirm wallet encryption - Підтвердити шифрування гаманця - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - УВАГА: Якщо ви зашифруєте гаманець і забудете пароль, ви <b>ВТРАТИТЕ ВСІ СВОЇ БІТКОІНИ</b>! - - - Are you sure you wish to encrypt your wallet? - Ви дійсно хочете зашифрувати свій гаманець? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Клієнт «Bitcoin Core» буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не зможе повністю захистити ваші біткоїни від крадіжки якщо ваш комп'ютер буде інфіковано шкідливими програмами. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець. - - - Warning: The Caps Lock key is on! - Увага: Ввімкнено Caps Lock! - - - Wallet encrypted - Гаманець зашифровано - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> щонайменше десять випадкових символів </b> або <b> щонайменше вісім слів </b>. - - - Enter the old passphrase and new passphrase to the wallet. - Введіть старий пароль та новий пароль до гаманця. - - - Wallet encryption failed - Не вдалося зашифрувати гаманець - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Виникла помилка під час шифрування гаманця. Ваш гаманець не було зашифровано. - - - The supplied passphrases do not match. - Введені паролі не співпадають. - - - Wallet unlock failed - Не вдалося розблокувати гаманець - - - The passphrase entered for the wallet decryption was incorrect. - Введений пароль є неправильним. - - - Wallet decryption failed - Не вдалося розшифрувати гаманець - - - Wallet passphrase was successfully changed. - Пароль було успішно змінено. - BanTableModel @@ -269,6 +110,10 @@ Quit application Вийти + + &About %1 + П&ро %1 + About &Qt &Про Qt @@ -305,14 +150,6 @@ Open &URI... Відкрити &URI - - Bitcoin Core client - Клієнт «Bitcoin Core» - - - Importing blocks from disk... - Імпорт блоків з диску... - Reindexing blocks on disk... Переіндексація блоків на диску ... @@ -357,10 +194,6 @@ &Receive &Отримати - - Show information about Bitcoin Core - Показати інформацію про Bitcoin Core - &Show / Hide Показа&ти / Приховати @@ -397,22 +230,10 @@ Tabs toolbar Панель вкладок - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Створити запит платежу (генерує QR-код та bitcoin: URI) - - &About Bitcoin Core - П&ро Bitcoin Core - - - Modify configuration options for Bitcoin Core - Редагувати параметри Bitcoin Core - Show the list of used sending addresses and labels Показати список адрес і міток, що були використані для відправлення @@ -429,10 +250,6 @@ &Command-line options П&араметри командного рядка - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Показати довідку Bitcoin Core для отримання переліку можливих параметрів командного рядка. - %n active connection(s) to Bitcoin network %n активне з'єднання з мережею Bitcoin%n активні з'єднання з мережею Bitcoin%n активних з'єднань з мережею Bitcoin @@ -544,13 +361,6 @@ <b>Зашифрований</b> гаманець <b>заблоковано</b> - - ClientModel - - Network Alert - Сповіщення мережі - - CoinControlDialog @@ -629,150 +439,6 @@ Priority Пріоритет - - Copy address - Скопіювати адресу - - - Copy label - Скопіювати мітку - - - Copy amount - Скопіювати суму - - - Copy transaction ID - Скопіювати ID транзакції - - - Lock unspent - Заблокувати - - - Unlock unspent - Розблокувати - - - Copy quantity - Скопіювати кількість - - - Copy fee - Скопіювати комісію - - - Copy after fee - Скопіювати після комісії - - - Copy bytes - Скопіювати байти - - - Copy priority - Скопіювати пріорітет - - - Copy dust - Скопіювати пил - - - Copy change - Скопіювати решту - - - highest - найвищий - - - higher - вищий - - - high - високий - - - medium-high - вище за середній - - - medium - середній - - - low-medium - нижче за середній - - - low - низький - - - lower - нижчий - - - lowest - найнижчий - - - (%1 locked) - (%1 заблоковано) - - - none - відсутній - - - This label turns red if the transaction size is greater than 1000 bytes. - Ця позначка стане червоною, якщо розмір транзакції перевищить 1000 байтів. - - - This label turns red if the priority is smaller than "medium". - Ця позначка стане червоною, якщо пріоритет транзакції менше, ніж «середній». - - - This label turns red if any recipient receives an amount smaller than %1. - Ця позначка стане червоною, якщо будь-який отримувач отримає суму, меншу за %1. - - - Can vary +/- %1 satoshi(s) per input. - Може відрізнятися на +/- %1 сатоші за вхід - - - yes - так - - - no - ні - - - This means a fee of at least %1 per kB is required. - Це означає, що необхідно внести комісію (щонайменше %1 за КБ). - - - Can vary +/- 1 byte per input. - Може відрізнятися на +/- 1 байт за вхід. - - - Transactions with higher priority are more likely to get included into a block. - Транзакції з вищим пріоритетом мають більше шансів бути включеними до блоку. - - - (no label) - (немає назви) - - - change from %1 (%2) - решта з %1 (%2) - - - (change) - (решта) - EditAddressDialog @@ -796,38 +462,6 @@ &Address &Адреса - - New receiving address - Нова адреса для отримання - - - New sending address - Нова адреса для відправлення - - - Edit receiving address - Редагувати адресу для отримання - - - Edit sending address - Редагувати адресу для відправлення - - - The entered address "%1" is already in the address book. - Введена адреса «%1» вже присутня в адресній книзі. - - - The entered address "%1" is not a valid Bitcoin address. - Введена адреса «%1» не є коректною адресою в мережі Bitcoin. - - - Could not unlock wallet. - Неможливо розблокувати гаманець. - - - New key generation failed. - Не вдалося згенерувати нові ключі. - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version версії @@ -866,10 +496,6 @@ (%1-bit) (%1-бітний) - - About Bitcoin Core - Про Bitcoin Core - Command-line options Параметри командного рядка @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) Показувати заставку під час запуску (типово: %u) - - Reset all settings changes made over the GUI - Скинути налаштування, які було змінено через графічний інтерфейс користувача - - + Intro Welcome Вітання - - Welcome to Bitcoin Core. - Ласкаво просимо в Bitcoin Core. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Оскільки це перший запуск програми, ви можете обрати де Bitcoin Core буде зберігати дані. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core завантажить та збереже копію ланцюжка блоків Bitcoin. Щонайменше %1ГБ даних буде збережено в цьому каталозі. Гаманець теж буде збережено в цьому каталозі. - Use the default data directory Використовувати типовий каталог даних @@ -937,10 +547,6 @@ Use a custom data directory: Використовувати свій каталог даних: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Помилка: неможливо створити обраний каталог даних «%1». @@ -976,10 +582,6 @@ Select payment request file Виберіть файл запиту платежу - - Select payment request file to open - Виберіть файл запиту платежу для відкриття - OptionsDialog @@ -1019,10 +621,6 @@ 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. Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню. - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin Core. - 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 |. Сторонні URL (наприклад, block explorer), що з'являться на вкладці транзакцій у вигляді пункту контекстного меню. %s в URL буде замінено на хеш транзакції. Для відокремлення URLів використовуйте вертикальну риску |. @@ -1047,14 +645,6 @@ &Network &Мережа - - Automatically start Bitcoin Core after logging in to the system. - Автоматично запускати Bitcoin Core при вході до системи. - - - &Start Bitcoin Core on system login - &Запускати Bitcoin Core при вході до системи - (0 = auto, <0 = leave that many cores free) (0 = автоматично, <0 = вказує кількість вільних ядер) @@ -1283,97 +873,6 @@ Поточний сукупний баланс в адресах для спостереження - - PaymentServer - - URI handling - Обробка URI - - - Invalid payment address %1 - Помилка в адресі платежу %1 - - - Payment request rejected - Запит платежу відхилено - - - Payment request network doesn't match client network. - Мережа запиту платежу не є мережею клієнта. - - - Payment request is not initialized. - Запит платежу не ініціалізовано. - - - Requested payment amount of %1 is too small (considered dust). - Сума запиту платежу для %1 занадто мала (вважається пилом) - - - Payment request error - Помилка запиту платежу - - - Cannot start bitcoin: click-to-pay handler - Неможливо запустити bitcoin: обробник click-to-pay - - - Payment request fetch URL is invalid: %1 - URL запиту платежу є некоректним: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - Неможливо обробити URI! Причиною цього може бути некоректна Bitcoin-адреса або неправильні параметри URI. - - - Payment request file handling - Обробка файлу запиту платежу - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено. - - - Payment request expired. - Запит платежу прострочено. - - - Unverified payment requests to custom payment scripts are unsupported. - Неперевірені запити платежів з власними платіжними сценаріями не підтримуються. - - - Invalid payment request. - Помилка в запиті платежу. - - - Refund from %1 - Відшкодування з %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт). - - - Error communicating with %1: %2 - Помилка зв'язку з %1: %2 - - - Payment request cannot be parsed! - Неможливо розпізнати запит платежу! - - - Bad response from server %1 - Погана відповідь від сервера %1 - - - Payment acknowledged - Платіж підтверджено - - - Network request error - Помилка мережевого запиту - - PeerTableModel @@ -1428,25 +927,6 @@ %1 мс - - QRImageWidget - - &Save Image... - &Зберегти зображення... - - - &Copy Image - &Копіювати зображення - - - Save QR Code - Зберегти QR-код - - - PNG Image (*.png) - Зображення PNG (*.png) - - RPCConsole @@ -1513,10 +993,6 @@ Memory usage Використання пам'яті - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів. - Received Отримано @@ -1633,10 +1109,6 @@ Out: Вихідних: - - Build date - Дата збирання - Debug log file Файл звіту зневадження @@ -1673,10 +1145,6 @@ &Unban Node &Розблокувати Вузол - - Welcome to the Bitcoin Core RPC console. - Вітаємо у RPC-консолі Bitcoin Core. - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Використовуйте стрілки вгору вниз для навігації по історії, і <b>Ctrl-L</b> для очищення екрана. @@ -1804,18 +1272,6 @@ Remove Вилучити - - Copy label - Скопіювати мітку - - - Copy message - Скопіювати повідомлення - - - Copy amount - Копіювати кількість - ReceiveRequestDialog @@ -1835,73 +1291,6 @@ &Save Image... &Зберегти зображення... - - Request payment to %1 - Запит платежу на %1 - - - Payment information - Інформація про платіж - - - URI - URI - - - Address - Адреса - - - Amount - Кількість - - - Label - Назва - - - Message - Повідомлення - - - Resulting URI too long, try to reduce the text for label / message. - Кінцевий URI занадто довгий, спробуйте зменшити текст для мітки / повідомлення. - - - Error encoding URI into QR Code. - Помилка при кодуванні URI в QR-код. - - - - RecentRequestsTableModel - - Date - Дата - - - Label - Назва - - - Message - Повідомлення - - - Amount - Кількість - - - (no label) - (немає назви) - - - (no message) - (без повідомлення) - - - (no amount) - (без суми) - SendCoinsDialog @@ -2021,14 +1410,6 @@ fast швидкий - - Send as zero-fee transaction if possible - Надіслати транзакцію без сплати комісії, якщо це можливо - - - (confirmation may take longer) - (підтвердження може зайняти більше часу) - Send to multiple recipients at once Відправити на декілька адрес @@ -2061,118 +1442,6 @@ S&end &Відправити - - Confirm send coins - Підтвердіть відправлення - - - %1 to %2 - %1 на %2 - - - Copy quantity - Копіювати кількість - - - Copy amount - Копіювати суму - - - Copy fee - Копіювати комісію - - - Copy after fee - Копіювати після комісії - - - Copy bytes - Копіювати байти - - - Copy priority - Копіювати пріорітет - - - Copy change - Копіювати решту - - - Total Amount %1 - Всього %1 - - - or - або - - - The amount to pay must be larger than 0. - Кількість монет для відправлення повинна бути більше 0. - - - The amount exceeds your balance. - Кількість монет для відправлення перевищує ваш баланс. - - - The total exceeds your balance when the %1 transaction fee is included. - Сума перевищить ваш баланс, якщо комісія %1 буде додана до вашої транзакції. - - - Transaction creation failed! - Не вдалося створити транзакцію! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Транзакцію відхилено! Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій. - - - A fee higher than %1 is considered an absurdly high fee. - Плата вища, ніж %1 вважається шалено високою. - - - Payment request expired. - Запит платежу прострочено. - - - Pay only the required fee of %1 - Сплатіть лише мінімальну комісію у розмірі %1 - - - Estimated to begin confirmation within %n block(s). - Перше підтвердження очікується протягом %n блоку.Перше підтвердження очікується протягом %n блоків.Перше підтвердження очікується протягом %n блоків. - - - The recipient address is not valid. Please recheck. - Адреса отримувача неправильна. Будь ласка, перевірте її. - - - Duplicate address found: addresses should only be used once each. - Знайдено адресу, що дублюється: кожна адреса має бути вказана не більше одного разу. - - - Warning: Invalid Bitcoin address - Увага: Неправильна Bitcoin-адреса - - - (no label) - (немає назви) - - - Warning: Unknown change address - Увага: Невідома адреса для решти - - - Copy dust - Копіювати пил - - - Are you sure you want to send? - Ви впевнені, що хочете відправити? - - - added as transaction fee - додано як комісія за транзакцію - SendCoinsEntry @@ -2184,10 +1453,6 @@ Pay &To: &Отримувач: - - Enter a label for this address to add it to your address book - Введіть мітку для цієї адреси для додавання її в адресну книгу - &Label: &Мітка: @@ -2259,10 +1524,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - Bitcoin Core вимикається... - Do not shut down the computer until this window disappears. Не вимикайте комп’ютер до зникнення цього вікна. @@ -2354,69 +1615,9 @@ Reset all verify message fields Скинути всі поля перевірки повідомлення - - Click "Sign Message" to generate signature - Натисніть кнопку «Підписати повідомлення», для отримання підпису - - - The entered address is invalid. - Введена нечинна адреса. - - - Please check the address and try again. - Будь ласка, перевірте адресу та спробуйте ще. - - - The entered address does not refer to a key. - Введена адреса не відноситься до ключа. - - - Wallet unlock was cancelled. - Розблокування гаманця було скасоване. - - - Private key for the entered address is not available. - Приватний ключ для введеної адреси недоступний. - - - Message signing failed. - Не вдалося підписати повідомлення. - - - Message signed. - Повідомлення підписано. - - - The signature could not be decoded. - Підпис не можливо декодувати. - - - Please check the signature and try again. - Будь ласка, перевірте підпис та спробуйте ще. - - - The signature did not match the message digest. - Підпис не збігається з хешем повідомлення. - - - Message verification failed. - Не вдалося перевірити повідомлення. - - - Message verified. - Повідомлення перевірено. - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Розробники Bitcoin Core - [testnet] [тестова мережа] @@ -2429,422 +1630,13 @@ КБ/с - - TransactionDesc - - Open until %1 - Відкрито до %1 - - - conflicted - суперечить - - - %1/offline - %1/поза інтернетом - - - %1/unconfirmed - %1/не підтверджено - - - %1 confirmations - %1 підтверджень - - - Status - Статус - - - , broadcast through %n node(s) - , розіслано через %n вузол, розіслано через %n вузли, розіслано через %n вузлів - - - Date - Дата - - - Source - Джерело - - - Generated - Згенеровано - - - From - Відправник - - - To - Отримувач - - - own address - Власна адреса - - - watch-only - тільки спостереження - - - label - Мітка - - - Credit - Кредит - - - matures in %n more block(s) - «дозріє» через %n блок«дозріє» через %n блоки«дозріє» через %n блоків - - - not accepted - не прийнято - - - Debit - Дебет - - - Total debit - Загальний дебет - - - Total credit - Загальний кредит - - - Transaction fee - Комісія за транзакцію - - - Net amount - Загальна сума - - - Message - Повідомлення - - - Comment - Коментар - - - Transaction ID - ID транзакції - - - Merchant - Продавець - - - 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. - Після генерації монет, потрібно зачекати %1 блоків, перш ніж їх можна буде використати. Коли ви згенерували цей блок, його було відправлено в мережу для того, щоб він був доданий до ланцюжка блоків. Якщо ця процедура не вдасться, статус буде змінено на «не підтверджено» і ви не зможете витратити згенеровані монети. Таке може статись, якщо хтось інший згенерував блок на декілька секунд раніше. - - - Debug information - Налагоджувальна інформація - - - Transaction - Транзакція - - - Inputs - Входи - - - Amount - Кількість - - - true - true - - - false - false - - - , has not been successfully broadcast yet - , ще не було успішно розіслано - - - Open for %n more block(s) - Відкрито на %n блокВідкрито на %n блокиВідкрито на %n блоків - - - unknown - невідомо - - TransactionDescDialog - - Transaction details - Деталі транзакції - This pane shows a detailed description of the transaction Даний діалог показує детальну статистику по вибраній транзакції - - TransactionTableModel - - Date - Дата - - - Type - Тип - - - Immature (%1 confirmations, will be available after %2) - Незрілі (%1 підтверджень, будуть доступні після %2) - - - Open for %n more block(s) - Відкрито на %n блокВідкрито на %n блокиВідкрито на %n блоків - - - Open until %1 - Відкрито до %1 - - - Confirmed (%1 confirmations) - Підтверджено (%1 підтверджень) - - - This block was not received by any other nodes and will probably not be accepted! - Цей блок не був отриманий жодними іншими вузлами і, ймовірно, не буде прийнятий! - - - Generated but not accepted - Згенеровано, але не підтверджено - - - Offline - Поза мережею - - - Label - Назва - - - Unconfirmed - Не підтверджено - - - Confirming (%1 of %2 recommended confirmations) - Підтверджується (%1 з %2 рекомендованих підтверджень) - - - Conflicted - Суперечить - - - Received with - Отримані на - - - Received from - Отримано від - - - Sent to - Відправлені на - - - Payment to yourself - Відправлено собі - - - Mined - Добуті - - - watch-only - тільки спостереження - - - (n/a) - (недоступно) - - - Transaction status. Hover over this field to show number of confirmations. - Статус транзакції. Наведіть вказівник на це поле, щоб показати кількість підтверджень. - - - Date and time that the transaction was received. - Дата і час, коли транзакцію було отримано. - - - Type of transaction. - Тип транзакції. - - - Whether or not a watch-only address is involved in this transaction. - Показує, чи було залучено адресу для спостереження в цій транзакції. - - - User-defined intent/purpose of the transaction. - Призначення транзакції (визначається користувачем). - - - Amount removed from or added to balance. - Сума, додана чи знята з балансу. - - - - TransactionView - - All - Всі - - - Today - Сьогодні - - - This week - На цьому тижні - - - This month - На цьому місяці - - - Last month - Минулого місяця - - - This year - Цього року - - - Range... - Проміжок... - - - Received with - Отримані на - - - Sent to - Відправлені на - - - To yourself - Відправлені собі - - - Mined - Добуті - - - Other - Інше - - - Enter address or label to search - Введіть адресу чи мітку для пошуку - - - Min amount - Мінімальна сума - - - Copy address - Скопіювати адресу - - - Copy label - Скопіювати мітку - - - Copy amount - Скопіювати суму - - - Copy transaction ID - Скопіювати ID транзакції - - - Copy raw transaction - Скопіювати RAW транзакцію - - - Edit label - Редагувати мітку - - - Show transaction details - Показати деталі транзакції - - - Export Transaction History - Експортувати історію транзакцій - - - Watch-only - Для спостереження - - - Exporting Failed - Помилка експорту - - - There was an error trying to save the transaction history to %1. - Виникла помилка при спробі зберігання історії транзакцій до %1. - - - Exporting Successful - Експорт успішно виконано - - - The transaction history was successfully saved to %1. - Історію транзакцій було успішно збережено до %1. - - - Comma separated file (*.csv) - Значення, розділені комою (*.csv) - - - Confirmed - Підтверджені - - - Date - Дата - - - Type - Тип - - - Label - Назва - - - Address - Адреса - - - ID - Ідентифікатор - - - Range: - Діапазон від: - - - to - до - - UnitDisplayStatusBarControl @@ -2852,55 +1644,6 @@ Одиниця виміру монет. Натисніть для вибору іншої. - - WalletFrame - - No wallet has been loaded. - Гаманець не завантажувався - - - - WalletModel - - Send Coins - Відправити - - - - WalletView - - &Export - &Експорт - - - Export the data in the current tab to a file - Експортувати дані з поточної вкладки в файл - - - Backup Wallet - Зробити резервне копіювання гаманця - - - Wallet Data (*.dat) - Данi гаманця (*.dat) - - - Backup Failed - Помилка резервного копіювання - - - There was an error trying to save the wallet data to %1. - Виникла помилка при спробі зберегти гаманець в %1. - - - The wallet data was successfully saved to %1. - Дані гаманця успішно збережено в %1. - - - Backup Successful - Успішне створення резервної копії - - bitcoin-core @@ -2927,14 +1670,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Якщо <category> не задано, або ж якщо <category> = 1, виводить всю налагоджувальну інформацію. - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - Максимальна загальна комісія (в %s) за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - Будь ласка, перевірте коректність дати і часу на своєму комп'ютері! За наявності значної похибки Bitcoin Core буде працювати неправильно. - Prune configured below the minimum of %d MiB. Please use a higher number. Встановлений розмір ланцюжка блоків є замалим (меншим за %d МіБ). Будь ласка, виберіть більше число. @@ -2975,6 +1710,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) Приймати підключення ззовні (типово: 1 за відсутності -proxy чи -connect) + + Bitcoin Core + Bitcoin Core + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Прив'язатися до даної адреси та прослуховувати її. Використовуйте запис виду [хост]:порт для IPv6 @@ -3003,10 +1742,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Це тестова збірка пре-релізної версії - використовуйте на свій страх і ризик - не застосовувати для добування монет або торгівлі - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) Використовувати UPnP для відображення порту, що прослуховується (типово: 1 при прослуховуванні та за відсутності -proxy) @@ -3027,10 +1762,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Увага: Наш ланцюжок блоків відрізняється від ланцюжків підключених учасників! Можливо, вам, або іншим вузлам, необхідно оновитися. - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Увага: файл wallet.dat пошкоджено, дані врятовано! Оригінальний wallet.dat збережено як wallet.{timestamp}.bak до %s; якщо Ваш баланс чи транзакції неправильні, Ви можете відновити їх з резервної копії. - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Додати учасників, що під'єднуються з заданої підмережі чи IP-адреси, в білий список. Можна вказувати декілька разів. @@ -3195,10 +1926,6 @@ Wallet options: Параметри гаманця: - - You need to rebuild the database using -reindex to change -txindex - Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times Дозволити підключення по протоколу JSON-RPC зі вказаного джерела. Правильною для <ip> є окрема IP-адреса (наприклад, 1.2.3.4), IP-адреса та маска підмережі (наприклад, 1.2.3.4/255.255.255.0) або CIDR-адреса (наприклад, 1.2.3.4/24). Цей параметр можна вказувати декілька разів. @@ -3211,10 +1938,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) Прив'язатися до даної адреси для прослуховування JSON-RPC підключень. Використовуйте запис виду [хост]:порт для IPv6. Цей параметр можна вказувати декілька разів (типово: прив'язуватися до всіх інтерфейсів) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - Не вдалося встановити блокування на каталог даних %s. Bitcoin Core, ймовірно, вже запущений. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці) @@ -3259,10 +1982,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d) - The transaction amount is too small to send after the fee has been deducted Залишок від суми транзакції зі сплатою комісії занадто малий @@ -3287,34 +2006,14 @@ Accept public REST requests (default: %u) Приймати публічні REST-запити (типово: %u) - - Activating best chain... - Активація найкращого ланцюжка... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - Спочатку спробуйте відновити приватні ключі в пошкодженому wallet.dat - Automatically create Tor hidden service (default: %d) Автоматичне з'єднання з прихованим сервісом Tor (типово: %d) - - Cannot resolve -whitebind address: '%s' - Не вдалося розпізнати адресу для -whitebind: «%s» - Connect through SOCKS5 proxy Підключитись через SOCKS5-проксі - - Copyright (C) 2009-%i The Bitcoin Core Developers - (C) 2009-%i Розробники Bitcoin Core - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core - Error reading from database, shutting down. Помилка читання бази даних, припиняю роботу. @@ -3327,22 +2026,6 @@ Information Інформація - - Initialization sanity check failed. Bitcoin Core is shutting down. - Не вдалося пройти базові перевірки під час ініціалізації. Bitcoin Core буде вимкнено. - - - Invalid amount for -maxtxfee=<amount>: '%s' - Неприпустима сума для -maxtxfee = <amount>: «%s» - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - Вказано некоректну суму для параметру -minrelaytxfee: «%s» - - - Invalid amount for -mintxfee=<amount>: '%s' - Вказано некоректну суму для параметру -mintxfee: «%s» - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) Вказано некоректну суму для параметру -paytxfee: «%s» (повинно бути щонайменше %s) @@ -3367,14 +2050,6 @@ RPC server options: Параметри сервера RPC: - - Rebuild block chain index from current blk000??.dat files on startup - При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat - - - Receive and display P2P network alerts (default: %u) - Отримувати та відображати попередження з мережі (типово: %u) - Reducing -maxconnections from %d to %d, because of system limitations. Зменшення значення -maxconnections з %d до %d із-за обмежень системи. @@ -3447,10 +2122,6 @@ Username for JSON-RPC connections Ім'я користувача для JSON-RPC-з'єднань - - Wallet needed to be rewritten: restart Bitcoin Core to complete - Потрібно перезаписати гаманець: перезапустіть Bitcoin Core для завершення - Warning Попередження @@ -3467,10 +2138,6 @@ ZeroMQ notification options: Параметри сповіщень ZeroMQ: - - wallet.dat corrupt, salvage failed - wallet.dat пошкоджено, відновлення не вдалося - Password for JSON-RPC connections Пароль для JSON-RPC-з'єднань @@ -3479,10 +2146,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) Виконати команду, коли з'явиться новий блок (%s в команді змінюється на хеш блоку) - - This help message - Дана довідка - Allow DNS lookups for -addnode, -seednode and -connect Дозволити пошук в DNS для команд -addnode, -seednode та -connect @@ -3491,10 +2154,6 @@ Loading addresses... Завантаження адрес... - - Error loading wallet.dat: Wallet corrupted - Помилка при завантаженні wallet.dat: Гаманець пошкоджено - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути) @@ -3511,10 +2170,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) Не тримати транзакції в пам'яті довше <n> годин (типово: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Помилка читання wallet.dat! Всі ключі прочитано коректно, але дані транзакцій чи записи адресної книги можуть бути пропущені або пошкоджені. - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для створення транзакцій (типово: %s) @@ -3567,14 +2222,6 @@ Always query for peer addresses via DNS lookup (default: %u) Завжди дізнаватися адреси учасників через DNS (типово: %u) - - Error loading wallet.dat - Помилка при завантаженні wallet.dat - - - Generate coins (default: %u) - Генерація монет (типово: %u) - How many blocks to check at startup (default: %u, 0 = all) Скільки блоків перевіряти під час запуску (типово: %u, 0 = всі) @@ -3659,18 +2306,6 @@ Unknown network specified in -onlynet: '%s' Невідома мережа вказана в -onlynet: «%s» - - Cannot resolve -bind address: '%s' - Не вдалося розпізнати адресу для -bind: «%s» - - - Cannot resolve -externalip address: '%s' - Не вдалося розпізнати адресу для -externalip: «%s» - - - Invalid amount for -paytxfee=<amount>: '%s' - Помилка у величині комісії -paytxfee=<amount>: «%s» - Insufficient funds Недостатньо коштів diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index e37c87baa..6b43bf63e 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -25,10 +25,6 @@ C&lose بند - - &Copy Address - کاپی پتہ - Delete the currently selected address from the list سلیکٹڈ پتے کو مٹائیں @@ -45,37 +41,6 @@ &Delete مٹا - - Choose the address to send coins to - کوئین وصول کرنے والے کا پتہ - - - Choose the address to receive coins with - کوئین بھیجنے والے کا پتہ - - - C&hoose - چننا - - - Sending addresses - جس پتے پر بھیجنے ہیں - - - - AddressTableModel - - Label - چٹ - - - Address - پتہ - - - (no label) - چٹ کے بغیر - AskPassphraseDialog @@ -91,23 +56,7 @@ Repeat new passphrase نیا پاس فریز دہرائیں - - Encrypt wallet - بٹوے کی رمزنگاری - - - Unlock wallet - بٹوا ان لاک - - - Decrypt wallet - خفیہ کشائی کر یںبٹوے کے - - - Change passphrase - پاس فریز تبدیل کریں - - + BanTableModel @@ -118,9 +67,6 @@ نقص - - ClientModel - CoinControlDialog @@ -135,10 +81,6 @@ Date تاریخ - - (no label) - چٹ کے بغیر - EditAddressDialog @@ -150,7 +92,7 @@ &Address پتہ - + FreespaceChecker @@ -173,9 +115,6 @@ OverviewPage - - PaymentServer - PeerTableModel @@ -186,9 +125,6 @@ رقم - - QRImageWidget - RPCConsole @@ -201,37 +137,6 @@ Copy &Address کاپی پتہ - - Address - پتہ - - - Amount - رقم - - - Label - چٹ - - - - RecentRequestsTableModel - - Date - تاریخ - - - Label - چٹ - - - Amount - رقم - - - (no label) - چٹ کے بغیر - SendCoinsDialog @@ -247,10 +152,6 @@ Balance: بیلنس: - - (no label) - چٹ کے بغیر - SendCoinsEntry @@ -267,120 +168,14 @@ TrafficGraphWidget - - TransactionDesc - - Date - تاریخ - - - Amount - رقم - - TransactionDescDialog - - TransactionTableModel - - Date - تاریخ - - - Type - ٹائپ - - - Label - چٹ - - - Sent to - کو بھیجا - - - (n/a) - (N / A) - - - - TransactionView - - All - تمام - - - Today - آج - - - This week - اس ہفتے - - - This month - اس مہینے - - - Last month - پچھلے مہینے - - - This year - اس سال - - - Range... - دیگر - - - Sent to - کو بھیجا - - - Date - تاریخ - - - Type - ٹائپ - - - Label - چٹ - - - Address - پتہ - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - برآمد - - - Export the data in the current tab to a file - موجودہ ڈیٹا کو فائیل میں محفوظ کریں - - bitcoin-core - - This help message - یہ مدد کا پیغام - Insufficient funds ناکافی فنڈز diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index a9f9af668..ce3326297 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -25,10 +25,6 @@ C&lose &Ёпиш - - &Copy Address - Манзилдан &нусха олиш - Delete the currently selected address from the list Жорий танланган манзилни рўйхатдан ўчириш @@ -45,73 +41,6 @@ &Delete &Ўчириш - - Choose the address to send coins to - Тангаларни жўнатиш учун манзилни танланг - - - Choose the address to receive coins with - Тангаларни қабул қилиш учун манзилни танланг - - - C&hoose - &Танлаш - - - Sending addresses - Жўнатиладиган манзиллар - - - Receiving addresses - Қабул қилинадиган манзиллар - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Улар тўловларни жўнатиш учун сизнинг Bitcoin манзилларингиз. Доимо тангаларни жўнатишдан олдин сумма ва қабул қилувчи манзилни текшириб кўринг. - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Улар тўловларни қабул қилиш учун сизнинг Bitcoin манзилларингиз. Ҳар бир ўтказма учун янги қабул қилувчи манзилдан фойдаланиш тавсия қилинади. - - - Copy &Label - Нусха олиш ва ёрлиқ - - - &Edit - &Таҳрирлаш - - - Export Address List - Манзил рўйхатини экспорт қилиш - - - Comma separated file (*.csv) - Вергул билан ажратилган файл (*.csv) - - - Exporting Failed - Экспорт қилиб бўлмади - - - There was an error trying to save the address list to %1. Please try again. - Манзил рўйхатини %1.га сақлашда хатолик юз берди. Яна уриниб кўринг. - - - - AddressTableModel - - Label - Ёрлиқ - - - Address - Манзил - - - (no label) - (Ёрлиқ мавжуд эмас) - AskPassphraseDialog @@ -131,86 +60,6 @@ Repeat new passphrase Янги махфий сузни такрорланг - - Encrypt wallet - Ҳамённи қодлаш - - - This operation needs your wallet passphrase to unlock the wallet. - Ушбу операцияни амалга ошириш учун ҳамённи қулфдан чиқариш парол сўзини талаб қилади. - - - Unlock wallet - Ҳамённи қулфдан чиқариш - - - This operation needs your wallet passphrase to decrypt the wallet. - Ушбу операцияни амалга ошириш учун ҳамённи коддан чиқариш парол сўзини талаб қилади. - - - Decrypt wallet - Ҳамённи коддан чиқариш - - - Change passphrase - Махфий сузни узгартириш - - - Confirm wallet encryption - Ҳамённи кодлашни тасдиқлаш - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Диққат: Агар сиз ҳамёнингизни кодласангиз ва махфий сўзингизни унутсангиз, сиз <b>БАРЧА BITCOIN ПУЛЛАРИНГИЗНИ ЙЎҚОТАСИЗ</b>! - - - Are you sure you wish to encrypt your wallet? - Ҳамёнингизни кодлашни ростдан хоҳлайсизми? - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - МУҲИМ: Сиз қилган олдинги ҳамён файли заҳиралари янги яратилган, кодланган ҳамён файли билан алмаштирилиши керак. Хавфсизлик сабабларига кўра олдинги кодланган ҳамён файли заҳираси янги кодланган ҳамёндан фойдаланишингиз билан яроқсиз ҳолга келади. - - - Warning: The Caps Lock key is on! - Диққат: Caps Lock тугмаси ёқилган! - - - Wallet encrypted - Ҳамёни кодланган - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Ҳамёнга янги махфий сўз киритинг.<br/>Илтимос, <b>ўнта ёки тасодифий белгили</b> махфий сўздан фойдаланинг ёки <b>саккизта ёки кўпроқ сўзлар</b>дан фойдаланинг. - - - Wallet encryption failed - Ҳамённи кодлаш амалга ошмади - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Ҳамённи кодлаш ташқи хато туфайли амалга ошмади. Ҳамёнингиз кодланмади. - - - The supplied passphrases do not match. - Киритилган пароллар мос келмади. - - - Wallet unlock failed - Ҳамённи қулфдан чиқариш амалга ошмади - - - The passphrase entered for the wallet decryption was incorrect. - Ҳамённи коддан чиқариш учун киритилган парол нотўғри. - - - Wallet decryption failed - Ҳамённи коддан чиқариш амалга ошмади - - - Wallet passphrase was successfully changed. - Ҳамён пароли муваффақиятли алмаштирилди. - BanTableModel @@ -289,14 +138,6 @@ Open &URI... Интернет манзилни очиш - - Bitcoin Core client - Bitcoin асос мижози - - - Importing blocks from disk... - Дискдан блоклар импорт қилинмоқда... - Reindexing blocks on disk... Дискдаги блоклар қайта индексланмоқда... @@ -341,10 +182,6 @@ &Receive &Қабул қилиш - - Show information about Bitcoin Core - Bitcoin Core ҳақидаги маълумотларни кўрсатиш - &Show / Hide &Кўрсатиш / Яшириш @@ -381,18 +218,10 @@ Tabs toolbar Ички ойналар асбоблар панели - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) Тўловлар (QR кодлари ва bitcoin ёрдамида яратишлар: URI’лар) сўраш - - &About Bitcoin Core - Bitcoin Core &ҳақида - Show the list of used sending addresses and labels Фойдаланилган жўнатилган манзиллар ва ёрлиқлар рўйхатини кўрсатиш @@ -409,10 +238,6 @@ &Command-line options &Буйруқлар сатри мосламалари - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Мавжуд Bitcoin буйруқлар матни мосламалари билан Bitcoin Core ёрдам хабарларини олиш рўйхатини кўрсатиш - %n active connection(s) to Bitcoin network %n та Bitcoin тармоғига фаол уланиш мавжуд @@ -490,13 +315,6 @@ Ҳамён <b>кодланган</b> ва вақтинча <b>қулфланган</b> - - ClientModel - - Network Alert - Тармоқ огоҳлантиргичи - - CoinControlDialog @@ -563,138 +381,6 @@ Priority Муҳимлиги - - Copy address - Манзилни нусхалаш - - - Copy label - Ёрликни нусхала - - - Copy amount - Кийматни нусхала - - - Copy transaction ID - Ўтказам рақамидан нусха олиш - - - Lock unspent - Сарфланмаганларни қулфлаш - - - Unlock unspent - Сарфланмаганларни қулфдан чиқариш - - - Copy quantity - Нусха сони - - - Copy fee - Нусха солиғи - - - Copy after fee - Нусха солиқдан сўнг - - - Copy bytes - Нусха байти - - - Copy priority - Нусха муҳимлиги - - - Copy dust - Нусха чангги - - - Copy change - Нусха қайтими - - - highest - энг юқори - - - higher - юқорирок - - - high - юқори - - - medium-high - ўртача-юқори - - - medium - ўрта - - - low-medium - паст-юқори - - - low - паст - - - lower - пастроқ - - - lowest - энг паст - - - (%1 locked) - (%1 қулфланган) - - - none - йўқ - - - Can vary +/- %1 satoshi(s) per input. - Ҳар бир кирим +/- %1 сатоши(лар) билан ўзгариши мумкин. - - - yes - ҳа - - - no - йўқ - - - This means a fee of at least %1 per kB is required. - Бу дегани солиқ ҳар кб учун камида %1 талаб қилинади. - - - Can vary +/- 1 byte per input. - Ҳар бир кирим +/- 1 байт билан ўзгариши мумкин. - - - Transactions with higher priority are more likely to get included into a block. - Юқори муҳимликка эга бўлган ўтказмалар тезда блокнинг ичига қўшимча олади. - - - (no label) - (Ёрлик мавжуд эмас) - - - change from %1 (%2) - %1 (%2)дан ўзгартириш - - - (change) - (ўзгартириш) - EditAddressDialog @@ -718,38 +404,6 @@ &Address &Манзил - - New receiving address - Янги кабул килувчи манзил - - - New sending address - Янги жунатилувчи манзил - - - Edit receiving address - Кабул килувчи манзилни тахрирлаш - - - Edit sending address - Жунатилувчи манзилни тахрирлаш - - - The entered address "%1" is already in the address book. - Киритилган "%1" манзили аллақачон манзил китобида. - - - The entered address "%1" is not a valid Bitcoin address. - Киритилган "%1" манзили тўғри Bitcoin манзили эмас. - - - Could not unlock wallet. - Ҳамён қулфдан чиқмади. - - - New key generation failed. - Янги калит яратиш амалга ошмади. - FreespaceChecker @@ -776,10 +430,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version версияси @@ -788,10 +438,6 @@ (%1-bit) (%1-bit) - - About Bitcoin Core - Bitcoin Core ҳақида - Command-line options Буйруқлар сатри мосламалари @@ -811,18 +457,6 @@ Welcome Хуш келибсиз - - Welcome to Bitcoin Core. - "Bitcoin Core"га хуш келибсиз. - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - Биринчи марта дастур ишга тушгани каби сиз Bitcoin Core маълумотларини жойлаштирадиган жойни танлашингиз мумкин. - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core юклаб олинади ва Bitcoin блок занжири нусхаси жойлаштирилади. Камида %1GB маълумот ушбу директорияга жойлаштирилади ва вақт давомида ўсиб боради. Ҳамён ҳам ушбу директорияда жойлашади. - Use the default data directory Стандарт маълумотлар директориясидан фойдаланиш @@ -831,10 +465,6 @@ Use a custom data directory: Бошқа маълумотлар директориясида фойдаланинг: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. Хато: кўрсатилган "%1" маълумотлар директориясини яратиб бўлмайди. @@ -862,10 +492,6 @@ Select payment request file Тўлов сўрови файлини танлаш - - Select payment request file to open - Очиш учун тўлов сўрови файлини танлаш - OptionsDialog @@ -1057,29 +683,6 @@ Жорий умумий баланс фақат кўринадиган манзилларда - - PaymentServer - - URI handling - URI осилиб қолмоқда - - - Invalid payment address %1 - Нотўғри тўлов манзили %1 - - - Payment request rejected - Тўлов сўрови инкор этилди - - - Payment request network doesn't match client network. - Тўлов сўрови тармоғи мижоз тармоғига мос келмайди. - - - Payment request error - Тўлов сўрови хато - - PeerTableModel @@ -1122,25 +725,6 @@ %1 мс - - QRImageWidget - - &Save Image... - Расмни &сақлаш - - - &Copy Image - Расмдан &нусха олиш - - - Save QR Code - QR кодни сақлаш - - - PNG Image (*.png) - PNG расм (*.png) - - RPCConsole @@ -1259,10 +843,6 @@ Out: Ташқарига: - - Build date - Тузилган санаси - Debug log file Тузатиш журнали файли @@ -1386,18 +966,6 @@ Remove Ўчириш - - Copy label - Ёрликни нусхала - - - Copy message - Хабарни нусхала - - - Copy amount - Кийматни нусхала - ReceiveRequestDialog @@ -1413,65 +981,6 @@ &Save Image... Расмни &сақлаш - - Request payment to %1 - %1 дан Тўловни сўраш - - - Payment information - Тўлов маълумоти - - - URI - URI - - - Address - Манзил - - - Amount - Миқдори - - - Label - Ёрлик - - - Message - Хабар - - - - RecentRequestsTableModel - - Date - Сана - - - Label - Ёрлик - - - Message - Хабар - - - Amount - Миқдори - - - (no label) - (Ёрлик мавжуд эмас) - - - (no message) - (Хабар йўқ) - - - (no amount) - (Миқдор мавжуд эмас) - SendCoinsDialog @@ -1583,74 +1092,6 @@ S&end Жў&натиш - - Confirm send coins - Тангалар жўнаишни тасдиқлаш - - - %1 to %2 - %1 дан %2 - - - Copy quantity - Нусха сони - - - Copy amount - Кийматни нусхала - - - Copy fee - Нусха солиғи - - - Copy after fee - Нусха солиқдан сўнг - - - Copy bytes - Нусха байти - - - Copy priority - Нусха муҳимлиги - - - Copy change - Нусха қайтими - - - or - ёки - - - The amount to pay must be larger than 0. - Тўлов миқдори 0. дан катта бўлиши керак. - - - Warning: Invalid Bitcoin address - Диққат: Нотўғр Bitcoin манзили - - - (no label) - (Ёрлик мавжуд эмас) - - - Warning: Unknown change address - Диққат: Номаълум ўзгариш манзили - - - Copy dust - Нусха чангги - - - Are you sure you want to send? - Жўнатишни хоҳлашингизга ишончингиз комилми? - - - added as transaction fee - ўтказма солиғи қўшилди - SendCoinsEntry @@ -1662,10 +1103,6 @@ Pay &To: &Тўлов олувчи: - - Enter a label for this address to add it to your address book - Манзил китобингизга қўшиш учун ушбу манзил учун ёрлиқ киритинг - &Label: &Ёрлиқ: @@ -1728,21 +1165,9 @@ Clear &All Барчасини & Тозалаш - - Message verified. - Хабар тасдиқланди. - - + SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core дастурчилари - [testnet] [testnet] @@ -1751,358 +1176,16 @@ TrafficGraphWidget - - TransactionDesc - - Open until %1 - %1 гача очиш - - - %1/unconfirmed - %1/тасдиқланмади - - - %1 confirmations - %1 тасдиқлашлар - - - Date - Сана - - - Source - Манба - - - Generated - Яратилган - - - From - Дан - - - To - Га - - - own address - ўз манзили - - - label - ёрлиқ - - - Credit - Кредит (қарз) - - - not accepted - қабул қилинмади - - - Transaction fee - Ўтказма тўлови - - - Net amount - Умумий миқдор - - - Message - Хабар - - - Comment - Шарҳ - - - Transaction ID - ID - - - Merchant - Савдо - - - Transaction - Ўтказма - - - Amount - Миқдори - - - true - рост - - - false - ёлғон - - - , has not been successfully broadcast yet - , ҳалигача трансляция қилингани йўқ - - - unknown - Номаълум - - TransactionDescDialog - - Transaction details - Операция тафсилотлари - This pane shows a detailed description of the transaction Ушбу ойна операциянинг батафсил таърифини кўрсатади - - TransactionTableModel - - Date - Сана - - - Type - Тури - - - Open until %1 - %1 гача очиш - - - Confirmed (%1 confirmations) - Тасдиқланди (%1 та тасдиқ) - - - This block was not received by any other nodes and will probably not be accepted! - Ушбу тўсиқ бирорта бошқа уланишлар томонидан қабул қилинмаган ва тасдиқланмаган! - - - Generated but not accepted - Яратилди, аммо қабул қилинмади - - - Offline - Оффлайн - - - Label - Ёрлиқ - - - Unconfirmed - Тасдиқланмаган - - - Received with - Ёрдамида қабул қилиш - - - Received from - Дан қабул қилиш - - - Sent to - Жўнатиш - - - Payment to yourself - Ўзингизга тўлов - - - Mined - Фойда - - - (n/a) - (қ/қ) - - - Transaction status. Hover over this field to show number of confirmations. - Ўтказма ҳолати. Ушбу майдон бўйлаб тасдиқлашлар сонини кўрсатиш. - - - Date and time that the transaction was received. - Ўтказма қабул қилинган сана ва вақт. - - - Type of transaction. - Пул ўтказмаси тури - - - Amount removed from or added to balance. - Миқдор ўчирилган ёки балансга қўшилган. - - - - TransactionView - - All - Барча - - - Today - Бугун - - - This week - Шу ҳафта - - - This month - Шу ой - - - Last month - Ўтган хафта - - - This year - Шу йил - - - Range... - Оралиқ... - - - Received with - Ёрдамида қабул қилинган - - - Sent to - Жўнатиш - - - To yourself - Ўзингизга - - - Mined - Фойда - - - Other - Бошка - - - Enter address or label to search - Излаш учун манзил ёки ёрлиқни киритинг - - - Min amount - Мин қиймат - - - Copy address - Манзилни нусхалаш - - - Copy label - Ёрликни нусхалаш - - - Copy amount - Кийматни нусхала - - - Copy transaction ID - Ўтказам рақамидан нусха олиш - - - Edit label - Ёрликни тахрирлаш - - - Show transaction details - Ўтказма тафсилотларини кўрсатиш - - - Export Transaction History - Ўтказмалар тарихини экспорт қилиш - - - Watch-only - Фақат кўришга - - - Exporting Failed - Экспорт қилиб бўлмади - - - The transaction history was successfully saved to %1. - Ўтказмалар тарихи %1 га муваффаққиятли сақланди. - - - Comma separated file (*.csv) - Вергул билан ажратилган файл (*.csv) - - - Confirmed - Тасдиқланди - - - Date - Сана - - - Type - Туркум - - - Label - Ёрлик - - - Address - Манзил - - - ID - ID - - - Range: - Оралиқ: - - - to - Кимга - - UnitDisplayStatusBarControl - - WalletFrame - - No wallet has been loaded. - Хали бирорта хамён юкланмади - - - - WalletModel - - Send Coins - Тангаларни жунат - - - - WalletView - - &Export - &Экспорт - - - Export the data in the current tab to a file - Жорий ички ойна ичидаги маълумотларни файлга экспорт қилиш - - bitcoin-core @@ -2121,6 +1204,10 @@ Run in the background as a daemon and accept commands Демон сифатида орқа фонда ишга туширинг ва буйруқларга рози бўлинг + + Bitcoin Core + Bitcoin Core + Connection options: Уланиш кўрсаткичлари: @@ -2141,10 +1228,6 @@ Password for JSON-RPC connections JSON-RPC уланишлари учун парол - - This help message - Бу ёрдам хабари - Loading addresses... Манзиллар юкланмоқда... diff --git a/src/qt/locale/bitcoin_uz@Latn.ts b/src/qt/locale/bitcoin_uz@Latn.ts deleted file mode 100644 index 2e4dabb59..000000000 --- a/src/qt/locale/bitcoin_uz@Latn.ts +++ /dev/null @@ -1,169 +0,0 @@ - - - AddressBookPage - - Create a new address - Yangi manzil yaratish - - - &New - &Yangi - - - &Copy - &Nusxalash - - - C&lose - Yo&pish - - - &Copy Address - &Manzillarni nusxalash - - - &Delete - &O'chirish - - - - AddressTableModel - - Label - Yorliq - - - Address - Manzil - - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - Address - Manzil - - - Label - Yorliq - - - - RecentRequestsTableModel - - Label - Yorliq - - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - Label - Yorliq - - - - TransactionView - - Label - Yorliq - - - Address - Manzil - - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 47745a3bc..e8bf01ab1 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -17,33 +17,10 @@ &Copy Sao chép - - &Copy Address - Sao chép địa chỉ - &Delete &Xóa - - Comma separated file (*.csv) - Tập tin tách biệt bởi dấu phẩy (*.csv) - - - - AddressTableModel - - Label - Nhãn dữ liệu - - - Address - Địa chỉ - - - (no label) - (chưa có nhãn) - AskPassphraseDialog @@ -54,9 +31,6 @@ BitcoinGUI - - ClientModel - CoinControlDialog @@ -67,10 +41,6 @@ Amount Số lượng - - (no label) - (chưa có nhãn) - EditAddressDialog @@ -82,7 +52,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -101,9 +71,6 @@ OverviewPage - - PaymentServer - PeerTableModel @@ -114,9 +81,6 @@ Số lượng - - QRImageWidget - RPCConsole @@ -129,33 +93,6 @@ Copy &Address Sao chép địa chỉ - - Address - Địa chỉ - - - Amount - Số lượng - - - Label - Nhãn dữ liệu - - - - RecentRequestsTableModel - - Label - Nhãn dữ liệu - - - Amount - Số lượng - - - (no label) - (chưa có nhãn) - SendCoinsDialog @@ -163,10 +100,6 @@ Amount: Số lượng: - - (no label) - (chưa có nhãn) - SendCoinsEntry @@ -183,50 +116,12 @@ TrafficGraphWidget - - TransactionDesc - - Amount - Số lượng - - TransactionDescDialog - - TransactionTableModel - - Label - Nhãn dữ liệu - - - - TransactionView - - Comma separated file (*.csv) - Tập tin tách biệt bởi dấu phẩy (*.csv) - - - Label - Nhãn dữ liệu - - - Address - Địa chỉ - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - bitcoin-core diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index d55fa6188..a4e1588c9 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -25,10 +25,6 @@ C&lose Đó&ng - - &Copy Address - &Copy Địa Chỉ - Delete the currently selected address from the list Xóa địa chỉ hiện tại từ danh sách @@ -45,61 +41,6 @@ &Delete &Xó&a - - Choose the address to send coins to - Chọn địa chỉ để gửi coin tới - - - Choose the address to receive coins with - Chọn địa chỉ để nhận coin - - - C&hoose - C&họn - - - Sending addresses - Địa chỉ gửi - - - Receiving addresses - Địa chỉ nhận - - - Copy &Label - Copy &Nhãn - - - &Edit - &Sửa - - - Export Address List - Xuất Danh Sách Địa Chỉ - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Exporting Failed - Xuất Đã Thất Bại - - - - AddressTableModel - - Label - Nhãn - - - Address - Địa chỉ - - - (no label) - (không nhãn) - AskPassphraseDialog @@ -119,23 +60,7 @@ Repeat new passphrase Điền lại passphrase - - Encrypt wallet - Mã hóa ví - - - Unlock wallet - Mở khóa ví - - - Decrypt wallet - Giải mã ví - - - Wallet encrypted - Ví đã được mã hóa - - + BanTableModel @@ -173,10 +98,6 @@ Open &URI... Mở &URI... - - Bitcoin Core client - Bitcoin Core client - Bitcoin Bitcoin @@ -213,14 +134,6 @@ &Help Trợ &giúp - - Bitcoin Core - Bitcoin Core - - - &About Bitcoin Core - &Về Bitcoin Core - %n hour(s) %n giờ @@ -266,13 +179,6 @@ Giao dịch đang tới - - ClientModel - - Network Alert - Network Alert - - CoinControlDialog @@ -319,43 +225,7 @@ Priority Tầm quan trọng - - Copy address - Copy địa chỉ - - - Copy label - Copy nhãn - - - Copy amount - Lượng copy - - - low - thấp - - - lower - thấp hơn - - - lowest - thấp nhất - - - yes - - - - no - không - - - (no label) - (không nhãn) - - + EditAddressDialog @@ -366,7 +236,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -376,18 +246,10 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version version - - About Bitcoin Core - Về Bitcoin Core - Intro @@ -395,10 +257,6 @@ Welcome Chào mừng - - Bitcoin Core - Bitcoin Core - Error Lỗi @@ -461,9 +319,6 @@ Tổng: - - PaymentServer - PeerTableModel @@ -478,9 +333,6 @@ Lượng - - QRImageWidget - RPCConsole @@ -514,52 +366,13 @@ &Amount: Lượng: - - Copy label - Copy nhãn - - - Copy amount - Lượng copy - - + ReceiveRequestDialog Copy &Address &Copy Địa Chỉ - - Address - Địa chỉ - - - Amount - Lượng - - - Label - Nhãn - - - - RecentRequestsTableModel - - Date - Ngày tháng - - - Label - Nhãn - - - Amount - Lượng - - - (no label) - (không nhãn) - SendCoinsDialog @@ -591,14 +404,6 @@ Change: Thay đổi: - - Copy amount - Lượng copy - - - (no label) - (không nhãn) - SendCoinsEntry @@ -615,104 +420,26 @@ SplashScreen - - Bitcoin Core - Bitcoin Core - TrafficGraphWidget - - TransactionDesc - - Date - Ngày tháng - - - Amount - Lượng - - TransactionDescDialog - - TransactionTableModel - - Date - Ngày tháng - - - Label - Nhãn - - - - TransactionView - - Copy address - Copy địa chỉ - - - Copy label - Copy nhãn - - - Copy amount - Lượng copy - - - Exporting Failed - Xuất Đã Thất Bại - - - Comma separated file (*.csv) - Comma separated file (*.csv) - - - Confirmed - Đã xác nhận - - - Date - Ngày tháng - - - Label - Nhãn - - - Address - Địa chỉ - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - X&uất - - - Export the data in the current tab to a file - Xuất dữ liệu trong mục hiện tại ra file - - bitcoin-core Options: Lựa chọn: + + Bitcoin Core + Bitcoin Core + (default: %u) (mặc định: %u) @@ -729,10 +456,6 @@ Warning Chú ý - - This help message - Thông điệp trợ giúp này - Loading addresses... Đang đọc các địa chỉ... diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts index aeb4faa71..bceba9dfd 100644 --- a/src/qt/locale/bitcoin_zh.ts +++ b/src/qt/locale/bitcoin_zh.ts @@ -2,9 +2,6 @@ AddressBookPage - - AddressTableModel - AskPassphraseDialog @@ -22,9 +19,6 @@ 警告 - - ClientModel - CoinControlDialog @@ -57,18 +51,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -78,13 +66,6 @@ ReceiveRequestDialog - - RecentRequestsTableModel - - Date - 日期 - - SendCoinsDialog @@ -95,18 +76,6 @@ Choose... 选择... - - Pay only the required fee of %1 - 仅支付全额的%1 - - - The recipient address is not valid. Please recheck. - 收款人地址无效,请再次确认。 - - - Warning: Invalid Bitcoin address - 警告:比特币地址无效 - SendCoinsEntry @@ -123,42 +92,12 @@ TrafficGraphWidget - - TransactionDesc - - Date - 日期 - - TransactionDescDialog - - TransactionTableModel - - Date - 日期 - - - - TransactionView - - Date - 日期 - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - bitcoin-core @@ -177,26 +116,10 @@ Warning 警告 - - wallet.dat corrupt, salvage failed - wallet.dat文件受损,修复失败 - - - This help message - 此条帮助信息 - Loading addresses... 正在载入地址... - - Error loading wallet.dat: Wallet corrupted - wallet.dat文件加载错误:钱包受损 - - - Error loading wallet.dat - wallet.dat文件加载错误 - Insufficient funds 余额不足 diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index cc1b03356..8f467b79c 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -25,10 +25,6 @@ C&lose 关闭(&l) - - &Copy Address - 复制地址(&C) - Delete the currently selected address from the list 从列表中删除选中的地址 @@ -45,73 +41,6 @@ &Delete 删除(&D) - - Choose the address to send coins to - 选择发币地址 - - - Choose the address to receive coins with - 选择收币地址 - - - C&hoose - 选择(&H) - - - Sending addresses - 正在发送地址 - - - Receiving addresses - 正在接收地址 - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 这是您用来付款的比特币地址。在付款前,请仔细核实付款金额和收款地址。 - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - 这些都是您的比特币地址,可用于收款。建议对每笔交易都使用一个新的地址。 - - - Copy &Label - 复制标签(&L) - - - &Edit - 编辑(&E) - - - Export Address List - 导出地址列表 - - - Comma separated file (*.csv) - 逗号分隔文件 (*.csv) - - - Exporting Failed - 导出失败 - - - There was an error trying to save the address list to %1. Please try again. - 保存地址列表出现 %1错误。请重试。 - - - - AddressTableModel - - Label - 标签 - - - Address - 地址 - - - (no label) - (没有标签) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase 重复新密码 - - Encrypt wallet - 加密钱包 - - - This operation needs your wallet passphrase to unlock the wallet. - 此操作需要您首先使用密码解锁该钱包。 - - - Unlock wallet - 解锁钱包 - - - This operation needs your wallet passphrase to decrypt the wallet. - 该操作需要您首先使用密码解密钱包。 - - - Decrypt wallet - 解密钱包 - - - Change passphrase - 更改密码 - - - Confirm wallet encryption - 确认加密钱包 - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 警告:如果您加密了您的钱包,但是忘记了密码,你将会<b>丢失所有的比特币</b>! - - - Are you sure you wish to encrypt your wallet? - 您确定需要为钱包加密吗? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - 比特币核心现在将关闭以完成加密过程。请记住,在您的计算机被恶意软件感染的情况下,加密不能完全保护您的比特币免于被盗。 - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 重要提示:您以前备份的钱包文件应该替换成最新生成的加密钱包文件(重新备份)。从安全性上考虑,您以前备份的未加密的钱包文件,在您使用新的加密钱包后将无效,请重新备份。 - - - Warning: The Caps Lock key is on! - 警告:大写锁定键处于打开状态! - - - Wallet encrypted - 钱包已加密 - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - 请输入新的钱包密码. <br/>密码须包含<b>10个以上随机字符</b>,或<b>8个以上单词</b>. - - - Enter the old passphrase and new passphrase to the wallet. - 请输入钱包的旧密码与新密码。 - - - Wallet encryption failed - 钱包加密失败 - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 由于一个本地错误,加密钱包的操作已经失败。您的钱包没能被加密。 - - - The supplied passphrases do not match. - 密码不匹配。 - - - Wallet unlock failed - 钱包解锁失败 - - - The passphrase entered for the wallet decryption was incorrect. - 用于解密钱包的密码不正确。 - - - Wallet decryption failed - 钱包解密失败。 - - - Wallet passphrase was successfully changed. - 修改钱包密码成功。 - BanTableModel @@ -269,6 +110,10 @@ Quit application 退出程序 + + &About %1 + &关于 %1 + About &Qt 关于Qt(&Q) @@ -305,14 +150,6 @@ Open &URI... 打开 &URI... - - Bitcoin Core client - 比特币核心钱包客户端 - - - Importing blocks from disk... - 正在从磁盘导入数据块... - Reindexing blocks on disk... 正在为数据块重建索引... @@ -357,10 +194,6 @@ &Receive 接收(&R) - - Show information about Bitcoin Core - 显示有关比特币核心钱包信息 - &Show / Hide 显示 / 隐藏(&S) @@ -397,22 +230,10 @@ Tabs toolbar 分页工具栏 - - Bitcoin Core - 比特币核心 - Request payments (generates QR codes and bitcoin: URIs) 请求支付(生成二维码和 bitcoin: URI) - - &About Bitcoin Core - 关于比特币核心(&A) - - - Modify configuration options for Bitcoin Core - 修改比特币核心的配置选项 - Show the list of used sending addresses and labels 显示用过的发送地址和标签的列表 @@ -429,10 +250,6 @@ &Command-line options 命令行选项(&C) - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 显示比特币核心 程序帮助信息,获取可用的命令行选项 - %n active connection(s) to Bitcoin network %n 个到比特币网络的活动连接 @@ -544,13 +361,6 @@ 钱包已被<b>加密</b>,当前为<b>锁定</b>状态 - - ClientModel - - Network Alert - 网络警报 - - CoinControlDialog @@ -629,150 +439,6 @@ Priority 优先级 - - Copy address - 复制地址 - - - Copy label - 复制标签 - - - Copy amount - 复制金额 - - - Copy transaction ID - 复制交易编号 - - - Lock unspent - 锁定未花费 - - - Unlock unspent - 解锁未花费 - - - Copy quantity - 复制金额 - - - Copy fee - 复制交易费 - - - Copy after fee - 复制含交易费的金额 - - - Copy bytes - 复制字节 - - - Copy priority - 复制优先级 - - - Copy dust - 复制小额 - - - Copy change - 复制零钱 - - - highest - 最高 - - - higher - 更高 - - - high - - - - medium-high - 中高 - - - medium - 中等 - - - low-medium - 中低 - - - low - - - - lower - 更低 - - - lowest - 最低 - - - (%1 locked) - (%1 锁定) - - - none - - - - This label turns red if the transaction size is greater than 1000 bytes. - 如果交易规模大于 1000 字节,此标签将变为红色。 - - - This label turns red if the priority is smaller than "medium". - 如果优先级小于“中等”,此标签将变为红色。 - - - This label turns red if any recipient receives an amount smaller than %1. - 如果任何接收人收到的金额小于 %1,此标签将变为红色。 - - - Can vary +/- %1 satoshi(s) per input. - 可能会有 正负 %1 聪(satoshi)的偏差 - - - yes - - - - no - - - - This means a fee of at least %1 per kB is required. - 这意味着将对交易收取 %1/千字节 的交易费。 - - - Can vary +/- 1 byte per input. - 每笔输入可能会有 正负1字节的偏差。 - - - Transactions with higher priority are more likely to get included into a block. - 交易的优先级越高,被矿工收入数据块的速度也越快。 - - - (no label) - (没有标签) - - - change from %1 (%2) - 来自%1的零钱 (%2) - - - (change) - (零钱) - EditAddressDialog @@ -796,38 +462,6 @@ &Address 地址(&A) - - New receiving address - 新建接收地址 - - - New sending address - 新建发送地址 - - - Edit receiving address - 编辑接收地址 - - - Edit sending address - 编辑发送地址 - - - The entered address "%1" is already in the address book. - 输入的地址“%1”已经存在于地址簿中。 - - - The entered address "%1" is not a valid Bitcoin address. - 您输入的“%1”不是有效的比特币地址。 - - - Could not unlock wallet. - 无法解锁钱包 - - - New key generation failed. - 新的密钥生成失败。 - FreespaceChecker @@ -854,10 +488,6 @@ HelpMessageDialog - - Bitcoin Core - 比特币核心 - version 版本 @@ -866,10 +496,6 @@ (%1-bit) (%1 位) - - About Bitcoin Core - 关于比特币核心 - Command-line options 命令行选项 @@ -906,29 +532,13 @@ Show splash screen on startup (default: %u) 显示启动画面(默认:%u) - - Reset all settings changes made over the GUI - 重置所有图形界面所做的更改 - - + Intro Welcome 欢迎 - - Welcome to Bitcoin Core. - 欢迎使用 比特币核心 程序。 - - - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - 由于这是第一次运行 比特币核心 程序,您可以选择数据存储目录。 - - - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - 比特币核心 程序会下载储存一份数据块链(blockchain)。至少需要 %1 GB的存储空间,随着时间推移会需要更多的存储空间。钱包文件也储存在该目录。 - Use the default data directory 使用默认的数据目录 @@ -937,10 +547,6 @@ Use a custom data directory: 使用自定义的数据目录: - - Bitcoin Core - 比特币核心 - Error: Specified data directory "%1" cannot be created. 错误:无法创建 指定的数据目录 "%1" @@ -976,10 +582,6 @@ Select payment request file 选择付款请求文件 - - Select payment request file to open - 选择需要打开的付款请求文件 - OptionsDialog @@ -1019,10 +621,6 @@ 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. 窗口被关闭时最小化而不是退出应用程序。当此选项启用时,应用程序只会在菜单中选择退出时退出。 - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - 可以在这里设置用户界面语言。此设置将在重新启动比特币核心后生效。 - 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 |. 出现在交易的选项卡的上下文菜单项的第三方网址 (例如:区块链接查询) 。 %s的URL被替换为交易哈希。多个的URL需要竖线 | 分隔。 @@ -1047,14 +645,6 @@ &Network 网络(&N) - - Automatically start Bitcoin Core after logging in to the system. - 登录到系统后自动启动比特币核心。 - - - &Start Bitcoin Core on system login - 系统登录时启动比特币核心(&S) - (0 = auto, <0 = leave that many cores free) (0 = 自动, <0 = 离开很多免费的核心) @@ -1283,97 +873,6 @@ 观察地址(watch-only address)中的当前总余额 - - PaymentServer - - URI handling - URI 处理 - - - Invalid payment address %1 - 无效的付款地址 %1 - - - Payment request rejected - 支付请求被拒绝 - - - Payment request network doesn't match client network. - 付款请求所在的网络与当前客户端所在的网络不匹配。 - - - Payment request is not initialized. - 支付请求未成形。 - - - Requested payment amount of %1 is too small (considered dust). - 请求支付的金额 %1 太小(就像尘埃)。 - - - Payment request error - 支付请求出错 - - - Cannot start bitcoin: click-to-pay handler - 暂时无法启动比特币:点击支付功能 - - - Payment request fetch URL is invalid: %1 - 付款请求URI链接非法: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI无法解析!原因可能是比特币地址不正确,或者URI参数错误。 - - - Payment request file handling - 付款请求文件处理 - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - 付款请求文件无法读取!可能是付款请求文件不合格。 - - - Payment request expired. - 支付请求已过期。 - - - Unverified payment requests to custom payment scripts are unsupported. - 不支持到自定义付款脚本的未验证付款请求。 - - - Invalid payment request. - 无效的支付请求。 - - - Refund from %1 - 退款来自 %1 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - 支付请求 %1 太大 (%2 字节。只允许 %3 字节)。 - - - Error communicating with %1: %2 - %1: %2 通讯出错 - - - Payment request cannot be parsed! - 无法解析 付款请求! - - - Bad response from server %1 - 来自 %1 服务器的错误响应 - - - Payment acknowledged - 支付已到账 - - - Network request error - 网络请求出错 - - PeerTableModel @@ -1428,25 +927,6 @@ %1 毫秒 - - QRImageWidget - - &Save Image... - 保存图片(&S)... - - - &Copy Image - 复制图片(&C) - - - Save QR Code - 保存二维码 - - - PNG Image (*.png) - PNG图片(*.png) - - RPCConsole @@ -1513,10 +993,6 @@ Memory usage 内存使用 - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - 从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。 - Received 收到 @@ -1629,10 +1105,6 @@ Out: 输出: - - Build date - 创建时间 - Debug log file 调试日志文件 @@ -1669,10 +1141,6 @@ &Unban Node (&U)允许节点连接 - - Welcome to the Bitcoin Core RPC console. - 欢迎使用 比特币核心 RPC 控制台。 - Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 使用上下方向键浏览历史, <b>Ctrl-L</b>清除屏幕。 @@ -1800,18 +1268,6 @@ Remove 移除 - - Copy label - 复制标签 - - - Copy message - 复制消息 - - - Copy amount - 复制金额 - ReceiveRequestDialog @@ -1831,73 +1287,6 @@ &Save Image... 保存图片(&S)... - - Request payment to %1 - 请求付款到 %1 - - - Payment information - 付款信息 - - - URI - URI - - - Address - 地址 - - - Amount - 金额 - - - Label - 标签 - - - Message - 消息 - - - Resulting URI too long, try to reduce the text for label / message. - URI 太长,请试着精简标签或消息文本。 - - - Error encoding URI into QR Code. - 将 URI 转为二维码失败。 - - - - RecentRequestsTableModel - - Date - 日期 - - - Label - 标签 - - - Message - 消息 - - - Amount - 金额 - - - (no label) - (没有标签) - - - (no message) - (无消息) - - - (no amount) - (无金额) - SendCoinsDialog @@ -2017,14 +1406,6 @@ fast 快速 - - Send as zero-fee transaction if possible - 发送时尽可能 不支付交易费用 - - - (confirmation may take longer) - (确认时间更长) - Send to multiple recipients at once 一次发送给多个接收者 @@ -2057,118 +1438,6 @@ S&end 发送(&E) - - Confirm send coins - 确认发送货币 - - - %1 to %2 - %1 到 %2 - - - Copy quantity - 复制金额 - - - Copy amount - 复制金额 - - - Copy fee - 复制交易费 - - - Copy after fee - 复制含交易费的金额 - - - Copy bytes - 复制字节 - - - Copy priority - 复制优先级 - - - Copy change - 复制零钱 - - - Total Amount %1 - 总金额 %1 - - - or - - - - The amount to pay must be larger than 0. - 支付金额必须大于0。 - - - The amount exceeds your balance. - 金额超出您的账上余额。 - - - The total exceeds your balance when the %1 transaction fee is included. - 计入 %1 交易费后的金额超出您的账上余额。 - - - Transaction creation failed! - 交易创建失败! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - 错误:该交易被拒绝!发生这种错误的原因可能是:钱包中的比特币已经被用掉,有可能您复制了wallet.dat钱包文件,然后用复制的钱包文件支付了比特币,但是这个钱包文件中没有记录。 - - - A fee higher than %1 is considered an absurdly high fee. - 超过 %1 的交易费被认为是荒谬的高费率。 - - - Payment request expired. - 支付请求已过期。 - - - Pay only the required fee of %1 - 只支付必要费用 %1 - - - Estimated to begin confirmation within %n block(s). - 预计 %n 个数据块后被确认。 - - - The recipient address is not valid. Please recheck. - 接收人地址无效。请重新检查。 - - - Duplicate address found: addresses should only be used once each. - 发现重复地址:每个地址应该只使用一次。 - - - Warning: Invalid Bitcoin address - 警告:无效的比特币地址 - - - (no label) - (没有标签) - - - Warning: Unknown change address - 警告:未知的更改地址 - - - Copy dust - 复制小额 - - - Are you sure you want to send? - 您确定要发出吗? - - - added as transaction fee - 已添加交易费 - SendCoinsEntry @@ -2180,10 +1449,6 @@ Pay &To: 付给(&T): - - Enter a label for this address to add it to your address book - 为这个地址输入一个标签,以便将它添加到您的地址簿 - &Label: 标签(&L): @@ -2255,10 +1520,6 @@ ShutdownWindow - - Bitcoin Core is shutting down... - 比特币核心正在关机... - Do not shut down the computer until this window disappears. 在此窗口消失前不要关闭计算机。 @@ -2350,69 +1611,9 @@ Reset all verify message fields 清空所有验证消息栏 - - Click "Sign Message" to generate signature - 单击“签名消息“产生签名。 - - - The entered address is invalid. - 输入的地址非法。 - - - Please check the address and try again. - 请检查地址后重试。 - - - The entered address does not refer to a key. - 输入的地址没有关联的公私钥对。 - - - Wallet unlock was cancelled. - 钱包解锁动作取消。 - - - Private key for the entered address is not available. - 找不到输入地址关联的私钥。 - - - Message signing failed. - 消息签名失败。 - - - Message signed. - 消息已签名。 - - - The signature could not be decoded. - 签名无法解码。 - - - Please check the signature and try again. - 请检查签名后重试。 - - - The signature did not match the message digest. - 签名与消息摘要不匹配。 - - - Message verification failed. - 消息验证失败。 - - - Message verified. - 消息验证成功。 - SplashScreen - - Bitcoin Core - 比特币核心 - - - The Bitcoin Core developers - Bitcoin Core 的开发者 - [testnet] [测试网络] @@ -2425,422 +1626,13 @@ KB/s - - TransactionDesc - - Open until %1 - 至 %1 个数据块时开启 - - - conflicted - 发现冲突 - - - %1/offline - %1 / 离线 - - - %1/unconfirmed - %1/未确认 - - - %1 confirmations - %1 已确认 - - - Status - 状态 - - - , broadcast through %n node(s) - , 通过 %n 个节点广播 - - - Date - 日期 - - - Source - - - - Generated - 生成 - - - From - 来自 - - - To - - - - own address - 自己的地址 - - - watch-only - 观察地址(watch-only) - - - label - 标签 - - - Credit - 收入 - - - matures in %n more block(s) - %n 个数据块后成熟(mature) - - - not accepted - 未被接受 - - - Debit - 支出 - - - Total debit - 总收入 - - - Total credit - 总支出 - - - Transaction fee - 交易费 - - - Net amount - 净额 - - - Message - 消息 - - - Comment - 备注 - - - Transaction ID - ID - - - Merchant - 商店 - - - 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. - 生成的比特币在可以使用前必须有 %1 个成熟的区块。当您生成了此区块后,它将被广播到网络中以加入区块链。如果它未成功进入区块链,其状态将变更为“不接受”并且不可使用。这可能偶尔会发生,如果另一个节点比你早几秒钟成功生成一个区块。 - - - Debug information - 调试信息 - - - Transaction - 交易 - - - Inputs - 输入 - - - Amount - 金额 - - - true - 正确 - - - false - 错误 - - - , has not been successfully broadcast yet - ,未被成功广播 - - - Open for %n more block(s) - 再打开 %n 个数据块 - - - unknown - 未知 - - TransactionDescDialog - - Transaction details - 交易细节 - This pane shows a detailed description of the transaction 当前面板显示了交易的详细信息 - - TransactionTableModel - - Date - 日期 - - - Type - 类别 - - - Immature (%1 confirmations, will be available after %2) - 未成熟 (%1 个确认,将在 %2 个后可用) - - - Open for %n more block(s) - 再打开 %n 个数据块 - - - Open until %1 - 至 %1 个数据块时开启 - - - Confirmed (%1 confirmations) - 已确认 (%1 条确认信息) - - - This block was not received by any other nodes and will probably not be accepted! - 此数据块未被任何其他节点接收,可能不被接受! - - - Generated but not accepted - 已生成但未被接受 - - - Offline - 掉线 - - - Label - 标签 - - - Unconfirmed - 未确认的 - - - Confirming (%1 of %2 recommended confirmations) - 确认中 (推荐 %2个确认,已经有 %1个确认) - - - Conflicted - 冲突的 - - - Received with - 接收于 - - - Received from - 收款来自 - - - Sent to - 发送给 - - - Payment to yourself - 付款给自己 - - - Mined - 挖矿所得 - - - watch-only - 观察地址(watch-only) - - - (n/a) - (不可用) - - - Transaction status. Hover over this field to show number of confirmations. - 交易状态。 鼠标移到此区域可显示确认项数量。 - - - Date and time that the transaction was received. - 接收到交易的时间 - - - Type of transaction. - 交易类别。 - - - Whether or not a watch-only address is involved in this transaction. - 该交易中是否涉及 观察地址(watch-only address)。 - - - User-defined intent/purpose of the transaction. - 用户定义的该交易的意图/目的。 - - - Amount removed from or added to balance. - 从余额添加或移除的金额。 - - - - TransactionView - - All - 全部 - - - Today - 今天 - - - This week - 本周 - - - This month - 本月 - - - Last month - 上月 - - - This year - 今年 - - - Range... - 范围... - - - Received with - 接收于 - - - Sent to - 发送给 - - - To yourself - 到自己 - - - Mined - 挖矿所得 - - - Other - 其他 - - - Enter address or label to search - 输入地址或标签进行搜索 - - - Min amount - 最小金额 - - - Copy address - 复制地址 - - - Copy label - 复制标签 - - - Copy amount - 复制金额 - - - Copy transaction ID - 复制交易编号 - - - Copy raw transaction - 复制原始交易 - - - Edit label - 编辑标签 - - - Show transaction details - 显示交易详情 - - - Export Transaction History - 导出交易历史 - - - Watch-only - 观察地址(Watch-only) - - - Exporting Failed - 导出失败 - - - There was an error trying to save the transaction history to %1. - 导出交易历史到 %1 时发生错误。 - - - Exporting Successful - 导出成功 - - - The transaction history was successfully saved to %1. - 交易历史已成功保存到 %1。 - - - Comma separated file (*.csv) - 逗号分隔文件 (*.csv) - - - Confirmed - 已确认 - - - Date - 日期 - - - Type - 类别 - - - Label - 标签 - - - Address - 地址 - - - ID - ID - - - Range: - 范围: - - - to - - - UnitDisplayStatusBarControl @@ -2848,55 +1640,6 @@ 金额单位。单击选择别的单位。 - - WalletFrame - - No wallet has been loaded. - 没有载入钱包。 - - - - WalletModel - - Send Coins - 发送比特币 - - - - WalletView - - &Export - 导出(&E) - - - Export the data in the current tab to a file - 导出当前数据到文件 - - - Backup Wallet - 备份钱包 - - - Wallet Data (*.dat) - 钱包文件(*.dat) - - - Backup Failed - 备份失败 - - - There was an error trying to save the wallet data to %1. - 尝试保存钱包数据至 %1 时发生错误。 - - - The wallet data was successfully saved to %1. - 钱包数据成功保存至 %1 。 - - - Backup Successful - 备份成功 - - bitcoin-core @@ -2926,14 +1669,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. 如果<category>未提供或<category> = 1,输出所有调试信息。 - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - 最大单次转账费用(%s),设置太低可能导致大宗交易失败(默认:%s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - 警请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。 - Prune configured below the minimum of %d MiB. Please use a higher number. 修剪值被设置为低于最小值%d MiB,请使用更大的数值。 @@ -2976,6 +1711,10 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 接受来自外部的连接 (缺省: 如果不带 -proxy or -connect 参数设置为1) + + Bitcoin Core + 比特币核心 + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfree 交易费设置得很高!这是在费用估计不可用时你可能会支付的交易费。 @@ -3020,14 +1759,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 这是测试用的预发布版本 - 请谨慎使用 - 不要用来挖矿,或者在正式商用环境下使用 - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - 无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。 - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - 一个不被支持的参数 -whitelistalwaysrelay 被忽略了。请使用 -whitelistrelay 或者 -whitelistforcerelay. - Use UPnP to map the listening port (default: 1 when listening and no -proxy) 使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理) @@ -3044,18 +1775,10 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告:网络似乎并不完全同意!有些矿工似乎遇到了问题。 - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - 警告: 未知的区块版本被挖掘!未知规则可能已生效 - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 警告:我们的同行似乎不完全同意!您可能需要升级,或者其他节点可能需要升级。 - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - 警告:钱包文件wallet.dat损坏! 原始的钱包文件已经备份到%s目录下并重命名为{timestamp}.bak 。如果您的账户余额或者交易记录不正确,请使用您的钱包备份文件恢复。 - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 节点白名单,网络掩码或IP址。可多次指定。 @@ -3240,10 +1963,6 @@ Wallet options: 钱包选项: - - You need to rebuild the database using -reindex to change -txindex - 您需要将 -reindex 改为 -txindex 以重建数据库 - Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times 允许来自指定地址的 JSON-RPC 连接。 <ip>为单一IP (如: 1.2.3.4), 网络/掩码 (如: 1.2.3.4/255.255.255.0), 网络/CIDR (如: 1.2.3.4/24)。该选项可多次指定。 @@ -3256,10 +1975,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) 绑定到指定地址监听 JSON-RPC连接。 IPv6使用[主机]:端口 格式。该选项可多次指定 (默认: 绑定到所有接口) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - 无法获取数据目录的 %s. 比特币核心钱包可能已经在运行. - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) 创建系统默认权限的文件,而不是 umask 077 (只在关闭钱包功能时有效) @@ -3304,10 +2019,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 设置 高优先级/低交易费 交易的最大字节 (缺省: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - 设置比特币生成线程数 ( -1=所有核, 默认: %d) - The transaction amount is too small to send after the fee has been deducted 在交易费被扣除后发送的交易金额太小 @@ -3332,34 +2043,14 @@ Accept public REST requests (default: %u) 接受公共 REST 请求 (默认: %u) - - Activating best chain... - 正在激活最佳数据链... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - 尝试从启动页上的损坏钱包文件中恢复私钥 - Automatically create Tor hidden service (default: %d) 自动建立Tor隐藏服务 (默认:%d) - - Cannot resolve -whitebind address: '%s' - 无法解析 -whitebind 地址: '%s' - Connect through SOCKS5 proxy 通过 SOCKS5 代理连接 - - Copyright (C) 2009-%i The Bitcoin Core Developers - 版权所有 (C) 2009-%i Bitcoin Core 开发者 - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - 加载wallet.dat错误:需要新版的比特币核心钱包 - Error reading from database, shutting down. 读取数据库出错,关闭中。 @@ -3368,22 +2059,6 @@ Information 信息 - - Initialization sanity check failed. Bitcoin Core is shutting down. - 初始化完整性检查失败。Bitcoin Core 即将关闭。 - - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<amount>: '%s' 的金额无效 - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - -minrelaytxfee=<amount>: '%s' 无效的金额 - - - Invalid amount for -mintxfee=<amount>: '%s' - -mintxfee=<amount>: '%s' 无效的金额 - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) 无效的金额 -paytxfee=<amount>: '%s' (必须至少为 %s) @@ -3408,14 +2083,6 @@ RPC server options: RPC 服务器选项: - - Rebuild block chain index from current blk000??.dat files on startup - 启动时重新为当前的 blk000??.dat 文件建立索引 - - - Receive and display P2P network alerts (default: %u) - 收到并且显示P2P网络的告警(默认:%u) - Rescan the block chain for missing wallet transactions on startup 重新扫描区块链以查找遗漏的钱包交易 @@ -3476,10 +2143,6 @@ Username for JSON-RPC connections JSON-RPC 连接用户名 - - Wallet needed to be rewritten: restart Bitcoin Core to complete - 钱包需要被改写:重新启动核心钱包来完成 - Warning 警告 @@ -3496,10 +2159,6 @@ ZeroMQ notification options: ZeroMQ 通知选项: - - wallet.dat corrupt, salvage failed - 钱包文件wallet.dat损坏,抢救备份失败 - Password for JSON-RPC connections JSON-RPC 连接密码 @@ -3509,11 +2168,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) 当最佳数据块变化时执行命令 (命令行中的 %s 会被替换成数据块哈希值) - - This help message - 本帮助信息 - - Allow DNS lookups for -addnode, -seednode and -connect 使用 -addnode, -seednode 和 -connect 选项时允许查询DNS @@ -3522,10 +2176,6 @@ Loading addresses... 正在加载地址簿... - - Error loading wallet.dat: Wallet corrupted - wallet.dat 钱包文件加载出错:钱包损坏 - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) @@ -3550,10 +2200,18 @@ Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) 尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d) + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 一个不被支持的参数 -whitelistalwaysrelay 被忽略了。请使用 -whitelistrelay 或者 -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s) + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 未知的区块版本被挖掘!未知规则可能已生效 + (default: %s) (默认: %s) @@ -3562,14 +2220,6 @@ Always query for peer addresses via DNS lookup (default: %u) 始终通过 DNS 查询节点地址 (默认: %u) - - Error loading wallet.dat - wallet.dat 钱包文件加载出错 - - - Generate coins (default: %u) - 生成比特币 (默认: %u) - How many blocks to check at startup (default: %u, 0 = all) 启动时检测多少个数据块(默认: %u, 0=所有) @@ -3654,18 +2304,6 @@ Unknown network specified in -onlynet: '%s' -onlynet 指定的是未知网络:%s - - Cannot resolve -bind address: '%s' - 无法解析 -bind 端口地址: '%s' - - - Cannot resolve -externalip address: '%s' - 无法解析 -externalip 地址: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - 非法金额 -paytxfee=<amount>: '%s' - Insufficient funds 金额不足 diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index 740a86e11..aa014db0b 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -25,10 +25,6 @@ C&lose 關閉 &l - - &Copy Address - 複製位址 &C - Delete the currently selected address from the list 把目前選擇的位址從列表中刪除 @@ -45,73 +41,6 @@ &Delete 刪除 &D - - Choose the address to send coins to - 選擇要付錢過去的位址 - - - Choose the address to receive coins with - 選擇要收錢的位址 - - - C&hoose - 選取 &h - - - Sending addresses - 付款位址 - - - Receiving addresses - 收款位址 - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 這些是你要付款過去的 Bitcoin 位址。在付款之前,務必要檢查金額和收款位址是否正確。 - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 - - - Copy &Label - 複製標記 &L - - - &Edit - 編輯 &E - - - Export Address List - 匯出位址清單 - - - Comma separated file (*.csv) - 逗號分隔檔(*.csv) - - - Exporting Failed - 匯出失敗 - - - There was an error trying to save the address list to %1. Please try again. - 儲存位址列表到 %1 時發生錯誤。請再試一次。 - - - - AddressTableModel - - Label - 標記 - - - Address - 位址 - - - (no label) - (無標記) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase 重複新密碼 - - Encrypt wallet - 加密錢包 - - - This operation needs your wallet passphrase to unlock the wallet. - 這個動作需要你的錢包密碼來將錢包解鎖。 - - - Unlock wallet - 解鎖錢包 - - - This operation needs your wallet passphrase to decrypt the wallet. - 這個動作需要你的錢包密碼來將錢包解密。 - - - Decrypt wallet - 解密錢包 - - - Change passphrase - 改變密碼 - - - Confirm wallet encryption - 確認錢包加密 - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 警告: 如果把錢包加密後又忘記密碼,你就會<b>失去所有 Bitcoin 了</b>! - - - Are you sure you wish to encrypt your wallet? - 你確定要把錢包加密嗎? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core 現在要關閉以完成加密程序。請記得將錢包加密不能完全防止你的 Bitcoin 經被入侵電腦的惡意程式偷取。 - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 重要: 請改用新產生的加密錢包檔,來取代所以舊錢包檔的備份。為安全計,當你開始使用新的加密錢包檔後,舊錢包檔的備份就不能再使用了。 - - - Warning: The Caps Lock key is on! - 警告: Caps Lock 已啟用! - - - Wallet encrypted - 錢包已加密 - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - 輸入錢包的新密碼。<br/>密碼請用<b>10 個或以上的隨機字元</b>,或是<b>8 個或以上的字詞</b>。 - - - Enter the old passphrase and new passphrase to the wallet. - 請輸入舊密碼和新密碼至錢包。 - - - Wallet encryption failed - 錢包加密失敗 - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 因內部錯誤導致錢包加密失敗。你的錢包尚未加密。 - - - The supplied passphrases do not match. - 提供的密碼不一樣。 - - - Wallet unlock failed - 錢包解鎖失敗 - - - The passphrase entered for the wallet decryption was incorrect. - 用來解密錢包的密碼不對。 - - - Wallet decryption failed - 錢包解密失敗 - - - Wallet passphrase was successfully changed. - 錢包密碼已成功更改。 - BanTableModel @@ -305,14 +146,6 @@ Open &URI... 開啓網址... &U - - Bitcoin Core client - Bitcoin Core 客戶端 - - - Importing blocks from disk... - 正在從磁碟匯入區塊資料... - Reindexing blocks on disk... 正在為磁碟區塊重建索引... @@ -357,10 +190,6 @@ &Receive 收款 &R - - Show information about Bitcoin Core - 顯示 Bitcoin Core 的相關資訊 - &Show / Hide 顯示 / 隱藏 &S @@ -370,15 +199,8 @@ 顯示或隱藏主視窗 - - ClientModel - CoinControlDialog - - (no label) - (無標記) - EditAddressDialog @@ -401,18 +223,12 @@ OverviewPage - - PaymentServer - PeerTableModel QObject - - QRImageWidget - RPCConsole @@ -421,32 +237,9 @@ ReceiveRequestDialog - - Address - 位址 - - - Label - 標記 - - - - RecentRequestsTableModel - - Label - 標記 - - - (no label) - (無標記) - SendCoinsDialog - - (no label) - (無標記) - SendCoinsEntry @@ -463,58 +256,12 @@ TrafficGraphWidget - - TransactionDesc - TransactionDescDialog - - TransactionTableModel - - Label - 標記 - - - - TransactionView - - Exporting Failed - 匯出失敗 - - - Comma separated file (*.csv) - 逗號分隔檔(*.csv) - - - Label - 標記 - - - Address - 位址 - - UnitDisplayStatusBarControl - - WalletFrame - - - WalletModel - - - WalletView - - &Export - 匯出 &E - - - Export the data in the current tab to a file - 把目前分頁的資料匯出至檔案 - - bitcoin-core diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 107e7034e..cbdb8f2c0 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -25,10 +25,6 @@ C&lose 關閉 - - &Copy Address - 複製位址 - Delete the currently selected address from the list 把目前選擇的位址從列表中刪掉 @@ -45,73 +41,6 @@ &Delete 刪掉 - - Choose the address to send coins to - 選擇要付錢過去的位址 - - - Choose the address to receive coins with - 選擇要收錢進來的位址 - - - C&hoose - 選取 - - - Sending addresses - 付款位址 - - - Receiving addresses - 收款位址 - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 這些是你要付款過去的 Bitcoin 位址。在付錢之前,務必要檢查金額和收款位址是否正確。 - - - These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 - - - Copy &Label - 複製標記 - - - &Edit - 編輯 - - - Export Address List - 匯出位址清單 - - - Comma separated file (*.csv) - 逗號分隔資料檔(*.csv) - - - Exporting Failed - 匯出失敗 - - - There was an error trying to save the address list to %1. Please try again. - 儲存位址列表到 %1 時發生錯誤。請重試一次。 - - - - AddressTableModel - - Label - 標記 - - - Address - 位址 - - - (no label) - (無標記) - AskPassphraseDialog @@ -131,94 +60,6 @@ Repeat new passphrase 重複新密碼 - - Encrypt wallet - 加密錢包 - - - This operation needs your wallet passphrase to unlock the wallet. - 這個動作需要你的錢包密碼來解鎖錢包。 - - - Unlock wallet - 解鎖錢包 - - - This operation needs your wallet passphrase to decrypt the wallet. - 這個動作需要你的錢包密碼來把錢包解密。 - - - Decrypt wallet - 解密錢包 - - - Change passphrase - 改變密碼 - - - Confirm wallet encryption - 確認錢包加密 - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 警告: 如果把錢包加密後又忘記密碼,你就會從此<b>失去其中所有的 Bitcoin 了</b>! - - - Are you sure you wish to encrypt your wallet? - 你確定要把錢包加密嗎? - - - Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - Bitcoin Core 現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取錢幣。 - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。 - - - Warning: The Caps Lock key is on! - 警告: 大寫字母鎖定作用中! - - - Wallet encrypted - 錢包已加密 - - - Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - 輸入錢包的新密碼。<br/>密碼請用<b>10 個以上的字元</b>,或是<b>8 個以上的字詞</b>。 - - - Enter the old passphrase and new passphrase to the wallet. - 請輸入錢包的舊密碼和新密碼。 - - - Wallet encryption failed - 錢包加密失敗 - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - 因為內部錯誤導致錢包加密失敗。你的錢包還是沒加密。 - - - The supplied passphrases do not match. - 提供的密碼不一樣。 - - - Wallet unlock failed - 錢包解鎖失敗 - - - The passphrase entered for the wallet decryption was incorrect. - 輸入要用來解密錢包的密碼不對。 - - - Wallet decryption failed - 錢包解密失敗 - - - Wallet passphrase was successfully changed. - 錢包密碼改成功了。 - BanTableModel @@ -269,6 +110,14 @@ Quit application 結束應用程式 + + &About %1 + 關於%1 + + + Show information about %1 + 顯示 %1 的相關資訊 + About &Qt 關於 &Qt @@ -281,6 +130,10 @@ &Options... 選項... + + Modify configuration options for %1 + 修改 %1 的設定選項 + &Encrypt Wallet... 加密錢包... @@ -305,14 +158,6 @@ Open &URI... 開啓 URI... - - Bitcoin Core client - Bitcoin Core 客戶端軟體 - - - Importing blocks from disk... - 正在從磁碟匯入區塊資料... - Reindexing blocks on disk... 正在為磁碟裡的區塊重建索引... @@ -357,10 +202,6 @@ &Receive 收款 - - Show information about Bitcoin Core - 顯示 Bitcoin Core 的相關資訊 - &Show / Hide 顯示或隱藏 @@ -397,22 +238,10 @@ Tabs toolbar 分頁工具列 - - Bitcoin Core - Bitcoin Core - Request payments (generates QR codes and bitcoin: URIs) 要求付款(產生 QR Code 和 bitcoin 付款協議的資源識別碼: URI) - - &About Bitcoin Core - 關於 Bitcoin Core - - - Modify configuration options for Bitcoin Core - 修改 Bitcoin Core 的設定選項 - Show the list of used sending addresses and labels 顯示已使用過的付款位址和標記的清單 @@ -429,14 +258,18 @@ &Command-line options 命令列選項 - - Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - 顯示 Bitcoin Core 的說明訊息,來取得可用命令列選項的列表 - %n active connection(s) to Bitcoin network %n 個運作中的 Bitcoin 網路連線 + + Indexing blocks on disk... + 正在為磁碟裡的區塊建立索引... + + + Processing blocks on disk... + 正在處理磁碟裡的區塊資料... + No block source available... 沒有可用的區塊來源... @@ -493,6 +326,14 @@ Up to date 最新狀態 + + Show the %1 help message to get a list with possible Bitcoin command-line options + 顯示 %1 的說明訊息,來取得可用命令列選項的列表 + + + %1 client + %1 客戶端軟體 + Catching up... 正在趕進度... @@ -544,13 +385,6 @@ 錢包<b>已加密</b>並且<b>上鎖中</b> - - ClientModel - - Network Alert - 網路警報 - - CoinControlDialog @@ -629,150 +463,6 @@ Priority 優先度 - - Copy address - 複製位址 - - - Copy label - 複製標記 - - - Copy amount - 複製金額 - - - Copy transaction ID - 複製交易識別碼 - - - Lock unspent - 鎖定不用 - - - Unlock unspent - 解鎖可用 - - - Copy quantity - 複製數目 - - - Copy fee - 複製手續費 - - - Copy after fee - 複製計費後金額 - - - Copy bytes - 複製位元組數 - - - Copy priority - 複製優先度 - - - Copy dust - 複製零散金額 - - - Copy change - 複製找零金額 - - - highest - 最高 - - - higher - 很高 - - - high - - - - medium-high - 中高 - - - medium - 中等 - - - low-medium - 中低 - - - low - - - - lower - 很低 - - - lowest - 最低 - - - (%1 locked) - (鎖定 %1 枚) - - - none - - - - This label turns red if the transaction size is greater than 1000 bytes. - 當交易大小大於 1000 位元組時,文字會變紅色。 - - - This label turns red if the priority is smaller than "medium". - 當優先度低於「中等」時,文字會變紅色。 - - - This label turns red if any recipient receives an amount smaller than %1. - 當任何一個收款金額小於 %1 時,文字會變紅色。 - - - Can vary +/- %1 satoshi(s) per input. - 每組輸入可能有 +/- %1 個 satoshi 的誤差。 - - - yes - - - - no - - - - This means a fee of at least %1 per kB is required. - 表示每一千位元組(kB)需要至少 %1 的手續費。 - - - Can vary +/- 1 byte per input. - 每組輸入可能會誤差多或少 1 個位元組。 - - - Transactions with higher priority are more likely to get included into a block. - 優先度較高的交易比較有可能被接受放進區塊中。 - - - (no label) - (無標記) - - - change from %1 (%2) - 找零前是 %1 (%2) - - - (change) - (找零) - EditAddressDialog @@ -796,38 +486,6 @@ &Address 位址 - - New receiving address - 造新的收款位址 - - - New sending address - 造新的付款位址 - - - Edit receiving address - 編輯收款位址 - - - Edit sending address - 編輯付款位址 - - - The entered address "%1" is already in the address book. - 輸入的位址 %1 在位址簿中已經有了。 - - - The entered address "%1" is not a valid Bitcoin address. - 輸入的位址 %1 並不是有效的 Bitcoin 位址。 - - - Could not unlock wallet. - 沒辦法把錢包解鎖。 - - - New key generation failed. - 產生新的密鑰失敗了。 - FreespaceChecker @@ -854,10 +512,6 @@ HelpMessageDialog - - Bitcoin Core - Bitcoin Core - version 版本 @@ -867,8 +521,8 @@ (%1 位元) - About Bitcoin Core - 關於 Bitcoin Core + About %1 + 關於 %1 Command-line options @@ -907,7 +561,7 @@ 顯示啓動畫面(預設值: %u) - Reset all settings changes made over the GUI + Reset all settings changed in the GUI 重置所有在使用界面更改的設定 @@ -918,16 +572,16 @@ 歡迎 - Welcome to Bitcoin Core. - 歡迎使用 Bitcoin Core + Welcome to %1. + 歡迎使用 %1。 - As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. - 因為這是程式第一次啓動,你可以選擇 Bitcoin Core 儲存資料的地方。 + As this is the first time the program is launched, you can choose where %1 will store its data. + 因為這是程式第一次啓動,你可以選擇 %1 儲存資料的地方。 - Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core 會下載並儲存一份 Bitcoin 區塊鏈的拷貝。至少有 %1GB 的資料會儲存到這個目錄中,並且還會持續增長。另外錢包資料也會儲存在這個目錄。 + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 會下載並儲存一份 Bitcoin 區塊鏈的拷貝。至少有 %2GB 的資料會儲存到這個目錄中,並且還會持續增長。另外錢包資料也會儲存在這個目錄。 Use the default data directory @@ -937,10 +591,6 @@ Use a custom data directory: 使用自訂的資料目錄: - - Bitcoin Core - Bitcoin Core - Error: Specified data directory "%1" cannot be created. 錯誤: 無法新增指定的資料目錄: %1 @@ -976,10 +626,6 @@ Select payment request file 選擇付款要求資料檔 - - Select payment request file to open - 選擇要開啟的付款要求資料檔 - OptionsDialog @@ -991,6 +637,14 @@ &Main 主要 + + Automatically start %1 after logging in to the system. + 在登入系統後自動啓動 %1。 + + + &Start %1 on system login + 系統登入時啟動 %1 + Size of &database cache 資料庫快取大小 @@ -1019,10 +673,6 @@ 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. 當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。 - - The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. - 可以在這裡設定使用者介面的語言。這個設定在重啓 Bitcoin Core 後才會生效。 - 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 |. 在交易頁籤的情境選單出現的第三方網址連結(URL),比如說區塊探索網站。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。 @@ -1047,14 +697,6 @@ &Network 網路 - - Automatically start Bitcoin Core after logging in to the system. - 在登入系統後自動啓動 Bitcoin Core。 - - - &Start Bitcoin Core on system login - 系統登入時啟動 Bitcoin Core - (0 = auto, <0 = leave that many cores free) (0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目) @@ -1139,13 +781,21 @@ &Window 視窗 + + &Hide the icon from the system tray. + 不在通知區顯示圖示。 + + + Hide tray icon + 不顯示通知區圖示 + Show only a tray icon after minimizing the window. - 視窗縮到最小後只在通知區域顯示圖示。 + 視窗縮到最小後只在通知區顯示圖示。 &Minimize to the tray instead of the taskbar - 縮到最小到通知區域而不是工作列 + 縮到最小到通知區而不是工作列 M&inimize on close @@ -1159,6 +809,10 @@ User Interface &language: 使用界面語言: + + The user interface language can be set here. This setting will take effect after restarting %1. + 可以在這裡設定使用者介面的語言。這個設定在重啓 %1 後才會生效。 + &Unit to show amounts in: 金額顯示單位: @@ -1283,97 +937,6 @@ 所有只能看位址的目前全部餘額 - - PaymentServer - - URI handling - URI 處理 - - - Invalid payment address %1 - 無效的付款位址 %1 - - - Payment request rejected - 付款的要求被拒絕了 - - - Payment request network doesn't match client network. - 付款要求的網路類型跟客戶端不符。 - - - Payment request is not initialized. - 付款的要求沒有完成初始化。 - - - Requested payment amount of %1 is too small (considered dust). - 要求付款的金額 %1 太少(會被網路認為是沒必要的零散錢)。 - - - Payment request error - 要求付款時發生錯誤 - - - Cannot start bitcoin: click-to-pay handler - 沒辦法啟動 bitcoin 協議的按就付處理器 - - - Payment request fetch URL is invalid: %1 - 取得付款要求的網址連結(URL)無效: %1 - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - 沒辦法解析資源識別碼(URI)!可能是因為 Bitcoin 位址無效,或是 URI 參數格式錯誤。 - - - Payment request file handling - 處理付款要求檔案 - - - Payment request file cannot be read! This can be caused by an invalid payment request file. - 沒辦法讀取付款要求檔案!可能是無效的檔案造成的。 - - - Payment request expired. - 付款的要求過期了。 - - - Unverified payment requests to custom payment scripts are unsupported. - 不支援含有自訂付款指令碼,且沒驗證過的付款要求。 - - - Invalid payment request. - 付款的要求無效。 - - - Refund from %1 - 來自 %1 的退款 - - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - 付款要求 %1 過大 (%2 位元組, 上限 %3 位元組). - - - Error communicating with %1: %2 - 跟 %1 通訊時發生錯誤: %2 - - - Payment request cannot be parsed! - 沒辦法解析付款要求內容! - - - Bad response from server %1 - 伺服器 %1 的回應有誤 - - - Payment acknowledged - 已確認付款 - - - Network request error - 發出要求時發生網路錯誤 - - PeerTableModel @@ -1428,25 +991,6 @@ %1 毫秒 - - QRImageWidget - - &Save Image... - 儲存圖片... - - - &Copy Image - 複製圖片 - - - Save QR Code - 儲存 QR Code - - - PNG Image (*.png) - PNG 圖檔(*.png) - - RPCConsole @@ -1477,6 +1021,10 @@ Using BerkeleyDB version 使用 BerkeleyDB 版本 + + Datadir + 資料目錄 + Startup time 啓動時間 @@ -1513,10 +1061,6 @@ Memory usage 記憶體使用量 - - Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - 從目前的資料目錄下開啓 Bitcoin Core 的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 - Received 收到 @@ -1565,6 +1109,18 @@ User Agent 使用者代理 + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + 從目前的資料目錄下開啓 %1 的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 + + + Decrease font size + 縮小文字 + + + Increase font size + 放大文字 + Services 服務 @@ -1633,10 +1189,6 @@ Out: 去: - - Build date - 建置日期 - Debug log file 除錯紀錄檔 @@ -1671,11 +1223,11 @@ &Unban Node - 解禁解點連線 + 解禁節點連線 - Welcome to the Bitcoin Core RPC console. - 歡迎使用 Bitcoin Core 的 RPC 主控台。 + Welcome to the %1 RPC console. + 歡迎使用 %1 的 RPC 主控台。 Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. @@ -1804,18 +1356,6 @@ Remove 刪掉 - - Copy label - 複製標記 - - - Copy message - 複製訊息 - - - Copy amount - 複製金額 - ReceiveRequestDialog @@ -1835,73 +1375,6 @@ &Save Image... 儲存圖片... - - Request payment to %1 - 付款給 %1 的要求 - - - Payment information - 付款資訊 - - - URI - URI - - - Address - 位址 - - - Amount - 金額 - - - Label - 標記 - - - Message - 訊息 - - - Resulting URI too long, try to reduce the text for label / message. - 產生的 URI 過長,請試著縮短標記或訊息的文字內容。 - - - Error encoding URI into QR Code. - 把 URI 編碼成 QR Code 時發生錯誤。 - - - - RecentRequestsTableModel - - Date - 日期 - - - Label - 標記 - - - Message - 訊息 - - - Amount - 金額 - - - (no label) - (無標記) - - - (no message) - (無訊息) - - - (no amount) - (無金額) - SendCoinsDialog @@ -2021,14 +1494,6 @@ fast 快速 - - Send as zero-fee transaction if possible - 盡可能送不用付手續費的交易 - - - (confirmation may take longer) - (確認時間可能拉長) - Send to multiple recipients at once 一次付給多個收款人 @@ -2061,118 +1526,6 @@ S&end 付款 - - Confirm send coins - 確認付款金額 - - - %1 to %2 - %1 給 %2 - - - Copy quantity - 複製數目 - - - Copy amount - 複製金額 - - - Copy fee - 複製手續費 - - - Copy after fee - 複製計費後金額 - - - Copy bytes - 複製位元組數 - - - Copy priority - 複製優先度 - - - Copy change - 複製找零金額 - - - Total Amount %1 - 總金額 %1 - - - or - - - - The amount to pay must be larger than 0. - 付款金額必須大於零。 - - - The amount exceeds your balance. - 金額超過餘額了。 - - - The total exceeds your balance when the %1 transaction fee is included. - 包含 %1 的交易手續費後,總金額超過你的餘額了。 - - - Transaction creation failed! - 製造交易失敗了! - - - The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - 交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。 - - - A fee higher than %1 is considered an absurdly high fee. - 高於 %1 的手續費會被認為是不合理。 - - - Payment request expired. - 付款的要求過期了。 - - - Pay only the required fee of %1 - 只付必要的手續費 %1 - - - Estimated to begin confirmation within %n block(s). - 預計可在 %n 個區塊內開始確認。 - - - The recipient address is not valid. Please recheck. - 收款位址無效。請再檢查看看。 - - - Duplicate address found: addresses should only be used once each. - 發現有重複的位址: 每個位址只能出現一次。 - - - Warning: Invalid Bitcoin address - 警告: Bitcoin 位址無效 - - - (no label) - (無標記) - - - Warning: Unknown change address - 警告: 不明的找零位址 - - - Copy dust - 複製零散金額 - - - Are you sure you want to send? - 你確定要付錢出去嗎? - - - added as transaction fee - 加做交易手續費 - SendCoinsEntry @@ -2184,10 +1537,6 @@ Pay &To: 付給: - - Enter a label for this address to add it to your address book - 請輸入這個位址的標記來把它加進位址簿中 - &Label: 標記: @@ -2260,8 +1609,8 @@ ShutdownWindow - Bitcoin Core is shutting down... - 正在關閉 Bitcoin Core 中... + %1 is shutting down... + 正在關閉 %1 中... Do not shut down the computer until this window disappears. @@ -2354,69 +1703,9 @@ Reset all verify message fields 重設所有訊息驗證欄位 - - Click "Sign Message" to generate signature - 請按一下「簽署訊息」來產生簽章 - - - The entered address is invalid. - 輸入的位址無效。 - - - Please check the address and try again. - 請檢查位址是否正確後再試一次。 - - - The entered address does not refer to a key. - 輸入的位址沒有對應到你的任何密鑰。 - - - Wallet unlock was cancelled. - 錢包解鎖已取消。 - - - Private key for the entered address is not available. - 沒有對應輸入位址的密鑰。 - - - Message signing failed. - 訊息簽署失敗。 - - - Message signed. - 訊息簽署好了。 - - - The signature could not be decoded. - 沒辦法把這個簽章解碼。 - - - Please check the signature and try again. - 請檢查簽章是否正確後再試一次。 - - - The signature did not match the message digest. - 這個簽章跟訊息的數位摘要不符。 - - - Message verification failed. - 訊息驗證失敗。 - - - Message verified. - 訊息驗證沒錯。 - SplashScreen - - Bitcoin Core - Bitcoin Core - - - The Bitcoin Core developers - Bitcoin Core 開發人員 - [testnet] [testnet] @@ -2429,422 +1718,13 @@ KB/s - - TransactionDesc - - Open until %1 - 到 %1 前可修改 - - - conflicted - 有衝突 - - - %1/offline - %1 次/離線中 - - - %1/unconfirmed - %1 次/未確認 - - - %1 confirmations - 確認 %1 次 - - - Status - 狀態 - - - , broadcast through %n node(s) - ,已公告給 %n 個節點 - - - Date - 日期 - - - Source - 來源 - - - Generated - 生產出來 - - - From - 來源 - - - To - 目的 - - - own address - 自己的位址 - - - watch-only - 只能看 - - - label - 標記 - - - Credit - 入帳 - - - matures in %n more block(s) - 再等 %n 個區塊生出來後成熟 - - - not accepted - 不被接受 - - - Debit - 出帳 - - - Total debit - 出帳總額 - - - Total credit - 入帳總額 - - - Transaction fee - 交易手續費 - - - Net amount - 淨額 - - - Message - 訊息 - - - Comment - 附註 - - - Transaction ID - 交易識別碼 - - - Merchant - 商家 - - - 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. - 生產出來的錢要再等 %1 個區塊生出來後才成熟可以用。當區塊生產出來時會公布到網路上,來被加進區塊鏈。如果加失敗了,狀態就會變成「不被接受」,而且不能夠花。如果在你生產出區塊的幾秒鐘內,也有其他節點生產出來的話,就有可能會發生這種情形。 - - - Debug information - 除錯資訊 - - - Transaction - 交易 - - - Inputs - 輸入 - - - Amount - 金額 - - - true - - - - false - - - - , has not been successfully broadcast yet - ,還沒成功公告出去 - - - Open for %n more block(s) - 到下 %n 個區塊生出來前可修改 - - - unknown - 未知 - - TransactionDescDialog - - Transaction details - 交易明細 - This pane shows a detailed description of the transaction 這個版面顯示這次交易的詳細說明 - - TransactionTableModel - - Date - 日期 - - - Type - 種類 - - - Immature (%1 confirmations, will be available after %2) - 未成熟(確認 %1 次,會在 %2 次後可用) - - - Open for %n more block(s) - 到下 %n 個區塊生出來前可修改 - - - Open until %1 - 到 %1 前可修改 - - - Confirmed (%1 confirmations) - 已確認(%1 次) - - - This block was not received by any other nodes and will probably not be accepted! - 沒有其他節點收到這個區塊,也許它不會被接受! - - - Generated but not accepted - 生產出來但是不被接受 - - - Offline - 離線中 - - - Label - 標記 - - - Unconfirmed - 未確認 - - - Confirming (%1 of %2 recommended confirmations) - 確認中(已經 %1 次,建議至少 %2 次) - - - Conflicted - 有衝突 - - - Received with - 收款在 - - - Received from - 收款自 - - - Sent to - 付款給 - - - Payment to yourself - 付給自己 - - - Mined - 開採所得 - - - watch-only - 只能看 - - - (n/a) - (不適用) - - - Transaction status. Hover over this field to show number of confirmations. - 交易狀態。把游標停在欄位上會顯示確認次數。 - - - Date and time that the transaction was received. - 收到交易的日期和時間。 - - - Type of transaction. - 交易的種類。 - - - Whether or not a watch-only address is involved in this transaction. - 不論如何有一個只能觀看的地只有參與這次的交易 - - - User-defined intent/purpose of the transaction. - 使用者定義的交易動機或理由。 - - - Amount removed from or added to balance. - 要減掉或加進餘額的金額。 - - - - TransactionView - - All - 全部 - - - Today - 今天 - - - This week - 這星期 - - - This month - 這個月 - - - Last month - 上個月 - - - This year - 今年 - - - Range... - 指定範圍... - - - Received with - 收款 - - - Sent to - 付款 - - - To yourself - 給自己 - - - Mined - 開採所得 - - - Other - 其它 - - - Enter address or label to search - 請輸入要搜尋的位址或標記 - - - Min amount - 最小金額 - - - Copy address - 複製位址 - - - Copy label - 複製標記 - - - Copy amount - 複製金額 - - - Copy transaction ID - 複製交易識別碼 - - - Copy raw transaction - 複製交易原始資料 - - - Edit label - 編輯標記 - - - Show transaction details - 顯示交易明細 - - - Export Transaction History - 匯出交易記錄 - - - Watch-only - 只能觀看的 - - - Exporting Failed - 匯出失敗 - - - There was an error trying to save the transaction history to %1. - 儲存交易記錄到 %1 時發生錯誤。 - - - Exporting Successful - 匯出成功 - - - The transaction history was successfully saved to %1. - 交易記錄已經成功儲存到 %1 了。 - - - Comma separated file (*.csv) - 逗點分隔資料檔(*.csv) - - - Confirmed - 已確認 - - - Date - 日期 - - - Type - 種類 - - - Label - 標記 - - - Address - 位址 - - - ID - 識別碼 - - - Range: - 範圍: - - - to - - - UnitDisplayStatusBarControl @@ -2852,55 +1732,6 @@ 金額顯示單位。可以點選其他單位。 - - WalletFrame - - No wallet has been loaded. - 沒有載入錢包。 - - - - WalletModel - - Send Coins - 付款 - - - - WalletView - - &Export - 匯出 - - - Export the data in the current tab to a file - 把目前分頁的資料匯出存成檔案 - - - Backup Wallet - 備份錢包 - - - Wallet Data (*.dat) - 錢包資料檔(*.dat) - - - Backup Failed - 備份失敗 - - - There was an error trying to save the wallet data to %1. - 儲存錢包資料到 %1 時發生錯誤。 - - - The wallet data was successfully saved to %1. - 錢包的資料已經成功儲存到 %1 了。 - - - Backup Successful - 備份成功 - - bitcoin-core @@ -2928,14 +1759,6 @@ If <category> is not supplied or if <category> = 1, output all debugging information. 如果沒有提供 <category> 或是值為 1 就會輸出所有的除錯資訊。 - - Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) - 一次錢包交易允許付出最高的總手續費(單位是 %s);設定太低的話,可能會無法進行資料量大的交易(預設值: %s) - - - Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. - 請檢查電腦日期和時間是否正確!Bitcoin Core 沒辦法在時鐘不準的情況下正常運作。 - Prune configured below the minimum of %d MiB. Please use a higher number. 設定的修剪值小於最小需求的 %d 百萬位元組(MiB)。請指定大一點的數字。 @@ -2976,6 +1799,14 @@ Accept connections from outside (default: 1 if no -proxy or -connect) 是否接受外來連線(預設值: 當沒有 -proxy 或 -connect 時為 1) + + Bitcoin Core + Bitcoin Core + + + The %s developers + %s 開發人員 + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. 警告: -fallbackfee 設定了很高的金額!這是當預估手續費還沒計算出來時,交易付款預設會付的手續費。 @@ -2992,6 +1823,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 和指定的位址繫結,並且一直在指定位址聽候連線。IPv6 請用 [主機]:通訊埠 這種格式 + + Cannot obtain a lock on data directory %s. %s is probably already running. + 沒辦法鎖定資料目錄 %s。%s 可能已經在執行了。 + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup 清掉錢包裡的所有交易,並且在下次啟動時,使用 -rescan 來從區塊鏈中復原回來。 @@ -3000,6 +1835,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. 這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + 載入 %s 發生錯誤:不能對已存在的非 HD 錢包啟用 HD 功能。 + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + 讀取錢包檔 %s 時發生錯誤!所有的密鑰都正確讀取了,但是交易資料或位址簿資料可能會缺少或不正確。 + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼) @@ -3008,6 +1851,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + 跟其他節點的時間差最高可接受的中位數值。本機所認為的時間可能會被其他節點影響,往前或往後在這個值之內。(預設值: %u 秒) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + 允許一次錢包交易或未加工交易付出的最高總手續費(單位是 %s);設定太低的話,可能會無法進行資料量大的交易(預設值: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + 請檢查電腦日期和時間是否正確!%s 沒辦法在時鐘不準的情況下正常運作。 + + + Please contribute if you find %s useful. Visit %s for further information about the software. + 如果你覺得 %s 有用,可以捐助我們。關於這個軟體的更多資訊請見 %s。 + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 設定指令碼驗證的執行緒數目 (%u 到 %d,0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目,預設值: %d) @@ -3020,14 +1879,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 這是個還沒發表的測試版本 - 使用請自負風險 - 請不要用來開採或商業應用 - - Unable to bind to %s on this computer. Bitcoin Core is probably already running. - 沒辦法繫結在這台電腦上的 %s 。Bitcoin Core 可能已經在執行了。 - - - Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. - 忽略不支援的參數 -whitelistalwaysrelay,請改用 -whitelistrelay 和 -whitelistforcerelay​ 的組合。 - Use UPnP to map the listening port (default: 1 when listening and no -proxy) 是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線且沒有指定 -proxy 參數時為 1) @@ -3044,22 +1895,22 @@ Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告: 節點網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。 - - Warning: Unknown block versions being mined! It's possible unknown rules are in effect - 警告: 有礦工正在開採不明版本的區塊!這表示有不明的交易規則正在作用中 - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. 警告: 我們和某些連線的節點對於區塊鏈結的決定不同!你可能需要升級,或是需要等其它的節點升級。 - - Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - 警告: 錢包檔 wallet.dat 壞掉,但資料被拯救回來了!原來的 wallet.dat 會改儲存在 %s, 檔名是 wallet.{timestamp}.bak. 如果餘額或交易資料有誤,你應該要用備份資料復原回來。 - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。 + + You need to rebuild the database using -reindex-chainstate to change -txindex + 改變 -txindex 參數後,必須要用 -reindex-chainstate 參數來重建資料庫 + + + %s corrupt, salvage failed + 錢包檔 %s 壞掉了,搶救失敗 + -maxmempool must be at least %d MB 參數 -maxmempool 至少要給 %d 百萬位元組(MB) @@ -3072,10 +1923,22 @@ Append comment to the user agent string 對使用者代理字串添加註解 + + Attempt to recover private keys from a corrupt wallet on startup + 啟動時嘗試從壞掉的錢包檔復原密鑰 + Block creation options: 區塊製造選項: + + Cannot resolve -%s address: '%s' + 沒辦法解析 -%s 參數指定的位址: '%s' + + + Change index out of range + 找零的索引值超出範圍 + Connect only to the specified node(s) 只連線到指定節點(可多個) @@ -3084,6 +1947,10 @@ Connection options: 連線選項: + + Copyright (C) %i-%i + 版權所有 (C) %i-%i + Corrupted block database detected 發現區塊資料庫壞掉了 @@ -3128,6 +1995,22 @@ Error initializing wallet database environment %s! 初始化錢包資料庫環境 %s 時發生錯誤! + + Error loading %s + 載入檔案 %s 時發生錯誤 + + + Error loading %s: Wallet corrupted + 載入檔案 %s 時發生錯誤: 錢包損毀了 + + + Error loading %s: Wallet requires newer version of %s + 載入檔案 %s 時發生錯誤: 這個錢包需要新版的 %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + 載入 %s 發生錯誤:不能對已存在的 HD 錢包停用 HD 功能。 + Error loading block database 載入區塊資料庫時發生錯誤 @@ -3152,10 +2035,18 @@ Incorrect or no genesis block found. Wrong datadir for network? 創世區塊不正確或找不到。資料目錄錯了嗎? + + Initialization sanity check failed. %s is shutting down. + 初始化時的基本檢查失敗了。%s 就要關閉了。 + Invalid -onion address: '%s' 無效的 -onion 位址: '%s' + + Invalid amount for -%s=<amount>: '%s' + 參數 -%s=<金額> 指定的金額無效: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' 設定 -fallbackfee=<金額> 的金額無效: '%s' @@ -3164,6 +2055,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) 在記憶體暫存池中保持最多 <n> 個百萬位元組的交易(預設值: %u) + + Loading banlist... + 正在載入禁止連線名單中... + Location of the auth cookie (default: data dir) 認證 cookie 資料的位置(預設值: 同資料目錄) @@ -3180,6 +2075,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) 只和 <net> 網路上的節點連線(ipv4, ipv6, 或 onion) + + Print this help message and exit + 顯示說明訊息後結束 + Print version and exit 顯示版本後結束 @@ -3192,6 +2091,14 @@ Prune mode is incompatible with -txindex. 修剪模式和 -txindex 參數不相容。 + + Rebuild chain state and block index from the blk*.dat files on disk + 從磁碟裡的區塊檔 blk*.dat 重建區塊鏈狀態和區塊索引 + + + Rebuild chain state from the currently indexed blocks + 從目前已編索引的區塊資料重建區塊鏈狀態 + Set database cache size in megabytes (%d to %d, default: %d) 設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d) @@ -3204,6 +2111,14 @@ Specify wallet file (within data directory) 指定錢包檔(會在資料目錄中) + + The source code is available from %s. + 原始碼可以在 %s 取得。 + + + Unable to bind to %s on this computer. %s is probably already running. + 沒辦法繫結在這台電腦上的 %s 。%s 可能已經在執行了。 + Unsupported argument -benchmark ignored, use -debug=bench. 忽略了不再支援的 -benchmark 參數,請改用 -debug=bench @@ -3237,12 +2152,16 @@ 錢包檔 %s 沒有在資料目錄 %s 裡面 - Wallet options: - 錢包選項: + Wallet debugging/testing options: + 錢包除錯與測試選項: - You need to rebuild the database using -reindex to change -txindex - 改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫 + Wallet needed to be rewritten: restart %s to complete + 錢包需要重寫: 請重新啓動 %s 來完成 + + + Wallet options: + 錢包選項: Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -3256,10 +2175,6 @@ Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) 和指定的位址繫結以聽候 JSON-RPC 連線。IPv6 請用 [主機]:通訊埠 這種格式。這個選項可以設定多次。(預設值: 跟所有網路界面上的位址繫結) - - Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. - 沒辦法鎖定資料目錄 %s。Bitcoin Core 可能已經在執行了。 - Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) 用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。 @@ -3304,10 +2219,6 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) 設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d) - - Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) - 設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d) - The transaction amount is too small to send after the fee has been deducted 扣除手續費後的交易金額太少而不能傳送 @@ -3316,6 +2227,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. 此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 <https://www.openssl.org/>, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。 + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + 在 BIP32 開始作用後,啟用階層式可預期性密鑰產生方式(HD)。只有在產生新錢包或第一次啟動時才有作用。 + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway 在白名單中的節點不會因為偵測到阻斷服務攻擊(DoS)而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。 @@ -3332,34 +2247,14 @@ Accept public REST requests (default: %u) 接受公開的REST請求 (預設值: %u) - - Activating best chain... - 啟用最佳鏈結... - - - Attempt to recover private keys from a corrupt wallet.dat on startup - 啟動時嘗試從壞掉的錢包檔 wallet.dat 復原密鑰 - Automatically create Tor hidden service (default: %d) 自動產生 Tor 隱藏服務(預設值: %d) - - Cannot resolve -whitebind address: '%s' - 沒辦法解析 -whitebind 指定的位址: '%s' - Connect through SOCKS5 proxy 透過 SOCKS5 代理伺服器連線 - - Copyright (C) 2009-%i The Bitcoin Core Developers - 版權為 Bitcoin Core 開發人員自西元 2009 至 %i 年起所有 - - - Error loading wallet.dat: Wallet requires newer version of Bitcoin Core - 載入 wallet.dat 檔案時發生錯誤: 這個錢包需要新版的 Bitcoin Core - Error reading from database, shutting down. 讀取資料庫時發生錯誤,要關閉了。 @@ -3372,22 +2267,6 @@ Information 資訊 - - Initialization sanity check failed. Bitcoin Core is shutting down. - 初始化時的基本檢查失敗了。Bitcoin Core 就要關閉了。 - - - Invalid amount for -maxtxfee=<amount>: '%s' - -maxtxfee=<amount>: '%s' 的金額無效 - - - Invalid amount for -minrelaytxfee=<amount>: '%s' - 設定最低轉發手續費 -minrelaytxfee=<金額> 的金額無效: '%s' - - - Invalid amount for -mintxfee=<amount>: '%s' - 設定 -mintxfee=<金額> 的金額無效: '%s' - Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) 設定 -paytxfee=<金額> 的金額無效: '%s' (至少要有 %s) @@ -3412,14 +2291,6 @@ RPC server options: RPC 伺服器選項: - - Rebuild block chain index from current blk000??.dat files on startup - 啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引 - - - Receive and display P2P network alerts (default: %u) - 接收並顯示對等網路(P2P)警示 (預設值: %u) - Reducing -maxconnections from %d to %d, because of system limitations. 因為系統的限制,將 -maxconnections 參數從 %d 降到了 %d @@ -3492,10 +2363,6 @@ Username for JSON-RPC connections JSON-RPC 連線使用者名稱 - - Wallet needed to be rewritten: restart Bitcoin Core to complete - 錢包需要重寫: 請重新啓動 Bitcoin Core 來完成 - Warning 警告 @@ -3516,10 +2383,6 @@ ZeroMQ notification options: ZeroMQ 通知選項: - - wallet.dat corrupt, salvage failed - 錢包檔 weallet.dat 壞掉了,拯救失敗 - Password for JSON-RPC connections JSON-RPC 連線密碼 @@ -3528,10 +2391,6 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) 當最新區塊改變時要執行的指令(指令中的 %s 會被取代成區塊雜湊值) - - This help message - 這些說明訊息 - Allow DNS lookups for -addnode, -seednode and -connect 允許對 -addnode, -seednode, -connect 的參數使用域名查詢 @@ -3540,10 +2399,6 @@ Loading addresses... 正在載入位址資料... - - Error loading wallet.dat: Wallet corrupted - 載入檔案 wallet.dat 時發生錯誤: 錢包損毀了 - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料) @@ -3560,10 +2415,6 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) 不要讓交易留在記憶池中超過 <n> 個小時(預設值: %u) - - Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - 讀取錢包檔 wallet.dat 時發生錯誤!所有的密鑰都正確讀取了,但是交易資料或位址簿資料可能會缺少或不正確。 - Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) 當製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s) @@ -3600,6 +2451,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. 找到不再支援的 -socks 參數。現在只支援 SOCKS5 協定的代理伺服器,因此不可以指定 SOCKS 協定版本了。 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + 忽略不支援的參數 -whitelistalwaysrelay,請改用 -whitelistrelay 和 -whitelistforcerelay​ 的組合。 + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟其他節點聯絡(預設值: %s) @@ -3608,6 +2463,14 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times JSON-RPC 連線要用的使用者名稱和雜湊密碼。<userpw> 的格式是:<使用者名稱>:<調味值>$<雜湊值>。在 share/rpcuser 目錄下有一個示範的 python 程式。這個選項可以給很多次。 + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + 警告: 有礦工正在開採不明版本的區塊!這表示有不明的交易規則正在作用中 + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + 警告: 錢包檔壞掉,但資料被救回來了!原來的檔案 %s 改儲存為 %s,在目錄 %s 下。 如果餘額或交易資料有誤的話,你應該要從備份資料復原回來。 + (default: %s) (預設值: %s) @@ -3616,14 +2479,6 @@ Always query for peer addresses via DNS lookup (default: %u) 是否一定要用域名查詢來搜尋節點(預設值: %u) - - Error loading wallet.dat - 載入錢包檔 wallet.dat 時發生錯誤 - - - Generate coins (default: %u) - 生產錢幣(預設值: %u) - How many blocks to check at startup (default: %u, 0 = all) 啓動時檢查的區塊數(預設值: %u, 指定 0 表示全部) @@ -3708,18 +2563,6 @@ Unknown network specified in -onlynet: '%s' 在 -onlynet 指定了不明的網路別: '%s' - - Cannot resolve -bind address: '%s' - 沒辦法解析 -bind 位址: '%s' - - - Cannot resolve -externalip address: '%s' - 沒辦法解析 -externalip 位址: '%s' - - - Invalid amount for -paytxfee=<amount>: '%s' - 設定 -paytxfee=<金額> 的金額無效: '%s' - Insufficient funds 累積金額不足 From 36f1b9df762f4819e67e060e1624911df9bd59de Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 28 Jun 2016 10:32:09 -0400 Subject: [PATCH 0880/1223] Tests: Increase sync_blocks() timeouts in pruning.py --- qa/rpc-tests/pruning.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index d225e29b5..7cbe69c29 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -151,14 +151,14 @@ class PruneTest(BitcoinTestFramework): print("Reconnect nodes") connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[2], 1) - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=120) print("Verify height on node 2:",self.nodes[2].getblockcount()) print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=300) usage = calc_usage(self.prunedir) print("Usage should be below target:", usage) From 14d01309bed59afb08651f2b701ff90371b15b20 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Tue, 16 Feb 2016 18:29:53 +0000 Subject: [PATCH 0881/1223] Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY --- doc/release-notes.md | 7 +++- qa/rpc-tests/test_framework/script.py | 8 ++-- src/script/script.cpp | 2 +- src/script/script.h | 4 +- src/test/data/script_tests.json | 24 ++++++------ src/test/data/tx_invalid.json | 28 +++++++------- src/test/data/tx_valid.json | 56 +++++++++++++-------------- 7 files changed, 66 insertions(+), 63 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6e4f390cb..e1f3e2427 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -113,12 +113,15 @@ git merge commit are mentioned. ### RPC and REST -Asm script outputs now contain OP_CHECKLOCKTIMEVERIFY in place of OP_NOP2 -------------------------------------------------------------------------- +Asm script outputs replacements for OP_NOP2 and OP_NOP3 +------------------------------------------------------- OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) +OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP +112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) + The following outputs are affected by this change: - RPC `getrawtransaction` (in verbose mode) - RPC `decoderawtransaction` diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 7678228c4..b46c643cc 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -233,7 +233,7 @@ OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf) # expansion OP_NOP1 = CScriptOp(0xb0) OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1) -OP_NOP3 = CScriptOp(0xb2) +OP_CHECKSEQUENCEVERIFY = CScriptOp(0xb2) OP_NOP4 = CScriptOp(0xb3) OP_NOP5 = CScriptOp(0xb4) OP_NOP6 = CScriptOp(0xb5) @@ -360,7 +360,7 @@ VALID_OPCODES = { OP_NOP1, OP_CHECKLOCKTIMEVERIFY, - OP_NOP3, + OP_CHECKSEQUENCEVERIFY, OP_NOP4, OP_NOP5, OP_NOP6, @@ -479,7 +479,7 @@ OPCODE_NAMES.update({ OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY', OP_NOP1 : 'OP_NOP1', OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY', - OP_NOP3 : 'OP_NOP3', + OP_CHECKSEQUENCEVERIFY : 'OP_CHECKSEQUENCEVERIFY', OP_NOP4 : 'OP_NOP4', OP_NOP5 : 'OP_NOP5', OP_NOP6 : 'OP_NOP6', @@ -598,7 +598,7 @@ OPCODES_BY_NAME = { 'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY, 'OP_NOP1' : OP_NOP1, 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY, - 'OP_NOP3' : OP_NOP3, + 'OP_CHECKSEQUENCEVERIFY' : OP_CHECKSEQUENCEVERIFY, 'OP_NOP4' : OP_NOP4, 'OP_NOP5' : OP_NOP5, 'OP_NOP6' : OP_NOP6, diff --git a/src/script/script.cpp b/src/script/script.cpp index da551c23e..ddf677556 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -132,7 +132,7 @@ const char* GetOpName(opcodetype opcode) // expanson case OP_NOP1 : return "OP_NOP1"; case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; - case OP_NOP3 : return "OP_NOP3"; + case OP_CHECKSEQUENCEVERIFY : return "OP_CHECKSEQUENCEVERIFY"; case OP_NOP4 : return "OP_NOP4"; case OP_NOP5 : return "OP_NOP5"; case OP_NOP6 : return "OP_NOP6"; diff --git a/src/script/script.h b/src/script/script.h index 71af3754b..278774d32 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -167,8 +167,8 @@ enum opcodetype OP_NOP1 = 0xb0, OP_CHECKLOCKTIMEVERIFY = 0xb1, OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, - OP_NOP3 = 0xb2, - OP_CHECKSEQUENCEVERIFY = OP_NOP3, + OP_CHECKSEQUENCEVERIFY = 0xb2, + OP_NOP3 = OP_CHECKSEQUENCEVERIFY, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 9b81e0c77..fcd545738 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], +["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], @@ -443,7 +443,7 @@ ["NOP", "NOP1 1", "P2SH,STRICTENC", "OK"], ["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP3 1", "P2SH,STRICTENC", "OK"], +["NOP", "CHECKSEQUENCEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], @@ -701,7 +701,7 @@ ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"], -["2147483648", "NOP3", "CHECKSEQUENCEVERIFY", "OK", "CSV passes if stack top bit 1 << 31 is set"], +["2147483648", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "OK", "CSV passes if stack top bit 1 << 31 is set"], ["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], [" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], @@ -857,13 +857,13 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1", "NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKSEQUENCEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -2119,11 +2119,11 @@ ], ["CHECKSEQUENCEVERIFY tests"], -["", "NOP3", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], -["-1", "NOP3", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], -["0x0100", "NOP3", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], -["0", "NOP3", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], -["4294967296", "NOP3", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], +["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], +["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], +["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], ["The End"] ] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 05502a83f..f8baee057 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -200,41 +200,41 @@ ["CHECKSEQUENCEVERIFY tests"], ["By-height locks, with argument just beyond txin.nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["By-time locks, with argument just beyond txin.nSequence (but within numerical boundries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument missing"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument negative with by-blockheight txin.nSequence=0"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument negative with by-blocktime txin.nSequence=CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument/tx height/time mismatch, both versions"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Failure due to failing CHECKSEQUENCEVERIFY in scriptSig"], @@ -246,9 +246,9 @@ "0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Failure due to insufficient tx.nVersion (<2)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Unknown witness program version (with DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index c9fe4e313..1ea70135b 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -236,77 +236,77 @@ ["CHECKSEQUENCEVERIFY tests"], ["By-height locks, with argument == 0 and == txin.nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["By-time locks, with argument == 0 and == txin.nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Upper sequence with upper sequence is fine"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument 2^31 with various nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument 2^32-1 with various nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument 3<<31 with various nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["5 byte non-minimally-encoded operandss are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["The argument can be calculated rather than created directly by a PUSHDATA"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194303 1ADD NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194303 1ADD CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 1SUB NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 1SUB CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["An ADD producing a 5-byte result that sets CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 65536 NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 65536 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 4259840 ADD NOP3 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 4259840 ADD CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Valid CHECKSEQUENCEVERIFY in scriptSig"], From 18c975c831a3a71b26df43a2617a06840f3aa377 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Tue, 28 Jun 2016 17:23:32 +0100 Subject: [PATCH 0882/1223] Rename NOP3 to CHECSEQUENCEVERIFY in rpc tests --- qa/rpc-tests/bip68-112-113-p2p.py | 6 +++--- qa/rpc-tests/bip9-softforks.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 8ba070438..55b3e2a04 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -173,7 +173,7 @@ class BIP68_112_113Test(ComparisonTestFramework): tx = self.create_transaction(self.nodes[0], input, self.nodeaddress, Decimal("49.98")) tx.nVersion = txversion signtx = self.sign_transaction(self.nodes[0], tx) - signtx.vin[0].scriptSig = CScript([-1, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + signtx.vin[0].scriptSig = CScript([-1, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) return signtx def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta = 0): @@ -196,9 +196,9 @@ class BIP68_112_113Test(ComparisonTestFramework): tx.nVersion = txversion signtx = self.sign_transaction(self.nodes[0], tx) if (varyOP_CSV): - signtx.vin[0].scriptSig = CScript([relative_locktimes[b31][b25][b22][b18], OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + signtx.vin[0].scriptSig = CScript([relative_locktimes[b31][b25][b22][b18], OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) else: - signtx.vin[0].scriptSig = CScript([base_relative_locktime, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) + signtx.vin[0].scriptSig = CScript([base_relative_locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig))) b18txs.append(signtx) b22txs.append(b18txs) b25txs.append(b22txs) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index d7e8e5e5a..979d1410c 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -9,7 +9,7 @@ from test_framework.util import * from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager -from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP +from test_framework.script import CScript, OP_1NEGATE, OP_CHECKSEQUENCEVERIFY, OP_DROP from io import BytesIO import time import itertools @@ -220,7 +220,7 @@ class BIP9SoftForksTest(ComparisonTestFramework): '''Modify the signature in vin 0 of the tx to fail CSV Prepends -1 CSV DROP in the scriptSig itself. ''' - tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP3, OP_DROP] + + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) def sequence_lock_invalidate(self, tx): From a7897c02f790cd487874f09bc7b4ec31c17968ee Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Jun 2016 18:27:49 +0200 Subject: [PATCH 0883/1223] qt: Remove client name from debug window Remove the client name from the debug window in the GUI. It is already part of the user agent, so adding it separately doesn't add anything. --- src/qt/clientmodel.cpp | 5 --- src/qt/clientmodel.h | 1 - src/qt/forms/debugwindow.ui | 75 +++++++++++++------------------------ src/qt/rpcconsole.cpp | 1 - 4 files changed, 26 insertions(+), 56 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 108500654..14661b857 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -179,11 +179,6 @@ bool ClientModel::isReleaseVersion() const return CLIENT_VERSION_IS_RELEASE; } -QString ClientModel::clientName() const -{ - return QString::fromStdString(CLIENT_NAME); -} - QString ClientModel::formatClientStartupTime() const { return QDateTime::fromTime_t(nClientStartupTime).toString(); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 439680431..99fd574b9 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -73,7 +73,6 @@ public: QString formatFullVersion() const; QString formatSubVersion() const; bool isReleaseVersion() const; - QString clientName() const; QString formatClientStartupTime() const; QString dataDir() const; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index c17efcf1b..9dc641979 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -41,36 +41,13 @@ - - - Client name - - - - - - - IBeamCursor - - - N/A - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - Client version - + IBeamCursor @@ -86,7 +63,7 @@ - + User Agent @@ -96,7 +73,7 @@ - + IBeamCursor @@ -112,7 +89,7 @@ - + Using BerkeleyDB version @@ -122,7 +99,7 @@ - + IBeamCursor @@ -138,14 +115,14 @@ - + Datadir - + IBeamCursor @@ -164,14 +141,14 @@ - + Startup time - + IBeamCursor @@ -187,7 +164,7 @@ - + @@ -200,14 +177,14 @@ - + Name - + IBeamCursor @@ -223,14 +200,14 @@ - + Number of connections - + IBeamCursor @@ -246,7 +223,7 @@ - + @@ -259,14 +236,14 @@ - + Current number of blocks - + IBeamCursor @@ -282,14 +259,14 @@ - + Last block time - + IBeamCursor @@ -305,7 +282,7 @@ - + @@ -318,14 +295,14 @@ - + Current number of transactions - + IBeamCursor @@ -341,14 +318,14 @@ - + Memory usage - + IBeamCursor @@ -364,7 +341,7 @@ - + 3 @@ -404,7 +381,7 @@ - + Qt::Vertical diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 11f3e49a0..650ff8b00 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -451,7 +451,6 @@ void RPCConsole::setClientModel(ClientModel *model) // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientUserAgent->setText(model->formatSubVersion()); - ui->clientName->setText(model->clientName()); ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); From 0ce8e99ec8ac0d2a60b577537bf0db747bb8ec50 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 29 Jun 2016 11:01:29 +0200 Subject: [PATCH 0884/1223] windows: Add testnet link to installer --- share/setup.nsi.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index c062f96a3..a3294a9f6 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -92,6 +92,7 @@ Section -post SEC0001 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" @@ -135,6 +136,7 @@ Section -un.post UNSEC0001 DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe Delete /REBOOTOK $INSTDIR\debug.log From 4f44cb616d98a0e17ae0599e5a58f50f3be2910b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 29 Jun 2016 17:29:29 +0200 Subject: [PATCH 0885/1223] qt: Network-specific example address Generate an (invalid) example address for in the bitcoin address widgets, based on the network prefix, instead of hardcoding a mainnet address. - `1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L` for mainnet (same as now) - `n2wxQmfexkjwEPgdD6iJA7T7RtzkmHxhFc` for testnet --- src/qt/guiutil.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 4327de9b0..947a4c682 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -107,6 +107,23 @@ QFont fixedPitchFont() #endif } +// Just some dummy data to generate an convincing random-looking (but consistent) address +static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47}; + +// Generate a dummy address with invalid CRC, starting with the network prefix. +static std::string DummyAddress(const CChainParams ¶ms) +{ + std::vector sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); + sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata)); + for(int i=0; i<256; ++i) { // Try every trailing byte + std::string s = EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)); + if (!CBitcoinAddress(s).IsValid()) + return s; + sourcedata[sourcedata.size()-1] += 1; + } + return ""; +} + void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) { parent->setFocusProxy(widget); @@ -115,7 +132,8 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) #if QT_VERSION >= 0x040700 // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. - widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg("1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L")); + widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg( + QString::fromStdString(DummyAddress(Params())))); #endif widget->setValidator(new BitcoinAddressEntryValidator(parent)); widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); From 975a41dcc259c966e1ab952b3681dda2f7b99009 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 29 Jun 2016 13:06:28 +0200 Subject: [PATCH 0886/1223] windows: Add testnet icon for testnet link Overhauled testnet icon by Jonas Schnelli --- share/setup.nsi.in | 2 +- src/Makefile.qt.include | 1 + src/qt/res/bitcoin-qt-res.rc | 1 + src/qt/res/icons/bitcoin_testnet.ico | Bin 0 -> 57251 bytes 4 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/qt/res/icons/bitcoin_testnet.ico diff --git a/share/setup.nsi.in b/share/setup.nsi.in index a3294a9f6..dd42085a2 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -92,7 +92,7 @@ Section -post SEC0001 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" 1 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 36a21dd06..ca2c7b2eb 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -231,6 +231,7 @@ RES_ICONS = \ qt/res/icons/about.png \ qt/res/icons/about_qt.png \ qt/res/icons/bitcoin.ico \ + qt/res/icons/bitcoin_testnet.ico \ qt/res/icons/bitcoin.png \ qt/res/icons/chevron.png \ qt/res/icons/clock1.png \ diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 19c3d5d97..94ae25647 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -1,4 +1,5 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" +IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico new file mode 100644 index 0000000000000000000000000000000000000000..909194ecd2e10985bbca35c3cd26fd1adb4730b8 GIT binary patch literal 57251 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 N250BL5H*Z+s*3%&l;+rD=4 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 Date: Thu, 30 Jun 2016 11:22:31 -0400 Subject: [PATCH 0887/1223] Exclude witness transactions in addPackageTxs() pre-segwit activation --- src/miner.cpp | 13 +++++++++---- src/miner.h | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index a3e29431d..f2ad1018b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -236,14 +236,19 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost return true; } -// Block size and sigops have already been tested. Check that all transactions -// are final. -bool BlockAssembler::TestPackageFinalityAndSerializedSize(const CTxMemPool::setEntries& package) +// Perform transaction-level checks before adding to block: +// - transaction finality (locktime) +// - premature witness (in case segwit transactions are added to mempool before +// segwit activation) +// - serialized size (in case -blockmaxsize is in use) +bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) { uint64_t nPotentialBlockSize = nBlockSize; // only used with fNeedSizeAccounting BOOST_FOREACH (const CTxMemPool::txiter it, package) { if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) return false; + if (!fIncludeWitness && !it->GetTx().wit.IsNull()) + return false; if (fNeedSizeAccounting) { uint64_t nTxSize = ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION); if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) { @@ -542,7 +547,7 @@ void BlockAssembler::addPackageTxs() ancestors.insert(iter); // Test if all tx's are Final - if (!TestPackageFinalityAndSerializedSize(ancestors)) { + if (!TestPackageTransactions(ancestors)) { if (fUsingModified) { mapModifiedTx.get().erase(modit); failedTx.insert(iter); diff --git a/src/miner.h b/src/miner.h index bc4da63da..9fab55611 100644 --- a/src/miner.h +++ b/src/miner.h @@ -192,8 +192,11 @@ private: void onlyUnconfirmed(CTxMemPool::setEntries& testSet); /** Test if a new package would "fit" in the block */ bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost); - /** Test if a set of transactions are all final */ - bool TestPackageFinalityAndSerializedSize(const CTxMemPool::setEntries& package); + /** Perform checks on each transaction in a package: + * locktime, premature-witness, serialized size (if necessary) + * These checks should always succeed, and they're here + * only as an extra check in case of suboptimal node configuration */ + bool TestPackageTransactions(const CTxMemPool::setEntries& package); /** Return true if given transaction from mapTx has already been evaluated, * or if the transaction's cached data in mapTx is incorrect. */ bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); From d2e46e1b5cf6c08829ec3bb2a923b4ba149ab3b7 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 30 Jun 2016 11:37:38 -0400 Subject: [PATCH 0888/1223] Remove addScoreTxs() --- src/miner.cpp | 60 --------------------------------------------------- src/miner.h | 6 ++---- 2 files changed, 2 insertions(+), 64 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index f2ad1018b..eb71355e7 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -338,66 +338,6 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) } } -void BlockAssembler::addScoreTxs() -{ - std::priority_queue, ScoreCompare> clearedTxs; - CTxMemPool::setEntries waitSet; - CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); - CTxMemPool::txiter iter; - while (!blockFinished && (mi != mempool.mapTx.get().end() || !clearedTxs.empty())) - { - // If no txs that were previously postponed are available to try - // again, then try the next highest score tx - if (clearedTxs.empty()) { - iter = mempool.mapTx.project<0>(mi); - mi++; - } - // If a previously postponed tx is available to try again, then it - // has higher score than all untried so far txs - else { - iter = clearedTxs.top(); - clearedTxs.pop(); - } - - // If tx already in block, skip (added by addPriorityTxs) - if (inBlock.count(iter)) { - continue; - } - - // cannot accept witness transactions into a non-witness block - if (!fIncludeWitness && !iter->GetTx().wit.IsNull()) - continue; - - // If tx is dependent on other mempool txs which haven't yet been included - // then put it in the waitSet - if (isStillDependent(iter)) { - waitSet.insert(iter); - continue; - } - - // If the fee rate is below the min fee rate for mining, then we're done - // adding txs based on score (fee rate) - if (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(iter->GetTxSize()) && nBlockSize >= nBlockMinSize) { - return; - } - - // If this tx fits in the block add it, otherwise keep looping - if (TestForBlock(iter)) { - AddToBlock(iter); - - // This tx was successfully added, so - // add transactions that depend on this one to the priority queue to try again - BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) - { - if (waitSet.count(child)) { - clearedTxs.push(child); - waitSet.erase(child); - } - } - } - } -} - void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) { diff --git a/src/miner.h b/src/miner.h index 9fab55611..037639b2b 100644 --- a/src/miner.h +++ b/src/miner.h @@ -157,7 +157,7 @@ private: int64_t nLockTimeCutoff; const CChainParams& chainparams; - // Variables used for addScoreTxs and addPriorityTxs + // Variables used for addPriorityTxs int lastFewTxs; bool blockFinished; @@ -174,14 +174,12 @@ private: void AddToBlock(CTxMemPool::txiter iter); // Methods for how to add transactions to a block. - /** Add transactions based on modified feerate */ - void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); /** Add transactions based on feerate including unconfirmed ancestors */ void addPackageTxs(); - // helper function for addScoreTxs and addPriorityTxs + // helper function for addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ From 27362dda4d583a43ebf687ae097d2f45ba1c4c32 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 30 Jun 2016 11:41:13 -0400 Subject: [PATCH 0889/1223] Remove -blockminsize option --- src/init.cpp | 1 - src/miner.cpp | 7 +------ src/miner.h | 2 +- src/policy/policy.h | 3 +-- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 5d29f14eb..fdf6301d2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -453,7 +453,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Block creation options:")); strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); - strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) diff --git a/src/miner.cpp b/src/miner.cpp index eb71355e7..8153fb9f9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -100,13 +100,8 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize)); - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); - // Whether we need to account for byte usage (in addition to cost usage) - fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000) || (nBlockMinSize > 0); + fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000); } void BlockAssembler::resetBlock() diff --git a/src/miner.h b/src/miner.h index 037639b2b..d16e37bb5 100644 --- a/src/miner.h +++ b/src/miner.h @@ -141,7 +141,7 @@ private: // Configuration parameters for the block size bool fIncludeWitness; - unsigned int nBlockMaxCost, nBlockMaxSize, nBlockMinSize; + unsigned int nBlockMaxCost, nBlockMaxSize; bool fNeedSizeAccounting; // Information on the current status of the block diff --git a/src/policy/policy.h b/src/policy/policy.h index fefb562ff..29a8cc57c 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -14,9 +14,8 @@ class CCoinsViewCache; -/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ +/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; -static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; /** Default for -blockmaxcost, which control the range of block costs the mining code will create **/ From 20f3cd75f6af8f75de943fef43b4b7769746f732 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 1 Jul 2016 13:22:52 +0200 Subject: [PATCH 0890/1223] wallet: Revert input selection post-pruning This reverts PR #4906, "Coinselection prunes extraneous inputs from ApproximateBestSubset". Apparently the previous behavior of slightly over-estimating the set of inputs was useful in cleaning up UTXOs. See also #7664, #7657, as well as 2016-07-01 discussion on #bitcoin-core-dev IRC. --- src/wallet/test/wallet_tests.cpp | 14 -------------- src/wallet/wallet.cpp | 10 ---------- 2 files changed, 24 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 0a4f06ba8..c6c505898 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -349,20 +349,6 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); - - empty_wallet(); - - // Test trimming - for (int i = 0; i < 100; i++) - add_coin(10 * COIN); - for (int i = 0; i < 100; i++) - add_coin(1000 * COIN); - - BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); - // We need all 100 larger coins and exactly one small coin. - // Superfluous small coins must be trimmed from the set: - BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 87b85eeb7..a0095ebd9 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1879,16 +1879,6 @@ static void ApproximateBestSubset(vector= nTargetValue ) - { - vfBest[i] = false; - nBest -= vValue[i].first; - } - } } bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector vCoins, From ab0c35a290b8cb05b9bed0c24627bcc98bb22b2b Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 5 Jul 2016 10:24:48 +0800 Subject: [PATCH 0891/1223] [Doc] Update bips.md for CSV softfork. --- doc/bips.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/bips.md b/doc/bips.md index 62bde20d9..039d5114f 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -18,11 +18,11 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). * [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). -* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)). +* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). -* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)). -* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)). +* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. +* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). From 4fbdc4365ba73e6947dd9052b28818a4a99c0d64 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 5 Jul 2016 20:45:14 +0000 Subject: [PATCH 0892/1223] Revert "net: Avoid duplicate getheaders requests." PR #8054 This reverts commit f93c2a1b7ee912f0651ebb4c8a5eca220e434f4a. This can cause synchronization to get stuck. --- src/main.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6cdd55e39..e26a73bc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5835,13 +5835,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - // If we already know the last header in the message, then it contains - // no new information for us. In this case, we do not request - // more headers later. This prevents multiple chains of redundant - // getheader requests from running in parallel if triggered by incoming - // blocks while the node is still in initial headers sync. - const bool hasNewHeaders = (mapBlockIndex.count(headers.back().GetHash()) == 0); - CBlockIndex *pindexLast = NULL; BOOST_FOREACH(const CBlockHeader& header, headers) { CValidationState state; @@ -5862,7 +5855,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, assert(pindexLast); UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); - if (nCount == MAX_HEADERS_RESULTS && hasNewHeaders) { + if (nCount == MAX_HEADERS_RESULTS) { // Headers message had its maximum size; the peer may have more headers. // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. From c1d61fbd080bcc29589b8d467df98efb7e89d231 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 5 Jul 2016 15:50:48 -0400 Subject: [PATCH 0893/1223] Add warning if -blockminsize is used. --- contrib/devtools/check-doc.py | 2 +- src/init.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 06c9551ce..9ea0131ac 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_RO REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags', '-blockminsize']) def main(): used = check_output(CMD_GREP_ARGS, shell=True) diff --git a/src/init.cpp b/src/init.cpp index fdf6301d2..7f8289328 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -876,6 +876,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-whitelistalwaysrelay", false)) InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); + if (mapArgs.count("-blockminsize")) + InitWarning("Unsupported argument -blockminsize ignored."); + // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { From 32cab91278651d07a11132b7636dc3d21144e616 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 27 Jun 2016 15:39:28 +0200 Subject: [PATCH 0894/1223] Bump `-dbcache` default to 300MiB Also cap the allocation for the leveldb-specific cache for the UTXO set to 8MiB. This avoids that the extra cache memory goes to the much less effective leveldb cache instead of our application-level cache. --- src/init.cpp | 4 ++-- src/txdb.h | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 5d29f14eb..22a6af74e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1216,10 +1216,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) - nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB + nBlockTreeDBCache = std::min(nBlockTreeDBCache, (GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20); nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache + nCoinDBCache = std::min(nCoinDBCache, nMaxCoinsDBCache << 20); // cap total coins db cache nTotalCache -= nCoinDBCache; nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache LogPrintf("Cache configuration:\n"); diff --git a/src/txdb.h b/src/txdb.h index ce3c39d7f..5b98d2792 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -22,11 +22,19 @@ class CCoinsViewDBCursor; class uint256; //! -dbcache default (MiB) -static const int64_t nDefaultDbCache = 100; -//! max. -dbcache in (MiB) +static const int64_t nDefaultDbCache = 300; +//! max. -dbcache (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; -//! min. -dbcache in (MiB) +//! min. -dbcache (MiB) static const int64_t nMinDbCache = 4; +//! Max memory allocated to block tree DB specific cache, if no -txindex (MiB) +static const int64_t nMaxBlockDBCache = 2; +//! Max memory allocated to block tree DB specific cache, if -txindex (MiB) +// Unlike for the UTXO database, for the txindex scenario the leveldb cache make +// a meaningful difference: https://github.com/bitcoin/bitcoin/pull/8273#issuecomment-229601991 +static const int64_t nMaxBlockDBAndTxIndexCache = 1024; +//! Max memory allocated to coin DB specific cache (MiB) +static const int64_t nMaxCoinsDBCache = 8; struct CDiskTxPos : public CDiskBlockPos { From efd1d8339ad9a2bb7a164e7475734a90f6fa034c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 30 Jun 2016 11:01:19 +0200 Subject: [PATCH 0895/1223] doc: Mention dbcache increase in release notes --- doc/release-notes.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6e4f390cb..df63bb53e 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -41,9 +41,21 @@ report issues about Windows XP to the issue tracker. Notable changes =============== -Example item ----------------- +Database cache memory increased +-------------------------------- +As a result of growth of the UTXO set, performance with the prior default +database cache of 100 MiB has suffered. +For this reason the default was changed to 300 MiB in this release. + +For nodes on low-memory systems, the database cache can be changed back to +100 MiB (or to another value) by either: + +- Adding `dbcache=100` in bitcoin.conf +- Changing it in the GUI under `Options → Size of database cache` + +Note that the database cache setting has the most performance impact +during initial sync of a node, and when catching up after downtime. bitcoin-cli: arguments privacy -------------------------------- From b978701ba1822140452d35f037ce776fdcba0175 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 6 Jul 2016 05:25:57 +0000 Subject: [PATCH 0896/1223] qt: periodic translations update --- src/qt/bitcoinstrings.cpp | 6 -- src/qt/locale/bitcoin_bg.ts | 124 ++++++++++++++++++++++++++++++++- src/qt/locale/bitcoin_da.ts | 12 ++++ src/qt/locale/bitcoin_de.ts | 4 ++ src/qt/locale/bitcoin_en.ts | 48 +++++-------- src/qt/locale/bitcoin_en_GB.ts | 12 ++++ src/qt/locale/bitcoin_es.ts | 12 ++++ src/qt/locale/bitcoin_fr.ts | 16 +++++ src/qt/locale/bitcoin_fr_FR.ts | 24 +++++++ src/qt/locale/bitcoin_ja.ts | 12 ++++ src/qt/locale/bitcoin_ms_MY.ts | 9 +++ src/qt/locale/bitcoin_nl.ts | 2 +- src/qt/locale/bitcoin_ru.ts | 42 ++++++++++- src/qt/locale/bitcoin_ru_RU.ts | 10 ++- src/qt/locale/bitcoin_sv.ts | 12 ++++ src/qt/locale/bitcoin_th_TH.ts | 24 +++++++ src/qt/locale/bitcoin_zh_TW.ts | 12 ++++ 17 files changed, 338 insertions(+), 43 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 7cf32cd34..9c5b1e09d 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -186,12 +186,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "comes in the format: :$. A canonical python script is " "included in share/rpcuser. This option can be specified multiple times"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"WARNING: abnormally high number of blocks generated, %d blocks received in " -"the last %d hours (%d expected)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"WARNING: check your network connection, %d blocks received in the last %d " -"hours (%d expected)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: The network does not appear to fully agree! Some miners appear to " "be experiencing issues."), QT_TRANSLATE_NOOP("bitcoin-core", "" diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 3bb881318..bd85d8c8b 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -63,6 +63,10 @@ BanTableModel + + IP/Netmask + IP/Netmask + Banned Until Със забранен достъп до @@ -106,6 +110,14 @@ Quit application Изход от приложението + + &About %1 + Относно %1 + + + Show information about %1 + Покажи информация относно %1 + About &Qt За &Qt @@ -118,6 +130,10 @@ &Options... &Опции... + + Modify configuration options for %1 + Промени настройки за %1 + &Encrypt Wallet... &Шифриране на портфейла... @@ -142,6 +158,10 @@ Open &URI... Отвори &URI... + + Reindexing blocks on disk... + Повторно индексиране на блоковете на диска... + Send coins to a Bitcoin address Изпращане към Биткоин адрес @@ -238,14 +258,46 @@ &Command-line options &Налични команди + + %n active connection(s) to Bitcoin network + %n активна връзка към Биткойн мрежата%n активни връзки към Биткойн мрежата + + + Indexing blocks on disk... + Индексиране на блокове на диска... + + + Processing blocks on disk... + Обработване на блокове на диска... + No block source available... Липсва източник на блоковете... + + Processed %n block(s) of transaction history. + Преработен %n блок от историята с транзакции.Преработени %n блокове от историята с транзакции. + + + %n hour(s) + %n час%n часа + + + %n day(s) + %n ден%n дни + + + %n week(s) + %n седмица%n седмици + %1 and %2 %1 и %2 + + %n year(s) + %n година%n години + %1 behind %1 зад @@ -274,6 +326,14 @@ Up to date Синхронизиран + + Show the %1 help message to get a list with possible Bitcoin command-line options + Покажи %1 помощно съобщение за да получиш лист с възможни Биткойн команди + + + %1 client + %1 клиент + Catching up... Зарежда блокове... @@ -414,6 +474,14 @@ &Label &Име + + The label associated with this address list entry + Етикетът свързан с това въведение в листа с адреси + + + The address associated with this address list entry. This can only be modified for sending addresses. + Адресът свързан с това въведение в листа с адреси. Това може да бъде променено само за адреси за изпращане. + &Address &Адрес @@ -452,6 +520,10 @@ (%1-bit) (%1-битов) + + About %1 + Относно %1 + Command-line options Списък с команди @@ -464,13 +536,45 @@ command-line options Списък с налични команди - + + UI Options: + Опции на интерфейс: + + + Choose data directory on startup (default: %u) + Избери директория за данни при стартирване (по подразбиране: %u) + + + Set language, for example "de_DE" (default: system locale) + Избери език, примерно "de_DE" (по подразбиране: system locale) + + + Start minimized + Стартирай минимизиран + + + Set SSL root certificates for payment request (default: -system-) + Задай SSL root сертификат за молба за изплащане (по подразбиране: -system-) + + + Show splash screen on startup (default: %u) + Покажи splash екран при стартирване (по подразбиране %u) + + + Reset all settings changed in the GUI + Нулиране на всички настройки променени в GUI + + Intro Welcome Добре дошли + + Welcome to %1. + Добре дошли в %1. + Use the default data directory Използване на директория по подразбиране @@ -483,13 +587,29 @@ Error Грешка - + + %n GB of free space available + %n GB свободно пространство на разположение%n GB свободно пространство на разположение + + + (of %n GB needed) + (%n GB е нужен)(%n GB са нужни) + + OpenURIDialog Open URI Отваряне на URI + + Open payment request from URI or file + Отвори молба за изплащане от URI или файл + + + URI: + URI: + OptionsDialog diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 91903088c..fd1a4a086 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1878,6 +1878,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dette er en foreløbig testudgivelse - brug på eget ansvar - brug ikke til udvinding eller handelsprogrammer + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Kan ikke spole databasen tilbage til en tilstand inden en splitning. Du er nødt til at downloade blokkæden igen + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Brug UPnP for at konfigurere den lyttende port (standard: 1 under lytning og ingen -proxy) @@ -2098,10 +2102,18 @@ Rebuild chain state from the currently indexed blocks Genopbyg kædetilstand ud fra de aktuelt indekserede blokke + + Rewinding blocks... + Spoler blokke tilbage… + Set database cache size in megabytes (%d to %d, default: %d) Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d) + + Set maximum block cost (default: %d) + Sæt maksimal blokudgift (standard: %d) + Set maximum block size in bytes (default: %d) Sæt maksimum blokstørrelse i byte (standard: %d) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 639bc3cf2..77482c774 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1009,6 +1009,10 @@ Using BerkeleyDB version Verwendete BerkeleyDB-Version + + Datadir + Datenverz + Startup time Startzeit diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 9723ffa39..c6f3a4013 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1262,13 +1262,7 @@ RPCConsole - - Client name - Client name - - - - + @@ -1305,7 +1299,7 @@ Client version - + &Information &Information @@ -1320,7 +1314,7 @@ - + Using BerkeleyDB version @@ -1399,7 +1393,7 @@ - + Select a peer to view detailed information. @@ -1550,7 +1544,7 @@ Clear console - + &Disconnect Node @@ -1588,7 +1582,7 @@ - + Welcome to the %1 RPC console. @@ -2232,7 +2226,7 @@ bitcoin-core - + Options: Options: @@ -2257,7 +2251,7 @@ Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -2282,7 +2276,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -2312,7 +2306,7 @@ Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -2423,16 +2417,6 @@ - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - - - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - - - - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. @@ -2782,7 +2766,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -2867,7 +2851,7 @@ - + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -3062,12 +3046,12 @@ Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect @@ -3077,7 +3061,7 @@ Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3157,7 +3141,7 @@ - + Warning: Unknown block versions being mined! It's possible unknown rules are in effect diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 89653e7aa..226444e9c 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -1878,6 +1878,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Unable to rewind the database to a pre-fork state. You will need to re-download the blockchain + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -2098,10 +2102,18 @@ Rebuild chain state from the currently indexed blocks Rebuild chain state from the currently indexed blocks + + Rewinding blocks... + Rewinding blocks... + Set database cache size in megabytes (%d to %d, default: %d) Set database cache size in megabytes (%d to %d, default: %d) + + Set maximum block cost (default: %d) + Set maximum block cost (default: %d) + Set maximum block size in bytes (default: %d) Set maximum block size in bytes (default: %d) diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index fc430e86b..80cbe3993 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1877,6 +1877,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería. + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + No es posible reconstruir la base de datos a un estado anterior. Debe descargar de nuevo la cadena de bloques. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) @@ -2097,10 +2101,18 @@ Rebuild chain state from the currently indexed blocks Reconstruir el estado de la cadena a partir de los bloques indexados + + Rewinding blocks... + Verificando bloques... + Set database cache size in megabytes (%d to %d, default: %d) Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) + + Set maximum block cost (default: %d) + Establecer tamaño máximo de bloque (por defecto: %d) + Set maximum block size in bytes (default: %d) Establecer tamaño máximo de bloque en bytes (predeterminado: %d) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index fe745f99b..5c4f7f2b0 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1858,6 +1858,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Impossible de rebobiner la base de données à un état préfourche. Vous devrez retélécharger la chaîne de blocs + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) @@ -2070,10 +2074,18 @@ Rebuild chain state from the currently indexed blocks Reconstruire l'état de la chaîne à partir des blocs indexés actuellement + + Rewinding blocks... + Rebobinage des blocs... + Set database cache size in megabytes (%d to %d, default: %d) Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) + + Set maximum block cost (default: %d) + Définir le coût maximal de bloc (par défaut : %d) + Set maximum block size in bytes (default: %d) Définir la taille minimale de bloc en octets (par défaut : %d) @@ -2190,6 +2202,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Ce produit comprend des logiciels développés par le projet OpenSSL pour être utilisés dans la boîte à outils OpenSSL <https://www.openssl.org/> et un logiciel cryptographique écrit par Eric Young, ainsi qu'un logiciel UPnP écrit par Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Utiliser une génération de clef hiérarchique déterministe (HD) après BIP32. N'a d'effet que lors de la création/premier lancement du porte-monnaie + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Les pairs de la liste blanche ne peuvent pas être bannis DoS et leurs transactions sont toujours relayées, même si elles sont déjà dans le mempool, utile p. ex. pour une passerelle diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index f7fd7e6a1..08824e113 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -254,6 +254,10 @@ %n active connection(s) to Bitcoin network %n connexion active au réseau Bitcoin%n connexions actives au réseau Bitcoin + + Indexing blocks on disk... + Indexation des blocs sur le disque... + No block source available... Aucun bloc source disponible @@ -306,6 +310,10 @@ Up to date À jour + + %1 client + %1 client + Catching up... Rattrapage... @@ -511,6 +519,10 @@ Welcome Bienvenue + + Welcome to %1. + Bienvenue sur %1. + Use the default data directory Utiliser le répertoire par défaut @@ -641,6 +653,14 @@ &Window &Fenêtre + + &Hide the icon from the system tray. + &Cacher l'icône dans la zone de notification. + + + Hide tray icon + Cacher l'icône de la zone de notification + &Minimize to the tray instead of the taskbar &Minimiser dans la barre système au lieu de la barre des tâches @@ -1326,6 +1346,10 @@ Run in the background as a daemon and accept commands Fonctionner en arrière-plan en tant que démon et accepter les commandes + + Unable to start HTTP server. See debug log for details. + Impossible de démarrer le serveur HTTP. Voir le journal de débogage pour plus de détails. + Bitcoin Core Bitcoin Core diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index b2dae186d..460a652e3 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1878,6 +1878,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications これはリリース前のテストビルドです - 各自の責任で利用すること - 採掘や商取引に使用しないでください + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + データベースをフォーク前の状態に巻き戻せませんでした。ブロックチェーンを再ダウンロードする必要があります + Use UPnP to map the listening port (default: 1 when listening and no -proxy) リスン ポートの割当に UPnP を使用 (初期値: リスン中および-proxyが指定されていない場合は1) @@ -2099,10 +2103,18 @@ Rebuild chain state from the currently indexed blocks 既にインデックスされたブロックからチェイン状態を再構築する + + Rewinding blocks... + ブロックを巻き戻しています... + Set database cache size in megabytes (%d to %d, default: %d) データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d) + + Set maximum block cost (default: %d) + 最大ブロックコストを設定 (初期値: %d) + Set maximum block size in bytes (default: %d) 最大ブロックサイズをバイトで設定 (初期値: %d) diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index de4c32c2d..acfb38e41 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -17,6 +17,15 @@ &Copy &Salin + + Delete the currently selected address from the list + Padam alamat semasa yang dipilih dari senaraiyang dipilih dari senarai + + + Export the data in the current tab to a file + +Alihkan fail data ke dalam tab semasa + &Export &Eksport diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 3009c154e..2b0cded38 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -870,7 +870,7 @@ 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. - De weergegeven informatie kan verouderd zijn. Uw portemonnee synchroniseert automaticsh met het Bitcoinnetwerk nadat een verbinding is gelegd, maar dit proces is nog niet voltooid. + De weergegeven informatie kan verouderd zijn. Uw portemonnee synchroniseert automatisch met het Bitcoinnetwerk nadat een verbinding is gelegd, maar dit proces is nog niet voltooid. Watch-only: diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index e2949a948..750ea7db6 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -130,6 +130,10 @@ &Options... &Параметры + + Modify configuration options for %1 + Изменить конфигурационные настройки для %1 + &Encrypt Wallet... &Зашифровать бумажник... @@ -552,7 +556,11 @@ Show splash screen on startup (default: %u) Показывать экран-заставку при запуске (по умолчанию: %u) - + + Reset all settings changed in the GUI + Сбросить все настройки, измененные в графическом интерфейсе + + Intro @@ -563,6 +571,14 @@ Welcome to %1. Добро пожаловать в %1 + + As this is the first time the program is launched, you can choose where %1 will store its data. + При первом запуске программы вы можете выбрать где %1 будет хранить свои данные. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 скачает и сохранит копию цепи блоков. Как минимум %2GB будут записаны в этот каталог, и со временем он будет расти. Бумажник также будет сохранен в этом каталоге. + Use the default data directory Использовать каталог данных по умолчанию @@ -617,6 +633,14 @@ &Main &Главная + + Automatically start %1 after logging in to the system. + Автоматически запускать %1 после входа в систему. + + + &Start %1 on system login + &Запускать %1 при входе в систему + Size of &database cache Размер кэша &БД @@ -753,6 +777,10 @@ &Window &Окно + + &Hide the icon from the system tray. + &Скрыть иконку из системного трея. + Hide tray icon Скрыть иконку в трее @@ -777,6 +805,10 @@ User Interface &language: &Язык интерфейса: + + The user interface language can be set here. This setting will take effect after restarting %1. + Здесь можно установить язык пользовательского интерфейса. Настройки вступят в силу после перезагрузки %1 + &Unit to show amounts in: &Отображать суммы в единицах: @@ -985,6 +1017,10 @@ Using BerkeleyDB version Используется версия BerkeleyDB + + Datadir + Каталог для данных + Startup time Время запуска @@ -1069,6 +1105,10 @@ User Agent Юзер-агент + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Открыть отладочный лог-файл %1 из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. + Services Сервисы diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index a6f9ffccb..66419728e 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + Кликните правой кнопкой мыши для редоктирования адреса или ярлыка + Create a new address Создать новый адрес @@ -40,7 +44,11 @@ AskPassphraseDialog - + + Repeat new passphrase + Повторите новый пароль + + BanTableModel diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index a637cebe2..6361b5ea5 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1874,6 +1874,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Detta är ett förhands testbygge - använd på egen risk - använd inte för mining eller handels applikationer + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Kan inte spola tillbaka databasen till obeskärt läge. Du måste ladda ner blockkedjan igen + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Använd UPnP för att mappa den lyssnande porten (förvalt: 1 när lyssning aktiverat och utan -proxy) @@ -2094,10 +2098,18 @@ Rebuild chain state from the currently indexed blocks Återskapa blockkedjans status från aktuella indexerade block + + Rewinding blocks... + Spolar tillbaka blocken... + Set database cache size in megabytes (%d to %d, default: %d) Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d) + + Set maximum block cost (default: %d) + Sätt maximal blockkostnad (förvalt: %d) + Set maximum block size in bytes (default: %d) Sätt maximal blockstorlek i byte (förvalt: %d) diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 263093914..34c752634 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -765,6 +765,30 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + เชื่อมต่อกับ เครือข่าย Bitcoin ผ่านทาง พร้อกซี่ SOCKS5 แยกต่างหาก สำหรับ Tor เซอร์วิส + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + ใช้ พร็อกซี่ SOCKS5 แยก เพื่อเข้าถึง peers ผ่าน Tor เซอร์วิสซ่อน: + + + &Window + &วันโดว์ + + + &Hide the icon from the system tray. + &ซ่อนไอคอน จากเทรย์ระบบ + + + Hide tray icon + ซ่อนไอคอนเทรย์ + + + Show only a tray icon after minimizing the window. + แสดงเทรย์ไอคอน หลังมืนิไมส์วินโดว์ เท่านั้น + OverviewPage diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index cbdb8f2c0..c71a37ba9 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -1879,6 +1879,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 這是個還沒發表的測試版本 - 使用請自負風險 - 請不要用來開採或商業應用 + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + 沒辦法將資料庫倒轉回分岔前的狀態。必須要重新下載區塊鍊。 + Use UPnP to map the listening port (default: 1 when listening and no -proxy) 是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線且沒有指定 -proxy 參數時為 1) @@ -2099,10 +2103,18 @@ Rebuild chain state from the currently indexed blocks 從目前已編索引的區塊資料重建區塊鏈狀態 + + Rewinding blocks... + 倒轉回區塊鏈之前的狀態... + Set database cache size in megabytes (%d to %d, default: %d) 設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d) + + Set maximum block cost (default: %d) + 設定區塊成本的最大值(預設值: %d) + Set maximum block size in bytes (default: %d) 設定區塊大小上限成多少位元組(預設值: %d) From cf2ef786a1ef78edefd7c1029feb46d1a9061b75 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 6 Jul 2016 17:29:43 -0400 Subject: [PATCH 0897/1223] build: require boost for bench --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 97af58bd7..496e4ad9e 100644 --- a/configure.ac +++ b/configure.ac @@ -583,7 +583,7 @@ BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no else use_boost=yes From 36ae37a9f910922954d48ed1f3f2177d8b227205 Mon Sep 17 00:00:00 2001 From: Bob McElrath Date: Wed, 6 Jul 2016 19:46:46 -0400 Subject: [PATCH 0898/1223] Rename CTxinWitness -> CTxInWitness --- qa/rpc-tests/p2p-segwit.py | 48 +++++++++++------------ qa/rpc-tests/test_framework/blocktools.py | 2 +- qa/rpc-tests/test_framework/mininode.py | 6 +-- src/core_memusage.h | 4 +- src/primitives/transaction.h | 6 +-- src/test/sigopcount_tests.cpp | 14 +++---- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index cf78954f2..8e4bc989b 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -252,7 +252,7 @@ class SegWitTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vout.append(CTxOut(self.utxo[0].nValue-1000, CScript([OP_TRUE]))) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)])] # Verify the hash with witness differs from the txid @@ -362,7 +362,7 @@ class SegWitTest(BitcoinTestFramework): tx2 = CTransaction() tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, witness_program)) - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] tx2.rehash() @@ -489,7 +489,7 @@ class SegWitTest(BitcoinTestFramework): child_tx.vin.append(CTxIn(COutPoint(parent_tx.sha256, i), b"")) child_tx.vout = [CTxOut(value - 100000, CScript([OP_TRUE]))] for i in range(NUM_OUTPUTS): - child_tx.wit.vtxinwit.append(CTxinWitness()) + child_tx.wit.vtxinwit.append(CTxInWitness()) child_tx.wit.vtxinwit[-1].scriptWitness.stack = [b'a'*195]*(2*NUM_DROPS) + [witness_program] child_tx.rehash() self.update_witness_block_with_transactions(block, [parent_tx, child_tx]) @@ -584,7 +584,7 @@ class SegWitTest(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vout.append(CTxOut(self.utxo[0].nValue-2000, scriptPubKey)) tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])] tx.rehash() self.update_witness_block_with_transactions(block, [tx]) @@ -607,7 +607,7 @@ class SegWitTest(BitcoinTestFramework): tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) # witness output tx2.vin.append(CTxIn(COutPoint(tx.sha256, 1), b"")) # non-witness tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.extend([CTxinWitness(), CTxinWitness()]) + tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()]) tx2.wit.vtxinwit[0].scriptWitness.stack = [ CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_program ] tx2.wit.vtxinwit[1].scriptWitness.stack = [ CScript([OP_TRUE]) ] @@ -663,7 +663,7 @@ class SegWitTest(BitcoinTestFramework): tx2 = CTransaction() tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) # First try a 521-byte stack element tx2.wit.vtxinwit[0].scriptWitness.stack = [ b'a'*(MAX_SCRIPT_ELEMENT_SIZE+1), witness_program ] tx2.rehash() @@ -705,7 +705,7 @@ class SegWitTest(BitcoinTestFramework): tx2 = CTransaction() tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a']*44 + [long_witness_program] tx2.rehash() @@ -782,7 +782,7 @@ class SegWitTest(BitcoinTestFramework): # First try using a too long vtxinwit for i in range(11): - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[i].scriptWitness.stack = [b'a', witness_program] block = self.build_next_block() @@ -798,7 +798,7 @@ class SegWitTest(BitcoinTestFramework): self.test_node.test_witness_block(block, accepted=False) # Now make one of the intermediate witnesses be incorrect - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[-1].scriptWitness.stack = [b'a', witness_program] tx2.wit.vtxinwit[5].scriptWitness.stack = [ witness_program ] @@ -825,7 +825,7 @@ class SegWitTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vout.append(CTxOut(self.utxo[0].nValue-1000, CScript([OP_TRUE]))) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a' ] tx.rehash() @@ -885,7 +885,7 @@ class SegWitTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vout.append(CTxOut(self.utxo[0].nValue-1000, CScript([OP_TRUE]))) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a' ] tx.rehash() @@ -914,7 +914,7 @@ class SegWitTest(BitcoinTestFramework): tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx3.wit.vtxinwit.append(CTxinWitness()) + tx3.wit.vtxinwit.append(CTxInWitness()) tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program ] tx3.rehash() @@ -1087,7 +1087,7 @@ class SegWitTest(BitcoinTestFramework): tx2 = CTransaction() tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] tx2.vout = [CTxOut(tx.vout[0].nValue-1000, scriptPubKey)] - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] tx2.rehash() # Gets accepted to test_node, because standardness of outputs isn't @@ -1102,7 +1102,7 @@ class SegWitTest(BitcoinTestFramework): total_value = 0 for i in temp_utxo: tx3.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) - tx3.wit.vtxinwit.append(CTxinWitness()) + tx3.wit.vtxinwit.append(CTxInWitness()) total_value += i.nValue tx3.wit.vtxinwit[-1].scriptWitness.stack = [witness_program] tx3.vout.append(CTxOut(total_value - 1000, CScript([OP_TRUE]))) @@ -1140,7 +1140,7 @@ class SegWitTest(BitcoinTestFramework): spend_tx = CTransaction() spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")] spend_tx.vout = [CTxOut(block.vtx[0].vout[0].nValue, witness_program)] - spend_tx.wit.vtxinwit.append(CTxinWitness()) + spend_tx.wit.vtxinwit.append(CTxInWitness()) spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] spend_tx.rehash() @@ -1200,7 +1200,7 @@ class SegWitTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) tx.vout.append(CTxOut(prev_utxo.nValue - 1000, scriptPubKey)) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) # Too-large input value sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue+1, key) self.update_witness_block_with_transactions(block, [tx]) @@ -1233,7 +1233,7 @@ class SegWitTest(BitcoinTestFramework): split_value = prev_utxo.nValue // NUM_TESTS for i in range(NUM_TESTS): tx.vout.append(CTxOut(split_value, scriptPubKey)) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, prev_utxo.nValue, key) for i in range(NUM_TESTS): temp_utxos.append(UTXO(tx.sha256, i, split_value)) @@ -1255,7 +1255,7 @@ class SegWitTest(BitcoinTestFramework): total_value = 0 for i in range(num_inputs): tx.vin.append(CTxIn(COutPoint(temp_utxos[i].sha256, temp_utxos[i].n), b"")) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) total_value += temp_utxos[i].nValue split_value = total_value // num_outputs for i in range(num_outputs): @@ -1295,7 +1295,7 @@ class SegWitTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b"")) tx.vout.append(CTxOut(temp_utxos[0].nValue, scriptPKH)) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, temp_utxos[0].nValue, key) tx2 = CTransaction() tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) @@ -1313,7 +1313,7 @@ class SegWitTest(BitcoinTestFramework): # Move the signature to the witness. block.vtx.pop() - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[0].scriptWitness.stack = [signature, pubkey] tx2.vin[0].scriptSig = b"" tx2.rehash() @@ -1333,7 +1333,7 @@ class SegWitTest(BitcoinTestFramework): # the signatures as we go. tx.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) tx.vout.append(CTxOut(i.nValue, CScript([OP_TRUE]))) - tx.wit.vtxinwit.append(CTxinWitness()) + tx.wit.vtxinwit.append(CTxInWitness()) sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, i.nValue, key) index += 1 block = self.build_next_block() @@ -1393,7 +1393,7 @@ class SegWitTest(BitcoinTestFramework): # segwit activates. spend_tx.vin[0].scriptSig = scriptSig spend_tx.rehash() - spend_tx.wit.vtxinwit.append(CTxinWitness()) + spend_tx.wit.vtxinwit.append(CTxInWitness()) spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a', witness_program ] # Verify mempool acceptance @@ -1499,7 +1499,7 @@ class SegWitTest(BitcoinTestFramework): total_value = 0 for i in range(outputs-1): tx2.vin.append(CTxIn(COutPoint(tx.sha256, i), b"")) - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program ] total_value += tx.vout[i].nValue tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_toomany ] @@ -1540,7 +1540,7 @@ class SegWitTest(BitcoinTestFramework): block_5 = self.build_next_block() tx2.vout.pop() tx2.vin.append(CTxIn(COutPoint(tx.sha256, outputs-1), b"")) - tx2.wit.vtxinwit.append(CTxinWitness()) + tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_justright ] tx2.rehash() self.update_witness_block_with_transactions(block_5, [tx2]) diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index df4fe13e5..f69958823 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -34,7 +34,7 @@ def add_witness_commitment(block, nonce=0): witness_root = block.calc_witness_merkle_root() witness_commitment = uint256_from_str(hash256(ser_uint256(witness_root)+ser_uint256(witness_nonce))) # witness_nonce should go to coinbase witness. - block.vtx[0].wit.vtxinwit = [CTxinWitness()] + block.vtx[0].wit.vtxinwit = [CTxInWitness()] block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(witness_nonce)] # witness commitment is the last OP_RETURN output in coinbase diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 4548e2e7c..cdd5292cd 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -419,7 +419,7 @@ class CScriptWitness(object): return True -class CTxinWitness(object): +class CTxInWitness(object): def __init__(self): self.scriptWitness = CScriptWitness() @@ -497,7 +497,7 @@ class CTransaction(object): else: self.vout = deser_vector(f, CTxOut) if flags != 0: - self.wit.vtxinwit = [CTxinWitness()]*len(self.vin) + self.wit.vtxinwit = [CTxInWitness()]*len(self.vin) self.wit.deserialize(f) self.nLockTime = struct.unpack("::const_iterator it = txwit.vtxinwit.begin(); it != txwit.vtxinwit.end(); it++) { + for (std::vector::const_iterator it = txwit.vtxinwit.begin(); it != txwit.vtxinwit.end(); it++) { mem += RecursiveDynamicUsage(*it); } return mem; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index e87ad90f0..8a2d5dd22 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -213,7 +213,7 @@ public: std::string ToString() const; }; -class CTxinWitness +class CTxInWitness { public: CScriptWitness scriptWitness; @@ -228,14 +228,14 @@ public: bool IsNull() const { return scriptWitness.IsNull(); } - CTxinWitness() { } + CTxInWitness() { } }; class CTxWitness { public: /** In case vtxinwit is missing, all entries are treated as if they were empty CTxInWitnesses */ - std::vector vtxinwit; + std::vector vtxinwit; ADD_SERIALIZE_METHODS; diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 8dea38833..e8a63ae60 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -84,7 +84,7 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction * and witness such that spendingTx spends output zero of creationTx. * Also inserts creationTx's output into the coins view. */ -void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxinWitness& witness) +void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxInWitness& witness) { creationTx.nVersion = 1; creationTx.vin.resize(1); @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) // Do not use a valid signature to avoid using wallet operations. CScript scriptSig = CScript() << OP_0 << OP_0; - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness()); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); // Legacy counting only includes signature operations in scriptSigs and scriptPubKeys // of a transaction and does not take the actual executed sig operations into account. // spendingTx in itself does not contain a signature operation. @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness()); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2 * WITNESS_SCALE_FACTOR); assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); } @@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; CScript scriptPubKey = GetScriptForWitness(p2pk); CScript scriptSig = CScript(); - CTxinWitness witness; + CTxInWitness witness; CScriptWitness scriptWitness; scriptWitness.stack.push_back(vector(0)); scriptWitness.stack.push_back(vector(0)); @@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript scriptSig = GetScriptForWitness(p2pk); CScript scriptPubKey = GetScriptForDestination(CScriptID(scriptSig)); scriptSig = CScript() << ToByteVector(scriptSig); - CTxinWitness witness; + CTxInWitness witness; CScriptWitness scriptWitness; scriptWitness.stack.push_back(vector(0)); scriptWitness.stack.push_back(vector(0)); @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; CScript scriptPubKey = GetScriptForWitness(witnessScript); CScript scriptSig = CScript(); - CTxinWitness witness; + CTxInWitness witness; CScriptWitness scriptWitness; scriptWitness.stack.push_back(vector(0)); scriptWitness.stack.push_back(vector(0)); @@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript redeemScript = GetScriptForWitness(witnessScript); CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); CScript scriptSig = CScript() << ToByteVector(redeemScript); - CTxinWitness witness; + CTxInWitness witness; CScriptWitness scriptWitness; scriptWitness.stack.push_back(vector(0)); scriptWitness.stack.push_back(vector(0)); From fa9976b853dbd04334cd0b5a058b99aa0014e649 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 6 Jul 2016 20:46:22 +0200 Subject: [PATCH 0899/1223] [qa] test_framework: Add wrapper for stop_node --- qa/rpc-tests/test_framework/test_framework.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 30e8b5755..0dfece6b2 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -20,6 +20,7 @@ from .util import ( sync_blocks, sync_mempools, stop_nodes, + stop_node, wait_bitcoinds, enable_coverage, check_json_precision, @@ -49,6 +50,9 @@ class BitcoinTestFramework(object): else: initialize_chain(self.options.tmpdir, self.num_nodes) + def stop_node(self, num_node): + stop_node(self.nodes[num_node], num_node) + def setup_nodes(self): return start_nodes(self.num_nodes, self.options.tmpdir) From 1ba3db6a8e9626984fc87314b15dfa2a6c831cb2 Mon Sep 17 00:00:00 2001 From: Christian von Roques Date: Sun, 26 Jun 2016 16:20:12 -0400 Subject: [PATCH 0900/1223] bash-completion: Adapt for 0.12 and 0.13 * separate completion for bitcoind and bitcoin-cli * remove RPC support from bitcoind completion * add completion for bitcoin-tx and bitcoin-qt * rely on autoloading of completions --- contrib/bitcoin-cli.bash-completion | 154 ++++++++++++++++++++++ contrib/bitcoin-tx.bash-completion | 57 ++++++++ contrib/bitcoind.bash-completion | 111 ++-------------- contrib/debian/bitcoin-tx.bash-completion | 1 + contrib/debian/bitcoind.bash-completion | 1 + 5 files changed, 224 insertions(+), 100 deletions(-) create mode 100644 contrib/bitcoin-cli.bash-completion create mode 100644 contrib/bitcoin-tx.bash-completion create mode 100644 contrib/debian/bitcoin-tx.bash-completion diff --git a/contrib/bitcoin-cli.bash-completion b/contrib/bitcoin-cli.bash-completion new file mode 100644 index 000000000..732981fe7 --- /dev/null +++ b/contrib/bitcoin-cli.bash-completion @@ -0,0 +1,154 @@ +# bash programmable completion for bitcoin-cli(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# call $bitcoin-cli for RPC +_bitcoin_rpc() { + # determine already specified args necessary for RPC + local rpcargs=() + for i in ${COMP_LINE}; do + case "$i" in + -conf=*|-datadir=*|-regtest|-rpc*|-testnet) + rpcargs=( "${rpcargs[@]}" "$i" ) + ;; + esac + done + $bitcoin_cli "${rpcargs[@]}" "$@" +} + +# Add wallet accounts to COMPREPLY +_bitcoin_accounts() { + local accounts + accounts=$(_bitcoin_rpc listaccounts | awk -F '"' '{ print $2 }') + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) +} + +_bitcoin_cli() { + local cur prev words=() cword + local bitcoin_cli + + # save and use original argument to invoke bitcoin-cli for -help, help and RPC + # as bitcoin-cli might not be in $PATH + bitcoin_cli="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + if ((cword > 5)); then + case ${words[cword-5]} in + sendtoaddress) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 4)); then + case ${words[cword-4]} in + importaddress|listtransactions|setban) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + signrawtransaction) + COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 3)); then + case ${words[cword-3]} in + addmultisigaddress) + _bitcoin_accounts + return 0 + ;; + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 2)); then + case ${words[cword-2]} in + addnode) + COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) + return 0 + ;; + setban) + COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) + return 0 + ;; + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + move|setaccount) + _bitcoin_accounts + return 0 + ;; + esac + fi + + case "$prev" in + backupwallet|dumpwallet|importwallet) + _filedir + return 0 + ;; + getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) + _bitcoin_accounts + return 0 + ;; + esac + + case "$cur" in + -conf=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + local helpopts commands + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + helpopts=$($bitcoin_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + fi + + # only parse help if senseful + if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then + commands=$(_bitcoin_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + fi + + COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _bitcoin_cli bitcoin-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/bitcoin-tx.bash-completion b/contrib/bitcoin-tx.bash-completion new file mode 100644 index 000000000..a83d2979e --- /dev/null +++ b/contrib/bitcoin-tx.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for bitcoin-tx(1) +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +_bitcoin_tx() { + local cur prev words=() cword + local bitcoin_tx + + # save and use original argument to invoke bitcoin-tx for -help + # it might not be in $PATH + bitcoin_tx="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n =: cur prev words cword + + case "$cur" in + load=*:*) + cur="${cur#load=*:}" + _filedir + return 0 + ;; + *=*) # prevent attempts to complete other arguments + return 0 + ;; + esac + + if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then + # only options (or an uncompletable hex-string) allowed + # parse bitcoin-tx -help for options + local helpopts + helpopts=$($bitcoin_tx -help | sed -e '/^ -/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + else + # only commands are allowed + # parse -help for commands + local helpcmds + helpcmds=$($bitcoin_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + + return 0 +} && +complete -F _bitcoin_tx bitcoin-tx + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion index 1338d2f2b..af87e97d8 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/bitcoind.bash-completion @@ -1,102 +1,21 @@ -# bash programmable completion for bitcoind(1) and bitcoin-cli(1) -# Copyright (c) 2012,2014 Christian von Roques +# bash programmable completion for bitcoind(1) and bitcoin-qt(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -have bitcoind && { - -# call $bitcoind for RPC -_bitcoin_rpc() { - # determine already specified args necessary for RPC - local rpcargs=() - for i in ${COMP_LINE}; do - case "$i" in - -conf=*|-proxy*|-rpc*) - rpcargs=( "${rpcargs[@]}" "$i" ) - ;; - esac - done - $bitcoind "${rpcargs[@]}" "$@" -} - -# Add bitcoin accounts to COMPREPLY -_bitcoin_accounts() { - local accounts - accounts=$(_bitcoin_rpc listaccounts | awk '/".*"/ { a=$1; gsub(/"/, "", a); print a}') - COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) -} - _bitcoind() { local cur prev words=() cword local bitcoind - # save and use original argument to invoke bitcoind - # bitcoind might not be in $PATH + # save and use original argument to invoke bitcoind for -help + # it might not be in $PATH bitcoind="$1" COMPREPLY=() _get_comp_words_by_ref -n = cur prev words cword - if ((cword > 4)); then - case ${words[cword-4]} in - listtransactions) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - signrawtransaction) - COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 3)); then - case ${words[cword-3]} in - addmultisigaddress) - _bitcoin_accounts - return 0 - ;; - getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 2)); then - case ${words[cword-2]} in - addnode) - COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) - return 0 - ;; - getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - move|setaccount) - _bitcoin_accounts - return 0 - ;; - esac - fi - - case "$prev" in - backupwallet|dumpwallet|importwallet) - _filedir - return 0 - ;; - getmempool|lockunspent|setgenerate) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) - _bitcoin_accounts - return 0 - ;; - esac - case "$cur" in - -conf=*|-pid=*|-loadblock=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 @@ -110,20 +29,14 @@ _bitcoind() { return 0 ;; *) - local helpopts commands - # only parse --help if senseful + # only parse -help if senseful if [[ -z "$cur" || "$cur" =~ ^- ]]; then - helpopts=$($bitcoind --help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + local helpopts + helpopts=$($bitcoind -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) fi - # only parse help if senseful - if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then - commands=$(_bitcoin_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') - fi - - COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) - # Prevent space if an argument is desired if [[ $COMPREPLY == *= ]]; then compopt -o nospace @@ -131,10 +44,8 @@ _bitcoind() { return 0 ;; esac -} - -complete -F _bitcoind bitcoind bitcoin-cli -} +} && +complete -F _bitcoind bitcoind bitcoin-qt # Local variables: # mode: shell-script diff --git a/contrib/debian/bitcoin-tx.bash-completion b/contrib/debian/bitcoin-tx.bash-completion new file mode 100644 index 000000000..7acb0b0ae --- /dev/null +++ b/contrib/debian/bitcoin-tx.bash-completion @@ -0,0 +1 @@ +contrib/bitcoin-tx.bash-completion bitcoin-tx diff --git a/contrib/debian/bitcoind.bash-completion b/contrib/debian/bitcoind.bash-completion index 0f84707b6..5c69d78fb 100644 --- a/contrib/debian/bitcoind.bash-completion +++ b/contrib/debian/bitcoind.bash-completion @@ -1 +1,2 @@ contrib/bitcoind.bash-completion bitcoind +contrib/bitcoin-cli.bash-completion bitcoin-cli From 0c928cb13cc9146bb2c0f39d1d3b6e1e660a375d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 7 Jul 2016 13:46:59 -0400 Subject: [PATCH 0901/1223] build: Fix Qt5PlatformSupport check without pkg-config The non-pkg-config case can't use pkg-config to check the version. Also, make sure that the check is properly guarded in the case of missing pkg-config macros. --- build-aux/m4/bitcoin_qt.m4 | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 74d910267..d26136cbe 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -331,8 +331,9 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi fi - m4_ifdef([PKG_CHECK_MODULES],[ if test x$use_pkgconfig = xyes; then + : dnl + m4_ifdef([PKG_CHECK_MODULES],[ PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) if test x$TARGET_OS = xlinux; then PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) @@ -342,12 +343,23 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test x$TARGET_OS = xdarwin; then PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi + ]) else - if ${PKG_CONFIG} --exists "Qt5Core >= 5.6" 2>/dev/null; then - QT_LIBS="-lQt5PlatformSupport $QT_LIBS" + if test x$TARGET_OS = xwindows; then + AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]],[[ + #if QT_VERSION < 0x050600 + choke; + #endif + ]])], + [bitcoin_cv_need_platformsupport=yes], + [bitcoin_cv_need_platformsupport=no]) + ]) + if test x$bitcoin_cv_need_platformsupport = xyes; then + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) + fi fi fi - ]) else if test x$qt_plugin_path != x; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" From b556beda264308e040f8d88aca4f2f386a0183d9 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 7 Jul 2016 13:47:54 -0400 Subject: [PATCH 0902/1223] build: fix Windows builds without pkg-config - guard PKG_PROG_PKG_CONFIG with an m4_ifdef. If not building for windows, require it - add nops as necessary in case the ifdef reduces the if/then to nothing - AC_SUBST some missing _LIBS. These were split out over time, but not all were properly substituted. They continued to work if pkg-config is installed because it does the AC_SUBST itself --- configure.ac | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 97af58bd7..ae0972262 100644 --- a/configure.ac +++ b/configure.ac @@ -79,9 +79,6 @@ AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) -dnl pkg-config check. -PKG_PROG_PKG_CONFIG - # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], @@ -375,6 +372,16 @@ case $host in ;; esac +if test x$use_pkgconfig = xyes; then + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [ + PKG_PROG_PKG_CONFIG + if test x"$PKG_CONFIG" = "x"; then + AC_MSG_ERROR(pkg-config not found.) + fi + ]) +fi + if test x$use_comparison_tool != xno; then AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool) fi @@ -752,12 +759,7 @@ fi fi if test x$use_pkgconfig = xyes; then - - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - - : #NOP + : dnl m4_ifdef( [PKG_CHECK_MODULES], [ @@ -1058,6 +1060,13 @@ AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(CRYPTO_LIBS) +AC_SUBST(SSL_LIBS) +AC_SUBST(EVENT_LIBS) +AC_SUBST(EVENT_PTHREADS_LIBS) +AC_SUBST(ZMQ_LIBS) +AC_SUBST(PROTOBUF_LIBS) +AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) From bb66a11396335b5f4e5914806fcb2dc6165edf6f Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Jul 2016 15:49:26 -0400 Subject: [PATCH 0903/1223] Fix DoS vulnerability in mempool acceptance Moves the IsStandard check to happen after the premature-witness check, so that adding a witness to a transaction can't prevent mempool acceptance. Note that this doesn't address the broader category of potential mempool DoS issues that affect transactions after segwit activation. --- src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b86bbda1b..2f16a4c8e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1132,11 +1132,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (tx.IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "coinbase"); - // Rather not work on nonstandard transactions (unless -testnet/-regtest) - string reason; - if (fRequireStandard && !IsStandardTx(tx, reason)) - return state.DoS(0, false, REJECT_NONSTANDARD, reason); - // Don't relay version 2 transactions until CSV is active, and we can be // sure that such transactions will be mined (unless we're on // -testnet/-regtest). @@ -1150,6 +1145,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } + // Rather not work on nonstandard transactions (unless -testnet/-regtest) + string reason; + if (fRequireStandard && !IsStandardTx(tx, reason)) + return state.DoS(0, false, REJECT_NONSTANDARD, reason); + // Only accept nLockTime-using transactions that can be mined in the next // block; we don't want our mempool filled up with transactions that can't // be mined yet. From fade505e8b0fa37e2d99bf94259250271a9604d4 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 6 Jul 2016 10:36:46 +0200 Subject: [PATCH 0904/1223] [qa] Add wallet-hd test --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/wallet-hd.py | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100755 qa/rpc-tests/wallet-hd.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 37979a933..11b83bac1 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -106,6 +106,7 @@ testScripts = [ 'walletbackup.py', 'bip68-112-113-p2p.py', 'wallet.py', + 'wallet-hd.py', 'listtransactions.py', 'receivedby.py', 'mempool_resurrect_test.py', diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py new file mode 100755 index 000000000..845eec027 --- /dev/null +++ b/qa/rpc-tests/wallet-hd.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + start_nodes, + start_node, + assert_equal, + connect_nodes_bi, +) +import os +import shutil + + +class WalletHDTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 + self.node_args = [['-usehd=0'], ['-usehd=1', '-keypool=0']] + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.node_args) + self.is_network_split = False + connect_nodes_bi(self.nodes, 0, 1) + + def run_test (self): + tmpdir = self.options.tmpdir + + # Import a non-HD private key in the HD wallet + non_hd_add = self.nodes[0].getnewaddress() + self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) + + # This should be enough to keep the master key and the non-HD key + self.nodes[1].backupwallet(tmpdir + "hd.bak") + #self.nodes[1].dumpwallet(tmpdir + "hd.dump") + + # Derive some HD addresses and remember the last + # Also send funds to each add + self.nodes[0].generate(101) + hd_add = None + num_hd_adds = 300 + for _ in range(num_hd_adds): + hd_add = self.nodes[1].getnewaddress() + self.nodes[0].sendtoaddress(hd_add, 1) + self.nodes[0].generate(1) + self.nodes[0].sendtoaddress(non_hd_add, 1) + self.nodes[0].generate(1) + + self.sync_all() + assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + + print("Restore backup ...") + self.stop_node(1) + os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") + shutil.copyfile(tmpdir + "hd.bak", tmpdir + "/node1/regtest/wallet.dat") + self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1]) + #connect_nodes_bi(self.nodes, 0, 1) + + # Assert that derivation is deterministic + hd_add_2 = None + for _ in range(num_hd_adds): + hd_add_2 = self.nodes[1].getnewaddress() + assert_equal(hd_add, hd_add_2) + + # Needs rescan + self.stop_node(1) + self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1] + ['-rescan']) + #connect_nodes_bi(self.nodes, 0, 1) + assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + + +if __name__ == '__main__': + WalletHDTest().main () From 099d4b0b65b7dceb14dc4ec5231a60996dff4c69 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 7 Jul 2016 20:09:55 -0400 Subject: [PATCH 0905/1223] gitian: use a wrapped gcc/g++ to avoid the need for a system change C_INCLUDE_PATH and CPLUS_INCLUDE_PATH work globally as though -isystem was used for each invocation. Since that changes the build results, force a rebuild of x86 depends by adding the value to $HOST_ID_SALT. --- contrib/gitian-descriptors/gitian-linux.yml | 40 +++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index a2788c9d7..6f43119ba 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -33,12 +33,6 @@ remotes: files: [] script: | - #unlock sudo - echo "ubuntu" | sudo -S true - - sudo mkdir -p /usr/include/i386-linux-gnu/ - sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/i386-linux-gnu/asm - WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" @@ -90,11 +84,45 @@ script: | create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} + EXTRA_INCLUDES_BASE=$WRAP_DIR/extra_includes + mkdir -p $EXTRA_INCLUDES_BASE + + # x86 needs /usr/include/i386-linux-gnu/asm pointed to /usr/include/x86_64-linux-gnu/asm, + # but we can't write there. Instead, create a link here and force it to be included in the + # search paths by wrapping gcc/g++. + + mkdir -p $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu + rm -f $WRAP_DIR/extra_includes/i686-pc-linux-gnu/asm + ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu/asm + + for prog in gcc g++; do + rm -f ${WRAP_DIR}/${prog} + cat << EOF > ${WRAP_DIR}/${prog} + #!/bin/bash + REAL="`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1`" + for var in "\$@" + do + if [ "\$var" = "-m32" ]; then + export C_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + break + fi + done + \$REAL \$@ + EOF + chmod +x ${WRAP_DIR}/${prog} + done + cd bitcoin BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do + EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" + if [ -d "$EXTRA_INCLUDES" ]; then + export HOST_ID_SALT="$EXTRA_INCLUDES" + fi make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + unset HOST_ID_SALT done # Faketime for binaries From 46c9620f11acfd2b528959d6cbab324105c3adef Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 7 Jul 2016 21:18:05 -0400 Subject: [PATCH 0906/1223] Test that unnecessary witnesses can't be used for mempool DoS Check that pre-segwit activation, unnecessary witnesses won't cause a txid to be permanently rejected. --- qa/rpc-tests/p2p-segwit.py | 54 +++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index cf78954f2..2a2079d5e 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -43,6 +43,7 @@ class TestNode(NodeConnCB): self.last_pong = msg_pong(0) self.sleep_time = 0.05 self.getdataset = set() + self.last_reject = None def add_connection(self, conn): self.connection = conn @@ -68,7 +69,7 @@ class TestNode(NodeConnCB): def on_reject(self, conn, message): self.last_reject = message - #print message + #print (message) # Syncing helpers def sync(self, test_function, timeout=60): @@ -136,13 +137,17 @@ class TestNode(NodeConnCB): self.wait_for_block(blockhash, timeout) return self.last_block - def test_transaction_acceptance(self, tx, with_witness, accepted): + def test_transaction_acceptance(self, tx, with_witness, accepted, reason=None): tx_message = msg_tx(tx) if with_witness: tx_message = msg_witness_tx(tx) self.send_message(tx_message) self.sync_with_ping() assert_equal(tx.hash in self.connection.rpc.getrawmempool(), accepted) + if (reason != None and not accepted): + # Check the rejection reason as well. + with mininode_lock: + assert_equal(self.last_reject.reason, reason) # Test whether a witness block had the correct effect on the tip def test_witness_block(self, block, accepted, with_witness=True): @@ -277,9 +282,52 @@ class SegWitTest(BitcoinTestFramework): self.test_node.sync_with_ping() assert_equal(self.nodes[0].getbestblockhash(), block.hash) + sync_blocks(self.nodes) + + # Create a p2sh output -- this is so we can pass the standardness + # rules (an anyone-can-spend OP_TRUE would be rejected, if not wrapped + # in P2SH). + p2sh_program = CScript([OP_TRUE]) + p2sh_pubkey = hash160(p2sh_program) + scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) + + # Now check that unnecessary witnesses can't be used to blind a node + # to a transaction, eg by violating standardness checks. + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptPubKey)) + tx2.rehash() + self.test_node.test_transaction_acceptance(tx2, False, True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # We'll add an unnecessary witness to this transaction that would cause + # it to be too large according to IsStandard. + tx3 = CTransaction() + tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) + tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptPubKey)) + tx3.wit.vtxinwit.append(CTxinWitness()) + tx3.wit.vtxinwit[0].scriptWitness.stack = [b'a'*400000] + tx3.rehash() + self.std_node.test_transaction_acceptance(tx3, True, False, b'no-witness-yet') + + # If we send without witness, it should be accepted. + self.std_node.test_transaction_acceptance(tx3, False, True) + + # Now create a new anyone-can-spend utxo for the next test. + tx4 = CTransaction() + tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), CScript([p2sh_program]))) + tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, CScript([OP_TRUE]))) + tx4.rehash() + self.test_node.test_transaction_acceptance(tx3, False, True) + self.test_node.test_transaction_acceptance(tx4, False, True) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + # Update our utxo list; we spent the first entry. self.utxo.pop(0) - self.utxo.append(UTXO(tx.sha256, 0, tx.vout[0].nValue)) + self.utxo.append(UTXO(tx4.sha256, 0, tx4.vout[0].nValue)) # Mine enough blocks for segwit's vb state to be 'started'. From 477777f2503e3a56a267556f0fc5091042d93340 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 8 Jul 2016 12:01:39 +0200 Subject: [PATCH 0907/1223] [rpcwallet] Don't use floating point --- src/wallet/rpcwallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8538f880f..2747477fd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -564,8 +564,8 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CScript scriptPubKey = GetScriptForDestination(address.Get()); - if (!IsMine(*pwalletMain,scriptPubKey)) - return (double)0.0; + if (!IsMine(*pwalletMain, scriptPubKey)) + return ValueFromAmount(0); // Minimum confirmations int nMinDepth = 1; @@ -643,7 +643,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) } } - return (double)nAmount / (double)COIN; + return ValueFromAmount(nAmount); } From d6dc1bc49b958e3c89aa0885ce39ad7a0e0f7493 Mon Sep 17 00:00:00 2001 From: Krzysztof Jurewicz Date: Fri, 8 Jul 2016 22:15:08 +0200 Subject: [PATCH 0908/1223] Fix 0.12 release notes on block relaying The previous information about block relaying in pruned mode suggested that blocks are relayed only to nodes that support BIP 130, which is not true. --- doc/release-notes/release-notes-0.12.0.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index 1b7bd06ec..cf74a1797 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -104,9 +104,6 @@ announcing their headers directly, instead of just announcing the hash. In a reorganization, all new headers are sent, instead of just the new tip. This can often prevent an extra roundtrip before the actual block is downloaded. -With this change, pruning nodes are now able to relay new blocks to compatible -peers. - Memory pool limiting -------------------- @@ -188,6 +185,14 @@ the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire serialized scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three bytes overhead) +Relay: New and only new blocks relayed when pruning +--------------------------------------------------- + +When running in pruned mode, the client will now relay new blocks. When +responding to the `getblocks` message, only hashes of blocks that are on disk +and are likely to remain there for some reasonable time window (1 hour) will be +returned (previously all relevant hashes were returned). + Relay and Mining: Priority transactions --------------------------------------- @@ -887,4 +892,3 @@ Thanks to everyone who directly contributed to this release: - zathras-crypto As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). - From 5b95dd2c256dd7ba3808021adc31bb85b41553c8 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 9 Jul 2016 11:41:01 +0200 Subject: [PATCH 0909/1223] [Wallet] extend CKeyMetadata with HD keypath --- src/wallet/wallet.cpp | 2 ++ src/wallet/walletdb.h | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a0095ebd9..33e516a7f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -126,6 +126,8 @@ CPubKey CWallet::GenerateNewKey() // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649 externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT); + metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'"; + metadata.hdMasterKeyID = hdChain.masterKeyID; // increment childkey index hdChain.nExternalChainCounter++; } while(HaveKey(childKey.key.GetPubKey().GetID())); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index d083722dd..eaa406857 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -73,9 +73,13 @@ public: class CKeyMetadata { public: - static const int CURRENT_VERSION=1; + static const int VERSION_BASIC=1; + static const int VERSION_WITH_HDDATA=10; + static const int CURRENT_VERSION=VERSION_WITH_HDDATA; int nVersion; int64_t nCreateTime; // 0 means unknown + std::string hdKeypath; //optional HD/bip32 keypath + CKeyID hdMasterKeyID; //id of the hd masterkey used to derive this key CKeyMetadata() { @@ -85,6 +89,7 @@ public: { nVersion = CKeyMetadata::CURRENT_VERSION; nCreateTime = nCreateTime_; + hdKeypath.clear(); } ADD_SERIALIZE_METHODS; @@ -94,12 +99,18 @@ public: READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(nCreateTime); + if (this->nVersion >= VERSION_WITH_HDDATA) + { + READWRITE(hdKeypath); + READWRITE(hdMasterKeyID); + } } void SetNull() { nVersion = CKeyMetadata::CURRENT_VERSION; nCreateTime = 0; + hdKeypath.clear(); } }; From b1c7b244e21ba67c38fe3d1a4d1638ca52835ac5 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 9 Jul 2016 11:41:32 +0200 Subject: [PATCH 0910/1223] [Wallet] report optional HDKeypath/HDMasterKeyId in validateaddress --- src/rpc/misc.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index f2a29416e..a8c5bcd17 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -166,6 +166,8 @@ UniValue validateaddress(const UniValue& params, bool fHelp) " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n" + " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n" + " \"hdmasterkeyid\" : \"\" (string, optional) The Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") @@ -200,6 +202,12 @@ UniValue validateaddress(const UniValue& params, bool fHelp) ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + CKeyID keyID; + if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty()) + { + ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath)); + ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex())); + } #endif } return ret; From 986c2232143e5c2f909f5b27bf74470654faf49c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 9 Jul 2016 11:25:02 +0200 Subject: [PATCH 0911/1223] [Wallet] print hd masterkeyid in getwalletinfo --- src/wallet/rpcwallet.cpp | 4 ++++ src/wallet/wallet.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8538f880f..f4625743b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2269,6 +2269,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" + " \"masterkeyid\": \"\", (string) the Hash160 of the hd master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2288,6 +2289,9 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + if (!masterKeyID.IsNull()) + obj.push_back(Pair("masterkeyid",masterKeyID.GetHex())); return obj; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7fc6ce5de..d58cb7b0e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -901,6 +901,7 @@ public: /* Set the current hd master key (will reset the chain child index counters) */ bool SetHDMasterKey(const CKey& key); + const CHDChain& GetHDChain() { return hdChain; } }; /** A key allocated from the key pool. */ From f70808596fb4108e53c8b433820593b88c4fa81b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 9 Jul 2016 12:05:30 +0200 Subject: [PATCH 0912/1223] [QA] extend wallet-hd test to cover HD metadata --- qa/rpc-tests/wallet-hd.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index 845eec027..f3ae69e10 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -30,6 +30,10 @@ class WalletHDTest(BitcoinTestFramework): def run_test (self): tmpdir = self.options.tmpdir + # Make sure we use hd, keep masterkeyid + masterkeyid = self.nodes[1].getwalletinfo()['masterkeyid'] + assert_equal(len(masterkeyid), 40) + # Import a non-HD private key in the HD wallet non_hd_add = self.nodes[0].getnewaddress() self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) @@ -45,6 +49,9 @@ class WalletHDTest(BitcoinTestFramework): num_hd_adds = 300 for _ in range(num_hd_adds): hd_add = self.nodes[1].getnewaddress() + hd_info = self.nodes[1].validateaddress(hd_add) + assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(_+1)+"'") + assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) self.nodes[0].sendtoaddress(non_hd_add, 1) @@ -64,6 +71,9 @@ class WalletHDTest(BitcoinTestFramework): hd_add_2 = None for _ in range(num_hd_adds): hd_add_2 = self.nodes[1].getnewaddress() + hd_info_2 = self.nodes[1].validateaddress(hd_add_2) + assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_+1)+"'") + assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) # Needs rescan From b993671921c0c301f18c542e77d695fdc50ffd91 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 9 Jul 2016 12:56:56 +0200 Subject: [PATCH 0913/1223] [Wallet] keep HD seed during salvagewallet --- src/wallet/wallet.cpp | 2 +- src/wallet/walletdb.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a0095ebd9..7cb294bec 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3291,7 +3291,7 @@ bool CWallet::InitLoadWallet() if (fFirstRun) { // Create new keyUser and set as default key - if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET)) { + if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { // generate a new master key CKey key; key.MakeNewKey(true); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 7bfd49095..72af8ab7b 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -977,7 +977,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss, strType, strErr); } - if (!IsKeyType(strType)) + if (!IsKeyType(strType) && strType != "hdchain") continue; if (!fReadOK) { From 4831a16223dbb42da3091e616c47eeb01f53f73b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 12 Jul 2016 09:36:17 +0000 Subject: [PATCH 0914/1223] qt: periodic translation update Added languages: - `bg_BG`: Bulgarian (Bulgaria) --- src/Makefile.qt.include | 1 + src/qt/bitcoin_locale.qrc | 1 + src/qt/locale/bitcoin_af.ts | 4 - src/qt/locale/bitcoin_ar.ts | 158 ++++++++++++++++-- src/qt/locale/bitcoin_bg.ts | 4 - src/qt/locale/bitcoin_bg_BG.ts | 236 +++++++++++++++++++++++++++ src/qt/locale/bitcoin_ca.ts | 12 -- src/qt/locale/bitcoin_ca@valencia.ts | 12 -- src/qt/locale/bitcoin_ca_ES.ts | 12 -- src/qt/locale/bitcoin_cs.ts | 12 -- src/qt/locale/bitcoin_da.ts | 12 -- src/qt/locale/bitcoin_de.ts | 58 +++++-- src/qt/locale/bitcoin_el_GR.ts | 4 - src/qt/locale/bitcoin_en_GB.ts | 12 -- src/qt/locale/bitcoin_eo.ts | 4 - src/qt/locale/bitcoin_es.ts | 12 -- src/qt/locale/bitcoin_es_CL.ts | 4 - src/qt/locale/bitcoin_es_DO.ts | 4 - src/qt/locale/bitcoin_et.ts | 4 - src/qt/locale/bitcoin_fa.ts | 4 - src/qt/locale/bitcoin_fa_IR.ts | 4 - src/qt/locale/bitcoin_fi.ts | 12 -- src/qt/locale/bitcoin_fr.ts | 12 -- src/qt/locale/bitcoin_fr_FR.ts | 4 - src/qt/locale/bitcoin_gl.ts | 4 - src/qt/locale/bitcoin_he.ts | 4 - src/qt/locale/bitcoin_hr.ts | 4 - src/qt/locale/bitcoin_hu.ts | 4 - src/qt/locale/bitcoin_id_ID.ts | 4 - src/qt/locale/bitcoin_it.ts | 12 -- src/qt/locale/bitcoin_ja.ts | 12 -- src/qt/locale/bitcoin_ka.ts | 4 - src/qt/locale/bitcoin_ko_KR.ts | 12 -- src/qt/locale/bitcoin_la.ts | 4 - src/qt/locale/bitcoin_lt.ts | 4 - src/qt/locale/bitcoin_lv_LV.ts | 4 - src/qt/locale/bitcoin_mn.ts | 4 - src/qt/locale/bitcoin_nb.ts | 12 -- src/qt/locale/bitcoin_nl.ts | 12 -- src/qt/locale/bitcoin_pam.ts | 4 - src/qt/locale/bitcoin_pl.ts | 12 -- src/qt/locale/bitcoin_pt_BR.ts | 60 +++++-- src/qt/locale/bitcoin_pt_PT.ts | 12 -- src/qt/locale/bitcoin_ro_RO.ts | 4 - src/qt/locale/bitcoin_ru.ts | 108 ++++++++++-- src/qt/locale/bitcoin_sk.ts | 12 -- src/qt/locale/bitcoin_sl_SI.ts | 12 -- src/qt/locale/bitcoin_sv.ts | 12 -- src/qt/locale/bitcoin_ta.ts | 4 - src/qt/locale/bitcoin_tr.ts | 12 -- src/qt/locale/bitcoin_uk.ts | 12 -- src/qt/locale/bitcoin_uz@Cyrl.ts | 4 - src/qt/locale/bitcoin_zh_CN.ts | 12 -- src/qt/locale/bitcoin_zh_TW.ts | 14 +- 54 files changed, 574 insertions(+), 422 deletions(-) create mode 100644 src/qt/locale/bitcoin_bg_BG.ts diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index ca2c7b2eb..7730aba37 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -8,6 +8,7 @@ QT_TS = \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ qt/locale/bitcoin_bg.ts \ + qt/locale/bitcoin_bg_BG.ts \ qt/locale/bitcoin_ca_ES.ts \ qt/locale/bitcoin_ca.ts \ qt/locale/bitcoin_ca@valencia.ts \ diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index 54d36ac01..8dd07c3d4 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -5,6 +5,7 @@ locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm locale/bitcoin_bg.qm + locale/bitcoin_bg_BG.qm locale/bitcoin_ca_ES.qm locale/bitcoin_ca.qm locale/bitcoin_ca@valencia.qm diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 7c2d294c7..97ada8dd5 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -256,10 +256,6 @@ Bitcoin Core Bitcoin Kern - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - WAARSKUWING: toets die status van u netwerk, %d blokke ontvang in die laaste %d ure (%d verwag) - Do not keep transactions in the mempool longer than <n> hours (default: %u) Moenie transaksies vir langer as <n> ure in die geheuepoel hou nie (verstek: %u) diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 78fd07443..af62207df 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -110,10 +110,6 @@ Quit application الخروج من التطبيق - - &About %1 - &عن %1 - Show information about %1 أظهر المعلومات حولة %1 @@ -306,6 +302,20 @@ Catching up... اللحاق بالركب ... + + Date: %1 + + التاريخ %1 + + + + + + Label: %1 + + علامه: %1 + + Sent transaction المعاملات المرسلة @@ -325,10 +335,18 @@ CoinControlDialog + + Coin Selection + اختيار العمله + Quantity: الكمية : + + Bytes: + بايت + Amount: القيمة : @@ -341,6 +359,10 @@ Fee: رسوم : + + Dust: + غبار: + After Fee: بعد الرسوم : @@ -349,9 +371,21 @@ Change: تعديل : + + (un)select all + عدم اختيار الجميع + + + Tree mode + صيغة الشجرة + + + List mode + صيغة القائمة + Amount - المبلغ + مبلغ Received with label @@ -363,11 +397,11 @@ Date - التاريخ + تاريخ Confirmations - تأكيد + تأكيدات Confirmed @@ -388,6 +422,14 @@ &Label &وصف + + The label associated with this address list entry + الملصق المرتبط بقائمة العناوين المدخلة + + + The address associated with this address list entry. This can only be modified for sending addresses. + العنوان المرتبط بقائمة العناوين المدخلة. و التي يمكن تعديلها فقط بواسطة ارسال العناوين + &Address &العنوان @@ -442,6 +484,14 @@ Choose data directory on startup (default: %u) اختر دليل البيانات عند بدء التشغير (افتراضي: %u) + + Set language, for example "de_DE" (default: system locale) + أضع لغة, على سبيل المثال " de_DE " (افتراضي:- مكان النظام) + + + Start minimized + الدخول مصغر + Set SSL root certificates for payment request (default: -system-) أضع شهادة بروتوكول الشبقة الأمنية لطلب المدفوع (افتراضي: -نظام-) @@ -450,7 +500,11 @@ Show splash screen on startup (default: %u) أظهر شاشة البداية عند بدء التشغيل (افتراضي: %u) - + + Reset all settings changed in the GUI + اعد تعديل جميع النظم المتغيرة في GUI + + Intro @@ -472,6 +526,14 @@ OpenURIDialog + + Open URI + افتح URL + + + Open payment request from URI or file + حدد طلب الدفع من ملف او URI + Select payment request file حدد ملف طلب الدفع @@ -527,10 +589,18 @@ Port of the proxy (e.g. 9050) منفذ البروكسي (مثلا 9050) + + Used for reaching peers via: + مستخدم للاتصال بالاصدقاء من خلال: + &Window نافذه + + Hide tray icon + اخفاء لوحة الايقون + &Display &عرض @@ -615,10 +685,6 @@ RPCConsole - - Client name - اسم العميل - N/A غير معروف @@ -663,6 +729,10 @@ Sent تم الإرسال + + &Peers + &اصدقاء + Direction جهة @@ -703,6 +773,22 @@ Out: خارج: + + 1 &hour + 1 &ساعة + + + 1 &day + 1 & يوم + + + 1 &week + 1 & اسبوع + + + 1 &year + 1 & سنة + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة @@ -723,6 +809,18 @@ %1 GB %1 قيقا بايت + + never + ابدا + + + Inbound + داخل + + + Outbound + خارجي + Yes نعم @@ -808,6 +906,10 @@ Quantity: الكمية : + + Bytes: + بايت + Amount: القيمة : @@ -836,6 +938,14 @@ Hide إخفاء + + normal + طبيعي + + + fast + سريع + Send to multiple recipients at once إرسال إلى عدة مستلمين في وقت واحد @@ -848,6 +958,10 @@ Clear all fields of the form. مسح كل حقول النموذج المطلوبة + + Dust: + غبار + Clear &All مسح الكل @@ -879,6 +993,18 @@ &Label: &وصف : + + Choose previously used address + اختر عنوانا مستخدم سابقا + + + This is a normal payment. + هذا دفع اعتيادي + + + The Bitcoin address to send the payment to + عنوان البت كوين المرسل اليه الدفع + Alt+A Alt+A @@ -891,6 +1017,10 @@ Alt+P Alt+P + + Remove this entry + ازل هذه المداخله + Message: الرسائل @@ -913,6 +1043,10 @@ &Sign Message &توقيع الرسالة + + Choose previously used address + اختر عنوانا مستخدم سابقا + Alt+A Alt+A diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index bd85d8c8b..acb60cf41 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -881,10 +881,6 @@ RPCConsole - - Client name - Име на клиента - N/A Несъществуващ diff --git a/src/qt/locale/bitcoin_bg_BG.ts b/src/qt/locale/bitcoin_bg_BG.ts new file mode 100644 index 000000000..4bddb5ff4 --- /dev/null +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -0,0 +1,236 @@ + + + AddressBookPage + + Right-click to edit address or label + Клик с десен бутон на мишката за промяна на адрес или етикет + + + Create a new address + Създай нов адрес + + + &New + Нов + + + Copy the currently selected address to the system clipboard + Копирай текущо избрания адрес към клипборда + + + &Copy + Копирай + + + C&lose + Затвори + + + Delete the currently selected address from the list + Изтрий текущо избрания адрес от листа + + + Export the data in the current tab to a file + Изнеси данните в избрания раздел към файл + + + &Export + Изнеси + + + &Delete + Изтрий + + + + AskPassphraseDialog + + Passphrase Dialog + Диалог за пропуск + + + Enter passphrase + Въведи парола + + + New passphrase + Нова парола + + + Repeat new passphrase + Повтори парола + + + + BanTableModel + + IP/Netmask + IP/Мрежова маска + + + Banned Until + Блокиран до + + + + BitcoinGUI + + Sign &message... + Подпиши съобщение... + + + Synchronizing with network... + Синхронизиране с мрежата... + + + &Overview + Преглед + + + Node + Възел + + + Show general overview of wallet + Покажи общ преглед на портфейла + + + &Transactions + Транзакции + + + Browse transaction history + Разгледай история на транзакциите + + + E&xit + Изход + + + Quit application + Излез от приложението + + + &About %1 + За %1 + + + Show information about %1 + Покажи информация за %1 + + + About &Qt + Относно Qt + + + Show information about Qt + Покажи информация отностно Qt + + + &Options... + Настройки... + + + Modify configuration options for %1 + Промени конфигурации за %1 + + + &Encrypt Wallet... + Криптирай портфейл + + + &Backup Wallet... + Направи резервно копие на портфейла... + + + &Change Passphrase... + Промени паролата... + + + &Sending addresses... + Адреси за пращане... + + + &Receiving addresses... + Адреси за получаване... + + + Open &URI... + Отвори URI + + + Reindexing blocks on disk... + Повторно индексиране на блоковете на диска... + + + + CoinControlDialog + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PeerTableModel + + + QObject + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDescDialog + + + UnitDisplayStatusBarControl + + + bitcoin-core + + Bitcoin Core + Биткойн ядро + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 3eb384868..ed259c4d0 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -925,10 +925,6 @@ RPCConsole - - Client name - Nom del client - N/A N/A @@ -1738,14 +1734,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes. diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index 1fdf0249a..df0f750a6 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -869,10 +869,6 @@ RPCConsole - - Client name - Nom del client - N/A N/A @@ -1570,14 +1566,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Esta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avís: la xarxa no pareix que hi estiga plenament d'acord. Alguns miners pareix que estan experimentant problemes. diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 30004e10e..f985a6928 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -925,10 +925,6 @@ RPCConsole - - Client name - Nom del client - N/A N/A @@ -1734,14 +1730,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes. diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index d76839723..2dfa295ce 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -917,10 +917,6 @@ RPCConsole - - Client name - Název klienta - N/A N/A @@ -1714,14 +1710,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá a nepoužívá -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Upozornění: Síť podle všeho není v konzistentním stavu. Někteří těžaři jsou zřejmě v potížích. diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index fd1a4a086..d298c81bd 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Klientnavn - N/A N/A @@ -1886,14 +1882,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Brug UPnP for at konfigurere den lyttende port (standard: 1 under lytning og ingen -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Advarsel: Netværket ser ikke ud til at være fuldt ud enige! Enkelte minere ser ud til at opleve problemer. diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 77482c774..f38f4c10f 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -781,6 +781,14 @@ &Window &Programmfenster + + &Hide the icon from the system tray. + &Das Icon im System Tray verstecken. + + + Hide tray icon + Tray Icon verstecken + Show only a tray icon after minimizing the window. Nur ein Symbol im Infobereich anzeigen, nachdem das Programmfenster minimiert wurde. @@ -981,10 +989,6 @@ RPCConsole - - Client name - Clientname - N/A k.A. @@ -1011,7 +1015,7 @@ Datadir - Datenverz + Datenverzeichnis Startup time @@ -1097,6 +1101,10 @@ User Agent User-Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Öffnet die %1-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern. + Decrease font size Schrift verkleinern @@ -1790,6 +1798,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden + + Cannot obtain a lock on data directory %s. %s is probably already running. + Datenverzeichnis %s kann nicht gesperrt werden. Evtl. wurde %s bereits gestartet. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen @@ -1806,6 +1818,14 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da %s ansonsten nicht ordnungsgemäß funktionieren wird. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Wenn sie %s nützlich finden, sind Helfer sehr gern gesehen. Besuchen Sie %s um mehr über das Softwareprojekt zu erfahren. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Maximale Anzahl an Skript-Verifizierungs-Threads festlegen (%u bis %d, 0 = automatisch, <0 = so viele Kerne frei lassen, Standard: %d) @@ -1822,14 +1842,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet). - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet). - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben. @@ -1842,6 +1854,14 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Sie müssen die Datenbank mit Hilfe von -reindex-chainstate neu aufbauen, um -txindex zu verändern + + + %s corrupt, salvage failed + %s beschädigt, Datenrettung fehlgeschlagen + -maxmempool must be at least %d MB -maxmempool muss mindestens %d MB betragen @@ -1854,6 +1874,10 @@ Append comment to the user agent string Hänge ein Kommentar zur User Agent-Zeichenkette an + + Attempt to recover private keys from a corrupt wallet on startup + Es wird versucht, private Schlüssel beim Starten aus einem beschädigtem Wallet wiederherzustellen + Block creation options: Blockerzeugungsoptionen: @@ -1918,6 +1942,14 @@ Error loading %s Fehler beim Laden von %s + + Error loading %s: Wallet corrupted + Fehler beim Laden von %s: Das Wallet ist beschädigt + + + Error loading %s: Wallet requires newer version of %s + Fehler beim Laden von %s: Das Wallet benötigt eine neuere Version von %s + Error loading block database Fehler beim Laden der Blockdatenbank diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 59779692d..2814e4f6e 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -834,10 +834,6 @@ RPCConsole - - Client name - Όνομα Πελάτη - N/A Μη διαθέσιμο diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 226444e9c..1893aaca0 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Client name - N/A N/A @@ -1886,14 +1882,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP to map the listening port (default: 1 when listening and no -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 043b28abc..4471aeb72 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -741,10 +741,6 @@ RPCConsole - - Client name - Nomo de kliento - N/A neaplikebla diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 80cbe3993..c67016637 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -989,10 +989,6 @@ RPCConsole - - Client name - Nombre del cliente - N/A N/D @@ -1885,14 +1881,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes. diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index ff0fce611..188641d6e 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -457,10 +457,6 @@ RPCConsole - - Client name - Nombre del cliente - N/A N/A diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 3f4380840..ba963d2b8 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -639,10 +639,6 @@ RPCConsole - - Client name - Nombre del cliente - N/A N/D diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index e861d4e47..0d659fd71 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -541,10 +541,6 @@ RPCConsole - - Client name - Kliendi nimi - N/A N/A diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 5bebb3582..8bf727a0c 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -729,10 +729,6 @@ RPCConsole - - Client name - نام کلاینت - N/A ناموجود diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index b329612de..8faa3ce65 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -299,10 +299,6 @@ RPCConsole - - Client name - نام کنسول RPC - Client version ویرایش کنسول RPC diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index c2226e9b9..b7b3115e2 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -929,10 +929,6 @@ RPCConsole - - Client name - Pääteohjelman nimi - N/A Ei saatavilla @@ -1718,14 +1714,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Käytä UPnP:ta kuuntelevan portin kartoitukseen (oletus: 1 kun kuunnellaan ja -proxy ei käytössä) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - VAROITUS: epätavallisen monta lohkoa generoitu, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - VAROITUS: tarkista verkkoyhteytesi, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varoitus: Tietoverkko ei ole sovussa! Luohijat näyttävät kokevan virhetilanteita. diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 5c4f7f2b0..0b538d766 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Nom du client - N/A N.D. @@ -1866,14 +1862,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Avertissement : le réseau ne semble pas totalement d'accord ! Quelques mineurs semblent éprouver des difficultés. diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index 08824e113..a6f6ac4fd 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -809,10 +809,6 @@ RPCConsole - - Client name - Nom du client - N/A N/A diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index f3673b6dc..9aa7b5509 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -595,10 +595,6 @@ RPCConsole - - Client name - Nome do cliente - N/A N/A diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index fbe16364e..4a293c1c3 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -827,10 +827,6 @@ RPCConsole - - Client name - שם לקוח - N/A לא זמין diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index 0d8d3d5c9..f5accfb0b 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -657,10 +657,6 @@ RPCConsole - - Client name - Ime klijenta - N/A N/A diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index bddc430f2..9eb0cf76c 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -805,10 +805,6 @@ RPCConsole - - Client name - Kliens néve - N/A Nem elérhető diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index fe07ab7a2..feb6f690c 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -853,10 +853,6 @@ RPCConsole - - Client name - Nama Klien - N/A T/S diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index b92dbb2cb..55bc9c3c8 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -930,10 +930,6 @@ Per specificare più URL separarli con una barra verticale "|". RPCConsole - - Client name - Nome del client - N/A N/D @@ -1747,14 +1743,6 @@ Per specificare più URL separarli con una barra verticale "|". Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Attenzione: La rete non sembra trovarsi in pieno consenso! Alcuni minatori sembrano riscontrare problemi. diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 460a652e3..4948cc306 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - クライアント名 - N/A N/A @@ -1886,14 +1882,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) リスン ポートの割当に UPnP を使用 (初期値: リスン中および-proxyが指定されていない場合は1) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - 警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - 警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告: ネットワークは完全に同意しないみたいです。マイナーは何かの問題を経験してるみたいなんです。 diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 22e7651f6..80508be8e 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -663,10 +663,6 @@ RPCConsole - - Client name - კლიენტი - N/A მიუწვდ. diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 11e5d35af..012632c0e 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -925,10 +925,6 @@ RPCConsole - - Client name - 클라이언트 이름 - N/A 없음 @@ -1758,14 +1754,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: 열려있거나 -proxy 옵션을 사용하지 않을 시 1) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - 경고: 비정상적으로 많은 블록이 생성되고 있습니다. %d 블록은 마지막 %d에 수신되었습니다 (%d 예측됨) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - 경고: 네트워크 연결을 확인해 주세요. %d 블록은 마지막 %d에 수신되었습니다 (%d 예측됨) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 경고 : 모든 네트워크가 동의해야 하나, 일부 채굴자들에게 문제가 있는 것으로 보입니다. diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index ebaddba7e..dc532fe01 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -443,10 +443,6 @@ RPCConsole - - Client name - Nomen clientis - N/A N/A diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 9e98baa77..1f6cda1f5 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -563,10 +563,6 @@ RPCConsole - - Client name - Kliento pavadinimas - N/A nėra diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index bac587569..38333531e 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -651,10 +651,6 @@ RPCConsole - - Client name - Klienta vārds - N/A N/A diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index e38320ac5..d9ef0d127 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -291,10 +291,6 @@ RPCConsole - - Client name - Клиентийн нэр - N/A Алга Байна diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index b5ffdb2e1..4538fd6e1 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -929,10 +929,6 @@ RPCConsole - - Client name - Klientnavn - N/A - @@ -1746,14 +1742,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Bruk UPnP for lytteport (standardverdi: 1 ved lytting og uten -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Advarsel: Nettverket ser ikke ut til å være enig! Noen minere ser ut til å ha problemer. diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 2b0cded38..781c5a8fd 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Clientnaam - N/A N.v.t. @@ -1870,14 +1866,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - WAARSCHUWING: abnormaal hoog aantal blokken is gegenereerd, %d blokken ontvangen in de laatste %d uren (%d verwacht) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Waarschuwing: Het lijkt erop dat het netwerk geen consensus kan vinden! Sommige delvers lijken problemen te ondervinden. diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 12151a576..535154333 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -427,10 +427,6 @@ RPCConsole - - Client name - Lagyu ning kliente - N/A N/A diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 6d41cbeef..a88e505b3 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Nazwa klienta - N/A NIEDOSTĘPNE @@ -1839,14 +1835,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Use UPnP to map the listening port (default: 1 when listening and no -proxy) Użyj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje i brak -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - UWAGA: nienaturalnie duża liczba wygenerowanych bloków, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - UWAGA: sprawdź swoje połączenie sieciowe, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Ostrzeżenie: Sieć nie wydaje się w pełni zgodna! Niektórzy górnicy wydają się doświadczać problemów. diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index fe9dd6626..294143039 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -114,6 +114,10 @@ &About %1 &About %1 + + Show information about %1 + Mostrar informações sobre %1 + About &Qt Sobre &Qt @@ -571,6 +575,14 @@ Welcome to %1. Bem vindo ao %1 + + As this is the first time the program is launched, you can choose where %1 will store its data. + Como essa é a primeira vez que o programa é executado, você pode escolher onde %1 armazenará seus dados. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + O %1 irá baixar e armazenar uma cópia do block chain do Bitcoin. Pelo menos %2GB de dados serão armazenados neste diretório, e ele crescerá ao longo do tempo. A carteira também será armazenada neste diretório. + Use the default data directory Use o diretório de dados padrão @@ -981,10 +993,6 @@ RPCConsole - - Client name - Nome do cliente - N/A N/A @@ -1009,6 +1017,10 @@ Using BerkeleyDB version Versão do BerkeleyDB + + Datadir + Datadir + Startup time Horário de inicialização @@ -1093,6 +1105,10 @@ User Agent User Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Abrir o arquivo de log de depuração do %1 localizado no diretório atual de dados. Isso pode levar alguns segundos para arquivos de log grandes. + Decrease font size Diminuir o tamanho da fonte @@ -1794,6 +1810,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Não foi possível obter exclusividade de escrita no endereço %s. O %s provavelmente já está sendo executado. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Apaga todas as transações da carteira e somente recupera essas partes da blockchain usando o comando -rescan na inicialização @@ -1802,6 +1822,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuido sob a licença MIT software license. Veja os termos em <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Erro ao carregar %s. Não é permitido habilitar HD em carteiras não-HD pre existentes. + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Erro ao ler arquivo %s! Todas as chaves foram lidas corretamente, mas os dados de transação ou o livro de endereos podem estar faltando ou incorretos. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID) @@ -1810,6 +1838,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + A mediana máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Preço máximo total (in %s) aplicado a uma única transação de carteira ou transação crua; aplicar isto tão baixo pode abortar grandes transações (padrão: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Por favor verifique que a data e o horário de seu computador estão corretos. Se o relógio de seu computador estiver incorreto, %s não funcionarão corretamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Por favor contribua se você entender que %s é útil. Visite %s para mais informações sobre o software. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Define o número de threads de verificação de script (%u a %d, 0 = automático, <0 = número de cores deixados livres, padrão: %d) @@ -1826,14 +1870,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVISO: números estranhamente altos de blocos gerados, %d blocos recebidos nas últimas %d horas (%d esperados) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ATENÇÃO: verifique sua conexão %d blocos recebidos nas últimas %d horas (%d tempo estimado) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Atenção: A rede não parecem concordar plenamente! Alguns mineiros parecem estar enfrentando problemas. diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 16b912dfd..f63bfece6 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -962,10 +962,6 @@ RPCConsole - - Client name - Nome do Cliente - N/A N/D @@ -1811,14 +1807,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizar UPnP para mapear a porta de escuta (predefinição: 1 quando escutar e sem -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - AVISO: gerado um número anormalmente elevado de blocos, %d blocos recebidos nas últimas %d horas (%d esperados) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - AVISO: verifique a sua conexão à rede, %d blocos recebidos nas últimas %d horas (%d esperados) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Aviso: A rede não parece estar completamente de acordo! Parece que alguns mineiros estão com dificuldades técnicas. diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index e6f591aa9..489ed0763 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -913,10 +913,6 @@ RPCConsole - - Client name - Nume client - N/A indisponibil diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 750ea7db6..60f5d5dfa 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -989,10 +989,6 @@ RPCConsole - - Client name - Имя клиента - N/A Н/Д @@ -1109,6 +1105,14 @@ Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. Открыть отладочный лог-файл %1 из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. + + Decrease font size + Уменьшить размер текста + + + Increase font size + Увеличить размер текста + Services Сервисы @@ -1213,6 +1217,10 @@ &Unban Node &Разблокировать узел + + Welcome to the %1 RPC console. + Добро пожаловать в консоль RPC %1. + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Используйте стрелки вверх и вниз для просмотра истории и <b>Ctrl-L</b> для очистки экрана. @@ -1592,6 +1600,10 @@ ShutdownWindow + + %1 is shutting down... + %1 выключается... + Do not shut down the computer until this window disappears. Не выключайте компьютер, пока это окно не исчезнет. @@ -1782,10 +1794,22 @@ Bitcoin Core Bitcoin Core + + The %s developers + Разработчики %s + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + Установлено очень большое значение -fallbackfee! Это комиссия за транзацию, которую вы можете заплатить, если оценка размера комиссии не доступна. + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Невозможно заблокировать каталог данных %s. %s возможно уже работает. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Удалить все транзакции бумажника с возможностью восстановить эти части цепи блоков с помощью -rescan при запуске @@ -1794,6 +1818,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>. + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Ошибка чтения %s! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID) @@ -1802,6 +1830,10 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Всегда разрешать транзакции, полученные от участников из белого списка (по умолчанию: %d) + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Пожалуйста убедитесь в корректности установки времени и даты на вашем компьютере! Если время установлено неверно, %s не будет работать правильно. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d) @@ -1818,14 +1850,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Внимание: похоже, в сети нет полного согласия! Некоторый майнеры, возможно, испытывают проблемы. @@ -1838,6 +1862,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно. + + %s corrupt, salvage failed + %s поврежден, восстановить не удалось + -maxmempool must be at least %d MB -maxmempool должен быть как минимум %d MB @@ -1850,6 +1878,10 @@ Append comment to the user agent string Добавить комментарий к строке пользовательского агента + + Attempt to recover private keys from a corrupt wallet on startup + Попытаться восстановить приватные ключи из повреждённого бумажника при запуске + Block creation options: Параметры создания блоков: @@ -1862,6 +1894,10 @@ Connection options: Параметры подключения: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected БД блоков повреждена @@ -1906,6 +1942,14 @@ Error loading %s Ошибка загрузки %s + + Error loading %s: Wallet corrupted + Ошибка загрузки %s: Бумажник поврежден + + + Error loading %s: Wallet requires newer version of %s + Ошибка загрузки %s: Для бумажника требуется более новая версия %s + Error loading block database Ошибка чтения базы данных блоков @@ -1934,10 +1978,18 @@ Invalid -onion address: '%s' Неверный -onion адрес: '%s' + + Invalid amount for -%s=<amount>: '%s' + Неверная сумма для -%s=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Сбрасывать транзакции из памяти на диск каждые <n> мегабайт (по умолчанию: %u) + + Loading banlist... + Загрузка банлиста... + Location of the auth cookie (default: data dir) Расположение куки входы(по умолчанию: data dir) @@ -1950,6 +2002,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Соединяться только по сети <net> (ipv4, ipv6 или onion) + + Print this help message and exit + Вывести эту справку и выйти + Print version and exit Написать версию и выйти @@ -1962,10 +2018,18 @@ Prune mode is incompatible with -txindex. Режим удаления блоков несовместим с -txindex. + + Rebuild chain state from the currently indexed blocks + Перестроить индекс цепи из текущих индексированных блоков + Set database cache size in megabytes (%d to %d, default: %d) Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d) + + Set maximum block cost (default: %d) + Задать максимальную стоимость блока (по умолчанию: %d) + Set maximum block size in bytes (default: %d) Задать максимальный размер блока в байтах (по умолчанию: %d) @@ -1974,6 +2038,14 @@ Specify wallet file (within data directory) Укажите файл бумажника (внутри каталога данных) + + The source code is available from %s. + Исходный код доступен в %s. + + + Unable to bind to %s on this computer. %s is probably already running. + Невозможно привязаться к %s на этом компьютере. Возможно, %s уже работает. + Unsupported argument -benchmark ignored, use -debug=bench. Неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench. @@ -2006,6 +2078,14 @@ Wallet %s resides outside data directory %s Бумажник %s располагается вне каталога данных %s + + Wallet debugging/testing options: + Параметры отладки/тестирования бумажника: + + + Wallet needed to be rewritten: restart %s to complete + Необходимо перезаписать бумажник, перезапустите %s для завершения операции. + Wallet options: Настройки бумажника: @@ -2306,6 +2386,10 @@ Warning: Unknown block versions being mined! It's possible unknown rules are in effect Внимание: Получена неизвестная версия блока! Возможно неизвестные правила вступили в силу. + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Внимание: Файл бумажника поврежден, данные восстановлены! Оригинальный %s сохранен как %s в %s; Если баланс или транзакции некорректны, вы должны восстановить файл из резервной копии. + (default: %s) (по умолчанию: %s) diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index e2b8a0201..a4f0ebcb4 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -929,10 +929,6 @@ RPCConsole - - Client name - Meno klienta - N/A nie je k dispozícii @@ -1707,14 +1703,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie. - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - VAROVANIE: príliš veľa vygenerovaných blokov; %d prijatých blokov v posledných %d hodinách (očakávaných %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - VAROVANIE: skontrolujte sieťové pripojenie, %d prijatých blokov za posledných %d hodín (očakávané %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varovanie: Javí sa že sieť sieť úplne nesúhlasí! Niektorí mineri zjavne majú ťažkosti. diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 155be7bb2..16ef20ea3 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -869,10 +869,6 @@ RPCConsole - - Client name - Ime odjemalca - N/A Neznano @@ -1566,14 +1562,6 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije. - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave. diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 6361b5ea5..ee46974d8 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - Klientnamn - N/A ej tillgänglig @@ -1882,14 +1878,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Använd UPnP för att mappa den lyssnande porten (förvalt: 1 när lyssning aktiverat och utan -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varning: Nätverket verkar inte vara helt överens! Några miners verkar ha problem. diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index 6878d23fe..921171c54 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -371,10 +371,6 @@ RPCConsole - - Client name - வாடிக்கையாளர் பெயர் - N/A N/A diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index f6ab2ca18..bbd011740 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - İstemci ismi - N/A Mevcut değil @@ -1874,14 +1870,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Uyarı: şebeke tamamen mutabık değil gibi görünüyor! Bazı madenciler sorun yaşıyor gibi görünüyor. diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 668e787a6..a06cc9e09 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -929,10 +929,6 @@ RPCConsole - - Client name - Назва клієнту - N/A Н/Д @@ -1746,14 +1742,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Використовувати UPnP для відображення порту, що прослуховується (типово: 1 при прослуховуванні та за відсутності -proxy) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Увага: Частина мережі використовує інший головний ланцюжок! Деякі добувачі, можливо, зазнають проблем. diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index ce3326297..0062abfc1 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -727,10 +727,6 @@ RPCConsole - - Client name - Мижоз номи - N/A Тўғри келмайди diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 8f467b79c..92a7006d3 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -929,10 +929,6 @@ RPCConsole - - Client name - 客户端名称 - N/A 不可用 @@ -1763,14 +1759,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) 使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - 警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - 警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告:网络似乎并不完全同意!有些矿工似乎遇到了问题。 diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index c71a37ba9..ab56f9679 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -993,10 +993,6 @@ RPCConsole - - Client name - 客戶端軟體名稱 - N/A 未知 @@ -1865,7 +1861,7 @@ Please contribute if you find %s useful. Visit %s for further information about the software. - 如果你覺得 %s 有用,可以捐助我們。關於這個軟體的更多資訊請見 %s。 + 如果你覺得 %s 有用,可以幫助我們。關於這個軟體的更多資訊請見 %s。 Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -1887,14 +1883,6 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) 是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線且沒有指定 -proxy 參數時為 1) - - WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) - 警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個) - - - WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) - 警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個) - Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. 警告: 節點網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。 From 96fa95361f68dd8169fa60e73290afae47445299 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 6 Jul 2016 21:18:38 -0400 Subject: [PATCH 0915/1223] Improve handling of unconnecting headers When processing a headers message that looks like a block announcement, send peer a getheaders if the headers message won't connect. Apply DoS points after too many consecutive unconnecting headers messages. --- src/main.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/main.h | 3 +++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index b86bbda1b..dd71ee551 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -276,6 +276,8 @@ struct CNodeState { CBlockIndex *pindexLastCommonBlock; //! The best header we have sent our peer. CBlockIndex *pindexBestHeaderSent; + //! Length of current-streak of unconnecting headers announcements + int nUnconnectingHeaders; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; //! Since when we're stalling block download progress (in microseconds), or 0. @@ -304,6 +306,7 @@ struct CNodeState { hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; pindexBestHeaderSent = NULL; + nUnconnectingHeaders = 0; fSyncStarted = false; nStallingSince = 0; nDownloadingSince = 0; @@ -5773,6 +5776,35 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } + CNodeState *nodestate = State(pfrom->GetId()); + + // If this looks like it could be a block announcement (nCount < + // MAX_BLOCKS_TO_ANNOUNCE), use special logic for handling headers that + // don't connect: + // - Send a getheaders message in response to try to connect the chain. + // - The peer can send up to MAX_UNCONNECTING_HEADERS in a row that + // don't connect before giving DoS points + // - Once a headers message is received that is valid and does connect, + // nUnconnectingHeaders gets reset back to 0. + if (mapBlockIndex.find(headers[0].hashPrevBlock) == mapBlockIndex.end() && nCount < MAX_BLOCKS_TO_ANNOUNCE) { + nodestate->nUnconnectingHeaders++; + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()); + LogPrint("net", "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n", + headers[0].GetHash().ToString(), + headers[0].hashPrevBlock.ToString(), + pindexBestHeader->nHeight, + pfrom->id, nodestate->nUnconnectingHeaders); + // Set hashLastUnknownBlock for this peer, so that if we + // eventually get the headers - even from a different peer - + // we can use this peer to download. + UpdateBlockAvailability(pfrom->GetId(), headers.back().GetHash()); + + if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) { + Misbehaving(pfrom->GetId(), 20); + } + return true; + } + CBlockIndex *pindexLast = NULL; BOOST_FOREACH(const CBlockHeader& header, headers) { CValidationState state; @@ -5790,6 +5822,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + if (nodestate->nUnconnectingHeaders > 0) { + LogPrint("net", "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->id, nodestate->nUnconnectingHeaders); + } + nodestate->nUnconnectingHeaders = 0; + assert(pindexLast); UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); @@ -5802,7 +5839,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); - CNodeState *nodestate = State(pfrom->GetId()); // If this set of headers is valid and ends in a block with at least as // much work as our tip, download as much as possible. if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { diff --git a/src/main.h b/src/main.h index 7ea570d85..65ae2488f 100644 --- a/src/main.h +++ b/src/main.h @@ -138,6 +138,9 @@ static const bool DEFAULT_FEEFILTER = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; +/** Maximum number of unconnecting headers announcements before DoS score */ +static const int MAX_UNCONNECTING_HEADERS = 10; + static const bool DEFAULT_PEERBLOOMFILTERS = true; struct BlockHasher From e91cf4b210db72ed020612a04b55e9715d8f9831 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 6 Jul 2016 21:19:32 -0400 Subject: [PATCH 0916/1223] Add test for handling of unconnecting headers --- qa/rpc-tests/sendheaders.py | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 6ab17d59b..c3f3180b6 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -63,6 +63,21 @@ e. Announce 16 more headers that build on that fork. Expect: getdata request for 14 more blocks. f. Announce 1 more header that builds on that fork. Expect: no response. + +Part 5: Test handling of headers that don't connect. +a. Repeat 10 times: + 1. Announce a header that doesn't connect. + Expect: getheaders message + 2. Send headers chain. + Expect: getdata for the missing blocks, tip update. +b. Then send 9 more headers that don't connect. + Expect: getheaders message each time. +c. Announce a header that does connect. + Expect: no response. +d. Announce 49 headers that don't connect. + Expect: getheaders message each time. +e. Announce one more that doesn't connect. + Expect: disconnect. ''' class BaseNode(NodeConnCB): @@ -77,6 +92,8 @@ class BaseNode(NodeConnCB): self.last_getdata = None self.sleep_time = 0.05 self.block_announced = False + self.last_getheaders = None + self.disconnected = False def clear_last_announcement(self): with mininode_lock: @@ -127,6 +144,12 @@ class BaseNode(NodeConnCB): def on_pong(self, conn, message): self.last_pong = message + def on_getheaders(self, conn, message): + self.last_getheaders = message + + def on_close(self, conn): + self.disconnected = True + # Test whether the last announcement we received had the # right header or the right inv # inv and headers should be lists of block hashes @@ -178,6 +201,11 @@ class BaseNode(NodeConnCB): self.sync(test_function, timeout) return + def wait_for_getheaders(self, timeout=60): + test_function = lambda: self.last_getheaders != None + self.sync(test_function, timeout) + return + def wait_for_getdata(self, hash_list, timeout=60): if hash_list == []: return @@ -186,6 +214,11 @@ class BaseNode(NodeConnCB): self.sync(test_function, timeout) return + def wait_for_disconnect(self, timeout=60): + test_function = lambda: self.disconnected + self.sync(test_function, timeout) + return + def send_header_for_blocks(self, new_blocks): headers_message = msg_headers() headers_message.headers = [ CBlockHeader(b) for b in new_blocks ] @@ -510,6 +543,78 @@ class SendHeadersTest(BitcoinTestFramework): print("Part 4: success!") + # Now deliver all those blocks we announced. + [ test_node.send_message(msg_block(x)) for x in blocks ] + + print("Part 5: Testing handling of unconnecting headers") + # First we test that receipt of an unconnecting header doesn't prevent + # chain sync. + for i in range(10): + test_node.last_getdata = None + blocks = [] + # Create two more blocks. + for j in range(2): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + # Send the header of the second block -> this won't connect. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[1]]) + test_node.wait_for_getheaders(timeout=1) + test_node.send_header_for_blocks(blocks) + test_node.wait_for_getdata([x.sha256 for x in blocks]) + [ test_node.send_message(msg_block(x)) for x in blocks ] + test_node.sync_with_ping() + assert_equal(int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) + + blocks = [] + # Now we test that if we repeatedly don't send connecting headers, we + # don't go into an infinite loop trying to get them to connect. + MAX_UNCONNECTING_HEADERS = 10 + for j in range(MAX_UNCONNECTING_HEADERS+1): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + + for i in range(1, MAX_UNCONNECTING_HEADERS): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i]]) + test_node.wait_for_getheaders(timeout=1) + + # Next header will connect, should re-set our count: + test_node.send_header_for_blocks([blocks[0]]) + + # Remove the first two entries (blocks[1] would connect): + blocks = blocks[2:] + + # Now try to see how many unconnecting headers we can send + # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS + for i in range(5*MAX_UNCONNECTING_HEADERS - 1): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i%len(blocks)]]) + test_node.wait_for_getheaders(timeout=1) + + # Eventually this stops working. + with mininode_lock: + self.last_getheaders = None + test_node.send_header_for_blocks([blocks[-1]]) + + # Should get disconnected + test_node.wait_for_disconnect() + with mininode_lock: + self.last_getheaders = True + + print("Part 5: success!") + # Finally, check that the inv node never received a getdata request, # throughout the test assert_equal(inv_node.last_getdata, None) From 66668c420a23936cb228737f982ee58c08211071 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 14 Jul 2016 10:30:03 +0200 Subject: [PATCH 0917/1223] [qa] Solve merge conflict of 4324bd237c3147fc153ba5046c211f03e8ac956a --- qa/rpc-tests/p2p-segwit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 9d64c5fe3..b30d41af9 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -306,7 +306,7 @@ class SegWitTest(BitcoinTestFramework): tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptPubKey)) - tx3.wit.vtxinwit.append(CTxinWitness()) + tx3.wit.vtxinwit.append(CTxInWitness()) tx3.wit.vtxinwit[0].scriptWitness.stack = [b'a'*400000] tx3.rehash() self.std_node.test_transaction_acceptance(tx3, True, False, b'no-witness-yet') From 68d7682b9f8c0f548e0a9ef03296320b8ae3960d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 15 Jul 2016 10:33:25 +0200 Subject: [PATCH 0918/1223] [Wallet] ensure CKeyMetadata.hdMasterKeyID will be cleared during SetNull() --- src/wallet/walletdb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index eaa406857..42179f228 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -87,9 +87,8 @@ public: } CKeyMetadata(int64_t nCreateTime_) { - nVersion = CKeyMetadata::CURRENT_VERSION; + SetNull(); nCreateTime = nCreateTime_; - hdKeypath.clear(); } ADD_SERIALIZE_METHODS; @@ -111,6 +110,7 @@ public: nVersion = CKeyMetadata::CURRENT_VERSION; nCreateTime = 0; hdKeypath.clear(); + hdMasterKeyID.SetNull(); } }; From 7945088d413819d8cf1772fd25e0f355c84c64d6 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 15 Jul 2016 10:34:08 +0200 Subject: [PATCH 0919/1223] [Wallet] comsetic non-code changes for the HD feature --- qa/rpc-tests/wallet-hd.py | 4 ++-- src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.h | 6 +++--- src/wallet/walletdb.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index f3ae69e10..c738ee220 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -47,10 +47,10 @@ class WalletHDTest(BitcoinTestFramework): self.nodes[0].generate(101) hd_add = None num_hd_adds = 300 - for _ in range(num_hd_adds): + for i in range(num_hd_adds): hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].validateaddress(hd_add) - assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(_+1)+"'") + assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i+1)+"'") assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f4625743b..960d193e5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2269,7 +2269,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" - " \"masterkeyid\": \"\", (string) the Hash160 of the hd master pubkey\n" + " \"masterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2291,7 +2291,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) - obj.push_back(Pair("masterkeyid",masterKeyID.GetHex())); + obj.push_back(Pair("masterkeyid", masterKeyID.GetHex())); return obj; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d58cb7b0e..e9d669a7d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -577,7 +577,7 @@ private: void SyncMetaData(std::pair); - /* the hd chain data model (external chain counters) */ + /* the HD chain data model (external chain counters) */ CHDChain hdChain; public: @@ -896,10 +896,10 @@ public: bool BackupWallet(const std::string& strDest); - /* Set the hd chain model (chain child index counters) */ + /* Set the HD chain model (chain child index counters) */ bool SetHDChain(const CHDChain& chain, bool memonly); - /* Set the current hd master key (will reset the chain child index counters) */ + /* Set the current HD master key (will reset the chain child index counters) */ bool SetHDMasterKey(const CKey& key); const CHDChain& GetHDChain() { return hdChain; } }; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 42179f228..5addd5c5c 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -41,7 +41,7 @@ enum DBErrors DB_NEED_REWRITE }; -/* simple hd chain data model */ +/* simple HD chain data model */ class CHDChain { public: @@ -79,7 +79,7 @@ public: int nVersion; int64_t nCreateTime; // 0 means unknown std::string hdKeypath; //optional HD/bip32 keypath - CKeyID hdMasterKeyID; //id of the hd masterkey used to derive this key + CKeyID hdMasterKeyID; //id of the HD masterkey used to derive this key CKeyMetadata() { From 8cef5bd58ac33ad4207d00c0696438706e8f035e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 10:56:25 +0200 Subject: [PATCH 0920/1223] mining: Improve `-blockmaxcost` help message One-word replacement to #8354. --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index d127ecd48..509bc45f5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -452,7 +452,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); + strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum BIP141 block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) From e4382fbef56a0e04b0ed834e8b3a3a16f81db149 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 10:12:16 +0000 Subject: [PATCH 0921/1223] qt: periodic translations update --- src/qt/bitcoinstrings.cpp | 3 +- src/qt/locale/bitcoin_de.ts | 4 ++ src/qt/locale/bitcoin_en.ts | 43 +++++++++----------- src/qt/locale/bitcoin_es_MX.ts | 12 ++++++ src/qt/locale/bitcoin_es_UY.ts | 2 +- src/qt/locale/bitcoin_fa.ts | 74 ++++++++++++++++++++++++++++++++-- src/qt/locale/bitcoin_pl.ts | 2 +- src/qt/locale/bitcoin_pt_BR.ts | 4 ++ src/qt/locale/bitcoin_pt_PT.ts | 8 ++++ src/qt/locale/bitcoin_tr.ts | 32 +++++++++++++++ 10 files changed, 153 insertions(+), 31 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 9c5b1e09d..bca5b7282 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -311,9 +311,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of d QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block cost (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum BIP141 block cost (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index f38f4c10f..2708324d1 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -2006,6 +2006,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Nur zu Knoten des Netzwerktyps <net> verbinden (ipv4, ipv6 oder onion) + + Print this help message and exit + Drucke diese Hilfemeldung und beende + Print version and exit Gibt die Versionsnummer aus und beendet das Programm diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index c6f3a4013..79c3e87b2 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1218,12 +1218,12 @@ Amount - + Enter a Bitcoin address (e.g. %1) - + %1 d @@ -2231,22 +2231,22 @@ Options: - + Specify data directory Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands @@ -2296,12 +2296,12 @@ Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) @@ -2686,17 +2686,12 @@ - - Set maximum block cost (default: %d) - - - - + Set maximum block size in bytes (default: %d) - + Specify wallet file (within data directory) Specify wallet file (within data directory) @@ -2766,7 +2761,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -2946,7 +2941,12 @@ - + + Set maximum BIP141 block cost (default: %d) + + + + Show all debugging options (usage: --help -help-debug) @@ -3041,7 +3041,7 @@ - + Password for JSON-RPC connections Password for JSON-RPC connections @@ -3227,11 +3227,6 @@ - Set minimum block size in bytes (default: %u) - - - - Set the number of threads to service RPC calls (default: %d) @@ -3266,7 +3261,7 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 26432190a..0a6ea1e1d 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -44,6 +44,10 @@ AskPassphraseDialog + + Passphrase Dialog + Dialogo de contraseña + Enter passphrase Ingrese la contraseña @@ -59,6 +63,10 @@ BanTableModel + + IP/Netmask + IP/Máscara de red + BitcoinGUI @@ -178,6 +186,10 @@ &Receive &Recibir + + &Show / Hide + &Mostrar / Ocultar + &File &Archivo diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 8d361620d..c565a63cd 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -108,7 +108,7 @@ Send coins to a Bitcoin address - Enviar monedas a una dirección BItCoin + Enviar monedas a una dirección Bitcoin Change the passphrase used for wallet encryption diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 8bf727a0c..98543ded4 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -67,7 +67,11 @@ IP/Netmask آی‌پی/نت‌ماسک - + + Banned Until + مسدود شده تا + + BitcoinGUI @@ -110,6 +114,10 @@ &About %1 &حدود%1 + + Show information about %1 + نمایش اطلاعات دربارهٔ %1 + About &Qt دربارهٔ &کیوت @@ -510,6 +518,10 @@ OpenURIDialog + + Open URI + بازکردن آدرس + OptionsDialog @@ -525,6 +537,10 @@ Accept connections from outside پذیرش اتصالات از بیرون + + Allow incoming connections + اجازه دادن به اتصالات دریافتی + Reset all client options to default. بازنشانی تمام تنظیمات به پیش‌فرض. @@ -691,7 +707,11 @@ PeerTableModel - + + Ping Time + زمان پینگ + + QObject @@ -797,6 +817,14 @@ Last Receive آخرین دریافتی + + Ping Time + زمان پینگ + + + Ping Wait + انتظار پینگ + Last block time زمان آخرین بلوک @@ -833,6 +861,22 @@ Type <b>help</b> for an overview of available commands. برای نمایش یک مرور کلی از دستورات ممکن، عبارت <b>help</b> را بنویسید. + + %1 B + %1 بایت + + + %1 KB + %1 کیلوبایت + + + %1 MB + %1 مگابایت + + + %1 GB + %1 گیگابایت + never هرگز @@ -887,7 +931,11 @@ Copy &Address &کپی نشانی - + + &Save Image... + &ذخیره عکس... + + SendCoinsDialog @@ -934,6 +982,18 @@ Hide پنهان کردن + + Recommended: + توصیه شده: + + + Custom: + سفارشی: + + + Confirmation time: + روز تایید: + normal نرمال @@ -1024,6 +1084,10 @@ ShutdownWindow + + %1 is shutting down... + %1 در حال خاموش شدن است... + SignVerifyMessageDialog @@ -1250,6 +1314,10 @@ Wallet options: گزینه‌های کیف پول: + + (default: %u) + (پیش‌فرض %u) + Information اطلاعات diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index a88e505b3..09f748b83 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -300,7 +300,7 @@ %1 behind - %1 wstecz + %1 za Last received block was generated %1 ago. diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 294143039..ee48c6734 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1894,6 +1894,10 @@ Append comment to the user agent string Adiciona comentário ao user-agent do navegador + + Attempt to recover private keys from a corrupt wallet on startup + Tentando recuperar a chape privada da carteira corrompida ao inicializar + Block creation options: Opções de criação de blocos: diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index f63bfece6..eed262e01 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -617,6 +617,10 @@ &Main &Principal + + Automatically start %1 after logging in to the system. + Começar o %1 automaticamente ao iniciar a sessão no sistema. + &Start %1 on system login &Iniciar o %1 no início de sessão do sistema @@ -1831,6 +1835,10 @@ Append comment to the user agent string Anexar um comentário para a entrada de agente do utilizador + + Attempt to recover private keys from a corrupt wallet on startup + Tentar reuperar as chaves privadas de um "wallet" ao iniciar + Block creation options: Opções da criação de bloco: diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index bbd011740..e3a811b50 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1830,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + %s yüklenmesinde hata: zaten var olan ve HD olmayan bir cüzdanda HD etkinleştirilemez. + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. %s dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. @@ -1854,6 +1858,10 @@ Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontrol ediniz! Saatinizde gecikme varsa %s doğru şekilde çalışamaz. + + Please contribute if you find %s useful. Visit %s for further information about the software. + %s programını faydalı buluyorsanız lütfen katkıda bulununuz. Yazılım hakkında daha fazla bilgi için %s adresini ziyaret ediniz. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) @@ -1866,6 +1874,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Veritabanını çatallama öncesi duruma geri sarmak mümkün değil. Blok zincirini tekrar indirmeniz gerekmektedir + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) @@ -1986,6 +1998,10 @@ Error loading %s: Wallet requires newer version of %s %s unsurunun yüklenmesinde hata oluştu: cüzdan %s programının yeni bir sürümüne ihtiyaç duyuyor + + Error loading %s: You can't disable HD on a already existing HD wallet + %s yüklenmesinde hata: zaten var olan HD bir cüzdanda HD devre dışı bırakılamaz. + Error loading block database Blok veritabanının yüklenmesinde hata @@ -2074,10 +2090,18 @@ Rebuild chain state from the currently indexed blocks Zincir durumunu güncel olarak endekslenen bloklardan yeniden derle + + Rewinding blocks... + Bloklar geri sarılıyor... + Set database cache size in megabytes (%d to %d, default: %d) Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d) + + Set maximum block cost (default: %d) + Azami blok maliyetini ayarla (varsayılan: %d) + Set maximum block size in bytes (default: %d) Azami blok boyutunu bayt olarak ayarla (varsayılan: %d) @@ -2086,6 +2110,10 @@ Specify wallet file (within data directory) Cüzdan dosyası belirtiniz (veri klasörünün içinde) + + The source code is available from %s. + Kaynak kod şuradan elde edilebilir: %s. + Unable to bind to %s on this computer. %s is probably already running. Bu bilgisayarda %s unsuruna bağlanılamadı. %s muhtemelen hâlihazırda çalışmaktadır. @@ -2198,6 +2226,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Bu ürün OpenSSL projesi tarafından OpenSSL araç takımı (http://www.openssl.org/) için geliştirilen yazılımlar, Eric Young (eay@cryptsoft.com) tarafından hazırlanmış şifreleme yazılımları ve Thomas Bernard tarafından programlanmış UPnP yazılımı içerir. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + BIP32'den sonra hiyerarşik determinist (HD) anahtar üretimini kullan. Sadece cüzdan oluşturulmasında/ilk başlamada etkiye sahiptir. + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve muameleleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır From 084d1ddf8fbfaf153e0ef4f47b4049d60de60c12 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 12:17:57 +0200 Subject: [PATCH 0922/1223] build: bump version to 0.13.0 --- configure.ac | 6 +++--- doc/Doxyfile | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- src/clientversion.h | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 011af6bd1..19861d24c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 12) -define(_CLIENT_VERSION_REVISION, 99) +define(_CLIENT_VERSION_MINOR, 13) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 0) -define(_CLIENT_VERSION_IS_RELEASE, false) +define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2016) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]]) diff --git a/doc/Doxyfile b/doc/Doxyfile index 428fba98e..93da55fbb 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.12.99 +PROJECT_NUMBER = 0.13.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index c30f29452..7aa82e1d5 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.12.99 +Bitcoin Core 0.13.0 ===================== Setup diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 2d1c4503c..3f41db14b 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.12.99 +Bitcoin Core 0.13.0 ===================== Intro diff --git a/src/clientversion.h b/src/clientversion.h index 47263d534..30f557526 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -15,12 +15,12 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 12 -#define CLIENT_VERSION_REVISION 99 +#define CLIENT_VERSION_MINOR 13 +#define CLIENT_VERSION_REVISION 0 #define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build -#define CLIENT_VERSION_IS_RELEASE false +#define CLIENT_VERSION_IS_RELEASE true /** * Copyright year (2009-this) From 37269105c8817a2922410ec17d976263cd589987 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 14:08:43 +0200 Subject: [PATCH 0923/1223] build: Release notes update Fill in the header, and move items to the appropriate part of the release notes structure. --- doc/release-notes.md | 144 +++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 68 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3d2baaaae..1b69daf37 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,9 +1,6 @@ -(note: this is a temporary file, to be added-to by anybody, and moved to -release-notes at release time) +Bitcoin Core version 0.13.0 is now available from: -Bitcoin Core version *version* is now available from: - - + This is a new major version release, including new features, various bugfixes and performance improvements, as well as updated translations. @@ -70,18 +67,6 @@ It is recommended to use this for sensitive information such as wallet passphrases, as command-line arguments can usually be read from the process table by any user on the system. -RPC low-level changes ----------------------- - -- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between - 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been - fixed, but this means that the output will be different than from previous versions. - -- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, - wallet labels have always been malformed because they weren't taken into account - properly in JSON RPC processing. This is no longer the case. This also affects - the GUI debug console. - C++11 and Python 3 ------------------- @@ -115,33 +100,6 @@ possible to resolve them. Note that Android is not considered ARM Linux in this context. The executables are not expected to work out of the box on Android. -0.13.0 Change log -================= - -Detailed release notes follow. This overview includes changes that affect -behavior, not code moves, refactors and string updates. For convenience in locating -the code changes and accompanying discussion, both the pull request and -git merge commit are mentioned. - -### RPC and REST - -Asm script outputs replacements for OP_NOP2 and OP_NOP3 -------------------------------------------------------- - -OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP -65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) - -OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP -112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) - -The following outputs are affected by this change: -- RPC `getrawtransaction` (in verbose mode) -- RPC `decoderawtransaction` -- RPC `decodescript` -- REST `/rest/tx/` (JSON format) -- REST `/rest/block/` (JSON format when including extended tx details) -- `bitcoin-tx -json` - New mempool information RPC calls --------------------------------- @@ -149,24 +107,6 @@ RPC calls have been added to output detailed statistics for individual mempool entries, as well as to calculate the in-mempool ancestors or descendants of a transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. -### ZMQ - -Each ZMQ notification now contains an up-counting sequence number that allows -listeners to detect lost notifications. -The sequence number is always the last element in a multi-part ZMQ notification and -therefore backward compatible. -Each message type has its own counter. -(https://github.com/bitcoin/bitcoin/pull/7762) - -### Configuration and command-line options - -### Block and transaction handling - -### P2P protocol and network code - -The p2p alert system has been removed in #7692 and the 'alert' message is no longer supported. - - Fee filtering of invs (BIP 133) ------------------------------------ @@ -175,12 +115,6 @@ version is bumped to 70013. Upon receiving a feefilter message from a peer, a node will not send invs for any transactions which do not meet the filter feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) -### Validation - -### Build system - -### Wallet - Hierarchical Deterministic Key Generation ----------------------------------------- Newly created wallets will use hierarchical deterministic key generation @@ -199,9 +133,83 @@ There is no distinction between internal (change) and external keys. [Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) +Low-level P2P changes +---------------------- + +- The P2P alert system has been removed in PR #7692 and the `alert` P2P message + is no longer supported. + +Low-level RPC changes +---------------------- + +- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between + 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been + fixed, but this means that the output will be different than from previous versions. + +- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, + wallet labels have always been malformed because they weren't taken into account + properly in JSON RPC processing. This is no longer the case. This also affects + the GUI debug console. + +- Asm script outputs replacements for OP_NOP2 and OP_NOP3 + + - OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP +65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) + + - OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP +112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) + + - The following outputs are affected by this change: + + - RPC `getrawtransaction` (in verbose mode) + - RPC `decoderawtransaction` + - RPC `decodescript` + - REST `/rest/tx/` (JSON format) + - REST `/rest/block/` (JSON format when including extended tx details) + - `bitcoin-tx -json` + +Low-level ZMQ changes +---------------------- + +- Each ZMQ notification now contains an up-counting sequence number that allows + listeners to detect lost notifications. + The sequence number is always the last element in a multi-part ZMQ notification and + therefore backward compatible. Each message type has its own counter. + PR [#7762](https://github.com/bitcoin/bitcoin/pull/7762). + +0.13.0 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### RPC and REST + +### ZMQ + +### Configuration and command-line options + +### Block and transaction handling + +### P2P protocol and network code + +### Validation + +### Build system + +### Wallet + ### GUI ### Tests ### Miscellaneous +Credits +======= + +Thanks to everyone who directly contributed to this release: + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From df854637b14e17adfb70f57aa2c4ea5d066ddeb0 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 18 Jul 2016 16:02:37 +0200 Subject: [PATCH 0924/1223] Some 0.13 release notes about p2p changes --- doc/release-notes.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 1b69daf37..93c501e58 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -115,6 +115,17 @@ version is bumped to 70013. Upon receiving a feefilter message from a peer, a node will not send invs for any transactions which do not meet the filter feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) +Compact Block support (BIP 152) +------------------------------- + +Support for block relay using the Compact Blocks protocol has been implemented +in PR 8068. + +The primary goal is reducing the bandwidth spikes at relay time, though in many +cases it also reduces propagation relay. It is automatically enabled between +compatible peers. +[BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) + Hierarchical Deterministic Key Generation ----------------------------------------- Newly created wallets will use hierarchical deterministic key generation @@ -139,6 +150,28 @@ Low-level P2P changes - The P2P alert system has been removed in PR #7692 and the `alert` P2P message is no longer supported. +- The transaction relay mechanism used to relay one quarter of all transactions + instantly, while queueing up the rest and sending them out in batch. As + this resulted in chains of dependent transactions being reordered, it + systematically hurt transaction relay. The relay code was redesigned in PRs + #7840 and #8082, and now always batches transactions announcements while also + sorting them according to dependency order. This significantly reduces orphan + transactions. To compensate for the removal of instant relay, the frequency of + batch sending was doubled for outgoing peers. + +- Since PR 7840 the BIP35 mempool command is also subject to batch processing. + +- The maximum size of orphan transactions that are kept in memory until their + ancestors arrive has been raised in PR 8179 from 5000 to 99999 bytes. They + are now also removed from memory when they are included in a block, conflict + with a block, and time out after 20 minutes. + +- We respond at most once to a getaddr request during the lifetime of a + connection since PR 7856. + +- Connections to peers who have recently been the first one to give us a valid + new block or transaction are protected from disconnections since PR 8084. + Low-level RPC changes ---------------------- From 3b38a6a96a955d7b0192ece6ddcc7d750e155d81 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 15 Jul 2016 11:42:47 +0200 Subject: [PATCH 0925/1223] [Wallet] Ensure <0.13 clients can't open HD wallets --- doc/release-notes.md | 2 ++ src/wallet/wallet.cpp | 3 +++ src/wallet/wallet.h | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 1b69daf37..b0efd9b63 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -131,6 +131,8 @@ You can't disable HD key generation once you have created a HD wallet. There is no distinction between internal (change) and external keys. +HD wallets are incompatible with older versions of Bitcoin Core. + [Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) Low-level P2P changes diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 46ed54215..ae0a546ea 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3299,6 +3299,9 @@ bool CWallet::InitLoadWallet() key.MakeNewKey(true); if (!walletInstance->SetHDMasterKey(key)) throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); + + // ensure this wallet.dat can only be opened by clients supporting HD + walletInstance->SetMinVersion(FEATURE_HD); } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index e9d669a7d..3a3cb6d85 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -78,7 +78,8 @@ enum WalletFeature FEATURE_WALLETCRYPT = 40000, // wallet encryption FEATURE_COMPRPUBKEY = 60000, // compressed public keys - FEATURE_LATEST = 60000 + FEATURE_HD = 130000, // Hierarchical key derivation after BIP32 (HD Wallet) + FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version }; From ded0599281fccc3523e676e9fa43ad631f8ca25f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 15:21:38 +0200 Subject: [PATCH 0926/1223] doc: Add a few items to release notes Do a few TODOs from #7678: - Removal of internal miner - `mempool`/`NODE_BLOOM` interaction - Sorting of `getrawmempool` output --- doc/release-notes.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 93c501e58..09b3d47cb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -144,6 +144,20 @@ There is no distinction between internal (change) and external keys. [Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) +Removal of internal miner +-------------------------- + +As CPU mining has been useless for a long time, the internal miner has been +removed in this release, and replaced with a simpler implementation for the +test framework. + +The overall result of this is that `setgenerate` RPC call has been removed, as +well as the `-gen` and `-genproclimit` command-line options. + +For testing, the `generate` call can still be used to mine a block, and a new +RPC call `generatetoaddress` has been added to mine to a specific address. This +works with wallet disabled. + Low-level P2P changes ---------------------- @@ -159,18 +173,20 @@ Low-level P2P changes transactions. To compensate for the removal of instant relay, the frequency of batch sending was doubled for outgoing peers. -- Since PR 7840 the BIP35 mempool command is also subject to batch processing. +- Since PR #7840 the BIP35 `mempool` command is also subject to batch processing. + Also the `mempool` message is no longer handled for non-whitelisted peers when + `NODE_BLOOM` is disabled through `-peerbloomfilters=0`. - The maximum size of orphan transactions that are kept in memory until their - ancestors arrive has been raised in PR 8179 from 5000 to 99999 bytes. They + ancestors arrive has been raised in PR #8179 from 5000 to 99999 bytes. They are now also removed from memory when they are included in a block, conflict with a block, and time out after 20 minutes. - We respond at most once to a getaddr request during the lifetime of a - connection since PR 7856. + connection since PR #7856. - Connections to peers who have recently been the first one to give us a valid - new block or transaction are protected from disconnections since PR 8084. + new block or transaction are protected from disconnections since PR #8084. Low-level RPC changes ---------------------- @@ -201,6 +217,8 @@ Low-level RPC changes - REST `/rest/block/` (JSON format when including extended tx details) - `bitcoin-tx -json` +- The sorting of the output of the `getrawmempool` output has changed. + Low-level ZMQ changes ---------------------- From fca1a415cec6b7655448ce8b30778784ab4c181e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 18 Jul 2016 13:28:26 -0400 Subject: [PATCH 0927/1223] Rename "block cost" to "block weight" Github-Pull: #8363 Rebased-From: 2c06bae39edfaa9c0855d83377ad8fda09e4fa08 --- qa/rpc-tests/p2p-segwit.py | 6 ++--- src/consensus/consensus.h | 4 ++-- src/init.cpp | 2 +- src/main.cpp | 12 +++++----- src/main.h | 2 +- src/miner.cpp | 42 +++++++++++++++++----------------- src/miner.h | 4 ++-- src/policy/policy.cpp | 10 ++++---- src/policy/policy.h | 12 +++++----- src/primitives/block.cpp | 6 ++--- src/primitives/block.h | 4 ++-- src/primitives/transaction.cpp | 4 ++-- src/primitives/transaction.h | 4 ++-- src/rpc/blockchain.cpp | 4 ++-- src/rpc/mining.cpp | 12 +++++----- src/txmempool.cpp | 4 ++-- src/txmempool.h | 4 ++-- src/wallet/wallet.cpp | 2 +- 18 files changed, 69 insertions(+), 69 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index b30d41af9..fa2c5d1f0 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -1065,12 +1065,12 @@ class SegWitTest(BitcoinTestFramework): assert_equal(wit_block.serialize(False), non_wit_block.serialize()) assert_equal(wit_block.serialize(True), block.serialize(True)) - # Test size, vsize, cost + # Test size, vsize, weight rpc_details = self.nodes[0].getblock(block.hash, True) assert_equal(rpc_details["size"], len(block.serialize(True))) assert_equal(rpc_details["strippedsize"], len(block.serialize(False))) - cost = 3*len(block.serialize(False)) + len(block.serialize(True)) - assert_equal(rpc_details["cost"], cost) + weight = 3*len(block.serialize(False)) + len(block.serialize(True)) + assert_equal(rpc_details["weight"], weight) # Upgraded node should not ask for blocks from unupgraded block4 = self.build_next_block(nVersion=4) diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 81f40593b..690856586 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -10,8 +10,8 @@ /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; -/** The maximum allowed cost for a block, see BIP 141 (network rule) */ -static const unsigned int MAX_BLOCK_COST = 4000000; +/** The maximum allowed weight for a block, see BIP 141 (network rule) */ +static const unsigned int MAX_BLOCK_WEIGHT = 4000000; /** The maximum allowed size for a block excluding witness data, in bytes (network rule) */ static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000; /** The maximum allowed number of signature check operations in a block (network rule) */ diff --git a/src/init.cpp b/src/init.cpp index 509bc45f5..312dfe169 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -452,7 +452,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum BIP141 block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); + strUsage += HelpMessageOpt("-blockmaxweight=", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) diff --git a/src/main.cpp b/src/main.cpp index 73fbe53af..fe19895f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -694,8 +694,8 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // have been mined or received. // 100 orphans, each of which is at most 99,999 bytes big is // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): - unsigned int sz = GetTransactionCost(tx); - if (sz >= MAX_STANDARD_TX_COST) + unsigned int sz = GetTransactionWeight(tx); + if (sz >= MAX_STANDARD_TX_WEIGHT) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; @@ -3596,13 +3596,13 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } // After the coinbase witness nonce and commitment are verified, - // we can check if the block cost passes (before we've checked the - // coinbase witness, it would be possible for the cost to be too + // we can check if the block weight passes (before we've checked the + // coinbase witness, it would be possible for the weight to be too // large by filling up the coinbase witness, which doesn't change // the block hash, so we couldn't mark the block as permanently // failed). - if (GetBlockCost(block) > MAX_BLOCK_COST) { - return state.DoS(100, error("ContextualCheckBlock(): cost limit failed"), REJECT_INVALID, "bad-blk-cost"); + if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) { + return state.DoS(100, error("ContextualCheckBlock(): weight limit failed"), REJECT_INVALID, "bad-blk-weight"); } return true; diff --git a/src/main.h b/src/main.h index 65ae2488f..27121890f 100644 --- a/src/main.h +++ b/src/main.h @@ -155,7 +155,7 @@ typedef boost::unordered_map BlockMap; extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockSize; -extern uint64_t nLastBlockCost; +extern uint64_t nLastBlockWeight; extern const std::string strMessageMagic; extern CWaitableCriticalSection csBestBlock; extern CConditionVariable cvBlockChange; diff --git a/src/miner.cpp b/src/miner.cpp index 8153fb9f9..25a5becf9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -45,7 +45,7 @@ using namespace std; uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; -uint64_t nLastBlockCost = 0; +uint64_t nLastBlockWeight = 0; class ScoreCompare { @@ -77,30 +77,30 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) : chainparams(_chainparams) { // Block resource limits - // If neither -blockmaxsize or -blockmaxcost is given, limit to DEFAULT_BLOCK_MAX_* + // If neither -blockmaxsize or -blockmaxweight is given, limit to DEFAULT_BLOCK_MAX_* // If only one is given, only restrict the specified resource. // If both are given, restrict both. - nBlockMaxCost = DEFAULT_BLOCK_MAX_COST; + nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; - bool fCostSet = false; - if (mapArgs.count("-blockmaxcost")) { - nBlockMaxCost = GetArg("-blockmaxcost", DEFAULT_BLOCK_MAX_COST); + bool fWeightSet = false; + if (mapArgs.count("-blockmaxweight")) { + nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; - fCostSet = true; + fWeightSet = true; } if (mapArgs.count("-blockmaxsize")) { nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - if (!fCostSet) { - nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR; + if (!fWeightSet) { + nBlockMaxWeight = nBlockMaxSize * WITNESS_SCALE_FACTOR; } } - // Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity: - nBlockMaxCost = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_COST-4000), nBlockMaxCost)); + // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: + nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_WEIGHT-4000), nBlockMaxWeight)); // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize)); - // Whether we need to account for byte usage (in addition to cost usage) + // Whether we need to account for byte usage (in addition to weight usage) fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000); } @@ -110,7 +110,7 @@ void BlockAssembler::resetBlock() // Reserve space for coinbase tx nBlockSize = 1000; - nBlockCost = 4000; + nBlockWeight = 4000; nBlockSigOpsCost = 400; fIncludeWitness = false; @@ -167,7 +167,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - nLastBlockCost = nBlockCost; + nLastBlockWeight = nBlockWeight; LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOpsCost); // Create coinbase transaction. @@ -223,8 +223,8 @@ void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) { - // TODO: switch to cost-based accounting for packages instead of vsize-based accounting. - if (nBlockCost + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxCost) + // TODO: switch to weight-based accounting for packages instead of vsize-based accounting. + if (nBlockWeight + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxWeight) return false; if (nBlockSigOpsCost + packageSigOpsCost >= MAX_BLOCK_SIGOPS_COST) return false; @@ -257,17 +257,17 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { - if (nBlockCost + iter->GetTxCost() >= nBlockMaxCost) { + if (nBlockWeight + iter->GetTxWeight() >= nBlockMaxWeight) { // If the block is so close to full that no more txs will fit // or if we've tried more than 50 times to fill remaining space // then flag that the block is finished - if (nBlockCost > nBlockMaxCost - 400 || lastFewTxs > 50) { + if (nBlockWeight > nBlockMaxWeight - 400 || lastFewTxs > 50) { blockFinished = true; return false; } - // Once we're within 4000 cost of a full block, only look at 50 more txs + // Once we're within 4000 weight of a full block, only look at 50 more txs // to try to fill the remaining space. - if (nBlockCost > nBlockMaxCost - 4000) { + if (nBlockWeight > nBlockMaxWeight - 4000) { lastFewTxs++; } return false; @@ -315,7 +315,7 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) if (fNeedSizeAccounting) { nBlockSize += ::GetSerializeSize(iter->GetTx(), SER_NETWORK, PROTOCOL_VERSION); } - nBlockCost += iter->GetTxCost(); + nBlockWeight += iter->GetTxWeight(); ++nBlockTx; nBlockSigOpsCost += iter->GetSigOpCost(); nFees += iter->GetFee(); diff --git a/src/miner.h b/src/miner.h index d16e37bb5..11753f5e4 100644 --- a/src/miner.h +++ b/src/miner.h @@ -141,11 +141,11 @@ private: // Configuration parameters for the block size bool fIncludeWitness; - unsigned int nBlockMaxCost, nBlockMaxSize; + unsigned int nBlockMaxWeight, nBlockMaxSize; bool fNeedSizeAccounting; // Information on the current status of the block - uint64_t nBlockCost; + uint64_t nBlockWeight; uint64_t nBlockSize; uint64_t nBlockTx; uint64_t nBlockSigOpsCost; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index f2148bfe1..8617db00c 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -64,8 +64,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. - unsigned int sz = GetTransactionCost(tx); - if (sz >= MAX_STANDARD_TX_COST) { + unsigned int sz = GetTransactionWeight(tx); + if (sz >= MAX_STANDARD_TX_WEIGHT) { reason = "tx-size"; return false; } @@ -151,12 +151,12 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -int64_t GetVirtualTransactionSize(int64_t nCost) +int64_t GetVirtualTransactionSize(int64_t nWeight) { - return (nCost + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + return (nWeight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; } int64_t GetVirtualTransactionSize(const CTransaction& tx) { - return GetVirtualTransactionSize(GetTransactionCost(tx)); + return GetVirtualTransactionSize(GetTransactionWeight(tx)); } diff --git a/src/policy/policy.h b/src/policy/policy.h index 29a8cc57c..f5f8652fb 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -18,10 +18,10 @@ class CCoinsViewCache; static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; -/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/ -static const unsigned int DEFAULT_BLOCK_MAX_COST = 3000000; -/** The maximum size for transactions we're willing to relay/mine */ -static const unsigned int MAX_STANDARD_TX_COST = 400000; +/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/ +static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = 3000000; +/** The maximum weight for transactions we're willing to relay/mine */ +static const unsigned int MAX_STANDARD_TX_WEIGHT = 400000; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ @@ -66,8 +66,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason); */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); -/** Compute the virtual transaction size (cost reinterpreted as bytes). */ -int64_t GetVirtualTransactionSize(int64_t nCost); +/** Compute the virtual transaction size (weight reinterpreted as bytes). */ +int64_t GetVirtualTransactionSize(int64_t nWeight); int64_t GetVirtualTransactionSize(const CTransaction& tx); #endif // BITCOIN_POLICY_POLICY_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index df900388f..0e6ab4dd7 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -32,11 +32,11 @@ std::string CBlock::ToString() const return s.str(); } -int64_t GetBlockCost(const CBlock& block) +int64_t GetBlockWeight(const CBlock& block) { - // This implements the cost = (stripped_size * 4) + witness_size formula, + // This implements the weight = (stripped_size * 4) + witness_size formula, // using only serialization with and without witness data. As witness_size // is equal to total_size - stripped_size, this formula is identical to: - // cost = (stripped_size * 3) + total_size. + // weight = (stripped_size * 3) + total_size. return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); } diff --git a/src/primitives/block.h b/src/primitives/block.h index e2a309e63..72dfed985 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -154,7 +154,7 @@ struct CBlockLocator } }; -/** Compute the consensus-critical block cost (see BIP 141). */ -int64_t GetBlockCost(const CBlock& tx); +/** Compute the consensus-critical block weight (see BIP 141). */ +int64_t GetBlockWeight(const CBlock& tx); #endif // BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 7f10409c0..8d6380564 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -121,7 +121,7 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const // Providing any more cleanup incentive than making additional inputs free would // risk encouraging people to create junk outputs to redeem later. if (nTxSize == 0) - nTxSize = (GetTransactionCost(*this) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + nTxSize = (GetTransactionWeight(*this) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; for (std::vector::const_iterator it(vin.begin()); it != vin.end(); ++it) { unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); @@ -149,7 +149,7 @@ std::string CTransaction::ToString() const return str; } -int64_t GetTransactionCost(const CTransaction& tx) +int64_t GetTransactionWeight(const CTransaction& tx) { return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR -1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); } diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 8a2d5dd22..d37890667 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -459,7 +459,7 @@ struct CMutableTransaction uint256 GetHash() const; }; -/** Compute the cost of a transaction, as defined by BIP 141 */ -int64_t GetTransactionCost(const CTransaction &tx); +/** Compute the weight of a transaction, as defined by BIP 141 */ +int64_t GetTransactionWeight(const CTransaction &tx); #endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 20eefa1c5..9dc896b7a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -101,7 +101,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("cost", (int)::GetBlockCost(block))); + result.push_back(Pair("weight", (int)::GetBlockWeight(block))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); @@ -559,7 +559,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" - " \"cost\" : n (numeric) The block cost\n" + " \"weight\" : n (numeric) The block weight (BIP 141)\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 4c4e59978..92ca4bab6 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -224,7 +224,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) "{\n" " \"blocks\": nnn, (numeric) The current block\n" " \"currentblocksize\": nnn, (numeric) The last block size\n" - " \"currentblockcost\": nnn, (numeric) The last block cost\n" + " \"currentblockweight\": nnn, (numeric) The last block weight\n" " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" @@ -243,7 +243,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblockcost", (uint64_t)nLastBlockCost)); + obj.push_back(Pair("currentblockweight", (uint64_t)nLastBlockWeight)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); @@ -358,7 +358,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" - " \"cost\" : n, (numeric) total transaction size cost, as counted for purposes of block limits\n" + " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" " }\n" " ,...\n" @@ -377,7 +377,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n" " \"sigoplimit\" : n, (numeric) cost limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" - " \"costlimit\" : n, (numeric) limit of block cost\n" + " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" @@ -575,7 +575,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) int index_in_template = i - 1; entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); entry.push_back(Pair("sigops", pblocktemplate->vTxSigOpsCost[index_in_template])); - entry.push_back(Pair("cost", GetTransactionCost(tx))); + entry.push_back(Pair("weight", GetTransactionWeight(tx))); transactions.push_back(entry); } @@ -659,7 +659,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("noncerange", "00000000ffffffff")); result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_COST)); result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); - result.push_back(Pair("costlimit", (int64_t)MAX_BLOCK_COST)); + result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a48a6d946..691baa674 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -28,7 +28,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) { - nTxCost = GetTransactionCost(_tx); + nTxWeight = GetTransactionWeight(_tx); nModSize = _tx.CalculateModifiedSize(GetTxSize()); nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); @@ -75,7 +75,7 @@ void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp) size_t CTxMemPoolEntry::GetTxSize() const { - return GetVirtualTransactionSize(nTxCost); + return GetVirtualTransactionSize(nTxWeight); } // Update the given tx for any in-mempool descendants. diff --git a/src/txmempool.h b/src/txmempool.h index e5a500e19..2c2127f32 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -78,7 +78,7 @@ class CTxMemPoolEntry private: std::shared_ptr tx; CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups - size_t nTxCost; //!< ... and avoid recomputing tx cost (also used for GetTxSize()) + size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) size_t nModSize; //!< ... and modified size for priority size_t nUsageSize; //!< ... and total memory usage int64_t nTime; //!< Local time when entering the mempool @@ -122,7 +122,7 @@ public: double GetPriority(unsigned int currentHeight) const; const CAmount& GetFee() const { return nFee; } size_t GetTxSize() const; - size_t GetTxCost() const { return nTxCost; } + size_t GetTxWeight() const { return nTxWeight; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return entryHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 46ed54215..4b6d98025 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2356,7 +2356,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt *static_cast(&wtxNew) = CTransaction(txNew); // Limit size - if (GetTransactionCost(txNew) >= MAX_STANDARD_TX_COST) + if (GetTransactionWeight(txNew) >= MAX_STANDARD_TX_WEIGHT) { strFailReason = _("Transaction too large"); return false; From ec8f5fc8b5f68ddf7fed0d74a5ec82e6b03f7f92 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 19 Jul 2016 12:23:55 +0200 Subject: [PATCH 0928/1223] doc: Add list of pulls and authors to release notes --- doc/release-notes.md | 477 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 469 insertions(+), 8 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 1d358cbfd..c631c66c0 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -220,31 +220,492 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -### RPC and REST +### RPC and other APIs -### ZMQ - -### Configuration and command-line options +- #7156 `9ee02cf` Remove cs_main lock from `createrawtransaction` (laanwj) +- #7326 `2cd004b` Fix typo, wrong information in gettxout help text (paveljanik) +- #7222 `82429d0` Indicate which transactions are signaling opt-in RBF (sdaftuar) +- #7480 `b49a623` Changed getnetworkhps value to double to avoid overflow (instagibbs) +- #7550 `8b958ab` Input-from-stdin mode for bitcoin-cli (laanwj) +- #7670 `c9a1265` Use cached block hash in blockToJSON() (rat4) +- #7726 `9af69fa` Correct importaddress help reference to importpubkey (CypherGrue) +- #7766 `16555b6` Register calls where they are defined (laanwj) +- #7797 `e662a76` Fix generatetoaddress failing to parse address (mruddy) +- #7774 `916b15a` Add versionHex in getblock and getblockheader JSON results (mruddy) +- #7863 `72c54e3` Getblockchaininfo: make bip9_softforks an object, not an array (rustyrussell) +- #7842 `d97101e` Do not print minping time in getpeerinfo when no ping received yet (paveljanik) +- #7518 `be14ca5` Add multiple options to fundrawtransaction (promag) +- #7756 `9e47fce` Add cursor to iterate over utxo set, use this in `gettxoutsetinfo` (laanwj) +- #7848 `88616d2` Divergence between 32- and 64-bit when hashing >4GB affects `gettxoutsetinfo` (laanwj) +- #7827 `4205ad7` Speed up `getchaintips` (mrbandrews) +- #7762 `a1eb344` Append a message sequence number to every ZMQ notification (jonasschnelli) +- #7688 `46880ed` List solvability in listunspent output and improve help (sipa) +- #7926 `5725807` Push back `getaddednodeinfo` dead value (instagibbs) +- #7953 `0630353` Create `signmessagewithprivkey` rpc (achow101) +- #8049 `c028c7b` Expose information on whether transaction relay is enabled in `getnetworkinfo` (laanwj) +- #7967 `8c1e49b` Add feerate option to `fundrawtransaction` (jonasschnelli) +- #8118 `9b6a48c` Reduce unnecessary hashing in `signrawtransaction` (jonasnick) +- #7957 `79004d4` Add support for transaction sequence number (jonasschnelli) +- #8153 `75ec320` `fundrawtransaction` feeRate: Use BTC/kB (MarcoFalke) +- #7292 `7ce9ac5` Expose ancestor/descendant information over RPC (sdaftuar) +- #8171 `62fcf27` Fix createrawtx sequence number unsigned int parsing (jonasschnelli) +- #7892 `9c3d0fa` Add full UTF-8 support to RPC (laanwj) +- #8317 `304eff3` Don't use floating point in rpcwallet (MarcoFalke) +- #8258 `5a06ebb` Hide softfork in `getblockchaininfo` if timeout is 0 (jl2012) +- #8244 `1922e5a` Remove unnecessary LOCK(cs_main) in getrawmempool (dcousens) ### Block and transaction handling +- #7056 `6a07208` Save last db read (morcos) +- #6842 `0192806` Limitfreerelay edge case bugfix (ptschip) +- #7084 `11d74f6` Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee in mempool (MarcoFalke) +- #7539 `9f33dba` Add tags to mempool's mapTx indices (sdaftuar) +- #7592 `26a2a72` Re-remove ERROR logging for mempool rejects (laanwj) +- #7187 `14d6324` Keep reorgs fast for SequenceLocks checks (morcos) +- #7594 `01f4267` Mempool: Add tracking of ancestor packages (sdaftuar) +- #7904 `fc9e334` Txdb: Fix assert crash in new UTXO set cursor (laanwj) +- #7927 `f9c2ac7` Minor changes to dbwrapper to simplify support for other databases (laanwj) +- #7933 `e26b620` Fix OOM when deserializing UTXO entries with invalid length (sipa) +- #8020 `5e374f7` Use SipHash-2-4 for various non-cryptographic hashes (sipa) +- #8076 `d720980` VerifyDB: don't check blocks that have been pruned (sdaftuar) +- #8080 `862fd24` Do not use mempool for GETDATA for tx accepted after the last mempool req (gmaxwell) +- #7997 `a82f033` Replace mapNextTx with slimmer setSpends (kazcw) +- #8220 `1f86d64` Stop trimming when mapTx is empty (sipa) +- #8273 `396f9d6` Bump `-dbcache` default to 300MiB (laanwj) +- #7225 `eb33179` Eliminate unnecessary call to CheckBlock (sdaftuar) +- #7907 `006cdf6` Optimize and Cleanup CScript::FindAndDelete (pstratem) +- #7917 `239d419` Optimize reindex (sipa) +- #7763 `3081fb9` Put hex-encoded version in UpdateTip (sipa) +- #8149 `d612837` Testnet-only segregated witness (sipa) +- #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) +- #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) + ### P2P protocol and network code -### Validation +- #6589 `dc0305d` Log bytes recv/sent per command (jonasschnelli) +- #7164 `3b43cad` Do not download transactions during initial blockchain sync (ptschip) +- #7458 `898fedf` peers.dat, banlist.dat recreated when missing (kirkalx) +- #7637 `3da5d1b` Fix memleak in TorController (laanwj, jonasschnelli) +- #7553 `9f14e5a` Remove vfReachable and modify IsReachable to only use vfLimited (pstratem) +- #7708 `9426632` De-neuter NODE_BLOOM (pstratem) +- #7692 `29b2be6` Remove P2P alert system (btcdrak) +- #7542 `c946a15` Implement "feefilter" P2P message (morcos) +- #7573 `352fd57` Add `-maxtimeadjustment` command line option (mruddy) +- #7570 `232592a` Add IPv6 Link-Local Address Support (mruddy) +- #7874 `e6a4d48` Improve AlreadyHave (morcos) +- #7856 `64e71b3` Only send one GetAddr response per connection (gmaxwell) +- #7868 `7daa3ad` Split DNS resolving functionality out of net structures (theuni) +- #7919 `7617682` Fix headers announcements edge case (sdaftuar) +- #7514 `d9594bf` Fix IsInitialBlockDownload for testnet (jmacwhyte) +- #7959 `03cf6e8` fix race that could fail to persist a ban (kazcw) +- #7840 `3b9a0bf` Several performance and privacy improvements to inv/mempool handling (sipa) +- #8011 `65aecda` Don't run ThreadMessageHandler at lowered priority (kazcw) +- #7696 `5c3f8dd` Fix de-serialization bug where AddrMan is left corrupted (EthanHeilman) +- #7932 `ed749bd` CAddrMan::Deserialize handle corrupt serializations better (pstratem) +- #7906 `83121cc` Prerequisites for p2p encapsulation changes (theuni) +- #8033 `18436d8` Fix Socks5() connect failures to be less noisy and less unnecessarily scary (wtogami) +- #8082 `01d8359` Defer inserting into maprelay until just before relaying (gmaxwell) +- #7960 `6a22373` Only use AddInventoryKnown for transactions (sdaftuar) +- #8078 `2156fa2` Disable the mempool P2P command when bloom filters disabled (petertodd) +- #8065 `67c91f8` Addrman offline attempts (gmaxwell) +- #7703 `761cddb` Tor: Change auth order to only use password auth if -torpassword (laanwj) +- #8083 `cd0c513` Add support for dnsseeds with option to filter by servicebits (jonasschnelli) +- #8173 `4286f43` Use SipHash for node eviction (sipa) +- #8154 `1445835` Drop vAddrToSend after sending big addr message (kazcw) +- #7749 `be9711e` Enforce expected outbound services (sipa) +- #8208 `0a64777` Do not set extra flags for unfiltered DNS seed results (sipa) +- #8084 `e4bb4a8` Add recently accepted blocks and txn to AttemptToEvictConnection (gmaxwell) +- #8113 `3f89a53` Rework addnode behaviour (sipa) +- #8179 `94ab58b` Evict orphans which are included or precluded by accepted blocks (gmaxwell) +- #8068 `e9d76a1` Compact Blocks (TheBlueMatt) +- #8204 `0833894` Update petertodd's testnet seed (petertodd) +- #8247 `5cd35d3` Mark my dnsseed as supporting filtering (sipa) +- #8275 `042c323` Remove bad chain alert partition check (btcdrak) +- #8271 `1bc9c80` Do not send witnesses in cmpctblock (sipa) +- #8312 `ca40ef6` Fix mempool DoS vulnerability from malleated transactions (sdaftuar) +- #7180 `16ccb74` Account for `sendheaders` `verack` messages (laanwj) +- #8102 `425278d` Bugfix: use global ::fRelayTxes instead of CNode in version send (sipa) ### Build system -### Wallet +- #7302 `41f1a3e` C++11 build/runtime fixes (theuni) +- #7322 `fd9356b` c++11: add scoped enum fallbacks to CPPFLAGS rather than defining them locally (theuni) +- #7441 `a6771fc` Use Debian 8.3 in gitian build guide (fanquake) +- #7349 `152a821` Build against system UniValue when available (luke-jr) +- #7520 `621940e` LibreSSL doesn't define OPENSSL_VERSION, use LIBRESSL_VERSION_TEXT instead (paveljanik) +- #7528 `9b9bfce` autogen.sh: warn about needing autoconf if autoreconf is not found (knocte) +- #7504 `19324cf` Crystal clean make clean (paveljanik) +- #7619 `18b3f1b` Add missing sudo entry in gitian VM setup (btcdrak) +- #7616 `639ec58` [depends] Delete unused patches (MarcoFalke) +- #7658 `c15eb28` Add curl to Gitian setup instructions (btcdrak) +- #7710 `909b72b` [Depends] Bump miniupnpc and config.guess+sub (fanquake) +- #7723 `5131005` build: python 3 compatibility (laanwj) +- #7477 `28ad4d9` Fix quoting of copyright holders in configure.ac (domob1812) +- #7711 `a67bc5e` [build-aux] Update Boost & check macros to latest serials (fanquake) +- #7788 `4dc1b3a` Use relative paths instead of absolute paths in protoc calls (paveljanik) +- #7809 `bbd210d` depends: some base fixes/changes (theuni) +- #7603 `73fc922` Build System: Use PACKAGE_TARNAME in NSIS script (JeremyRand) +- #7905 `187186b` test: move accounting_tests and rpc_wallet_tests to wallet/test (laanwj) +- #7911 `351abf9` leveldb: integrate leveldb into our buildsystem (theuni) +- #7944 `a407807` Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035 (randy-waterhouse) +- #7920 `c3e3cfb` Switch Travis to Trusty (theuni) +- #7954 `08b37c5` build: quiet annoying warnings without adding new ones (theuni) +- #7165 `06162f1` build: Enable C++11 in build, require C++11 compiler (laanwj) +- #7982 `559fbae` build: No need to check for leveldb atomics (theuni) +- #8002 `f9b4582` [depends] Add -stdlib=libc++ to darwin CXX flags (fanquake) +- #7993 `6a034ed` [depends] Bump Freetype, ccache, ZeroMQ, miniupnpc, expat (fanquake) +- #8167 `19ea173` Ship debug tarballs/zips with debug symbols (theuni) +- #8175 `f0299d8` Add --disable-bench to config flags for windows (laanwj) +- #7283 `fd9881a` [gitian] Default reference_datetime to commit author date (MarcoFalke) +- #8181 `9201ce8` Get rid of `CLIENT_DATE` (laanwj) +- #8133 `fde0ac4` Finish up out-of-tree changes (theuni) +- #8188 `65a9d7d` Add armhf/aarch64 gitian builds (theuni) +- #8194 `cca1c8c` [gitian] set correct PATH for wrappers (MarcoFalke) +- #8198 `5201614` Sync ax_pthread with upstream draft4 (fanquake) +- #8210 `12a541e` [Qt] Bump to Qt5.6.1 (jonasschnelli) +- #8285 `da50997` windows: Add testnet link to installer (laanwj) +- #8304 `0cca2fe` [travis] Update SDK_URL (MarcoFalke) +- #8310 `6ae20df` Require boost for bench (theuni) +- #8315 `2e51590` Don't require sudo for Linux (theuni) +- #8314 `67caef6` Fix pkg-config issues for 0.13 (theuni) ### GUI -### Tests +- #7154 `00b4b8d` Add InMempool() info to transaction details (jonasschnelli) +- #7068 `5f3c670` [RPC-Tests] add simple way to run rpc test over QT clients (jonasschnelli) +- #7218 `a1c185b` Fix misleading translation (MarcoFalke) +- #7214 `be9a9a3` qt5: Use the fixed font the system recommends (MarcoFalke) +- #7256 `08ab906` Add note to coin control dialog QT5 workaround (fanquake) +- #7255 `e289807` Replace some instances of formatWithUnit with formatHtmlWithUnit (fanquake) +- #7317 `3b57e9c` Fix RPCTimerInterface ordering issue (jonasschnelli) +- #7327 `c079d79` Transaction View: LastMonth calculation fixed (crowning-) +- #7334 `e1060c5` coincontrol workaround is still needed in qt5.4 (fixed in qt5.5) (MarcoFalke) +- #7383 `ae2db67` Rename "amount" to "requested amount" in receive coins table (jonasschnelli) +- #7396 `cdcbc59` Add option to increase/decrease font size in the console window (jonasschnelli) +- #7437 `9645218` Disable tab navigation for peers tables (Kefkius) +- #7604 `354b03d` build: Remove spurious dollar sign. Fixes #7189 (dooglus) +- #7605 `7f001bd` Remove openssl info from init/log and from Qt debug window (jonasschnelli) +- #7628 `87d6562` Add 'copy full transaction details' option (ericshawlinux) +- #7613 `3798e5d` Add autocomplete to bitcoin-qt's console window (GamerSg) +- #7668 `b24266c` Fix history deletion bug after font size change (achow101) +- #7680 `41d2dfa` Remove reflection from `about` icon (laanwj) +- #7686 `f034bce` Remove 0-fee from send dialog (MarcoFalke) +- #7506 `b88e0b0` Use CCoinControl selection in CWallet::FundTransaction (promag) +- #7732 `0b98dd7` Debug window: replace "Build date" with "Datadir" (jonasschnelli) +- #7761 `60db51d` remove trailing output-index from transaction-id (jonasschnelli) +- #7772 `6383268` Clear the input line after activating autocomplete (paveljanik) +- #7925 `f604bf6` Fix out-of-tree GUI builds (laanwj) +- #7939 `574ddc6` Make it possible to show details for multiple transactions (laanwj) +- #8012 `b33824b` Delay user confirmation of send (Tyler-Hardin) +- #8006 `7c8558d` Add option to disable the system tray icon (Tyler-Hardin) +- #8046 `169d379` Fix Cmd-Q / Menu Quit shutdown on OSX (jonasschnelli) +- #8042 `6929711` Don't allow to open the debug window during splashscreen & verification state (jonasschnelli) +- #8014 `77b49ac` Sort transactions by date (Tyler-Hardin) +- #8073 `eb2f6f7` askpassphrasedialog: Clear pass fields on accept (rat4) +- #8129 `ee1533e` Fix RPC console auto completer (UdjinM6) +- #7636 `fb0ac48` Add bitcoin address label to request payment QR code (makevoid) +- #8231 `760a6c7` Fix a bug where the SplashScreen will not be hidden during startup (jonasschnelli) +- #8256 `af2421c` BUG: bitcoin-qt crash (fsb4000) +- #8257 `ff03c50` Do not ask a UI question from bitcoind (sipa) +- #8288 `91abb77` Network-specific example address (laanwj) +- #7707 `a914968` UI support for abandoned transactions (jonasschnelli) +- #8207 `f7a403b` Add a link to the Bitcoin-Core repository and website to the About Dialog (MarcoFalke) +- #8281 `6a87eb0` Remove client name from debug window (laanwj) -### Miscellaneous +### Wallet + +- #7262 `fc08994` Reduce inefficiency of GetAccountAddress() (dooglus) +- #7537 `78e81b0` Warn on unexpected EOF while salvaging wallet (laanwj) +- #7521 `3368895` Don't resend wallet txs that aren't in our own mempool (morcos) +- #7576 `86a1ec5` Move wallet help string creation to CWallet (jonasschnelli) +- #7577 `5b3b5a7` Move "load wallet phase" to CWallet (jonasschnelli) +- #7608 `0735c0c` Move hardcoded file name out of log messages (MarcoFalke) +- #7649 `4900641` Prevent multiple calls to CWallet::AvailableCoins (promag) +- #7646 `e5c3511` Fix lockunspent help message (promag) +- #7558 `b35a591` Add import/removeprunedfunds rpc call (instagibbs) +- #7691 `30c2dd8` Refactor wallet/init interaction (jonasschnelli) +- #6215 `48c5adf` add bip32 pub key serialization (jonasschnelli) +- #7913 `bafd075` Fix for incorrect locking in GetPubKey() (keystore.cpp) (yurizhykin) +- #7816 `0c95ebc` Slighly refactor GetOldestKeyPoolTime() (jonasschnelli) +- #8036 `41138f9` init: Move berkeleydb version reporting to wallet (laanwj) +- #8028 `373b50d` Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk (pstratem) +- #8061 `f6b7df3` Improve Wallet encapsulation (pstratem) +- #7891 `950be19` Always require OS randomness when generating secret keys (sipa) +- #7689 `b89ef13` Replace OpenSSL AES with ctaes-based version (sipa) +- #7825 `f972b04` Prevent multiple calls to ExtractDestination (pedrobranco) +- #8137 `243ac0c` Improve CWallet API with new AccountMove function (pstratem) +- #8142 `52c3f34` Improve CWallet API with new GetAccountPubkey function (pstratem) +- #8035 `b67a472` Add simplest BIP32/deterministic key generation implementation (jonasschnelli) +- #7687 `a6ddb19` Stop treating importaddress'ed scripts as change (sipa) +- #8298 `aef3811` wallet: Revert input selection post-pruning (laanwj) +- #8324 `bc94b87` Keep HD seed during salvagewallet (jonasschnelli) +- #8323 `238300b` Add HD keypath to CKeyMetadata, report metadata in validateaddress (jonasschnelli) +- #8367 `3b38a6a` Ensure <0.13 clients can't open HD wallets (jonasschnelli) + +### Tests and QA + +- #7320 `d3dfc6d` Test walletpassphrase timeout (MarcoFalke) +- #7208 `47c5ed1` Make max tip age an option instead of chainparam (laanwj) +- #7372 `21376af` Trivial: [qa] wallet: Print maintenance (MarcoFalke) +- #7280 `668906f` [travis] Fail when documentation is outdated (MarcoFalke) +- #7177 `93b0576` [qa] Change default block priority size to 0 (MarcoFalke) +- #7236 `02676c5` Use createrawtx locktime parm in txn_clone (dgenr8) +- #7212 `326ffed` Adds unittests for CAddrMan and CAddrinfo, removes source of non-determinism (EthanHeilman) +- #7490 `d007511` tests: Remove May15 test (laanwj) +- #7531 `18cb2d5` Add bip68-sequence.py to extended rpc tests (btcdrak) +- #7536 `ce5fc02` test: test leading spaces for ParseHex (laanwj) +- #7620 `1b68de3` [travis] Only run check-doc.py once (MarcoFalke) +- #7455 `7f96671` [travis] Exit early when check-doc.py fails (MarcoFalke) +- #7667 `56d2c4e` Move GetTempPath() to testutil (musalbas) +- #7517 `f1ca891` test: script_error checking in script_invalid tests (laanwj) +- #7684 `3d0dfdb` Extend tests (MarcoFalke) +- #7697 `622fe6c` Tests: make prioritise_transaction.py more robust (sdaftuar) +- #7709 `efde86b` Tests: fix missing import in mempool_packages (sdaftuar) +- #7702 `29e1131` Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke) +- #7720 `3b4324b` rpc-test: Normalize assert() (MarcoFalke) +- #7757 `26794d4` wallet: Wait for reindex to catch up (MarcoFalke) +- #7764 `a65b36c` Don't run pruning.py twice (MarcoFalke) +- #7773 `7c80e72` Fix comments in tests (btcdrak) +- #7489 `e9723cb` tests: Make proxy_test work on travis servers without IPv6 (laanwj) +- #7778 `ff5874b` Bug fixes and refactor (MarcoFalke) +- #7801 `70ac71b` Remove misleading "errorString syntax" (MarcoFalke) +- #7803 `401c65c` maxblocksinflight: Actually enable test (MarcoFalke) +- #7802 `3bc71e1` httpbasics: Actually test second connection (MarcoFalke) +- #7818 `3911a0a` Refactor script tests (sipa) +- #7849 `ab8586e` tests: add varints_bitpatterns test (laanwj) +- #7846 `491171f` Clean up lockorder data of destroyed mutexes (sipa) +- #7853 `6ef5e00` py2: Unfiddle strings into bytes explicitly (MarcoFalke) +- #7878 `53adc83` [test] bctest.py: Revert faa41ee (MarcoFalke) +- #7798 `cabba24` [travis] Print the commit which was evaluated (MarcoFalke) +- #7833 `b1bf511` tests: Check Content-Type header returned from RPC server (laanwj) +- #7851 `fa9d86f` pull-tester: Don't mute zmq ImportError (MarcoFalke) +- #7822 `0e6fd5e` Add listunspent() test for spendable/unspendable UTXO (jpdffonseca) +- #7912 `59ad568` Tests: Fix deserialization of reject messages (sdaftuar) +- #7941 `0ea3941` Fixing comment in script_test.json test case (Christewart) +- #7807 `0ad1041` Fixed miner test values, gave constants for less error-prone values (instagibbs) +- #7980 `88b77c7` Smartfees: Properly use ordered dict (MarcoFalke) +- #7814 `77b637f` Switch to py3 (MarcoFalke) +- #8030 `409a8a1` Revert fatal-ness of missing python-zmq (laanwj) +- #8018 `3e90fe6` Autofind rpc tests --srcdir (jonasschnelli) +- #7971 `4e14afe` Refactor test_framework and pull tester (MarcoFalke) +- #8016 `5767e80` Fix multithread CScheduler and reenable test (paveljanik) +- #7972 `423ca30` pull-tester: Run rpc test in parallel (MarcoFalke) +- #8039 `69b3a6d` Bench: Add crypto hash benchmarks (laanwj) +- #8041 `5b736dd` Fix bip9-softforks blockstore issue (MarcoFalke) +- #7994 `1f01443` Add op csv tests to script_tests.json (Christewart) +- #8038 `e2bf830` Various minor fixes (MarcoFalke) +- #8072 `1b87e5b` Travis: 'make check' in parallel and verbose (MarcoFalke) +- #8056 `8844ef1` Remove hardcoded "4 nodes" from test_framework (MarcoFalke) +- #8047 `37f9a1f` Test_framework: Set wait-timeout for bitcoind procs (MarcoFalke) +- #8095 `6700cc9` Test framework: only cleanup on successful test runs (sdaftuar) +- #8098 `06bd4f6` Test_framework: Append portseed to tmpdir (MarcoFalke) +- #8104 `6ff2c8d` Add timeout to sync_blocks() and sync_mempools() (sdaftuar) +- #8111 `61b8684` Benchmark SipHash (sipa) +- #8107 `52b803e` Bench: Added base58 encoding/decoding benchmarks (yurizhykin) +- #8115 `0026e0e` Avoid integer division in the benchmark inner-most loop (gmaxwell) +- #8090 `a2df115` Adding P2SH(p2pkh) script test case (Christewart) +- #7992 `ec45cc5` Extend #7956 with one more test (TheBlueMatt) +- #8139 `ae5575b` Fix interrupted HTTP RPC connection workaround for Python 3.5+ (sipa) +- #8164 `0f24eaf` [Bitcoin-Tx] fix missing test fixtures, fix 32bit atoi issue (jonasschnelli) +- #8166 `0b5279f` Src/test: Do not shadow local variables (paveljanik) +- #8141 `44c1b1c` Continuing port of java comparison tool (mrbandrews) +- #8201 `36b7400` fundrawtransaction: Fix race, assert amounts (MarcoFalke) +- #8214 `ed2cd59` Mininode: fail on send_message instead of silent return (MarcoFalke) +- #8215 `a072d1a` Don't use floating point in wallet tests (MarcoFalke) +- #8066 `65c2058` Test_framework: Use different rpc_auth_pair for each node (MarcoFalke) +- #8216 `0d41d70` Assert 'changePosition out of bounds' (MarcoFalke) +- #8222 `961893f` Enable mempool consistency checks in unit tests (sipa) +- #7751 `84370d5` test_framework: python3.4 authproxy compat (laanwj) +- #7744 `d8e862a` test_framework: detect failure of bitcoind startup (laanwj) +- #8280 `115735d` Increase sync_blocks() timeouts in pruning.py (MarcoFalke) +- #8340 `af9b7a9` Solve trivial merge conflict in p2p-segwit.py (MarcoFalke) +- #8067 `3e4cf8f` Travis: use slim generic image, and some fixups (theuni) +- #7951 `5c7df70` Test_framework: Properly print exception (MarcoFalke) +- #8070 `7771aa5` Remove non-determinism which is breaking net_tests #8069 (EthanHeilman) +- #8309 `bb2646a` Add wallet-hd test (MarcoFalke) + +### Mining + +- #7507 `11c7699` Remove internal miner (Leviathn) +- #7663 `c87f51e` Make the generate RPC call function for non-regtest (sipa) +- #7671 `e2ebd25` Add generatetoaddress RPC to mine to an address (achow101) +- #7935 `66ed450` Versionbits: GBT support (luke-jr) +- #7598 `e1486eb` Refactor CreateNewBlock to be a method of the BlockAssembler class (morcos) +- #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) +- #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) +- #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) + +### Documentation and miscellaneous + +- #7423 `69e2a40` Add example for building with constrained resources (jarret) +- #8254 `c2c69ed` Add OSX ZMQ requirement to QA readme (fanquake) +- #8203 `377d131` Clarify documentation for running a tor node (nathaniel-mahieu) +- #7428 `4b12266` Add example for listing ./configure flags (nathaniel-mahieu) +- #7847 `3eae681` Add arch linux build example (mruddy) +- #7968 `ff69aaf` Fedora build requirements (wtogami) +- #8013 `fbedc09` Fedora build requirements, add gcc-c++ and fix typo (wtogami) +- #8009 `fbd8478` Fixed invalid example paths in gitian-building.md (JeremyRand) +- #8240 `63fbdbc` Mention Windows XP end of support in release notes (laanwj) +- #8303 `5077d2c` Update bips.md for CSV softfork (fanquake) +- #7789 `e0b3e19` Add note about using the Qt official binary installer (paveljanik) +- #7791 `e30a5b0` Change Precise to Trusty in gitian-building.md (JeremyRand) +- #7838 `8bb5d3d` Update gitian build guide to debian 8.4.0 (fanquake) +- #7855 `b778e59` Replace precise with trusty (MarcoFalke) +- #7975 `fc23fee` Update bitcoin-core GitHub links (MarcoFalke) +- #8034 `e3a8207` Add basic git squash workflow (fanquake) +- #7813 `214ec0b` Update port in tor.md (MarcoFalke) +- #8193 `37c9830` Use Debian 8.5 in the gitian-build guide (fanquake) +- #8261 `3685e0c` Clarify help for `getblockchaininfo` (paveljanik) +- #7185 `ea0f5a2` Note that reviewers should mention the id of the commits they reviewed (pstratem) +- #7290 `c851d8d` [init] Add missing help for args (MarcoFalke) +- #7281 `f9fd4c2` Improve CheckInputs() comment about sig verification (petertodd) +- #7417 `1e06bab` Minor improvements to the release process (PRabahy) +- #7444 `4cdbd42` Improve block validity/ConnectBlock() comments (petertodd) +- #7527 `db2e1c0` Fix and cleanup listreceivedbyX documentation (instagibbs) +- #7541 `b6e00af` Clarify description of blockindex (pinheadmz) +- #7590 `f06af57` Improving wording related to Boost library requirements [updated] (jonathancross) +- #7635 `0fa88ef` Add dependency info to test docs (elliotolds) +- #7609 `3ba07bd` RPM spec file project (AliceWonderMiscreations) +- #7850 `229a17c` Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp` (alexreg) +- #7888 `ec870e1` Prevector: fix 2 bugs in currently unreached code paths (kazcw) +- #7922 `90653bc` CBase58Data::SetString: cleanse the full vector (kazcw) +- #7881 `c4e8390` Update release process (laanwj) +- #7952 `a9c8b74` Log invalid block hash to make debugging easier (paveljanik) +- #7974 `8206835` More comments on the design of AttemptToEvictConnection (gmaxwell) +- #7795 `47a7cfb` UpdateTip: log only one line at most per block (laanwj) +- #8110 `e7e25ea` Add benchmarking notes (fanquake) +- #8121 `58f0c92` Update implemented BIPs list (fanquake) +- #8029 `58725ba` Simplify OS X build notes (fanquake) +- #8143 `d46b8b5` comment nit: miners don't vote (instagibbs) +- #8136 `22e0b35` Log/report in 10% steps during VerifyDB (jonasschnelli) +- #8168 `d366185` util: Add ParseUInt32 and ParseUInt64 (laanwj) +- #8178 `f7b1bfc` Add git and github tips and tricks to developer notes (sipa) +- #8177 `67db011` developer notes: updates for C++11 (kazcw) +- #8229 `8ccdac1` [Doc] Update OS X build notes for 10.11 SDK (fanquake) +- #8233 `9f1807a` Mention Linux ARM executables in release process and notes (laanwj) +- #7540 `ff46dd4` Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY (btcdrak) +- #8289 `26316ff` bash-completion: Adapt for 0.12 and 0.13 (roques) +- #7453 `3dc3149` Missing patches from 0.12 (MarcoFalke) +- #7113 `54a550b` Switch to a more efficient rolling Bloom filter (sipa) +- #7257 `de9e5ea` Combine common error strings for different options so translations can be shared and reused (luke-jr) +- #7304 `b8f485c` [contrib] Add clang-format-diff.py (MarcoFalke) +- #7378 `e6f97ef` devtools: replace github-merge with python version (laanwj) +- #7395 `0893705` devtools: show pull and commit information in github-merge (laanwj) +- #7402 `6a5932b` devtools: github-merge get toplevel dir without extra whitespace (achow101) +- #7425 `20a408c` devtools: Fix utf-8 support in messages for github-merge (laanwj) +- #7632 `409f843` Delete outdated test-patches reference (Lewuathe) +- #7662 `386f438` remove unused NOBLKS_VERSION_{START,END} constants (rat4) +- #7737 `aa0d2b2` devtools: make github-merge.py use py3 (laanwj) +- #7781 `55db5f0` devtools: Auto-set branch to merge to in github-merge (laanwj) +- #7934 `f17032f` Improve rolling bloom filter performance and benchmark (sipa) +- #8004 `2efe38b` signal handling: fReopenDebugLog and fRequestShutdown should be type sig_atomic_t (catilac) +- #7713 `f6598df` Fixes for verify-commits script (petertodd) Credits ======= Thanks to everyone who directly contributed to this release: +- 21E14 +- accraze +- Adam Brown +- Alexander Regueiro +- Alex Morcos +- Alfie John +- Alice Wonder +- AlSzacrel +- Andrew Chow +- Andrés G. Aragoneses +- Bob McElrath +- BtcDrak +- calebogden +- Cédric Félizard +- Chirag Davé +- Chris Moore +- Chris Stewart +- Christian von Roques +- Chris Wheeler +- Cory Fields +- crowning- +- Daniel Cousens +- Daniel Kraft +- Denis Lukianov +- Elias Rohrer +- Elliot Olds +- Eric Shaw +- error10 +- Ethan Heilman +- face +- fanquake +- Francesco 'makevoid' Canessa +- fsb4000 +- Gavin Andresen +- gladoscc +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- James O'Beirne +- Jarret Dyrbye +- Jeremy Rand +- jl2012 +- jloughry +- jmacwhyte +- Joao Fonseca +- Johnson Lau +- Jonas Nick +- Jonas Schnelli +- Jonathan Cross +- João Barbosa +- Jorge Timón +- Kaz Wesley +- Kefkius +- kirkalx +- Krzysztof Jurewicz +- Leviathn +- lewuathe +- Luke Dashjr +- Luv Khemani +- Marcel Krüger +- Marco Falke +- Mark Friedenbach +- Matt +- Matt Bogosian +- Matt Corallo +- Matthew English +- Matthew Zipkin +- mb300sd +- Mitchell Cash +- mrbandrews +- mruddy +- Murch +- Mustafa +- Nathaniel Mahieu +- Nicolas Dorier +- Patrick Strateman +- Paul Rabahy +- paveljanik +- Pavel Janík +- Pavel Vasin +- Pedro Branco +- Peter Todd +- Philip Kaufmann +- Pieter Wuille +- Prayag Verma +- ptschip +- Puru +- randy-waterhouse +- R E Broadley +- Rusty Russell +- Suhas Daftuar +- Suriyaa Kudo +- TheLazieR Yip +- Thomas Kerin +- Tom Harding +- Tyler Hardin +- UdjinM6 +- Warren Togami +- Will Binns +- Wladimir J. van der Laan +- Yuri Zhykin + As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 1fe7f404078121ad370ec955aa23befa322549bb Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 19 Jul 2016 15:41:36 -0400 Subject: [PATCH 0929/1223] build: fix non-deterministic biplist The non-deterministic ordering produced by biplist ends up in the .DS_Store file that is included in the OSX dmg. Github-Pull: #8373 Rebased-From: 3b3ce25df6cc84cd1e75a7ec20fc7da8d2ef76e0 --- depends/packages/native_biplist.mk | 5 ++++ .../patches/native_biplist/sorted_list.patch | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 depends/patches/native_biplist/sorted_list.patch diff --git a/depends/packages/native_biplist.mk b/depends/packages/native_biplist.mk index eb8672d55..3c6e8900f 100644 --- a/depends/packages/native_biplist.mk +++ b/depends/packages/native_biplist.mk @@ -4,6 +4,11 @@ $(package)_download_path=https://pypi.python.org/packages/source/b/biplist $(package)_file_name=biplist-$($(package)_version).tar.gz $(package)_sha256_hash=b57cadfd26e4754efdf89e9e37de87885f9b5c847b2615688ca04adfaf6ca604 $(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_patches=sorted_list.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/sorted_list.patch +endef define $(package)_build_cmds python setup.py build diff --git a/depends/patches/native_biplist/sorted_list.patch b/depends/patches/native_biplist/sorted_list.patch new file mode 100644 index 000000000..89abdb1b7 --- /dev/null +++ b/depends/patches/native_biplist/sorted_list.patch @@ -0,0 +1,29 @@ +--- a/biplist/__init__.py 2014-10-26 19:03:11.000000000 +0000 ++++ b/biplist/__init__.py 2016-07-19 19:30:17.663521999 +0000 +@@ -541,7 +541,7 @@ + return HashableWrapper(n) + elif isinstance(root, dict): + n = {} +- for key, value in iteritems(root): ++ for key, value in sorted(iteritems(root)): + n[self.wrapRoot(key)] = self.wrapRoot(value) + return HashableWrapper(n) + elif isinstance(root, list): +@@ -616,7 +616,7 @@ + elif isinstance(obj, dict): + size = proc_size(len(obj)) + self.incrementByteCount('dictBytes', incr=1+size) +- for key, value in iteritems(obj): ++ for key, value in sorted(iteritems(obj)): + check_key(key) + self.computeOffsets(key, asReference=True) + self.computeOffsets(value, asReference=True) +@@ -714,7 +714,7 @@ + keys = [] + values = [] + objectsToWrite = [] +- for key, value in iteritems(obj): ++ for key, value in sorted(iteritems(obj)): + keys.append(key) + values.append(value) + for key in keys: From 48b92080a74c94c619615fa32055b4bc3b5b89f2 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Wed, 20 Jul 2016 17:48:09 +0800 Subject: [PATCH 0930/1223] Remove duplicated name in release notes --- doc/release-notes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 240e132a8..6bd2aa9f0 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -665,7 +665,6 @@ Thanks to everyone who directly contributed to this release: - James O'Beirne - Jarret Dyrbye - Jeremy Rand -- jl2012 - jloughry - jmacwhyte - Joao Fonseca From ebea65121e6c62f6b6acd79408a681b987126a0d Mon Sep 17 00:00:00 2001 From: Patrick Strateman Date: Tue, 19 Jul 2016 22:30:17 -0700 Subject: [PATCH 0931/1223] Move SetMinVersion for FEATURE_HD to SetHDMasterKey Github-Pull: #8378 Rebased-From: 6523fcaab2f0808d4e47b9cb9ebbef7ed69a309e --- src/wallet/wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a76085de3..5908dfeac 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1170,6 +1170,9 @@ bool CWallet::SetHDMasterKey(const CKey& key) { LOCK(cs_wallet); + // ensure this wallet.dat can only be opened by clients supporting HD + SetMinVersion(FEATURE_HD); + // store the key as normal "key"/"ckey" object // in the database // key metadata is not required @@ -3299,9 +3302,6 @@ bool CWallet::InitLoadWallet() key.MakeNewKey(true); if (!walletInstance->SetHDMasterKey(key)) throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); - - // ensure this wallet.dat can only be opened by clients supporting HD - walletInstance->SetMinVersion(FEATURE_HD); } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { From f891e34cf962b74ba6f29aaea6b368c412b8376d Mon Sep 17 00:00:00 2001 From: Jannes Faber Date: Wed, 20 Jul 2016 12:30:46 +0200 Subject: [PATCH 0932/1223] fix typo: propagation relay -> delay --- doc/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6bd2aa9f0..0d3323458 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -122,7 +122,7 @@ Support for block relay using the Compact Blocks protocol has been implemented in PR 8068. The primary goal is reducing the bandwidth spikes at relay time, though in many -cases it also reduces propagation relay. It is automatically enabled between +cases it also reduces propagation delay. It is automatically enabled between compatible peers. [BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) From ea9196189983358ab9d9a01ed5e989d5bd4d41de Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 20 Jul 2016 09:36:18 -0700 Subject: [PATCH 0933/1223] Fix formatting error Don't start a line with a # unless you want that line to be a header. --- doc/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6bd2aa9f0..f488fcad6 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -170,7 +170,7 @@ Low-level P2P changes instantly, while queueing up the rest and sending them out in batch. As this resulted in chains of dependent transactions being reordered, it systematically hurt transaction relay. The relay code was redesigned in PRs - #7840 and #8082, and now always batches transactions announcements while also + \#7840 and #8082, and now always batches transactions announcements while also sorting them according to dependency order. This significantly reduces orphan transactions. To compensate for the removal of instant relay, the frequency of batch sending was doubled for outgoing peers. From 52a4158f1f159a453c2db09ee8acf7045690e68e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 19 Jul 2016 15:50:57 -0400 Subject: [PATCH 0934/1223] Add release notes for mining changes --- doc/release-notes.md | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 240e132a8..b251e8355 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -146,6 +146,68 @@ HD wallets are incompatible with older versions of Bitcoin Core. [Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) +Segregated Witness +------------------ + +The code preparations for Segregated Witness ("segwit"), as described in [BIP +141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP +143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP +144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki), and [BIP +145](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki) are +finished and included in this release. However, BIP 141 does not yet specify +activation parameters on mainnet, and so this release does not support segwit +use on mainnet. Testnet use is supported, and after BIP 141 is updated with +proposed parameters, a future release of Bitcoin Core is expected that +implements those parameters for mainnet. + +Furthermore, because segwit activation is not yet specified for mainnet, +version 0.13.0 will behave similarly as other pre-segwit releases even after a +future activation of BIP 141 on the network. Upgrading from 0.13.0 will be +required in order to utilize segwit-related features on mainnet (such as signal +BIP 141 activation, mine segwit blocks, fully validate segwit blocks, relay +segwit blocks to other segwit nodes, and use segwit transactions in the +wallet, etc). + +Mining transaction selection ("Child Pays For Parent") +------------------------------------------------------ + +The mining transaction selection algorithm has been replaced with an algorithm +that selects transactions based on their feerate inclusive of unconfirmed +ancestor transactions. This means that a low-fee transaction can become more +likely to be selected if a high-fee transaction that spends its outputs is +relayed. + +With this change, the `-blockminsize` command line option has been removed. + +The command line option `-blockmaxsize` remains an option to specify the +maximum number of serialized bytes in a generated block. In addition, the new +command line option `-blockmaxweight` has been added, which specifies the +maximum "block weight" of a generated block, as defined by [BIP 141 (Segregated +Witness)] (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki). + +In preparation for Segregated Witness, the mining algorithm has been modified +to optimize transaction selection for a given block weight, rather than a given +number of serialized bytes in a block. In this release, transaction selection +is unaffected by this distinction (as BIP 141 activation is not supported on +mainnet in this release, see above), but in future releases and after BIP 141 +activation, these calculations would be expected to differ. + +For optimal runtime performance, miners using this release should specify +`-blockmaxweight` on the command line, and not specify `-blockmaxsize`. +Additionally (or only) specifying `-blockmaxsize`, or relying on default +settings for both, may result in performance degradation, as the logic to +support `-blockmaxsize` performs additional computation to ensure that +constraint is met. (Note that for mainnet, in this release, the equivalent +parameter for `-blockmaxweight` would be four times the desired +`-blockmaxsize`. See [BIP 141] +(https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) for additional +details.) + +In the future, the `-blockmaxsize` option may be removed, as block creation is +no longer optimized for this metric. Feedback is requested on whether to +deprecate or keep this command line option in future releases. + + Removal of internal miner -------------------------- From 73adfe3bb935cead8e4d91f8d1c8a9feb55e4a7d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 21 Jul 2016 21:52:30 +0200 Subject: [PATCH 0935/1223] [Wallet] Correct hdmasterkeyid/masterkeyid name confusion Github-Pull: #8390 Rebased-From: b50e1ac298363a7733069f82709674d3a8cb3058 --- qa/rpc-tests/wallet-hd.py | 2 +- src/wallet/rpcwallet.cpp | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index c738ee220..c11da1e9a 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -31,7 +31,7 @@ class WalletHDTest(BitcoinTestFramework): tmpdir = self.options.tmpdir # Make sure we use hd, keep masterkeyid - masterkeyid = self.nodes[1].getwalletinfo()['masterkeyid'] + masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] assert_equal(len(masterkeyid), 40) # Import a non-HD private key in the HD wallet diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b4831ad79..4087b8e77 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2260,16 +2260,16 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "Returns an object containing various wallet state info.\n" "\nResult:\n" "{\n" - " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" - " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" - " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" - " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" - " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" - " \"masterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" + " \"walletversion\": xxxxx, (numeric) the wallet version\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" + " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" + " \"hdmasterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2291,7 +2291,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) - obj.push_back(Pair("masterkeyid", masterKeyID.GetHex())); + obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex())); return obj; } From 86edc20a178cc17cdc6915e9e93a7241c27c368c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 18 Jul 2016 12:40:28 -0400 Subject: [PATCH 0936/1223] Scale legacy sigop count in CreateNewBlock Github-Pull: #8362 Rebased-From: 682aa0f289c550c029733966a2ce3449e4a471df --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 25a5becf9..957585884 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -187,7 +187,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; - pblocktemplate->vTxSigOpsCost[0] = GetLegacySigOpCount(pblock->vtx[0]); + pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { From f84ee3dab66831383e58c7de3fabc306754633db Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Wed, 20 Jul 2016 18:31:45 +0800 Subject: [PATCH 0937/1223] Make witness v0 outputs non-standard before segwit activation Github-Pull: #8381 Rebased-From: 1ffaff2f747af683513d6d74a7241d41e3f6e051 --- src/main.cpp | 5 +++-- src/policy/policy.cpp | 9 ++++++--- src/policy/policy.h | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fe19895f5..70f0a4247 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1144,13 +1144,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } // Reject transactions with witness before segregated witness activates (override with -prematurewitness) - if (!GetBoolArg("-prematurewitness",false) && !tx.wit.IsNull() && !IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { + bool witnessEnabled = IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()); + if (!GetBoolArg("-prematurewitness",false) && !tx.wit.IsNull() && !witnessEnabled) { return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; - if (fRequireStandard && !IsStandardTx(tx, reason)) + if (fRequireStandard && !IsStandardTx(tx, reason, witnessEnabled)) return state.DoS(0, false, REJECT_NONSTANDARD, reason); // Only accept nLockTime-using transactions that can be mined in the next diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 8617db00c..de3996bb4 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -31,7 +31,7 @@ * DUP CHECKSIG DROP ... repeated 100 times... OP_1 */ -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled) { std::vector > vSolutions; if (!Solver(scriptPubKey, whichType, vSolutions)) @@ -49,11 +49,14 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) } else if (whichType == TX_NULL_DATA && (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; + + else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH)) + return false; return whichType != TX_NONSTANDARD; } -bool IsStandardTx(const CTransaction& tx, std::string& reason) +bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled) { if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; @@ -92,7 +95,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) unsigned int nDataOut = 0; txnouttype whichType; BOOST_FOREACH(const CTxOut& txout, tx.vout) { - if (!::IsStandard(txout.scriptPubKey, whichType)) { + if (!::IsStandard(txout.scriptPubKey, whichType, witnessEnabled)) { reason = "scriptpubkey"; return false; } diff --git a/src/policy/policy.h b/src/policy/policy.h index f5f8652fb..ad209d030 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -53,12 +53,12 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_ static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST; -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled = false); /** * Check for standard transaction types * @return True if all outputs (scriptPubKeys) use only standard transaction forms */ -bool IsStandardTx(const CTransaction& tx, std::string& reason); +bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled = false); /** * Check for standard transaction types * @param[in] mapInputs Map of previous transactions that have outputs we're spending From 4f7f531af6e1c40ee24817b375f0c444da516cd0 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 22 Jul 2016 11:09:45 -0400 Subject: [PATCH 0938/1223] qa: Add test for standardness of segwit v0 outputs Github-Pull: #8381 Rebased-From: c59c434b7d1211c13f7904b9bc675e16910a1c0a --- qa/rpc-tests/p2p-segwit.py | 78 ++++++++++++++++++++++++++++++++++++++ src/policy/policy.cpp | 2 +- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index fa2c5d1f0..cd02692b1 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -1086,6 +1086,82 @@ class SegWitTest(BitcoinTestFramework): self.old_node.announce_tx_and_wait_for_getdata(block4.vtx[0]) assert(block4.sha256 not in self.old_node.getdataset) + # V0 segwit outputs should be standard after activation, but not before. + def test_standardness_v0(self, segwit_activated): + print("\tTesting standardness of v0 outputs (%s activation)" % ("after" if segwit_activated else "before")) + assert(len(self.utxo)) + + witness_program = CScript([OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + p2sh_pubkey = hash160(witness_program) + p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) + + # First prepare a p2sh output (so that spending it will pass standardness) + p2sh_tx = CTransaction() + p2sh_tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] + p2sh_tx.vout = [CTxOut(self.utxo[0].nValue-1000, p2sh_scriptPubKey)] + p2sh_tx.rehash() + + # Mine it on test_node to create the confirmed output. + self.test_node.test_transaction_acceptance(p2sh_tx, with_witness=True, accepted=True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # Now test standardness of v0 P2WSH outputs. + # Start by creating a transaction with two outputs. + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx.vout = [CTxOut(p2sh_tx.vout[0].nValue-10000, scriptPubKey)] + tx.vout.append(CTxOut(8000, scriptPubKey)) # Might burn this later + tx.rehash() + + self.std_node.test_transaction_acceptance(tx, with_witness=True, accepted=segwit_activated) + + # Now create something that looks like a P2PKH output. This won't be spendable. + scriptPubKey = CScript([OP_0, hash160(witness_hash)]) + tx2 = CTransaction() + if segwit_activated: + # if tx was accepted, then we spend the second output. + tx2.vin = [CTxIn(COutPoint(tx.sha256, 1), b"")] + tx2.vout = [CTxOut(7000, scriptPubKey)] + tx2.wit.vtxinwit.append(CTxInWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] + else: + # if tx wasn't accepted, we just re-spend the p2sh output we started with. + tx2.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx2.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, scriptPubKey)] + tx2.rehash() + + self.std_node.test_transaction_acceptance(tx2, with_witness=True, accepted=segwit_activated) + + # Now update self.utxo for later tests. + tx3 = CTransaction() + if segwit_activated: + # tx and tx2 were both accepted. Don't bother trying to reclaim the + # P2PKH output; just send tx's first output back to an anyone-can-spend. + sync_mempools(self.nodes) + tx3.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] + tx3.vout = [CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))] + tx3.wit.vtxinwit.append(CTxInWitness()) + tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program] + tx3.rehash() + self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=True) + else: + # tx and tx2 didn't go anywhere; just clean up the p2sh_tx output. + tx3.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx3.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, witness_program)] + tx3.rehash() + self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=True) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + self.utxo.pop(0) + self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) + assert_equal(len(self.nodes[1].getrawmempool()), 0) + + # Verify that future segwit upgraded transactions are non-standard, # but valid in blocks. Can run this before and after segwit activation. def test_segwit_versions(self): @@ -1658,6 +1734,7 @@ class SegWitTest(BitcoinTestFramework): self.test_witness_tx_relay_before_segwit_activation() self.test_block_relay(segwit_activated=False) self.test_p2sh_witness(segwit_activated=False) + self.test_standardness_v0(segwit_activated=False) sync_blocks(self.nodes) @@ -1679,6 +1756,7 @@ class SegWitTest(BitcoinTestFramework): self.test_witness_input_length() self.test_block_relay(segwit_activated=True) self.test_tx_relay_after_segwit_activation() + self.test_standardness_v0(segwit_activated=True) self.test_segwit_versions() self.test_premature_coinbase_witness_spend() self.test_signature_version_1() diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index de3996bb4..57df1f0b1 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -49,7 +49,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool w } else if (whichType == TX_NULL_DATA && (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; - + else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH)) return false; From cfd1280f23bf687a38d3d00355ac94a3646cb59f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 18 Jul 2016 10:55:46 +0200 Subject: [PATCH 0939/1223] [doc] gbuild: Set memory explicitly (default is too low) Github-Pull: #8358 Rebased-From: faa59318db48a0acc4b0ccff56b63cc05455c61f --- doc/release-process.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 35ee1edae..41c1ac855 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -112,16 +112,16 @@ The gbuild invocations below DO NOT DO THIS by default. ### Build and sign Bitcoin Core for Linux, Windows, and OS X: pushd ./gitian-builder - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gbuild --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ From 18b8ee1cd1b2c95faac53e49b9023200679f2bb1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 15 Jun 2016 10:49:29 +0200 Subject: [PATCH 0940/1223] [Wallet] add HD xpriv to dumpwallet Github-Pull: #8206 Rebased-From: 77c912d21c8cd153f4503c65225a5a46990cc85a --- src/wallet/rpcdump.cpp | 29 ++++++++++++++++++++++++++--- src/wallet/wallet.h | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index d55cc68dc..6647d3297 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -602,19 +602,42 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); file << "\n"; + + // add the base58check encoded extended master if the wallet uses HD + CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + if (!masterKeyID.IsNull()) + { + CKey key; + if (pwalletMain->GetKey(masterKeyID, key)) + { + CExtKey masterKey; + masterKey.SetMaster(key.begin(), key.size()); + + CBitcoinExtKey b58extkey; + b58extkey.SetKey(masterKey); + + file << "# extended private masterkey: " << b58extkey.ToString() << "\n\n"; + } + } for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { const CKeyID &keyid = it->second; std::string strTime = EncodeDumpTime(it->first); std::string strAddr = CBitcoinAddress(keyid).ToString(); CKey key; if (pwalletMain->GetKey(keyid, key)) { + file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); if (pwalletMain->mapAddressBook.count(keyid)) { - file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr); + file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name)); + } else if (keyid == masterKeyID) { + file << "hdmaster=1"; } else if (setKeyPool.count(keyid)) { - file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << "reserve=1"; + } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") { + file << "inactivehdmaster=1"; } else { - file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << "change=1"; } + file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwalletMain->mapKeyMetadata[keyid].hdKeypath : "")); } } file << "\n"; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3a3cb6d85..efed2ba11 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -899,10 +899,10 @@ public: /* Set the HD chain model (chain child index counters) */ bool SetHDChain(const CHDChain& chain, bool memonly); + const CHDChain& GetHDChain() { return hdChain; } /* Set the current HD master key (will reset the chain child index counters) */ bool SetHDMasterKey(const CKey& key); - const CHDChain& GetHDChain() { return hdChain; } }; /** A key allocated from the key pool. */ From f142c11ac634df487cc4bc65a5f1c9a3e3563dd9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 21 Jul 2016 21:19:02 +0200 Subject: [PATCH 0941/1223] [0.13] Create a new HD seed after encrypting the wallet --- doc/release-notes.md | 2 ++ qa/rpc-tests/keypool.py | 10 ++++++++++ src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 9 +++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index bb9118762..ad11fafd3 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -135,6 +135,8 @@ Existing wallets will still use traditional key generation. Backups of HD wallets, regardless of when they have been created, can therefore be used to re-generate all possible private keys, even the ones which haven't already been generated during the time of the backup. +**Attention:** Encrypting the wallet will create a new seed which requires +a new backup! HD key generation for new wallets can be disabled by `-usehd=0`. Keep in mind that this flag only has affect on newly created wallets. diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index c75303ecb..735b91ee9 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -12,6 +12,11 @@ class KeyPoolTest(BitcoinTestFramework): def run_test(self): nodes = self.nodes + addr_before_encrypting = nodes[0].getnewaddress() + addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting) + wallet_info_old = nodes[0].getwalletinfo() + assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['masterkeyid']) + # Encrypt wallet and wait to terminate nodes[0].encryptwallet('test') bitcoind_processes[0].wait() @@ -19,6 +24,11 @@ class KeyPoolTest(BitcoinTestFramework): nodes[0] = start_node(0, self.options.tmpdir) # Keep creating keys addr = nodes[0].getnewaddress() + addr_data = nodes[0].validateaddress(addr) + wallet_info = nodes[0].getwalletinfo() + assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['masterkeyid']) + assert(addr_data['hdmasterkeyid'] == wallet_info['masterkeyid']) + try: addr = nodes[0].getnewaddress() raise AssertionError('Keypool should be exhausted after one address') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4087b8e77..a90807e51 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2081,7 +2081,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) // slack space in .dat files; that is bad if the old data is // unencrypted private keys. So: StartShutdown(); - return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; + return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } UniValue lockunspent(const UniValue& params, bool fHelp) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5908dfeac..a1d9c4a59 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -626,6 +626,15 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Lock(); Unlock(strWalletPassphrase); + + // if we are using HD, replace the HD master key with a new one + if (!hdChain.masterKeyID.IsNull()) { + CKey key; + key.MakeNewKey(true); + if (!SetHDMasterKey(key)) + return false; + } + NewKeyPool(); Lock(); From de45c065f0648c4c41b57cb492420ceeed29dd11 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 22 Jul 2016 11:03:30 +0200 Subject: [PATCH 0942/1223] [Wallet] Add CKeyMetadata record for HDMasterKey(s), factor out HD key generation --- qa/rpc-tests/keypool.py | 6 ++--- src/wallet/wallet.cpp | 49 ++++++++++++++++++++++++++++++----------- src/wallet/wallet.h | 5 ++++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 735b91ee9..fa3947656 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -15,7 +15,7 @@ class KeyPoolTest(BitcoinTestFramework): addr_before_encrypting = nodes[0].getnewaddress() addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting) wallet_info_old = nodes[0].getwalletinfo() - assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['masterkeyid']) + assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) # Encrypt wallet and wait to terminate nodes[0].encryptwallet('test') @@ -26,8 +26,8 @@ class KeyPoolTest(BitcoinTestFramework): addr = nodes[0].getnewaddress() addr_data = nodes[0].validateaddress(addr) wallet_info = nodes[0].getwalletinfo() - assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['masterkeyid']) - assert(addr_data['hdmasterkeyid'] == wallet_info['masterkeyid']) + assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid']) + assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid']) try: addr = nodes[0].getnewaddress() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a1d9c4a59..e5ee5063a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -627,11 +627,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Lock(); Unlock(strWalletPassphrase); - // if we are using HD, replace the HD master key with a new one + // if we are using HD, replace the HD master key (seed) with a new one if (!hdChain.masterKeyID.IsNull()) { CKey key; - key.MakeNewKey(true); - if (!SetHDMasterKey(key)) + CPubKey masterPubKey = GenerateNewHDMasterKey(); + if (!SetHDMasterKey(masterPubKey)) return false; } @@ -1175,20 +1175,43 @@ CAmount CWallet::GetChange(const CTransaction& tx) const return nChange; } -bool CWallet::SetHDMasterKey(const CKey& key) +CPubKey CWallet::GenerateNewHDMasterKey() +{ + CKey key; + key.MakeNewKey(true); + + int64_t nCreationTime = GetTime(); + CKeyMetadata metadata(nCreationTime); + + // calculate the pubkey + CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); + + // set the hd keypath to "m" -> Master, refers the masterkeyid to itself + metadata.hdKeypath = "m"; + metadata.hdMasterKeyID = pubkey.GetID(); + + { + LOCK(cs_wallet); + + // mem store the metadata + mapKeyMetadata[pubkey.GetID()] = metadata; + + // write the key&metadata to the database + if (!AddKeyPubKey(key, pubkey)) + throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + } + + return pubkey; +} + +bool CWallet::SetHDMasterKey(const CPubKey& pubkey) { LOCK(cs_wallet); // ensure this wallet.dat can only be opened by clients supporting HD SetMinVersion(FEATURE_HD); - // store the key as normal "key"/"ckey" object - // in the database - // key metadata is not required - CPubKey pubkey = key.GetPubKey(); - if (!AddKeyPubKey(key, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); - // store the keyid (hash160) together with // the child index counter in the database // as a hdchain object @@ -3308,8 +3331,8 @@ bool CWallet::InitLoadWallet() if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { // generate a new master key CKey key; - key.MakeNewKey(true); - if (!walletInstance->SetHDMasterKey(key)) + CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); + if (!walletInstance->SetHDMasterKey(masterPubKey)) throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); } CPubKey newDefaultKey; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index efed2ba11..0c95fdf4b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -901,8 +901,11 @@ public: bool SetHDChain(const CHDChain& chain, bool memonly); const CHDChain& GetHDChain() { return hdChain; } + /* Generates a new HD master key (will not be activated) */ + CPubKey GenerateNewHDMasterKey(); + /* Set the current HD master key (will reset the chain child index counters) */ - bool SetHDMasterKey(const CKey& key); + bool SetHDMasterKey(const CPubKey& key); }; /** A key allocated from the key pool. */ From 0179a39f9da1fa417a592e7bf3ebbb1390a292b9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 27 Jul 2016 16:33:00 +0000 Subject: [PATCH 0943/1223] qt: periodic translations update --- src/qt/bitcoinstrings.cpp | 2 +- src/qt/locale/bitcoin_ca.ts | 4 - src/qt/locale/bitcoin_ca@valencia.ts | 4 - src/qt/locale/bitcoin_ca_ES.ts | 4 - src/qt/locale/bitcoin_cs.ts | 4 - src/qt/locale/bitcoin_da.ts | 12 +- src/qt/locale/bitcoin_de.ts | 4 - src/qt/locale/bitcoin_en.ts | 14 +-- src/qt/locale/bitcoin_en_GB.ts | 12 +- src/qt/locale/bitcoin_es.ts | 12 +- src/qt/locale/bitcoin_et.ts | 4 + src/qt/locale/bitcoin_fa_IR.ts | 4 - src/qt/locale/bitcoin_fi.ts | 24 +++- src/qt/locale/bitcoin_fr.ts | 12 +- src/qt/locale/bitcoin_hu.ts | 50 +++++++- src/qt/locale/bitcoin_it.ts | 4 - src/qt/locale/bitcoin_ja.ts | 12 +- src/qt/locale/bitcoin_nb.ts | 4 - src/qt/locale/bitcoin_nl.ts | 4 - src/qt/locale/bitcoin_pl.ts | 32 +++++- src/qt/locale/bitcoin_pt_BR.ts | 4 - src/qt/locale/bitcoin_pt_PT.ts | 4 - src/qt/locale/bitcoin_ro_RO.ts | 4 - src/qt/locale/bitcoin_ru.ts | 8 -- src/qt/locale/bitcoin_sk.ts | 164 +++++++++++++++++++++++++-- src/qt/locale/bitcoin_sr.ts | 12 ++ src/qt/locale/bitcoin_sv.ts | 12 +- src/qt/locale/bitcoin_tr.ts | 12 +- src/qt/locale/bitcoin_uk.ts | 4 - src/qt/locale/bitcoin_zh_CN.ts | 4 - src/qt/locale/bitcoin_zh_TW.ts | 12 +- 31 files changed, 309 insertions(+), 153 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index bca5b7282..22d3e0824 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -311,7 +311,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of d QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum BIP141 block cost (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum BIP141 block weight (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index ed259c4d0..f066760ff 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -2134,10 +2134,6 @@ Set key pool size to <n> (default: %u) Defineix la mida clau disponible a <n> (per defecte: %u) - - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index df0f750a6..bf779aad6 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1966,10 +1966,6 @@ Set key pool size to <n> (default: %u) Defineix la mida clau disponible a <n> (per defecte: %u) - - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index f985a6928..9835c8547 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -2130,10 +2130,6 @@ Set key pool size to <n> (default: %u) Defineix la mida clau disponible a <n> (per defecte: %u) - - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 2dfa295ce..4f198c9ae 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -2234,10 +2234,6 @@ Set key pool size to <n> (default: %u) Nastavit zásobník klíčů na velikost <n> (výchozí: %u) - - Set minimum block size in bytes (default: %u) - Nastavit minimální velikost bloku v bajtech (výchozí: %u) - Set the number of threads to service RPC calls (default: %d) Nastavení počtu vláken pro servisní RPC volání (výchozí: %d) diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index d298c81bd..04dd13fc7 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -2098,10 +2098,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d) - - Set maximum block cost (default: %d) - Sæt maksimal blokudgift (standard: %d) - Set maximum block size in bytes (default: %d) Sæt maksimum blokstørrelse i byte (standard: %d) @@ -2306,6 +2302,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u) + + Set maximum BIP141 block cost (default: %d) + Sæt maksimal BIP141-blokudgift (standard: %d) + Show all debugging options (usage: --help -help-debug) Vis alle tilvalg for fejlsøgning (brug: --help -help-debug) @@ -2531,10 +2531,6 @@ Sæt nøglepuljestørrelse til <n> (standard: %u) - - Set minimum block size in bytes (default: %u) - Angiv minimumsblokstørrelse i byte (standard: %u) - Set the number of threads to service RPC calls (default: %d) Angiv antallet af tråde til at håndtere RPC-kald (standard: %d) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 2708324d1..86355944e 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -2434,10 +2434,6 @@ Set key pool size to <n> (default: %u) Größe des Schlüsselpools festlegen auf <n> (Standard: %u) - - Set minimum block size in bytes (default: %u) - Minimale Blockgröße in Byte festlegen (Standard: %u) - Set the number of threads to service RPC calls (default: %d) Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 79c3e87b2..2785ed929 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -2686,7 +2686,12 @@ - + + Set maximum BIP141 block weight (default: %d) + + + + Set maximum block size in bytes (default: %d) @@ -2941,12 +2946,7 @@ - - Set maximum BIP141 block cost (default: %d) - - - - + Show all debugging options (usage: --help -help-debug) diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 1893aaca0..ac7108e66 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -2098,10 +2098,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Set database cache size in megabytes (%d to %d, default: %d) - - Set maximum block cost (default: %d) - Set maximum block cost (default: %d) - Set maximum block size in bytes (default: %d) Set maximum block size in bytes (default: %d) @@ -2306,6 +2302,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transactions as zero-fee transactions if possible (default: %u) + + Set maximum BIP141 block cost (default: %d) + Set maximum BIP141 block cost (default: %d) + Show all debugging options (usage: --help -help-debug) Show all debugging options (usage: --help -help-debug) @@ -2530,10 +2530,6 @@ Set key pool size to <n> (default: %u) Set key pool size to <n> (default: %u) - - Set minimum block size in bytes (default: %u) - Set minimum block size in bytes (default: %u) - Set the number of threads to service RPC calls (default: %d) Set the number of threads to service RPC calls (default: %d) diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index c67016637..8952a0adc 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -2097,10 +2097,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) - - Set maximum block cost (default: %d) - Establecer tamaño máximo de bloque (por defecto: %d) - Set maximum block size in bytes (default: %d) Establecer tamaño máximo de bloque en bytes (predeterminado: %d) @@ -2305,6 +2301,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Mandar transacciones como comisión-cero si es posible (por defecto: %u) + + Set maximum BIP141 block cost (default: %d) + Fijar coste máximo del bloque BIP141 (por defecto: %d) + Show all debugging options (usage: --help -help-debug) Muestra todas las opciones de depuración (uso: --help -help-debug) @@ -2519,10 +2519,6 @@ Set key pool size to <n> (default: %u) Ajustar el número de claves en reserva <n> (predeterminado: %u) - - Set minimum block size in bytes (default: %u) - Establecer tamaño mínimo de bloque en bytes (por defecto: %u) - Set the number of threads to service RPC calls (default: %d) Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d) diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 0d659fd71..d17904d97 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + Paremkliki aadressi või sildi muutmiseks + Create a new address Loo uus aadress diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index 8faa3ce65..afeab08c7 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -512,10 +512,6 @@ Loading addresses... لود شدن آدرسها.. - - Set minimum block size in bytes (default: %u) - تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u) - Set the number of threads to service RPC calls (default: %d) تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d) diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index b7b3115e2..4a2cc17f3 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1037,6 +1037,14 @@ User Agent Käyttöliittymä + + Decrease font size + Pienennä fontin kokoa + + + Increase font size + Suurenna fontin kokoa + Services Palvelut @@ -1508,6 +1516,10 @@ ShutdownWindow + + %1 is shutting down... + %1 sulkeutuu... + Do not shut down the computer until this window disappears. Älä sammuta tietokonetta ennenkuin tämä ikkuna katoaa. @@ -1690,6 +1702,10 @@ Bitcoin Core Bitcoin-ydin + + The %s developers + %s kehittäjät + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee on asetettu erittäin suureksi! Tämä on rahansiirtokulu jonka voit maksaa kun arvioitu rahansirtokulu ei ole saatavilla. @@ -1702,6 +1718,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa) + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Tarkistathan että tietokoneesi päivämäärä ja kellonaika ovat oikeassa! Jos kellosi on väärässä, %s ei toimi oikein. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d) @@ -2066,10 +2086,6 @@ Set key pool size to <n> (default: %u) Aseta avainaltaan kooksi <n> (oletus: %u) - - Set minimum block size in bytes (default: %u) - Aseta pienin mahdollinen lohkokoko tavuina (oletus: %u) - Set the number of threads to service RPC calls (default: %d) Aseta RPC-kutsujen palvelemiseen tarkoitettujen säikeiden lukumäärä (oletus: %d) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 0b538d766..086bc1deb 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -2070,10 +2070,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) - - Set maximum block cost (default: %d) - Définir le coût maximal de bloc (par défaut : %d) - Set maximum block size in bytes (default: %d) Définir la taille minimale de bloc en octets (par défaut : %d) @@ -2270,6 +2266,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Envoyer si possible les transactions comme étant sans frais (par défaut : %u) + + Set maximum BIP141 block cost (default: %d) + Définir le coût maximal de bloc BIP141 (par défaut : %d) + Show all debugging options (usage: --help -help-debug) Montrer toutes les options de débogage (utilisation : --help --help-debug) @@ -2494,10 +2494,6 @@ Set key pool size to <n> (default: %u) Définir la taille de la réserve de clefs à <n> (par défaut : %u) - - Set minimum block size in bytes (default: %u) - Définir la taille de bloc minimale en octets (par défaut : %u) - Set the number of threads to service RPC calls (default: %d) Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d) diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 9eb0cf76c..895e919c9 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -63,7 +63,15 @@ BanTableModel - + + IP/Netmask + IP-cím/maszk + + + Banned Until + Kitiltás vége + + BitcoinGUI @@ -869,6 +877,10 @@ &Peers &Peerek + + Banned peers + Kitiltott felek + Select a peer to view detailed information. Peer kijelölése a részletes információkért @@ -941,6 +953,10 @@ Clear console Konzol törlése + + Ban Node for + Kitiltás oka + 1 &hour 1 &óra @@ -957,6 +973,10 @@ 1 &year 1 &év + + &Unban Node + Kitiltás &feloldása + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt. @@ -1362,6 +1382,10 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Parancs, amit akkor hajt végre, amikor egy tárca-tranzakció megváltozik (%s a parancsban lecserélődik a blokk TxID-re) + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + UPnP használata porttovábbításra (alapértelmezett: 1, amikor kiszolgál és nem használt a -proxy) + Connect only to the specified node(s) Csatlakozás csak a megadott csomóponthoz @@ -1406,6 +1430,10 @@ Incorrect or no genesis block found. Wrong datadir for network? Helytelen vagy nemlétező genézis blokk. Helytelen hálózati adatkönyvtár? + + Loading banlist... + Tiltólista betöltése... + Not enough file descriptors available. Nincs elég fájlleíró. @@ -1422,6 +1450,18 @@ Wallet options: Tárca beállítások: + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Saját IP-cím felfedezése (alapértelmezett: 1, amikor kiszolgál és nem használt a -externalip) + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + A fehérlistán szereplő felek nem lesznek automatikusan kitiltva és a tranzakcióik is mindig továbbítva lesznek, akkor is ha már a megerősítésre váró listán (mempool) vannak. Hasznos például összekötő csomópontokon (gateway). + + + (default: %u) + (alapértelmezett: %u) + Error reading from database, shutting down. Hiba az adatbázis olvasásakor, leállítás @@ -1480,6 +1520,14 @@ Loading addresses... Címek betöltése... + + (default: %s) + (alapértelmezett: %s) + + + Include IP addresses in debug output (default: %u) + IP-címek megjelenítése a naplóban (alapértelmezett: %u) + Invalid -proxy address: '%s' Érvénytelen -proxy cím: '%s' diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 55bc9c3c8..752c4f4fe 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -2259,10 +2259,6 @@ Per specificare più URL separarli con una barra verticale "|". Set key pool size to <n> (default: %u) Imposta la dimensione del pool di chiavi a <n> (predefinito: %u) - - Set minimum block size in bytes (default: %u) - Imposta la dimensione minima del blocco in byte (predefinito: %u) - Set the number of threads to service RPC calls (default: %d) Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d) diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 4948cc306..767a14382 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -2099,10 +2099,6 @@ Set database cache size in megabytes (%d to %d, default: %d) データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d) - - Set maximum block cost (default: %d) - 最大ブロックコストを設定 (初期値: %d) - Set maximum block size in bytes (default: %d) 最大ブロックサイズをバイトで設定 (初期値: %d) @@ -2307,6 +2303,10 @@ Send transactions as zero-fee transactions if possible (default: %u) 可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u) + + Set maximum BIP141 block cost (default: %d) + BIP141ブロックコストの最大値を設定 (初期値: %d) + Show all debugging options (usage: --help -help-debug) すべてのデバッグオプションを表示する (使い方: --help -help-debug) @@ -2531,10 +2531,6 @@ Set key pool size to <n> (default: %u) key pool のサイズを <n> (初期値: %u) にセット - - Set minimum block size in bytes (default: %u) - 最小ブロックサイズをバイトで設定 (初期値: %u) - Set the number of threads to service RPC calls (default: %d) RPC サービスのスレッド数を設定 (初期値: %d) diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 4538fd6e1..a22feb0a6 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -2258,10 +2258,6 @@ Set key pool size to <n> (default: %u) Angi størrelse på nøkkel-lager til <n> (standardverdi: %u) - - Set minimum block size in bytes (default: %u) - Sett minimum blokkstørrelse i bytes (standardverdi: %u) - Set the number of threads to service RPC calls (default: %d) Sett antall tråder til betjening av RPC-kall (standardverdi: %d) diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 781c5a8fd..6fe1acfbb 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -2490,10 +2490,6 @@ Set key pool size to <n> (default: %u) Stel sleutelpoelgrootte in op <n> (standaard: %u) - - Set minimum block size in bytes (default: %u) - Stel minimum blokgrootte in in bytes (standaard: %u) - Set the number of threads to service RPC calls (default: %d) Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d) diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 09f748b83..929f38a5b 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1141,6 +1141,10 @@ Ping Time Czas odpowiedzi + + The duration of a currently outstanding ping. + Czas trwania nadmiarowego pingu + Ping Wait Czas odpowiedzi @@ -1755,6 +1759,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Prune configured below the minimum of %d MiB. Please use a higher number. Przycinanie skonfigurowano poniżej minimalnych %d MiB. Proszę użyć wyższej liczby. + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune: ostatnia synchronizacja portfela jest za danymi. Muszisz -reindexować (pobrać cały ciąg bloków ponownie w przypadku przyciętego węzła) + Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log @@ -1871,6 +1879,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Block creation options: Opcje tworzenia bloku: + + Cannot resolve -%s address: '%s' + Nie można rozpoznać -%s adresu: '%s' + Connect only to the specified node(s) Łącz się tylko do wskazanego węzła/węzłów @@ -1967,6 +1979,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Keep the transaction memory pool below <n> megabytes (default: %u) Utrzymuj obszar pamięci dla transakcji poniżej <n> MB (default: %u) + + Loading banlist... + Ładowanie listy zablokowanych... + + + Location of the auth cookie (default: data dir) + Lokalizacja autoryzacyjnego pliku cookie (domyślnie: ścieżka danych) + Not enough file descriptors available. Brak wystarczającej liczby deskryptorów plików. @@ -2011,6 +2031,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Specify wallet file (within data directory) Określ plik portfela (w obrębie folderu danych) + + The source code is available from %s. + Kod źródłowy dostępny jest z %s. + Unable to bind to %s on this computer. %s is probably already running. Nie można przywiązać do %s na tym komputerze. %s prawdopodobnie jest już uruchomiony. @@ -2211,6 +2235,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Tor control port password (default: empty) Hasło zabezpieczające portu kontrolnego Tora (domyślnie: puste) + + Tor control port to use if onion listening enabled (default: %s) + Port kontrolny sieci Tor jeśli onion listening jest włączone (domyślnie: %s) + Transaction amount too small Zbyt niska kwota transakcji @@ -2391,10 +2419,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Set key pool size to <n> (default: %u) Ustaw rozmiar puli kluczy na <n> (domyślnie: %u) - - Set minimum block size in bytes (default: %u) - Ustaw minimalny rozmiar bloku w bajtach (domyślnie: %u) - Set the number of threads to service RPC calls (default: %d) Ustaw liczbę wątków do obsługi RPC (domyślnie: %d) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index ee48c6734..8b7d08bc7 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -2426,10 +2426,6 @@ Set key pool size to <n> (default: %u) Defina o tamanho da chave para piscina<n> (padrão: %u) - - Set minimum block size in bytes (default: %u) - Definir tamanho mínimo do bloco, em bytes (padrão: %u) - Set the number of threads to service RPC calls (default: %d) Defina o número de threads para chamadas do serviço RPC (padrão: %d) diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index eed262e01..097c6de49 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -2387,10 +2387,6 @@ Set key pool size to <n> (default: %u) Definir tamanho do banco de memória da chave para <n> (predefinição: %u) - - Set minimum block size in bytes (default: %u) - Definir tamanho minímo de um bloco em bytes (por defeito: %u) - Set the number of threads to service RPC calls (default: %d) Defina o número de processos para servir as chamadas RPC (por defeito: %d) diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 489ed0763..afd3cc5f1 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -1862,10 +1862,6 @@ Invalid -proxy address: '%s' Adresa -proxy nevalidă: '%s' - - Set minimum block size in bytes (default: %u) - Setare mărime minimă bloc în octeţi (implicit: %u) - Specify configuration file (default: %s) Specificaţi fişierul configuraţie (implicit: %s) diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 60f5d5dfa..db9d37c8c 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -2026,10 +2026,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d) - - Set maximum block cost (default: %d) - Задать максимальную стоимость блока (по умолчанию: %d) - Set maximum block size in bytes (default: %d) Задать максимальный размер блока в байтах (по умолчанию: %d) @@ -2450,10 +2446,6 @@ Set key pool size to <n> (default: %u) Установить размер пула ключей в <n> (по умолчанию: %u) - - Set minimum block size in bytes (default: %u) - Задать минимальный размер блока в байтах (по умолчанию: %u) - Set the number of threads to service RPC calls (default: %d) Задать число потоков выполнения запросов RPC (по умолчанию: %d) diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index a4f0ebcb4..527f95d14 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Kliknutím pravým tlačidlom upravte adresu alebo popis + Kliknutím pravým tlačidlom upraviť adresu alebo popis Create a new address @@ -11,11 +11,11 @@ &New - &Nové + &Nový Copy the currently selected address to the system clipboard - Kopírovať práve zvolenú adresu do systémového klipbordu + Zkopírovať práve zvolenú adresu &Copy @@ -114,6 +114,10 @@ &About %1 &O %1 + + Show information about %1 + Ukázať informácie o %1 + About &Qt O &Qt @@ -126,6 +130,10 @@ &Options... &Možnosti... + + Modify configuration options for %1 + Upraviť nastavenia pre %1 + &Encrypt Wallet... &Zašifrovať Peňaženku... @@ -254,6 +262,14 @@ %n active connection(s) to Bitcoin network %n aktívne pripojenie do siete Bitcoin%n aktívne pripojenia do siete Bitcoin%n aktívnych pripojení do siete Bitcoin + + Indexing blocks on disk... + Indexujem bloky na disku... + + + Processing blocks on disk... + Spracovávam bloky na disku... + No block source available... Nedostupný zdroj blokov... @@ -310,6 +326,14 @@ Up to date Aktualizovaný + + Show the %1 help message to get a list with possible Bitcoin command-line options + Ukáž %1 zoznam možných nastavení Bitcoinu pomocou príkazového riadku + + + %1 client + %1 klient + Catching up... Sťahujem... @@ -496,6 +520,10 @@ (%1-bit) (%1-bit) + + About %1 + O %1 + Command-line options Voľby príkazového riadku @@ -532,13 +560,25 @@ Show splash screen on startup (default: %u) Zobraziť uvítaciu obrazovku pri štarte (predvolené: %u) - + + Reset all settings changed in the GUI + Zrušiť všetky zmeny v GUI + + Intro Welcome Vitajte + + Welcome to %1. + Vitajte v %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Keďže toto je prvé spustenie programu, môžete si vybrať, kam %1 bude ukladať vaše údaje. + Use the default data directory Použiť predvolený dátový adresár @@ -593,6 +633,14 @@ &Main &Hlavné + + Automatically start %1 after logging in to the system. + Automaticky spustiť %1 pri spustení systému. + + + &Start %1 on system login + &Spustiť %1 pri prihlásení + Size of &database cache Veľkosť vyrovnávacej pamäti &databázy @@ -729,6 +777,14 @@ &Window &Okno + + &Hide the icon from the system tray. + &Skryť ikonu zo systémovej lišty. + + + Hide tray icon + Skryť ikonu v oblasti oznámení + Show only a tray icon after minimizing the window. Zobraziť len ikonu na lište po minimalizovaní okna. @@ -749,6 +805,10 @@ User Interface &language: Jazyk užívateľského rozhrania: + + The user interface language can be set here. This setting will take effect after restarting %1. + Jazyk uživateľského rozhrania sa dá nastaviť tu. Toto nastavenie sa uplatní až po reštarte %1. + &Unit to show amounts in: &Zobrazovať hodnoty v jednotkách: @@ -1038,6 +1098,18 @@ User Agent Aplikácia + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Otvoriť %1 ladiaci výpis z aktuálnej zložky. Pre veľké súbory to môže chvíľu trvať. + + + Decrease font size + Zmenšiť písmo + + + Increase font size + Zväčšiť písmo + Services Služby @@ -1517,6 +1589,10 @@ ShutdownWindow + + %1 is shutting down... + %1 sa vypína... + Do not shut down the computer until this window disappears. Nevypínajte počítač kým toto okno nezmizne. @@ -1651,6 +1727,14 @@ Accept command line and JSON-RPC commands Prijímať príkazy z príkazového riadku a JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Pokiaľ <category> nie je nastavená, alebo <category> = 1, vypíš všetky informácie pre ladenie. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Redukcia nastavená pod minimálnu hodnotu %d MiB. Prosím použite vyššiu hodnotu. + Error: A fatal internal error occurred, see debug.log for details Chyba: Vyskytla sa interná chyba, pre viac informácií zobrazte debug.log @@ -1683,6 +1767,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6 + + Cannot obtain a lock on data directory %s. %s is probably already running. + Nemožné uzamknúť zložku %s. %s pravdepodobne už beží. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan @@ -1695,10 +1783,22 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID) + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Prosím skontrolujte systémový čas a dátum. Keď je váš čas nesprávny, %s nebude fungovať správne. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Keď si myslíte, že %s je užitočný, podporte nás. Pre viac informácií o software navštívte %s. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastaviť počeť vlákien overujúcich skripty (%u až %d, 0 = auto, <0 = nechať toľkoto jadier voľných, prednastavené: %d) + + 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 + Databáza blokov obsahuje blok, ktorý vyzerá byť z budúcnosti. Toto môže byť spôsobené nesprávnym systémovým časom vášho počítača. Obnovujte databázu blokov len keď ste si istý, že systémový čas je nastavený správne. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie. @@ -1729,6 +1829,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Block creation options: Voľby vytvorenia bloku: + + Change index out of range + Menný index mimo rozsah + Connect only to the specified node(s) Pripojiť sa len k určenej nóde @@ -1737,6 +1841,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Connection options: Možnosti pripojenia: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Zistená poškodená databáza blokov @@ -1765,6 +1873,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Enable publish raw block in <address> Povoliť zverejnenie raw bloku pre <address> + + Enable publish raw transaction in <address> + Povoliť publikovať hrubý prevod v <address> + Error initializing block database Chyba inicializácie databázy blokov @@ -1809,6 +1921,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Incorrect or no genesis block found. Wrong datadir for network? Nesprávny alebo žiadny genesis blok nájdený. Nesprávny dátový priečinok alebo sieť? + + Initialization sanity check failed. %s is shutting down. + Kontrola čistoty pri inicializácií zlyhala. %s sa vypína. + Invalid -onion address: '%s' Neplatná -onion adresa: '%s' @@ -1833,6 +1949,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Only connect to nodes in network <net> (ipv4, ipv6 or onion) Pripojiť iba k uzlom v sieti <net> (ipv4, ipv6, alebo onion) + + Print this help message and exit + Vytlačiť túto pomocnú správu a ukončiť + + + Print version and exit + Vytlačiť verziu a ukončiť + Prune cannot be configured with a negative value. Redukovanie nemôže byť nastavené na zápornú hodnotu. @@ -1841,6 +1965,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Prune mode is incompatible with -txindex. Redukovanie je nekompatibilné s -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Obnoviť stav reťazca a index blokov zo súborov blk*.dat na disku. + + + Rebuild chain state from the currently indexed blocks + Obnoviť stav reťazca z aktuálne indexovaných blokov. + Set database cache size in megabytes (%d to %d, default: %d) Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d) @@ -1853,6 +1985,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Specify wallet file (within data directory) Označ súbor peňaženky (v priečinku s dátami) + + The source code is available from %s. + Zdrojový kód je dostupný z %s + + + Unable to bind to %s on this computer. %s is probably already running. + Nemožné pripojiť k %s na tomto počíťači. %s už pravdepodobne beží. + Unsupported argument -benchmark ignored, use -debug=bench. Nepodporovaný parameter -benchmark bol ignorovaný, použite -debug=bench. @@ -1881,6 +2021,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Wallet %s resides outside data directory %s Peňaženka %s sa nachádza mimo dátového priečinka %s + + Wallet debugging/testing options: + Ladiace / testovacie možnosti peňaženky. + + + Wallet needed to be rewritten: restart %s to complete + Peňaženka musí byť prepísaná: pre dokončenie reštartujte %s + Wallet options: Voľby peňaženky: @@ -1997,6 +2145,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin RPC server options: Možnosti servra RPC: + + Rescan the block chain for missing wallet transactions on startup + Pri spustení skontrolovať reťaz blokov pre chýbajúce transakcie peňaženky + Send trace/debug info to console instead of debug.log file Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu @@ -2161,10 +2313,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Set key pool size to <n> (default: %u) Nastaviť veľkosť kľúča fronty na <n> (predvolené: %u) - - Set minimum block size in bytes (default: %u) - Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u) - Set the number of threads to service RPC calls (default: %d) Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d) diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 6b6f1af6f..729bd08b3 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -1,6 +1,10 @@ AddressBookPage + + Right-click to edit address or label + Kliknite desnim klikom radi izmene adrese ili oznake + Create a new address Napravite novu adresu @@ -17,10 +21,18 @@ &Copy Kopirajte + + C&lose + Zatvorite + Delete the currently selected address from the list Izbrisite trenutno izabranu adresu sa liste + + Export the data in the current tab to a file + Eksportuj podatke iz izabrane kartice u fajl + &Delete &Избриши diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index ee46974d8..0455ba189 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -2094,10 +2094,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d) - - Set maximum block cost (default: %d) - Sätt maximal blockkostnad (förvalt: %d) - Set maximum block size in bytes (default: %d) Sätt maximal blockstorlek i byte (förvalt: %d) @@ -2302,6 +2298,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u) + + Set maximum BIP141 block cost (default: %d) + Sätt maximal BIP141 blockkostnad (förvalt: %d) + Show all debugging options (usage: --help -help-debug) Visa alla avlusningsalternativ (använd: --help -help-debug) @@ -2526,10 +2526,6 @@ Set key pool size to <n> (default: %u) Sätt storleken på nyckelpoolen till <n> (förvalt: %u) - - Set minimum block size in bytes (default: %u) - Sätt minsta blockstorlek i byte (standard: %u) - Set the number of threads to service RPC calls (default: %d) Ange antalet trådar för att hantera RPC anrop (förvalt: %d) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index e3a811b50..3dfc85eaf 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -2098,10 +2098,6 @@ Set database cache size in megabytes (%d to %d, default: %d) Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d) - - Set maximum block cost (default: %d) - Azami blok maliyetini ayarla (varsayılan: %d) - Set maximum block size in bytes (default: %d) Azami blok boyutunu bayt olarak ayarla (varsayılan: %d) @@ -2306,6 +2302,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u) + + Set maximum BIP141 block cost (default: %d) + Azami BIP141 blok maliyetini ayarla (varsayılan: %d) + Show all debugging options (usage: --help -help-debug) Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug) @@ -2530,10 +2530,6 @@ Set key pool size to <n> (default: %u) Anahtar alan boyutunu <n> değerine ayarla (varsayılan: %u) - - Set minimum block size in bytes (default: %u) - Bayt olarak asgari blok boyutunu tanımla (varsayılan: %u) - Set the number of threads to service RPC calls (default: %d) Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d) diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index a06cc9e09..bdfe3f57e 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -2262,10 +2262,6 @@ Set key pool size to <n> (default: %u) Встановити розмір пулу ключів <n> (типово: %u) - - Set minimum block size in bytes (default: %u) - Встановити мінімальний розмір блоку в байтах (типово: %u) - Set the number of threads to service RPC calls (default: %d) Встановити число потоків для обслуговування викликів RPC (типово: %d) diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 92a7006d3..e7a706ee5 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -2260,10 +2260,6 @@ Set key pool size to <n> (default: %u) 设置私钥池大小为 <n> (默认:%u) - - Set minimum block size in bytes (default: %u) - 设置数据块 最小字节数 (默认: %u) - Set the number of threads to service RPC calls (default: %d) 设置RPC服务线程数 (默认: %d) diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index ab56f9679..e2934d0b9 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -2099,10 +2099,6 @@ Set database cache size in megabytes (%d to %d, default: %d) 設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d) - - Set maximum block cost (default: %d) - 設定區塊成本的最大值(預設值: %d) - Set maximum block size in bytes (default: %d) 設定區塊大小上限成多少位元組(預設值: %d) @@ -2307,6 +2303,10 @@ Send transactions as zero-fee transactions if possible (default: %u) 盡可能送出不用付手續費的交易(預設值: %u) + + Set maximum BIP141 block cost (default: %d) + 設定區塊成本(BIP141)的最大值(預設值: %d) + Show all debugging options (usage: --help -help-debug) 顯示所有的除錯選項 (用法: --help --help-debug) @@ -2531,10 +2531,6 @@ Set key pool size to <n> (default: %u) 設定密鑰池大小為 <n> (預設值: %u) - - Set minimum block size in bytes (default: %u) - 設定區塊大小下限為多少位元組(預設值: %u) - Set the number of threads to service RPC calls (default: %d) 設定處理 RPC 服務請求的執行緒數目(預設值: %d) From 45eba4b1e0658639bb92730723b987f05e171529 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 26 Jul 2016 14:01:36 +0200 Subject: [PATCH 0944/1223] [Qt] Add dbcache migration path Github-Pull: #8407 Rebased-From: 893f379ba0befef5301208b6bee8206ac4e76329 --- src/qt/optionsmodel.cpp | 21 +++++++++++++++++++++ src/qt/optionsmodel.h | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index cc2cbc0e6..684db71a8 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -43,6 +43,8 @@ void OptionsModel::Init(bool resetSettings) if (resetSettings) Reset(); + checkAndMigrate(); + QSettings settings; // Ensure restart flag is unset on client startup @@ -429,3 +431,22 @@ bool OptionsModel::isRestartRequired() QSettings settings; return settings.value("fRestartRequired", false).toBool(); } + +void OptionsModel::checkAndMigrate() +{ + // Migration of default values + // Check if the QSettings container was already loaded with this client version + QSettings settings; + static const char strSettingsVersionKey[] = "nSettingsVersion"; + int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0; + if (settingsVersion < CLIENT_VERSION) + { + // -dbcache was bumped from 100 to 300 in 0.13 + // see https://github.com/bitcoin/bitcoin/pull/8273 + // force people to upgrade to the new value if they are using 100MB + if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100) + settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); + + settings.setValue(strSettingsVersionKey, CLIENT_VERSION); + } +} \ No newline at end of file diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 3b491ceac..b23b5f260 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -84,9 +84,11 @@ private: /* settings that were overriden by command-line */ QString strOverriddenByCommandLine; - /// Add option to list of GUI options overridden through command line/config file + // Add option to list of GUI options overridden through command line/config file void addOverriddenOption(const std::string &option); + // Check settings version and upgrade default values if required + void checkAndMigrate(); Q_SIGNALS: void displayUnitChanged(int unit); void coinControlFeaturesChanged(bool); From 8360d5b37dd4d8248da0552de40e5ea1d17f51eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 27 Jul 2016 22:42:13 +0200 Subject: [PATCH 0945/1223] libconsensus: Expose a flag for BIP112 We added the segwit one, but we forgot CHECKSEQUENCEVERIFY Github-Pull: #8412 Rebased-From: d12b732ac287a1ed7543481b79801c9afc333b7f --- src/script/bitcoinconsensus.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 6f868d0d6..f73a8e30b 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -51,6 +51,7 @@ enum bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141) }; From b7e201181bcc0f6328e0a499803f1dbb2c2dbd28 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 26 Jul 2016 16:50:48 -0400 Subject: [PATCH 0946/1223] Prevent fingerprinting, disk-DoS with compact blocks - Ignore GETBLOCKTXN requests for unknown blocks Don't disconnect peers, or else we leak information that could be used for fingerprinting. - Ignore CMPCTBLOCK messages for pruned blocks Also ignores CMPCTBLOCK announcements that have too little work. This is to prevent disk-exhaustion DoS. Github-Pull: #8408 Rebased-From: 1de2a46632946990a7863020b61172232f8c5796 1d06e49834814eed45e07393dcffd7b6683311b2 --- src/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 70f0a4247..a80eb6212 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5344,7 +5344,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, BlockMap::iterator it = mapBlockIndex.find(req.blockhash); if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) { - Misbehaving(pfrom->GetId(), 100); LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id); return true; } @@ -5628,8 +5627,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, std::vector vInv(1); vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); - return true; } + return true; } // If we're not close to tip yet, give up and let parallel block fetch work its magic From b06808c58eb7a997c42b55cba63688aec448a0ea Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 29 Jul 2016 09:50:00 +0200 Subject: [PATCH 0947/1223] doc: Release notes update for rc2 --- doc/release-notes.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index ad11fafd3..78f29158d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -361,6 +361,7 @@ git merge commit are mentioned. - #8149 `d612837` Testnet-only segregated witness (sipa) - #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) - #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) +- #8381 `f84ee3d` Make witness v0 outputs non-standard (jl2012) ### P2P protocol and network code @@ -407,6 +408,7 @@ git merge commit are mentioned. - #8312 `ca40ef6` Fix mempool DoS vulnerability from malleated transactions (sdaftuar) - #7180 `16ccb74` Account for `sendheaders` `verack` messages (laanwj) - #8102 `425278d` Bugfix: use global ::fRelayTxes instead of CNode in version send (sipa) +- #8408 `b7e2011` Prevent fingerprinting, disk-DoS with compact blocks (sdaftuar) ### Build system @@ -450,6 +452,8 @@ git merge commit are mentioned. - #8310 `6ae20df` Require boost for bench (theuni) - #8315 `2e51590` Don't require sudo for Linux (theuni) - #8314 `67caef6` Fix pkg-config issues for 0.13 (theuni) +- #8373 `1fe7f40` Fix OSX non-deterministic dmg (theuni) +- #8358 `cfd1280` Gbuild: Set memory explicitly (default is too low) (MarcoFalke) ### GUI @@ -493,6 +497,7 @@ git merge commit are mentioned. - #7707 `a914968` UI support for abandoned transactions (jonasschnelli) - #8207 `f7a403b` Add a link to the Bitcoin-Core repository and website to the About Dialog (MarcoFalke) - #8281 `6a87eb0` Remove client name from debug window (laanwj) +- #8407 `45eba4b` Add dbcache migration path (jonasschnelli) ### Wallet @@ -523,6 +528,10 @@ git merge commit are mentioned. - #8324 `bc94b87` Keep HD seed during salvagewallet (jonasschnelli) - #8323 `238300b` Add HD keypath to CKeyMetadata, report metadata in validateaddress (jonasschnelli) - #8367 `3b38a6a` Ensure <0.13 clients can't open HD wallets (jonasschnelli) +- #8378 `ebea651` Move SetMinVersion for FEATURE_HD to SetHDMasterKey (pstratem) +- #8390 `73adfe3` Correct hdmasterkeyid/masterkeyid name confusion (jonasschnelli) +- #8206 `18b8ee1` Add HD xpriv to dumpwallet (jonasschnelli) +- #8389 `c3c82c4` Create a new HD seed after encrypting the wallet (jonasschnelli) ### Tests and QA @@ -616,6 +625,7 @@ git merge commit are mentioned. - #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) - #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) - #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) +- #8362 `86edc20` Scale legacy sigop count in CreateNewBlock (sdaftuar) ### Documentation and miscellaneous @@ -682,6 +692,7 @@ git merge commit are mentioned. - #7934 `f17032f` Improve rolling bloom filter performance and benchmark (sipa) - #8004 `2efe38b` signal handling: fReopenDebugLog and fRequestShutdown should be type sig_atomic_t (catilac) - #7713 `f6598df` Fixes for verify-commits script (petertodd) +- #8412 `8360d5b` libconsensus: Expose a flag for BIP112 (jtimon) Credits ======= @@ -727,6 +738,7 @@ Thanks to everyone who directly contributed to this release: - Gregory Sanders - instagibbs - James O'Beirne +- Jannes Faber - Jarret Dyrbye - Jeremy Rand - jloughry From ced6c940da35fcf33160d1c7f2f54a99dc7eedb1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 29 Jul 2016 07:55:53 +0000 Subject: [PATCH 0948/1223] qt: Translations update pre-rc2 --- src/qt/locale/bitcoin_da.ts | 4 - src/qt/locale/bitcoin_de.ts | 8 ++ src/qt/locale/bitcoin_en_GB.ts | 4 - src/qt/locale/bitcoin_es.ts | 4 - src/qt/locale/bitcoin_fr.ts | 8 +- src/qt/locale/bitcoin_ja.ts | 4 - src/qt/locale/bitcoin_nb.ts | 12 ++ src/qt/locale/bitcoin_pt_BR.ts | 44 +++++++ src/qt/locale/bitcoin_sv.ts | 4 - src/qt/locale/bitcoin_tr.ts | 4 - src/qt/locale/bitcoin_vi_VN.ts | 230 ++++++++++++++++++++++++++++++++- src/qt/locale/bitcoin_zh_TW.ts | 4 - 12 files changed, 296 insertions(+), 34 deletions(-) diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 04dd13fc7..db52367ef 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -2302,10 +2302,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u) - - Set maximum BIP141 block cost (default: %d) - Sæt maksimal BIP141-blokudgift (standard: %d) - Show all debugging options (usage: --help -help-debug) Vis alle tilvalg for fejlsøgning (brug: --help -help-debug) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 86355944e..502d02b7f 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -809,6 +809,10 @@ User Interface &language: &Sprache der Benutzeroberfläche: + + The user interface language can be set here. This setting will take effect after restarting %1. + Die Benutzeroberflächensprache kann hier festgelegt werden. Diese Einstellung wird nach einem Neustart von %1 wirksam werden. + &Unit to show amounts in: &Einheit der Beträge: @@ -1886,6 +1890,10 @@ Cannot resolve -%s address: '%s' Kann Adresse in -%s nicht auflösen: '%s' + + Change index out of range + Änderungsindex außerhalb des Bereichs + Connect only to the specified node(s) Mit nur dem oder den angegebenen Knoten verbinden diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index ac7108e66..596fd1db2 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -2302,10 +2302,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transactions as zero-fee transactions if possible (default: %u) - - Set maximum BIP141 block cost (default: %d) - Set maximum BIP141 block cost (default: %d) - Show all debugging options (usage: --help -help-debug) Show all debugging options (usage: --help -help-debug) diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 8952a0adc..1a367c276 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -2301,10 +2301,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Mandar transacciones como comisión-cero si es posible (por defecto: %u) - - Set maximum BIP141 block cost (default: %d) - Fijar coste máximo del bloque BIP141 (por defecto: %d) - Show all debugging options (usage: --help -help-debug) Muestra todas las opciones de depuración (uso: --help -help-debug) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 086bc1deb..ebfc773fb 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -2070,6 +2070,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) + + Set maximum BIP141 block weight (default: %d) + Définir le poids maximal de bloc BIP141 (par défaut : %d) + Set maximum block size in bytes (default: %d) Définir la taille minimale de bloc en octets (par défaut : %d) @@ -2266,10 +2270,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Envoyer si possible les transactions comme étant sans frais (par défaut : %u) - - Set maximum BIP141 block cost (default: %d) - Définir le coût maximal de bloc BIP141 (par défaut : %d) - Show all debugging options (usage: --help -help-debug) Montrer toutes les options de débogage (utilisation : --help --help-debug) diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 767a14382..4d866ce94 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -2303,10 +2303,6 @@ Send transactions as zero-fee transactions if possible (default: %u) 可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u) - - Set maximum BIP141 block cost (default: %d) - BIP141ブロックコストの最大値を設定 (初期値: %d) - Show all debugging options (usage: --help -help-debug) すべてのデバッグオプションを表示する (使い方: --help -help-debug) diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index a22feb0a6..4d270a6ef 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -310,6 +310,10 @@ Up to date Oppdatert + + %1 client + %1 klient + Catching up... Laster ned... @@ -496,6 +500,10 @@ (%1-bit) (%1-bit) + + About %1 + Om %1 + Command-line options Kommandolinjevalg @@ -539,6 +547,10 @@ Welcome Velkommen + + Welcome to %1. + Velkommen til %1. + Use the default data directory Bruk standard datamappe diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 8b7d08bc7..5e7f47cda 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1882,6 +1882,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes. + + %s corrupt, salvage failed + %s corrompido, recuperação falhou + -maxmempool must be at least %d MB -maxmempool deve ser pelo menos %d MB @@ -1910,6 +1914,10 @@ Connection options: Opções de conexão: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Detectado Banco de dados de blocos corrompido @@ -1954,6 +1962,22 @@ Error initializing wallet database environment %s! Erro ao inicializar ambiente de banco de dados de carteira %s! + + Error loading %s + Erro ao carregar %s + + + Error loading %s: Wallet corrupted + Erro ao carregar %s Carteira corrompida + + + Error loading %s: Wallet requires newer version of %s + Erro ao carregar %s A carteira requer a versão mais nova do %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Erro ao carregar %s: Você não pode desabilitar HD numa já existente carteira HD. + Error loading block database Erro ao carregar banco de dados de blocos @@ -1982,6 +2006,10 @@ Invalid -onion address: '%s' Endereço -onion inválido: '%s' + + Invalid amount for -%s=<amount>: '%s' + Valor inválido para -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Valor inválido para -fallbackfee=<amount>: '%s' @@ -1990,6 +2018,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Mantenha a mempool de transações abaixo de <n> megabytes (padrão: %u) + + Loading banlist... + Carregando banlist... + Location of the auth cookie (default: data dir) Localização do cookie de autenticação (padrão: diretório de dados) @@ -2030,6 +2062,10 @@ Specify wallet file (within data directory) Especifique o arquivo da carteira (dentro do diretório de dados) + + The source code is available from %s. + O código fonte está disponível pelo %s + Unsupported argument -benchmark ignored, use -debug=bench. Argumento não suportado -benchmark ignorado, use -debug=bench. @@ -2062,6 +2098,14 @@ Wallet %s resides outside data directory %s Carteira %s reside fora do diretório de dados %s + + Wallet debugging/testing options: + Opções de depuração/teste da Carteira + + + Wallet needed to be rewritten: restart %s to complete + A Carteira precisou ser reescrita: reinicie o %s para completar + Wallet options: Opções da carteira: diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 0455ba189..84ae9145e 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -2298,10 +2298,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u) - - Set maximum BIP141 block cost (default: %d) - Sätt maximal BIP141 blockkostnad (förvalt: %d) - Show all debugging options (usage: --help -help-debug) Visa alla avlusningsalternativ (använd: --help -help-debug) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 3dfc85eaf..ccf570b53 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -2302,10 +2302,6 @@ Send transactions as zero-fee transactions if possible (default: %u) Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u) - - Set maximum BIP141 block cost (default: %d) - Azami BIP141 blok maliyetini ayarla (varsayılan: %d) - Show all debugging options (usage: --help -help-debug) Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug) diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index a4e1588c9..8b92a3a2e 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -63,9 +63,21 @@ BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Bị cấm đến + + BitcoinGUI + + Synchronizing with network... + Đồng bộ hóa với mạng + &Overview &Tổng quan @@ -74,6 +86,14 @@ Node Node + + &Transactions + &Giao dịch + + + Browse transaction history + Duyệt tìm lịch sử giao dịch + E&xit T&hoát @@ -82,6 +102,14 @@ Quit application Thoát chương trình + + &About %1 + &Thông tin về %1 + + + Show information about %1 + Hiện thông tin về %1 + About &Qt Về &Qt @@ -90,6 +118,30 @@ Show information about Qt Xem thông tin về Qt + + &Options... + &Tùy chọn... + + + Modify configuration options for %1 + Chỉnh sửa thiết đặt tùy chọn cho %1 + + + &Encrypt Wallet... + &Mã hóa ví tiền + + + &Backup Wallet... + &Sao lưu ví tiền... + + + &Change Passphrase... + &Thay đổi mật khẩu... + + + &Sending addresses... + &Địa chỉ gửi + &Receiving addresses... Địa chỉ nhận @@ -98,6 +150,18 @@ Open &URI... Mở &URI... + + Send coins to a Bitcoin address + Gửi coins đến tài khoản Bitcoin + + + Backup wallet to another location + Sao lưu ví tiền ở vị trí khác + + + &Verify message... + &Tin nhắn xác thực + Bitcoin Bitcoin @@ -134,6 +198,18 @@ &Help Trợ &giúp + + Request payments (generates QR codes and bitcoin: URIs) + Yêu cầu thanh toán(tạo mã QR và địa chỉ Bitcoin: URLs) + + + Open a bitcoin: URI or payment request + Mở bitcoin:URL hoặc yêu cầu thanh toán + + + &Command-line options + 7Tùy chọn dòng lệnh + %n hour(s) %n giờ @@ -154,6 +230,10 @@ %n year(s) %n năm + + %1 behind + %1 chậm trễ + Error Lỗi @@ -170,6 +250,36 @@ Up to date Đã cập nhật + + Date: %1 + + Ngày: %1 + + + + Amount: %1 + + Số lượng: %1 + + + + Type: %1 + + Loại: %1 + + + + Label: %1 + + Nhãn hiệu: %1 + + + + Address: %1 + + Địa chỉ: %1 + + Sent transaction Giao dịch đã gửi @@ -178,7 +288,15 @@ Incoming transaction Giao dịch đang tới - + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Ví tiền <b> đã được mã hóa</b>và hiện <b>đang mở</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Ví tiền <b> đã được mã hóa</b>và hiện <b>đang khóa</b> + + CoinControlDialog @@ -201,10 +319,26 @@ Fee: Phí: + + After Fee: + Sau thuế, phí: + Change: Thay đổi: + + (un)select all + (bỏ)chọn tất cả + + + Tree mode + Chế độ cây + + + List mode + Chế độ danh sách + Amount Lượng @@ -228,6 +362,10 @@ EditAddressDialog + + Edit Address + Thay đổi địa chỉ + &Label Nhãn @@ -250,6 +388,30 @@ version version + + (%1-bit) + (%1-bit) + + + Command-line options + &Tùy chọn dòng lệnh + + + Usage: + Mức sử dụng + + + command-line options + tùy chọn dòng lệnh + + + Set language, for example "de_DE" (default: system locale) + Chọn ngôn ngữ, ví dụ "de_DE" (mặc định: Vị trí hệ thống) + + + Set SSL root certificates for payment request (default: -system-) + Đặt chứng nhận SSL gốc cho yêu cầu giao dịch (mặc định: -hệ thống-) + Intro @@ -257,6 +419,10 @@ Welcome Chào mừng + + Use the default data directory + Sử dụng vị trí dữ liệu mặc định + Error Lỗi @@ -287,14 +453,58 @@ MB MB + + Accept connections from outside + Chấp nhận các kết nối từ bên ngoài + + + Allow incoming connections + Cho phép nhận kết nối + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Địa chỉ IP của proxy (ví dụ IPv4: 127.0.0.1 / IPv6: ::1) + + + Third party transaction URLs + Phần mềm giao dịch bên thứ ba URLs + W&allet + + Connect to the Bitcoin network through a SOCKS5 proxy. + Kết nối đến máy chủ Bitcoin thông qua SOCKS5 proxy. + + + Proxy &IP: + Proxy &IP: + + + &Port: + &Cổng: + + + Port of the proxy (e.g. 9050) + Cổng proxy (e.g. 9050) + + + IPv4 + IPv4 + + + IPv6 + IPv6 + &Display &Hiển thị + + User Interface &language: + Giao diện người dùng & ngôn ngữ + &OK &OK @@ -307,6 +517,10 @@ default mặc định + + none + Trống + OverviewPage @@ -314,6 +528,14 @@ Form Form + + Available: + Khả dụng + + + Pending: + Đang chờ + Total: Tổng: @@ -400,6 +622,10 @@ Fee: Phí: + + After Fee: + Sau thuế, phí: + Change: Thay đổi: diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index e2934d0b9..1fd8d6df8 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -2303,10 +2303,6 @@ Send transactions as zero-fee transactions if possible (default: %u) 盡可能送出不用付手續費的交易(預設值: %u) - - Set maximum BIP141 block cost (default: %d) - 設定區塊成本(BIP141)的最大值(預設值: %d) - Show all debugging options (usage: --help -help-debug) 顯示所有的除錯選項 (用法: --help --help-debug) From 3f65ba2b3bd6c4e269f8f89b16d386b443431693 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 18 Jul 2016 20:57:20 +0200 Subject: [PATCH 0949/1223] Treat high-sigop transactions as larger rather than rejecting them --- src/init.cpp | 2 +- src/main.cpp | 3 +-- src/main.h | 2 -- src/policy/policy.cpp | 10 ++++++---- src/policy/policy.h | 8 ++++++-- src/txmempool.cpp | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 312dfe169..8d4a2cafb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -446,7 +446,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Node relay options:")); if (showDebug) strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard())); - strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); + strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); diff --git a/src/main.cpp b/src/main.cpp index a80eb6212..7ddf52fc5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,7 +74,6 @@ bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; bool fRequireStandard = true; -unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fCheckBlockIndex = false; bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; @@ -1297,7 +1296,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than // merely non-standard transaction. - if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOp && nSigOpsCost > nSize * WITNESS_SCALE_FACTOR / nBytesPerSigOp)) + if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, strprintf("%d", nSigOpsCost)); diff --git a/src/main.h b/src/main.h index 27121890f..631dc00d0 100644 --- a/src/main.h +++ b/src/main.h @@ -124,7 +124,6 @@ static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60; /** Default for -permitbaremultisig */ static const bool DEFAULT_PERMIT_BAREMULTISIG = true; -static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; static const bool DEFAULT_CHECKPOINTS_ENABLED = true; static const bool DEFAULT_TXINDEX = false; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; @@ -165,7 +164,6 @@ extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; extern bool fRequireStandard; -extern unsigned int nBytesPerSigOp; extern bool fCheckBlockIndex; extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 57df1f0b1..48080abc7 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -154,12 +154,14 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -int64_t GetVirtualTransactionSize(int64_t nWeight) +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; + +int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) { - return (nWeight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; } -int64_t GetVirtualTransactionSize(const CTransaction& tx) +int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost) { - return GetVirtualTransactionSize(GetTransactionWeight(tx)); + return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost); } diff --git a/src/policy/policy.h b/src/policy/policy.h index ad209d030..6bf5ca0ee 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -28,6 +28,8 @@ static const unsigned int MAX_P2SH_SIGOPS = 15; static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; +/** Default for -bytespersigop */ +static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid @@ -66,8 +68,10 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); +extern unsigned int nBytesPerSigOp; + /** Compute the virtual transaction size (weight reinterpreted as bytes). */ -int64_t GetVirtualTransactionSize(int64_t nWeight); -int64_t GetVirtualTransactionSize(const CTransaction& tx); +int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost); +int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0); #endif // BITCOIN_POLICY_POLICY_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 691baa674..82827b8e4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -75,7 +75,7 @@ void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp) size_t CTxMemPoolEntry::GetTxSize() const { - return GetVirtualTransactionSize(nTxWeight); + return GetVirtualTransactionSize(nTxWeight, sigOpCost); } // Update the given tx for any in-mempool descendants. From 719208c66f2df124cdf542ae80c2f99563fa7851 Mon Sep 17 00:00:00 2001 From: paveljanik Date: Mon, 1 Aug 2016 10:28:44 +0200 Subject: [PATCH 0950/1223] Rewrite shell example to not leave secrets in the history file --- doc/release-notes.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 78f29158d..aa9b48d72 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -61,7 +61,11 @@ The RPC command line client gained a new argument, `-stdin` to read extra arguments from standard input, one per line until EOF/Ctrl-D. For example: - $ echo -e "mysecretcode\n120" | src/bitcoin-cli -stdin walletpassphrase + $ src/bitcoin-cli -stdin walletpassphrase + mysecretcode + 120 + ..... press Ctrl-D here to end input + $ It is recommended to use this for sensitive information such as wallet passphrases, as command-line arguments can usually be read from the process From b8b97c98e86f81cd11a3c582dcea1c201139f187 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 1 Aug 2016 09:30:32 +0800 Subject: [PATCH 0951/1223] [doc] Increase recommended memory in gitian build guide Github-Pull: #8439 Rebased-From: 7fdbce9de43c600776e00a2f2042d302cfa4e411 --- doc/gitian-building.md | 2 +- doc/gitian-building/create_vm_memsize.png | Bin 89475 -> 22158 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 7796a5fc9..938f92ff1 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -55,7 +55,7 @@ In the VirtualBox GUI click "New" and choose the following parameters in the wiz ![](gitian-building/create_vm_memsize.png) -- Memory Size: at least 1024MB, anything less will really slow down the build. +- Memory Size: at least 3000MB, anything less and the build might not complete. ![](gitian-building/create_vm_hard_disk.png) diff --git a/doc/gitian-building/create_vm_memsize.png b/doc/gitian-building/create_vm_memsize.png index 5abfee5337058f9bd638a79416040bd6c6496194..6f42cda73f3cabb02e39ae0309ac67f419a168c7 100644 GIT binary patch literal 22158 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%0A-nL7Zl65qAwp5y$_efz^}#|Q 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 FV1lysU>^Vg literal 89475 zcmZs?b6_P~)(0B1qmFGGolZ`ibZpzUZQFLow(X>2J008hNnYPOcjlXU@14J@_TI~T z?fR`ctHR}EL=oU{;6Ok?5X8lPD1d-~8GwL*y1+pF8JT>!e*^)6gEkiuk`osaB9e2k zH8Hm`1_2QZcTRy;Qd-6cneLj$wbnaky5C#}ne$B45jMusJMNbgwi1)`4y<^y(?`)aqwye3U^3A@R?lv{4dI2SBV?q6DpwA1k zyPL?VgSd3>*GmMrMDhbe>xFmoLrF|d(mUAMf%|Am5dm#%-&|CCczyETqW`G9Cc^-U zgYN&L0!E3w0}k_6NKRRK%h4ZzXG9f*sgm9`%;b?Qw5)Dq9UGg9(0>ZDJt{>JiU1Pt ze|)cmfqO#?MO2ATh=Cq^UEaeUm{NKd-^V%!XEBoKK2-cJ6`M+O_$z4G8 zvLeIIZE+M4{bEc(5a>hx@x9VE?nVlOz$(jxFhn1o#mD>dy^%fl?SW=qC8&NE#94ybQVQQr-pa z1qcg*2ZCr}#aX9Ds5P{Uut(vBneb!nV=pJ_cEsNim%>}ZviX=Zxy)!$5F!YM0rve6 zdMjycQi#P^ih<^RS_4sf#mtgwbSWXq{W$vgb^a@6=ZIFkk7Ui*>%sW_GWwYI99dK{ z2&N&9Bh2=rt#})-8`vA@8%#DhPl&Spl6%fKkIzJ2+`RC*QMSFh!$^Ck*R&A40bqSW z+cGeuR+MPS<*?a7TtVjjaPhgNKiEiLkqg2-!^sCJcE9a%+#rPiNFc{f}v3_$@A6aK2bwA%uJabtu(C62Tbi7#9IeEJZA; zEY`G54oi+oj($#RCxi~94(%p=CwAvhC#Kug_0%28Gun&QbDCGj^Vl=sdH5OQrR*K> ze)(?y{_>9S{{6)i(he*F%mqvzY!$2o(gUKnl&TzWF=Q!fg}bCN*q#;AC1!Ybyylw$`guo(&tGl-|F1$1?&~=Q{1Yb-ETs_ z)&`Xar4Ay7&wmAejZ9ETKumy5pd|AoJ1R0$NKu$o5LQSnIxH-kJDiiB6P{Bo%$*ND zR=HR6fbB}{CL$%?qe>)Eq-G^*AgLfbqs=5=r+ZV2p&E&cjH69BOVNx=O>s?}PO?q% zE#;TfqxwOEr+TcYrlO>9uewpQQp{07mcL(^l($gIRxKspEGMH>tNm zUPV+zs^P7X+l0_)*i_L(cmi|Gab|SlblSP3yl8xqa>Z%e1KuKqp}oV%=NKJ(d0>{tqsch*N%fZ zmCdS&DojBp;tyg3V#4&x37SKLQbjZOW3cfM=d1^k36@GKD~1iaP9`ske!6@ngB0sw z-m#p>#xS~=tl0W+nrIL73oLDvF1$SgMcjethgj>Ffsx=r=Rx?vk-;aM#I=-eYbpVH zVoH6IS+X0oU9gd0#Y6~lYZ(h!j2|D|Z;DBZK4R%o-(=|}y;BcUU5K;!czC;fJ5C=1 z*G*Z@S$#JBH~ZFRv#Ar?zB@XUEKZGS&s5K7|L!<&F}=#!+^a3IVYIiM*xYJpY=CRn zyu905PNz@rqVzn44kg5KbaUX~G<=hOQpMvZ3NF_zhp`x|d#gA-NZQCw+Z|}e#LIR{4X>%N|6wede z>gx>`(m2w|lZ}U+j@w#eZAU#p?<^jh2VPH*!@rC9m}?~K6l>t? zp@1x|b}nfyO`rMqs>l3^p?XQdR5%7yMpNBGozd3%mE@UkzRBLs<(`&L1v!2>o?SUz z;LBRozgum5yGo|Zuf`A>a4~H&HqKjzS{Gf`uU#yA1boM@pn6)qU?DbcGPlq3nsKji zHtHYW)(%}Sb~L-zY&o{OdK&Hhnkl_H2G(uYg}>=PnGz22x;-#G?2Hxg?4{jojCjRH z=8AEby$T(~9>NZUOC~la0%f~$c{2>8yPjE3reo(UkRObbmvi{N5l4Quu_PQ^l(4pLP$wK+_d3A$dN}81H~|Q z)u**|Z@=7cm5vx@pRPy zixNogotF8cCj|0Gxfq_J$v|3VKzQw2Hqxbcwuy#ny(`mbR|5~9DCI9c+Ls7cEa3E4Ur6MbV~V_+iTg(D&& z;&w1H0VwZx{4YxN|D$C6 z&i3Dw|26XuB{$<=2K<*n|MJ$~qkr7R3&+j)AJ_B3Szi(mfq?LXi2o2!asxg0hV?=h zzWsbUAkor6CfC6WAla?T3V;*f7X|~xY=ig#sw#XRi;04+kFJjyr;V(FjEwA01&5=p z?;GF{K~jMSwhKm5y+J{|EV%?9AFX0a;pY=k@bc=+QLz6vD?Q{eKM*d3c2?yq?D~S_@bJjUNV#lc-2W5ymuxo_ zy`%DT{;V*dF5N4zv{Y1fCcio-kpPzQ z*-Q+Ec+89r6t@4PAQg<-lp34cm1=A6eZgd!J?CCnu+a3(e~kQ#CmtlIddfY(Fags? z-Xe-r1q~2l`rk}`!azL3O6Y_vfFDJ^85P+NI_*oX{hv0Vf&8$@aq5ir!(a z=Vmb2-T$L63CeZ%@nUAI)(VF~d>u31-~Ro#IikXTx~+_?`gp1Pknh7NTr`~`|79y^ zU@u{ypZ(wmmR7XN|BJ4d!$36n7fe!B+_ zI4kMd9e!Wu2z}+0(wC_yT5ApSKh|YMzzqJ%I4m>Esv9M;tAv5LjnSj5n&(17vwgu$ zvGoASK2vE_J~UVi_09VR)I;#!*#15ku)s=;&OiLL;j#ci59kUrxuFY>om*P_I7 zTAwtBu`IpE-(a$oAWBUm$H`qfTb#f-4G=1=E>+$wW9+8RIgm^J9u-r5+UxL+skZM= zKn*l*{_V>wJ%}h$mjKZ3i`m=|D&4o7E>D(zk-vfla8nHhP>S(3oAGR;ec=uH)G7;c zDEXp9p@7)Z6`Gg7V}=r$OlB#vH1|{*yDpK3qugL=TfmwUJ@$%H3Hl&25BFZWYxHa{ z*2GHPQ9Za{=q@Wgn-%w(5ALoH8=sht8j^oh1QtGuAM^fXw5iY(9_4sF+YGj8dA>dj z>rQK^XV%!##y?US6EL_FWxAgFgEoL?*K6ZfyC4TPoxV%}UE7n|G_R?lcF1`q;P2@= z{R0WBqF0=jb`*RZPkQFTT({78dp=z*VwegB ze;FdO(;$g^<00tTy+k&(9HhjZiB6&9BTNs{L2YTvNMUm#-aL2w_E_Ty|J}uHbSQCR zWe7J;tAm7n@;tJ+EG3bmGk{F+yBuixkfmMs?+1$;hAngFl7%#rl=} zrBhxPiSpw{EX z@Vdeh%hv-ED!y@4v5!^`EZKQBIwARDaUSQVGHozBH-xn=8b({EZ;Ek!cI2j!RSWQD zay_A;(`Df3H@N99D7M-v)hmxKF{^bA$hzS5WjtBCmQFR8?VS5J z44Pdc>Gn{{tPH5t8$*9|SW`o-USQvCK3%_gg*9X<#+%lUE%v9iIWoImzNs~uVYG+Q zpzDU;je%O4bQ^K$M>88-Dp+l_;(TJo6_Q~fdE(@Lp1LNpVE>caFv5QL9Cr&wR16^s z!^ou?R~TeZ%_%o3Q@SBn%T;yRVSv`R98KgJX`qqy2cBXP5WRxL_XyzC!$pX>P#aFm zH{x3f^ZSjzIax!tT+wW$Aoeb1)et9KLLFm%)%gjK5WWZ=h+@7k7j;)eA80; zlWEm3}!{YBH;WK2t1R2Sw2{+R5g^+ z{J<+8IUi|%=`0-E0egMJwp_9jYKyGUAhXy(;#$@I*7wh$8WRF?bZRovCJHdC_%6-QeKGFQ|B7(m>rN|A_{E=5TWYwv6@HcqE*sFfo&FM?)J zz6dp~AD)pV1dX2k6s+wgbNwh;sy;w>c5-)ZaeQy2V7=Nq-5!9TG@h6o__my@zWrm}?D ze~~|U)ii&(LJx!QmzHX;;Vhrs^jv;Ve^D!Eu++c$Qo*N%{zl!V>2Sxq~ z`(60jGrwXpD9^ltdAlX>*?oLj?Y2fZt=;c;OBL3w65vv&a&m2z!pJ%&ROGjg{g++! zwyE1%fwsGa%B=E?$MP<|ZgQ+bHL%fsDnfLI?g?tkum1o9WCDMOgR%6Y(d!v3i*!Lh zJm#MamrbdZMb`M5I^wb)FWNP2rEa6nQ$AHVocspBGkf5}gPjquqxEUi=6K1P7!m#T zhj93wBo15sc;#Rrb>yNC>;7eLBlGS(+1??buY^{`QvYw5WXNO6=b75=e{pOz8|BCt0-fFE2v zXCG>Q_%UQD6L({h@6Cgooeeg3Hsp24kZ`cc@b`J)GGMR16@-V?&5F2t7#~a0GC6i$ z<6sQd+uqvlK$cnx=L6(4QS{&#NgFnp@k4?PsWcjLN-;&Ps9bu=;ZTb~bAX0?K-1pP`f)f%qNJ zaaswcPl$7^WKjQ)=0A~{G9RQxsqSEuXiP750Y~LzN3gy7p*9GsD~O&B$EUoXy&Lk4 z??S z>o24d5g_tsTf3|-OI%ZVe7>KCWFzkJ7|e>{bmP@L$kek{zDH%%TGRY)orajLeB-$|@!3t%@r{>~jhyl&Les436vz1&2;@fwy(6e2!k{ol zwjKYnMKXoyh|M*U)gZ>M?jRx+x5p`c_YH#ibAR${K)iCQ{oo6T6g%A!E0Aa-e#1QN#?Lm7!dF}2*GUq9QRzfSOYd1!GP7X5{wO;EO5P9j-{qwi;h zRE8dEyzbGIPO4jy)YGH~{s)2vkr2hCdF_^x#iXSp!Vk^M{m*O`@?X$MP>((Nzu>tZ zGK}ya0GOAC74bh<6E)xuT9kpADE|6CXfY24OOy@`Rfze&ak-r!GE>Y7tpBQ#!G8l@ zA~gTBfB-Pz2Vr5-F`)I1ocaHf=^;~ngD{A}rX^gva84x|IZA5^}ph4{4kaiaxqqtUJEvjd*MKpJ3f{EU-}0A32WsSorU=(@zq*9hO4Ps zDTl!cpSt;na-5ET#QmiDOW2>P#F_L^Y&t`DjgdlTm3pz3BxCb$!8dVd^Ji+{GLF~}c@$^MaUfbYbV5$wnFM^R3u zk@%?Y!NC%WD$k9=U)1I6EHF--G9mX&ZdAda#pQrNvtblNqkkluQh@y_vsi21sAnx) zB<_nu4y@u;`=?UivWkO@hOqY>PQ49DimkUzkIt14PK}$4JUQSeZ}-bQ7NfNP-YMI$ ze?`WZu3N+t3&My(vP)oVVA(VREwU5iv1-sA#gs0V{iy+!vb_^AZHDJmRwBjv2;t>C zOc?H5E92i~pD6*@<;cub=VK;DE`^kTGg>TmX#O z!7!S8%_t_*vU$qjfnV<^WM$v^A8w1^k)h`msqfmPhw<+~4FB~E_!&j2XEG?$0DrD( zo683bv9y=MvXMEOEB36J9>RShw^OK3Sjxseh(g&DV>=->4RszP2HdOF=$53KXq=|D z|8dr4Qq4Mk8LxSPswkPe(7zL|-v6&$XgE{jk5NOMggB@pbqp|dk3pxgmulrM0X7Qc z@|hMw*Pv2x+YfWd3gaI|-JM6>P{!Ar-*s~^Nge%MHka?84|3(MYq41xLS*IAZwHE2 z40OoSY2n5c4_yDVSGVs4dwFnjbeeN#m+DCe2nQblY$Z5U?X1M+R|#b66EZ0g7l~t$ zn54`%EBf>GW7y-AC2V{EhQXJF*Cc~Cw3y;M$&ANS!}VM9(WX+MUi>M{cgMp;!m`S| zf8I9qo`nC)l434mi%%3z;`6v0sns$JCrZINpZZkONF#gY6s%R3MRtHVE@z55({E-gaZzm^mR*-Z%P-G6K}PfQ#Q|20b0d+>Iu$2`O>E})$0brH)PKt<^Y?Sr zq6t^dBUKfbz+FX+BYfP-kz&pr7Rn{lxwB-Y64NZ8o5f_BGJX~m zAOGj&NAw~-t2edcS^_?94c_DqxuoSu&zkyCV${%|rG1)N;rT`}&{*0v zh45yEU9U;;#cA0{E;`SJ2J|&B?DB3B3n`1{5i&7ypqxc9QKJ0ka$rukhrv2Z=kx>1 zfu_&Tqrc{0f*-vn9^B4o5P%|~|2%<`c)>>QJhcG@q9-k*W?uq9-p~oQNPa}5(z;J8 zAzJG(QWd*01b*B&k^M&2jxAih)bfe!##jlLk11NBN;U$Fa)xGai-Dy&n#=`>)zQg9 zfu%&2+*^9piHdD@&U7)4yBn_(xcErkB}#4{hre`9WldekS?47dk{`A^=dAS0 zU=Z#I`lZ66C$8_MAa?|vPQvpTWYxhF$`HhW@+jJAHW+ayzXDQhd5*&zopWgDa~N^Q zDSKk3TTHp?H-lorQz>7vva(1X^IqZ;vG+}{G(u(vO7g;JgfGkqI@Y!8ho9@5SFOIB zE`t|f+R&@d&dYgB*Uy?g4tn9ezQ9Kj^5E=^#Ja}J7K|9~)K?J$X+61~3TD+>nOCNj z=YbtezVBvHIa!EEqIE5d>Crm_BYTm#h`R#<7tB73-L+xa)xd?L@xJ=ey}JE0o7%mT z27P_9UHfD1)|}S?w)2ShJG8Pn)*Kx*u>wtIO5T2dW0S%DJco$6%D&$~ZIK*wnx6w_ zR${1b!-p`FF$anhh@$q0)D`1!Ri$eC>LK%A@95B{=jxECp&J(a>LunR>@*ItgOXkA zljOWQzO?9GVBT?*Le4JeEFCniGU$mK+x*yC@FlKOH|1ve3Hd1N z0sHi=EIRgNM6E^IN$k8J)!GXC_UjUU*t_J&RJm$sg^!V*NQGn^i)CP`^9c4DCeBLT96NfR;(rfu%f5Y#FX7V{l0F2@%elp9~ zszh6%h3;r9b_X&H-yVEE;C&*X*_-o=w?YQd!9#NOlGis+n1_P+<2wrg%L6Fo8wf8R z`&ZJ?`ya0=wmqA{tJ+Wo8?E{)ZdhhZ^sobK(L>dC-pog)b9~Qi=OsQ?1T0aPCwQ1T zLt}WdxzS2}_Q&tuBQ&Q-iq}1M%ajV*b1|tD$qcjE4GYma}$GdSW zAF<ZfBJd@WW8NYpPBw5qti`d3H zX+HxyFw_n?)xrheti2+!Ovh3x2gCaXS2LiRM^ZkcTM3-}qN~M8qlt=6t9JXr@=AJU z-2$~DpV-~Xkx&-NY#35td8Z+o%$E&`SnZ8uTL9h8UItfT%QjSjI=pM^`<4ly@UDet zeO(-iNKMsCWn(ks*~DwXwr+QYn1kMp)V&P`m*cC@JKB`~WEU$@8Xjh3nkr5zxOBag z9z6~fPwQrPQmORHu3qUdMY1VBSFramI?k!q%DH0Ah^6U6aN+i5|H?E{Fb~w+DQW&u zJ~RUfN+9&^>-XKVkkvE9jP8e5iay{xZ1a(#ym{}B2U{870&c9WDq^vZHtHNqRx^Llgqw;WGi z1OTf0gBh`*{3n1swaJ@WN21xNoRZ9Nss18js=*+%xo~eZ26HuNdqc2uIXNi#bjO9M*@R%@3oU8VRVjI<~2(OIT;Z%GboSF$Beqj z*iZ73g?$JzWJZ6hG?Vq8UuI=Lywx~9U^QcmG9O0zAC~;ujW?0+3Hb;UbInZd-V8s= zmD3LQ)oZ?-`B-Uj5R8`dN>0Bwc`8Y-Y91v=Yx#n zsrBQaQKd!`Q`!|L-q|Q3Vt0Tp^VI=?3=eQbQ__WeF%ag_0YB;qbv}j2o28|M80zk^ScLwP)%kX_Do97Xqj4d>yr@4L{$~M2;BVtpe44ISqrr?YuLy&82Fd zWUkkRt*^Yc=Oy&TI#S=c`2arN18)V|8fCn<rI!ecC5z55 zzScUqK#?@hbq(_+3WJV@> zctqLB%D3Qbj#N4buj@_8-U1G$v(REO&)r1lu^hR_6Qa`o;IA8>0nByS*91Rg>t>3g zEM`9UFFK)8J|yr-LMk!r8Jeuho!#0=s3gkx^h?&sPQ0An?bek-S=a|e@;b5UHTy-# zL;cI>=2psncbkv()q*yp-!=l`i&jPrV$chJCm>TnGLaYa_)k0r#i5jSWoclePW8)Y{Iizc1OkbynluNm_;o3*uaVPNr#A3xfbE65)EB9@V!|^Sv zD~a_Ah*uH^mZU1(;Joxa(@$+KI{B9&tVKh<6a0Lr6GA>O(3VH+5DTFagPS?0sCIX7 zsKzd+hB6sn9}4z8Pa|_osk-&asyuv$P14hs!$`pd+!URW}g-64B&Tv>I}ShVz)vY9%b0ORRP>$z>QXZTTP zTQ6TC=S4tmkpwziyzPMZv2`TgG#16N1Eg10at{-y-rop{E%^d#b+}E@*uR{Gdy3R3 zoJ!SY3iYp4C+wV$aF zu+|POqPy{W&VPqS1wz}~ZSh*^=En3OlI0O(+YhO~N7^IjcCug}FJn8?=msoJfA5P} zc#+YrJaz?WxEu@LS(!hZMPIxdTlL}h8FAH?mZD3Yat$}>g^2rFMRhjSORF^(wFyK zsRwx4T!c4fiq3S^g0Wt52P~Ub_eLP7UqibX3?f`G-Tvwl)2+ji#FPoLHKBo;tTXA| zJ7$-}WrsL;n;tnuKf$s`fABq>hkqj5U4mIYY}ZT_x?IdAobQ@-#9EV;8c;ahlAZT5 zShv(6t7N^o^lQcn_pEb!u<&}EvMY=}4}{)ynC=bj_>64d;+6xfj@DTB^0!a7+2%@L zSUDWI9o!2yPg8q{khx7zQBlc>vRV6c>QF`rMD7Tz1Sz6|+M5ivgE_#!;eQu-A>1A> zc|oss0!81?oihWR@MitGQ;h1|qbp`Y;=Mh8KpZl+)j5w-J34EYX!kRTb4bQSJ2yP1 zyQ##-9gE+U6ErA>jZMUBMWC_c;vieBmieA%q*6}@0^OdBKQNxeY6F7-s9a)zfE!;6idp#%`?Dm{3 zI#W93ejft#yrzkcz=!GyMgSKn@Ut%1>p&XTch|S1!S}1aHksVfIet2@&=mTk+n3Y_01{Hd|~(cC=*gzd&FhWr7djA-VKovz!Mz z!te=!vR>QPxSeBR*LawGo`z_Y*>7I%{WZ*JFt+x&+x*ZNo?#_MIFn)JSFeA4@BVz0 ze>Kx!L+Z~zq@39qwfb2en6gYU_p=KgeNX(Vjrp|T4DPC5Ny_`yCQEV--P3h|R#&Ol zZcJD3ucirwe_&(%HZg};^z2WxwWFe*s`%d%)06J zXiyF}JVi*fKtFe9+Eu$`%*EpvG0NSLu)e=B^MKsQ_7f|1?wdP+9)TxQRe2wFYihXD zvR&_n5qzfSg5Is`niQI~tFnGaju_C{hJ(~xD$K4O;}e}bIGA$cRy!FjvHWvk{03$* zwZl2Q+;lrDbhdD+jm>uk(HFlB%oV7Y-usgACrZ6Hu z;&#N`Eww$EjXG&q2+bi-SJe*Gm|Roj#)9v`4idG^uc)#j_Quo-We9|yb-C@iS)tFq zULWIpF1;4$oTvD0uATmP32D%7 z);JJznP=MQPi^+#WAm{mSd(#sYFVfP(alCQ`)&K>WW2EN8_tHm$I-r_?M85^sPzj2W$L{`PvM!y^D$nhmoBTZ z<`%5w%~>Zdllv@%m)$fel^4TAlQ=hF-CCE2wiU&uN62L~BI<0zVpAA}Xw#9R;q{m( z_|1tcQr?D6x#1PTyGtuFLgsz%+NY&o));2RD?UH>lYaqgKX8e>sYo#i)d4|-J|`w- z`F5x*GW_#9RO%)G`Ezp#GTrt^t?UC=_uaTnobUb+>|RPes)`1&2-M`9g4ul%0oZHP z4jUtVyO~n*1lTHXXt|a%&MiJ!?cTr?7U9<)I$ha(&3O6Zu8n-Mz}k8tl7}$I-DvgL zUtu!Y!<`#xY8YRA#lqur3vaDR*ME+vxJOpcIT<9X%cM^kQ|%xl-k2_P8 zxbRRz%3cImCeyizweSnFFS@S()!GARG5NntrHyOOSm{r$H$pG_gDvjY30 zt$JY3(@B`WxU$^YJgqYD^Vk9PgE&HY1N+52#ae|2T|6d5uli$!JQyeQ=ItUKhOG^M zG2flvz_Y+!Xr#N=6+W@7tu10|TzbEw%!z0QA{@QVCdK3n*nZ^= zjJE%rxf!a#00kZlo03fOaV#xnZ-gpfPxd4ez06#3INABu9?PGWrfijSDp&Q+VeHKg zQQSdi4S$c%Pg@sirVi;Qe2N&k)z3t|x_6~*-L5q7A)Q9DWS2zcq~&z zoJbJu^~!;cqvi(mY~JYWg$rE^zjP>VVyY6lpWeexP^VB0aB| zyV2O7o$u<32V|O5>%%|BALjNb#NH0AH@sqUA7h6}439qbd#k*eY?g2u-Of!a)t_aR zM=D%(qg9*OyV%a)@4HS22G^G4POiSEt2c6Tl3#M_86vAGYvI(NST%w_4yWIC4K}G3|VQ+o!ql$G0 zzck;4!tc9~O;{PIXz$-(chy0-*Mg}#oU6fJn}U zcP&8p!lgwZaGaLQI=n_6NmUO2&G!v9lXNw7yX$8et)n;r_=_I&x!Y5adtW%Ub?_#f z)W-_)HX)+D580$Fp-7@*Z_oGhv}?IB%kczNK6xjDk)Xga#R+wpyD!*WhVlfw@#afZ zh&~Qk2Jq%4Q6{m+GDh`=fh#0+1{Pjtp)#dLxYkL~C-ckQtHgyA95HCiy^FQ1Wm(h| zE6sHjE|p3|8F9*V?p#ae8@Vsn^1>T3MFFx>hK6Q_v>NEyXD#swK`V_28GTDvDRG|?#JDMv?XV7xQfEkSIWv)Y}X~48Zw6`uSoJg-I~BG zDlhuSA$;PtqgsJ;ZPOkWs@P>BQV!Y$= zkjoo?2P_pmcyH_(s1ju?+cRFQ*c&Vg8Xe0pH=yA;$)_!L_(S7>0G72YX^t+01lDBknycbPU^PIQ& z`ovA!QFe61jVh)I^MS;?x+u%T&CzdGPQj6O_`h*=w>pq@ zxh>A}ywk_$R7vtYKwYfD1(%mGchkQ+);^6~-Aq|p&oos7t)w8OcHPff8(Bc`M_=03aM@AX2DHxP(oo{<6H(+fA!94sirlAD(M z-4#jJN$OUH>T*(E)sRXK^l)2!c4#xLJcEmk)I(01D`yH3@Fcm&U1rY#!aB(%#=%G6b848QGH8C+XvRGp=SzPh_8V*yc0A zLT4jEPIo6V(7a}(+`32a>hg-I>GR@vYmXKhe#w2+TATV4ll$)U?fJ^~KKCrcb+*)5 zRcb3Me66Jj`AV7l8vws&W;1&-7l=yD*b_~9aN?QK7&URwv(bjgcg|Zm*B%}0-l=s9 z$@}>Pcuz4NW#L=431rYbYGxpNgUcbqZ3Z?IaxF~^IahTU(yaa*N8dNu1xYPA__a|f zv?AgFY?q}>->S`I@6@d4{I&R6rK2;~25DL#euYSdHxD{+SlxH|d;NO0wd96`-n(ei zk#tI;RJfhDzY|GyuVu?cZ}!)wTkvTW+OW&)$so$wipy*k%{!=qL z)=~*Ly|6QXB;crZ?ev&dCR-={?zG&)h+;4Q1dSwV0%GmAxvXgU;iG?S;w_@32;lz3$keFoL-f8}b_t6IiFLsNNQ1?s}}ExX59neNu7 zppOs2akxRZ!1U&&dFy&T=G(Jmst(y55zYcHU%fY{Q#R=_jighK)wK)<+Jz2!?s&s1 zMHUoH&>6_%j|eH9GHg6X>2K1~*t5PVN&39gQe~@b5$1xudGKFAUy-PKwA^29mtwIt zHI1)gZ`XR=(~0NZAy3PsfWGvWOOjT59;KzmHOS=C-0R5UoE0V`=Ppdycdsl(33-V+ zA*|fyKh0eB;N4SV)|A8$Q;j`qAsB&UXFO`T1Zokn4$c6>hkowDX3sCw=6ypMYt)Q- zqoq0)P-p&6Dcje9^!By|-|5hu-wZEb-@=ced#L;maZwUiFlY}yA)j1N15Ikw4a8%m zhb*%hg*dfBd}X&nF`l0KOB%mt2}zuCxwS)HwdMn9pPayReDI`GOy+zCfm)v^Z&U4Q z?6%88aXI2@-0!Rt=6&CC4mzg}tB{?er|Z!>_KY_@q>{v%0MZ{2Ol+5D%}H>EZ0xU*+yUee5;FYL!;oyF9RlEGl#`(hlb3IVA#QZ6cWFq{LN}46QB1PfV;%i@(QvQ(jf=$SQTANjjjQw8!cx=CQ9r8@` z@KUEW;g-l@J(9N?yo3QBe@DIn(*BOc^d#9imzOsu$1sH>ak?>^>>-L%jkED}$%fk% zfzK;L0zkP7=aUWh3A2(X_ySKZj(QURR!M3^NiwR!NxPXqrHkG4qdDw@KKgXf9L< z*ZL_VEkKSSWa8%Rv%+@^G@*v$alPusq(-P|#HLPbcr`zxUayWn=VIM}A=rD43lEjs zkICL$Z;8cdmF6%;p25cvcbt$BVz_Y3m&S;xI+r_W5Eb@k%*RVP%KKHFcx$*2Zljht zU}*XUebb>oXsH~<%`5Cm2`)jiJG8$9MA(~39gLg4 zQ-!WU;~ejrU&)IHGE$;q``Eacy@1VSO1CP{+0mALh}~MT>L&6Dw&<9eFDicJkyJpP zG2T)-&oH|9J$Dh`=({XPw#ft;*}~{oIR|%z6bsax&3%;8PVOFBJN^t+#VQM!`IxeO z^mXjhck+2ASj!v*z7Q3Y>&8&u%MD}3ZWf}U%jHf!N^aFT4XV~ZifDXOZ?yAn=U5i0 zY&y;J9O#}7nz9#v4b-VFeUna2Y+Tv4$sI!1;dm?bQja;B*7ZZgUn8cam86#reM2}* z=P$lJW>gc1jp63B+e!FFhnSQ1YO<5O2P-XOaSg}&A7&|M5ZEYm-hdWYo)-f5qt!9_&#si9J*0`ft zr|@LFD23d|WkHOX)ORyc5TMhH%pzEK!ABc+`lNE4D159K5NHLk|CmDwi=pJ)T|+n^ zG_Mejm-tZ(y-V9yJ{w$3gDmY4Ya?y+TiBj1Gcth+U*}I$@OZE_F%7P_m*YgZMn&nn zq&Y|9HBdawX{Dr30!53fobjT>>Wiee+P7=iR7E_ip3TP-aRlEyt)zHE5YB`o4|$j@ zdZnLVP+v(vb~x>ouEXcdN~Y^?@&EyidbtdvO(~98{|ba*Aadi% zPH>$pDs6+fORdoWudOBX6$))bDqw|)!0crksF_z#OEDt;bte}D;~rKA8|#)?-whXh`>Z!UUN3&)@M(vTlczTh3 z6-<&*m)kr%k)dRqKys&}??3v)Not*!XjNnqKuyh>m~Tw?@+&TTTN@V}@l3ATWBnj| zYMXwSqPvwtc_+@CEs9bp0*v@#l%(>Pb?%*0=p;pLPt3x_t-`f4Q}qpEGgg{i=<90; zV(x953ly{SZ@4us$lKUO=Z&9BFu+oTL}ZudeJ1vRJnWK*B{NNnjKzhVhXbMw9PYD? zu7a7T`^MrrIZh$wT=X%rt;N))K{6~W4N>m|v^m+St95pO74W-RhoV@MUtZ_IVquI| z90r2MZ_j$9oC-0-rhop5Av5{b4w&NVW0$cqYA;;%F&_wSWP2I)yehC3)yObvuktfY z(Z|i&9^+6-)=P=BHq~NFx%s+b(SJCoVnXvaC^q`%1IDj37p9T<>RjC?2eqp-)8@sw zl|Qq*Eg<>gE3%mSNn?r+_Rf>n5{*;Kmj7-aen){REb{hCN_w;~Pk6X{o{)@x^&Fa* z+b8sYhg~{x?pMkYeK&||*~JR;?X?$U&OE;Up$0)c-C&54N^8E2lvLoY*I33Lv9+8i zIwkmJGR?d}zfuBWuGuCAZ`~>*Kv_~!!C}&8dAH zJg#{xjXJ<3$F#<6=Af(MJSmt1z{aJDtm~gutEMrR)Su7Bp-CB17bF(m1&B`XN3yV= zU&vuHph30f!sioK92Ork$!^Y?6L+_PzEegf7)R;LzC>HrL_oO46g1M4+k_!2(x{i45Lx>#PMIL~URG)2;9-fz#&0l*LLx>k zzwUe0H%*HIOyV>G8t?Gz@xM9>&fz&CcPB@BVYq7tSj%1H2TdI{vMkGRa7!Hfz^6L@ z7L55Rnk%w=mU=J0LZXtdcA;BAyl-QmEIj#y(Bt(3vfYDQu}iK)(_ zjISG~R@cn=ep|6DS4%?AVc3vpHytA0HOD4=K^}!ZbIop_=hv^`W)d zWKE5Z=BYBP5i9i6trExkPSZr?b`Cb_XG(7$3|o0f5BX<-I8aS)twtGXgej0b-!;T1 zPgZxJyP!}EP%=6$l6KC8y)=Org#Kw^gt-EnX9g_2dUfN`WpWcpk|;Y=MntMtm$G9F z(H47QS?x%CQ zTZgl=Q^re|O8fKZ`Bry-Eivw5X5UGH%D$8EY)41_@lX-(yQu{2Lf5|Zj3)LCt`~JWT!Y@bJwqTLZYQb%1<}f?0{lY_vQKRk6DNCCZ-6FipCsr&24al3CGE~B-Lb*Z%{F9_ts)_oj4`mo%|th~ zwuN5+dZ^&fD@2iik6qKsj}B=xjjCjyhllgWY={|*c%BL@;13$oh@8%7@1MF1Z18(I zsDhf{rrWZy3d(mH^TS?_&_DOr?9Hh~nq9O7JYxuz5;|3XHw6B25t%u6@0aWS>abkF zUlLakwS!|Xe6AeqtbT#R^v+LHjA`vJF&iF9!L=Iq$f`H>q3f_%au)MCv1&$(HdM-z zF}WgTQ79`~ko`XJy!^ySU;HS6!vUTFKtIKY&{{5DGpPb}=1rFC3&d0trgvoYa-a!=pv?E-9{9!cD=KQ}iBVt98*E)2wnHWlxtA*d_8d-I^A8?U{&S_2XQpGB=N zdfvzk#k;+*y1)8)|5-^pp=Mhe;0GQBCuFGFOWsl*kS1g{M4gYtrf2>Mf)I#jwmXhd zgVIHKv)>iDvq}Eb-!G;Y`^LBN@rLV^iZ4Udv7R#F4feIV) zC>k9^bJA=-eG2lHx`ovG-rzTPCfw{bT%zX2#2}9qbg#zIP1vn1fLV}z3WWH}%bbTj z$hiD_>3C@H?%J~Wj6A~&VQ7V)po6SszmHf-iXcWGVJxPoz%zHKFll&$hj8MzA94nZ z4~WJ7XLf2M#Bsu_>Z`q2%wWndA``Yf4K~uK2YcCqR+Xf3mNfJ619)tJcD!er>zXUVF48;cxl4U& zQ7rklQ2ZxJr-c1a1WdQrH%}W_+;1d?7Cz*?&OE(eZnTsy7H?F^h1VK29W+&^-;0^; zR2Ww3!I5LY0Qb^Z$-_mz-%>uFT6PnW2Lc*I7h);+Bt|ASvNcc9{ez-D%|})~L+XqO zp2Su};wC=)offj%CJ-JJ=X_nIZn#|$$GICV{E2AusQplzX%I5^ss99iarTOWqEceK z{pllPkMW5Rcu^h$z#UOtZbHjScN^km{|xvsrfIy<|L}DBhYU{ViPWi4LG+eEF@Myi z?&|r5k=c1K`so#Q>eoci-y;?maGivURz&zA*sLny@lN%l0cv< z5(y6*RScGgH{APUUe`-~ao2LK@Z~K3!;tZkOST)iNM619Qdont9s(W2sH{1B%p^*S zqRo2`@3qILu}sAp%Wd7}Uk9?5s)y)j4tS)pLqFhowwDDRmoHME6f|jMKhmm5_EUBZ zJ2|x4jj44U^;E@T&>Afn08JMjNMhS`E2D z)iQxXdi@A&QB|hr>(^KohR_?@YKI-6Lip2g?Nfw=ISzREHaLj|W#?++d+Tv*SJpvz zyeM|BvXnF35U=#R{?!HvrFXqbejiR2=oq>+hGOHj>YQu67nQ;(tO!K|zi+Hd1TGDR zw%A-x7USAy$=~l|2;fyq{i0Ntj36Il5<^l4eWoG4)UR8GBuLKn!k>jY?jdRnOF}W+ zcKC4M9ZWzzJVUq{TeodZ3EIN`qKG?Yo#iv6*CtUd;(i9!g_E4Bkc*{+{3@n$Qxh?fOK(Tw z+?>NguR|nO`p2-%`(4+KKuFX&x7B>!;qV3Bd@HgH71_gqVvw)*H<%Bh*B#%PZ=1ju z>;UJUF*}0Z|3d3#MYL4jCcTp<^#;XZInbp~lfu(Hq+`P#keHJaVVNLAiwT`YG!9=}>ZW_k>2Z3~zxs z`(*2|&<1hn6?>BuPz)*?S1B1~$IZ8TKl!QWNWaq9j{M|Ekp0H>XXyAfOFx4$c03xZ z?L)uaZ=yr%W<6)-mFLu%-P?{PB zkE4}jP}70o6W26y8K=7F7Ue(qJ5h6!4g4{;Xl26N1Nn!~0;kJG>i~=(PFM^K?e>!OU8g{s9qR`xvK`8^LAkU?dl0qZW%qlN$EsputR8G~8wZv9 ztKUcEi{wk6or5$Vy^EVCxT5l>N5ad{yJmcWO~8LIPCAG^-@WGg0DzCU6|wfHXL;m= z%yVe6uUbLHh-`{z-ol7}KH0iRiiB@F!T-+!P*;eOkHyU884aWM#y}30SC@y-k4f!g zJ1)SJH5j1lhoR_TC*o$gh(yfRtz=V5Ks*u0IkDc;7_TAHEWyM4h zZVW8=thq852M0eZ!wWeh;(LT{!(`hm>W%HqqDpV6L!bNUgeDnWi_gtlme!b=x zHn{oEc2wN?aZ4}=mg$>ju_GSbzU5~IZ)W6T3_|}F!)>+CQ^k|fgVfe>aH%Nk?~7-= zzyIuX=gC?ZhTiHwqeTq%5EpM71!&bIp1T$JbenJ{Hh+j_HS4LMxK z(q-dLpf}npPa9!Nca*~vrmbvAOXkAeHuZa-u}d7mhM1&-_?j}U96IQybe##gsI&cf zwM}iB!|+;jrxRs(t}oj}6ZlZ6s0fMxjbr3Pd^|yu*r8KaZRPo^wGk3l=wcE#M#eM5 z99+yJEK}&V`)+$Xr}eQ;h5Z91a7(296PE%Z!UaxDhyU=Ou9x0HA9E#^o)ja9K?1fYHaOXi?q?O8O5=@sUeRCjNQC@&CxcBveDT>hJhmM8C5X1Gd8k@ ze+0&Utkhu)O(Fyf5lM27WKM2$ersCKiD^Sbrrq{|pJdEv4f-DZhCsbF%nA9x?;@B6>p#ok28S*In}_zm(`9~3^2 z2TGqz3Ls`-YZz<@8TkKfML3B=#Ztwb_gb?I(UU8=;_!z;Op@I2Zo>P5pa28FfC=EW zI+6=el~AyERCq-24y1!s-r_?X^A2mDaJr-A=B_bNAhg-)Eho)H$r$=e4yXr_AJvoz z$&<{i00l8$-F+gZ*L6+ENAO;<9GxnwsY`MI_Ia z?#a{|t!Bf`Tg~Vn11=g6tDQHA&kT4GR&{|}H-&=8m+)&jJhInr<>?`XLxOqt z)OI+bWNJi3^K2{IAM_f&ZTP_{4SCumzoce=(HV5%cl|aDj`QI)rsdgPqzw?|>N*5o zKh}xXJPT?mn6YMc7y#~sLN7|M8~%ntepjgmXz|MFw1d4OzDKCnQ_>bG628S_p3Fn; zRP}#XWY6u~Y)V?#sb;bo|!IBcf`Df3f9OerB=Z}Na@tjIf2oA(vYv1{0i!#N_QyLe<};|F53 z&!+I14lf~R{du_6yx`U*aOt&yk-bFGmbK=;mdytt;&&aPc~PG{N)sj$?4+z@4^}cG z`pm@_aitu!<(jxx(K{rC>d2E1Rz_y6tiY?+IN__!6(* zpVdJw8zEjEj}N?_=`*bfhz6sy~E9c zPa9Y2ol2aby?Nl#{PbVik;>C5YQo&5jUfklC&XV@CYCj9sGB}Bh_r{FKlpj?g;{kK zXH8VEbq>cY<4#%1i8kJ|2t@0oW6EUWRZon2suE50_(1bk3y9G}U9Wapuc7|Z0@n1{fbL;=m1W(9eM^(rHH{3NCCQ7q zL>mQ}4{cO`KbD>P>5c1xGo4HTn=4djyJs@1IXZ&f#_$7`-~|iO-P(G2ww^HiWCNnA z!;O%l$pFgwM~4YLTmST<#&S~R{ad^ScVzdrQYVYGHuZehp>$zkac-6m|LXL8xvYh=SGa;*=Y)k3qrP?I{u7q?^2KT{exs}@V+t1>W+zy`93oBth-5WooKRlR&e6!rEg{}mIm!YJLg-{kqG+<016 zZ-MnG)Wr&X=>!cV%h^_ldAJYkHOfvJT4Aj0Rn+9JmJAGVdoUG~zc0|CAx3zY)@qDD zl<`qgd90c!i%!MuxwOjIK$Pj$9|Icw10#;f0HMXrL+*cl-MHxtt_0%ad7II!C|Zw( z;j(Y0LFOVM;NcSjnJZy224mbpaiJ7OA7EwX*#^=dr_IoM*%cVLDq z{wa;PvDjiS#$_ehZ(<6lMZgjzM;+Q1)H)YKT?*1?G7gW3aZKP1s8!;bYb!JA^BjX) zOL8<6#FyZguh)uuxMV@UKFK6Wwblm|CA=z-zj~T0ZI+oDDiZoEY&~w)ZPWTC@1$r{ z2=iaO1iB=!d^v|B0)=!|proX&V#?_r1sPaE#@s2Nn<|Q+DdN(BekO87V@6 zH*7l9sJjs0z;%X4$$V|1qfG5xnCRjiYVP0|eqzj66KUNQy4}tFtcpmh>5S&|xyNyBGQvS!hw>Ku1KCfm>5T)i`Ew8`4ZYNI^v{X4#zIqZWgfPMOi{6hX5^_pETQ{eZA8tvn1y z7NB314FnA{i5N*CM~0e&(K8Sr!yc=`c-s|4-gL2o-Rx8#Ce7WeSp7?EwHKQ%8aDkO z7j<`9csKTO*mco{qAc|S%|KaC-zm}6ALn`DNJvztE)nyo`CsBN=qc#D2hqwz^%Xuder;+}(;Uf^X>N?=SgoJwQ3jLLSmBo_ z3?fn|am{4#_lwFf01ncA2$C-m=A5g5JLZG39@{EpF+RIT5Z`hEhM)%6d${z)V~;_% z56F71=7eMaf5H^fmfVVR><5*_?ei0y)jECWlB+X5RL@=dW=WdNw>l6=1{KbZ9C}f7 zP4(9jg;p9Tx%tcX%FJ!f$5Uh4tx$(G2Ju~17nqi>oNTv59#AWjHBk3MWUqHx)YK&y zc{Z+kdcd`VMxHWHx_k_lm2Qe$%SB?;%ft~UlEDY9lI@MkI1Xg2O2$5pnO&%kJtC$u z?m~`*c4ZnEB}Huy#!MF9o}#c1u$rYA{AAF2*PXxV7!=MyucKPj?qYOpmHr=(sz2)w zf7V`PR7y$X(;dj_OQ}w${=3Kuj!ss82^4Ixc`Xr2FFELNJ4gL!T6%`R{|;^ zK+nb&QBW+|+y&mbe+&yo6tEBt76;!gebfHwcfmPqq~0?}k2xZBa#o}cdCa)v#tN%%B4`@m6Y*Q*0_usLD_@w{w%q2aS{^%m)Hc5@(NOvK1wv2asym&_tE= zS=*}ci*yDKnpCPuDd1JlcRe#hbbM4U$QevC8GmGP|F2^`SSZb{e+`(z{;gDFPN>JL z5@80_RPu;4yw)mb2uQ^<(nbyN-tLaOP^-=yb{fadb4(7@pC7ffNOtz%<9R+h=Dev> z!>21jv33zfi*fSpvUye=t>ZUNP}TT1q&y%8<7R61kz1z_yu!O=nokIp3>e>Fg?+EoRd3pAF}}JR5HM52*g3Kvi(R|Ks{yDL$G65F%*mlI66=(J7_?G`Y`GKK>WgE zm*lj87GASS)EOm?o;pNoueYcl+Ty!mW3_M)DKwH`IV*<7vT|7YDHX|paUDubM|OEZ zv5?_X$x6i!mzn_CaF+0_d$vJL1JM!f1>%UwbERWQ@;hi3jSX(5CvUMeo z5D0?uwywoPkbm=DvhRS+VK@#_k2sG*@mk@{cZ)-~mCW~J4xHsuKgt+m)CV5Lc`MiG zK<9&7f1(Z*PA$Wll~AiRQnj(0=^@?%IjOuBs7pt90}D=S%&>S7RGL&1QAA)V0=RUG z0xTpsq@0SH1;@6HGq>clc-ixl>*+`XrpXv;M$&;ODfbvxM=Bh_%;T6;N*-fTT5PUd z*sLDZFWG`M5?+`I4}SP9eEMqkoo! z8Eny)TsAyy5)N1~?1~`i3_-#~8k=QIBP?RTo%Dzz%>_47L92I>3KOjAVr*$#IY-C_ zPKnQxAsVDQf=!D;%%ayJ7{x;(NIT-6LcXAy;FfLmR$mBlj|epV0vi1{hzPnBt>iCtW#rK6ymJOc#K?oa9U=88>tsOFYWczebS<2yy9zb(&meMoP z4#@H^lgrAMme-;cm7>l=ufIt2OC4kNH&8CRlsxdwxUk)o*E2Jys6QdPyag*@04cou z6T%s!v1HZ+y?xZmN@3nQ3NwR>87%2I>NU@;t-e_Br;eD>sYs#QXJMVfeNx#P<^M5q zs8oTeT>5LZ4pzn2c`?*{4tulnm|d!8Z!$HLyaS+ZYYrkv&kQ;c-bq|G0`3klSb|)9r{u{`yI*2cv=IL3^|XszdHExcE{@k&W8cn519Dc;y8E(4CXJRA1b_{Jk;D+d3c*pev;(<{H`*fb#M#Slo* zLeN^?tj4$9c$QWsn=Rc|LCS7>nPSHr?OfKR%f(&FITaE44Q?L^MKWf7jx<#36xeqE z3%{rr$sOl1<~hkjNM%PI{2q93`n^rNr@N((`@%iq`sc9M0N>{wZ?K2METXxC!4KZ; zz3}1PxP+1@+Noe$in$Kq(VBP9^nI>N{cIOgTY<4-;cIaziy-OHuw@8Le!Pi)vb4G6 z9V!-b*~|`=4Oxyewq$tanLz_v+8XFV41f&1wNkEuzOu#(a%%Yo<=I1L##derj3q46 z|AjVA3PG$9NMrvH!ee#og*lqIzguC_+yW!bX;1Uf23R8|8_#z40<|2WPzmDOLk+?s zC9&PI+e2~IdZ)#Kt`6iovC!)jye=cobpB(bc__VC{UoF{#;e$6DRm-aJBk0=HJkVM zf4#0qD$8T`}_IZ%tjLi-_oQ z!s3p~iRh*(miKHSuxJlwSFtfGAf$q~6d)ws$@sS+dT03d0op2tAubQ0fIYdz|LZmp z65XtvYV}uTqv(gUwLW)B{1YM9+mCawRPWqua{~qP4oAjBz&*?zB5o7w0s&gm#)M+q zxZQ*bn$j7XZh&K^$9Bjqo)=a4GRDYY;XeFZBX1fm0WR{eP%b_2AaM{QSO8|f+r*+-&y|u=WUV@ z|ChyH&iQoggrbpNK0)Iht76)yD`HPimYzDRoDFL*&$eKgv##scuKwr*&_9{*xeScgaz~Fp5!fFN*Hu{|O4IQPGeYp!rY+HQx-`EL@0yib{Uag7SU{Gex)npI=q*;l# z!~YwgFlj`l=f}vf{z3gFjhGLJz9A0?Hrnef49J?vbM+u`#;Z9}|BS>7B80ZXF+yLHAK3~RA|!X-yW4gZl6p3jqvtoBp}sv?FQUC| zG*jv<(r6pPg~~rvnmrBOogY1!GNNg&cSiraS^&~Dcg-e;wu4SA7uvHuRp?A!b?Efk zQC^j?8>*}#G@?(q6l2ZKbYiBuv_d~Gri7AkmUe)J2c;)gFouUobsyo3eqg_k7crwz z*1`XNj=!Lku6#p$=tTF=lD$4?v-#E!F9FolE5?Z4fN$h3@Ea;KierV`XjK9*YoSTR)r&N-3 zmfyI|)`-QphLy@pT%Vd99_$T`KuEc-qVyxr^wL)*uZeM~PWH4;{W2<*<-_K`7Iw?H zGJWmKxQvINu}O#E2kpL(Ak$KawWYvGOc`Z}7M%jSlNnEXx|~o>))P*4mhicta`vLl{W)`F;^;TuO`6FO}{O9klc@IdNZ!>ydh2fhH!s>uJRCoW+qo(a^)&?ssEv5;asf4(feNABPt1UMNzOil*#{|JD%}FB#7# zHdmi&cuVDhx9uK*pQ~L1OFL9nBw~ImP~**GT5iOB-|OIY76+!5UR;KzB1LD`Uc*r8 zL6XbdPBtQ2E_NOjDFJ71KpAwU6&G4sOOXEeQYlq{tlB;EZT!R>Ocg-~$EHRAN01!xmTvw9!S_jl<+3XYxR2iKZ!^`&`0Ze& zxZ_fK5^ggYXr|-{?B`QWV4VsHTL~Dm04o0aYsAL@;t=|(RAK&1bnY2?50C-e6&Lni{i#3H=lxg->HPyu^G-ahQpp@r`MPGVnD-vp+tu-DGiwdZ z$<@rMS^4LJe)bRN4_?G~$f^Di_By4EJqjNmq|P_~CkHXk`AQ9Oe8snS6Fd@aj@zq6 z7dYv%fUz)l?S^8kltu)NXrV<#S*EpZ^`0wi*|>our6*>)p9F-0nD+e3XzYxoB9eY| zS`8?yIhGMPhnjh$*mcS0YVY2w?ZjA8wW?6;17_jSrG~G{-ggVu?XR}5^Z#6t8QRKm z%^5c`lhjjxZ zkf$Ag+skGDg{Ua-c_sGvLNv%C9^jBR2~ZxKj* z-cW(-6F(Ew+iH)SXi+Z_FQQv;S<7poCt}yivD3*Z3nXI*=0AM3M4al6Nl1zn_7k@n zIojUEZAbSEJFZ+$ZZbQs7JWTl&!s(fqdA!XYD^43+Kc#DqQyiaPbO2Ash6*c8 z&8{rm!sxZ>?*2J-InH;Ro#uYfarPtGZ1Q3paB(<(JDCYM$Yix}06k+$d$4PQH$)es zU2t?hq$(i{?H>|ChRN}?#AV1zCBpRygo=6&WZLl1V~W;5H3FeT6izEtuNtX>!LYhg zC+TODLd9??51dH^?JX2Y3|7}d=;f*Js-$>C<9iRT3ZdKexO;6&&M(DhVUDeAd_n5> zwcdOArnapXv46&@pE=G(V3-pt!5LWpMUA>~Y|;d~RLA$U9!n#+?T6V~p;vGH#cn=& z5Znsip740epxmy%yo@yK;`(8e^CSSwaKdGHS@vFQb_e%szaYzOH!N5~vM@p%Gx*zy zpt$K3Zri=Axe-PBD7WQ)=mV+A2cS6k*apBYzp*g9pQJtIm{aeTo4-vVTm0I`7VH-l z{NPJB@WU$cxy5SNZG_+?xDlYh_oUGv_|RXw9WwDZL);#>&k4f(+I3QPxl*OuYz`E# z+V`!DeIUXbu3;-0T$_2n20=M~Ih*2%%oW?6PC2hT61qaaYpzFf#Q8j}e0h-EKM`a2 z*pd9+Hc=g(_d*@+2Dk=4T`ta>?~-4y>pCK@_U=n| zn%~o}W?xxnR9*?kbGQ-zO?4sr>C_W`+zvlFZ0!AGe&}dp_MDpoy$(D7k*=%0(#(-u zkLPu~8Mxgy_X&Hx-tc;R<+?coH18}vr?w$pJ;hKO^;+PXHCt2Y5PlF)D0D#`Zr<_A zahD=~yv;$!BFjf1J};}%H)yqcWZSATe{w_1<#b|O=zHTFM3Z!471_UGpq69>zXP8* zi!VMPC;2>378SDsODZ=p2|u(=De>X>9yuuTka(-ML4lMe1KXOvK2#^|nXO(%JUZRL z3{qA6U1>3lE|w#iPR41k{)GyJcICLx_&!am$TcSpW%tIv7MlzxESXpqW&Y7{cwVex zjNk5}Z+6`_J~M2=>EdxhpI#V+vynU!aP>>`WY*rTeFi>novtRrst0Qx4d<^((i)uF!0@I?lLD@6q3B=I_n<6 zYXP)_bGjcQdn3iWL~DCJx7cc ziVA-;en`BAm&u});JF-WO?zdJ+ltNzc&3nD0{5Y?YqeM;(aAM}azr6rkr~RQ3OW|U zaju71mBdg=O|v7(D!7uf2-NUa6y?acBG>~go+ z{u6I(QeeJ30m_@O$-tBE1-i|1G_Bc6nNZL97+M9K$$MqValZqxK$r(6Qz7EgzbSha^zXvenjbrjU5DgJ4p?@Lh)bO)?e@?aT4`eVT#V^c3=$U$?lQ>4BLauyp+ADD!i(^KI9M zX{h6-UvyE0UivwL?$JoZo)Q&W$0fb3h#x~{5Ii??QaUmBgjJ&ZMo`-kOP>*{*0kP? z9Ar?@{msy%(R;JJjInPH<9_efXQ~}PJ~8*_{0suhUd^);6prHCngNM~i){SX)uwAQ5AOaH|g zvw4;9{x#xb-92WZm~qwvJLrQUAvm~rZ^Eeg8avmf+>6E_4E@0&-+?bEy z6qLR%{8<_(c)Y;2(C^>PLWZkhlE&vM%M~n2a07y*VsA1Kj8^;%^-ER`fKy)_)+3Z| z%5o$kORSrvW+9Y0BmDSrMpwdmI+HDByqQpflZHN~_0R)K5>CyKz$3a{xyprbo*i3d zcvJRS|08!{?{z-W4F0}`%Dum~4=>mQCLbq1obWTH66*=Nr6xu$SBD`?%!^j7vG7{- zZI>Lw4SA4noG)t>wRX?u6{Cjrr5u6dyLGd=!O_N7AE)ws3zi2zF(O$|VYL{F$ z>R4q@Z1PaGQb6-3e>XRwTF&!P)kav`;$~RglmLMy&LEZE^}igWyAqbbq@=D_1YlgL zIq>cv8b4jk3nM3a1b~)AGKO~yq3zp&mYwk`3N1n&lFhLJvAK8I^65AB0nLqB*&D;a zkN+Jt+ESYhac*FOu>F~=(>%XQTI=d1`i8<3+MwmuNv`>fK(6ybx;))0f^oW#pRFnP zvSd(JaMP^We#H80<-?2GnP$-MFQc`=U9@b()wah;M=0}P+9*!^?N&r}j-TXH5FQdS`XLQ?aV%w1 zmHAZ1$tfE{9`4#v2kcebQ?h1HZyjkYL3N9FrA($$^<%N)Q;Y+$UcTQ^u{5_xZDaZE z$M_fpJ#XQcEhs)ri@7$K0n|s(_(<}@1IiTq17$2_w=&r0Gzmr@iz;YI)l*t33l~p} zWf!yw1id+3j@7AgU5ob~*D-zrTkCr|FKwiQ{DF*q%y6Ls@tvYVujCr^0G;29voRXn zXqgmjCu-QEZC6NtWrLTtpMx2VuCl#y_48ZCk~?E?DS%An4-b&#$r&%*eYd>WflbyX zVs7W;aOPFrf{Xeg#KpwlG&*XL?32!DJHizIrlv?PTQS@0dz01un;m-CzA+Qv-+U`M z@o~)SpG&xWfge4wkZrG>J|@3o!~3d=XHHO&&g&TbHG?6U0(KC^6KJ4(|g$bUNXG128DkY>kDUU0~B( zUP4CDa`1M!d(khpP1>wn`IB;5GkO~@$z)SK%^xZ9*0ayH(Rs93Nc&?T;|3&H0EaLu zJ0&VZpSf%ga>nf&4aD2q8D-@ETx8;&pQ}Heb(#ddlAP!SC0nh{MfroiuWy4j-Jc=M z@sCk_XSVRw0zX5SO|G_(!-BX9n#jxj!ygptSDtl{a1ZMMWOnXA=n&%B{Q-}(_xDDWS{VsFm$DLuyaRy*|&Piv191hf*NZ02Eo*> z_PbV{%W{RRyxEQ9K!Du7{I^bE*P0hOMV2#yfbB`-cSS751aFFMO4td&A$heO@TY3%a@vqRX!@IAe> zTX#Z@QTyw`TX*Bp7M6J)SDJ?g&jZUTX=yyShl*}~RwfgHs}9txyx;rQ9~&l{z09vU z;Xhxg~a)`n=rHi^G#&4%%s)xO!a5@7ap>%Gr*=uGeLCDkjpLL z&P-Z|8TZrm0B$^k6V(FWi<}zEuUFV0_V-W!bqiq1rp`RBi@F~uJ4K=r$exp3uxD%5DIkKY`u(A9Ikncig_ z&y`FJ+WoU}?7=o+o>P+8zA@~IsuAsF=p&Bx7?KZkxCm4%I0$g$I#+@&OqJ08v-$RJ z3rC;=q`cG%Wt8VeRUAXZE=Dzf!@wl$2!#u~@INGcrmp1LCh-=&c$N$Gy*FRGeutiP zAPZfWKon2&`JJ9oKze!>nk%x?&(T~fvd3*P$s5Psvc(1_l_lU1kvcdA=H>GlKFV z@;z1Ml9OQG#DM85@e{oL)2GY!-Q+Q2dqltCieAs-CB`A;>CSenM05R9 zGb$lZmRDWl>?Ch_^e#y6*VqX<%aFos(08VKu}PFmEXeI%$(-JUD*Qn1NHT}~@lxsL z&q|wWcXf92cA7+3i(ePLEvdx(8FChrt%OV2bvb5%^JH!~y=&6sZ3O<@sHVV92oI|q z>C|(BKpOXbt05Z8o4(1^@PVc5-v?WER@yPaDC77Bx1`(ZPkY8>4?^x9L^ZzeF9wcn z4S`g>J<*f9FOqK?rgh_#me$sZ4R6g0c@>vP^@)$-Hn=(ObM8fnNr*nR4yY;G?F0HVvil@L@ zZqEXZbcYFCLCIy5IaxoJgMdqi_>vuSrHj(_*qK zV*1oJ&Dw2jF!~^~l0Yd-*?sX}aUTAHN)>|+ihN}BE$BP`P50Y#%&*x(R3*(JE7;?H z#z&@$tzlfF^CxLpF;V;$^MVRHQ3S*lguyV@A67tTF1cekMGVX_6m(bIqM1uZQ8u`W z*>KUgjJ*&d*z*idiV1#IOT6rPME^Q0NZt7GUH#NBuictUL5@s@0mR@Dv01v1AJ#KK zqevrvgZHV9WMd66M!Z8o1o1y~?8Ux?_H>Uyk7lkx_pjwivue_XLkNO1;BF?@3+l^hE36#m zXTgoK9T)n<_i`keOlAm6s$4-POoY(e^x?$CVMxT(AEN>jov?z3511N6>sWmYfdJAH zY~-J9OEmOP&hfuF%79R`^s>JdxNvqCqp44Bc3g)LE+n+QNM(v~|1DU}?Y~1B-HEf- zY%O5_ob8^XANfqSLV z@>-tcngFR*tY4Jy@EibdHa?i;HCH3Vj-KYeCt!9e)}w=&VNVk${8Nn{a}$G6Y;iGi z+Y)iQgwLNR%_+@D3H{5#sgue8kQ2raO>c1@zz;zjNxVl``p#ljs~oVD(Ni=Y0tr|S zxrMlc&#;y7#Igs0s8iV+L)B?275j(;< zBHJcn1V1*zXOjw}1)ha(nMf3Gg;wGpk5x`JhDo0h=iK;;R#zFCb;_6VJAM1dUf&*z zB{l^8z=ZR)-L;6RT?f|Wxj(}V{REorsCw9}nb3hs@YtW9&z1DT z>4lhW1KuTchOjky|Hbt6uNe*HsZNA}?h$u!B@#l}QjE2kyBCyNtTV@p@kR~Gt*Wwl z*l6G34*<@6i@Krs>3qwSS?`^&5y;kb4=3-&F%=SR`=^R+RRJ>7h)k43o=S|P0$nuN z;}`9dmRHM}b&Xa=b^}iD{MN|cd;`boZ{q5etE@c$7SmGhna*BbnKZ?b*HTGY$>)!3 zzVQK)8YpALegY5;!I8SZ*6*02P|Ev^gmG@ZkzeI@V?4KmqSFYtckr&%w;E))UK9_& z8cn$bF#R&#YO@toWgR9>u%cB?^B8mJ;F(1HbPK8=nWFIE(Gqr((gK1bk{rpjnyLF==G*~YFJimIv-r3c@mr0ipuSqFa=yi9It+tjZ~xN_9!nQvDjn= z;f6lvBvwu)O);zN5Tss90ztT8rJty^mcgUCf0;qjh%RxL1>>f$gIdn;*=Gg071a~T zBQTLpjZUnU1-64?pmErQrp&&TZ|d-;(69w%-kC%Hldjx0{^?Wj8gKl;!SufPbV{={ zJB5uy%9xc^a-xI`F&VdZUvi%X`G@Ec-fE{HGxT!uR03jpVlXksv4QrC$|-CgR5o1UAp6Aru-?3sF<9Tl1H@= z5pm;|n3!0gHb_9bZ!&1c;-XEnZfLv9jx^V|)4LgEe(y}5$4R`=tVT@MWdBE)dq7>n zksY-ko8>LCGf)~Kaq;nGdsASHLplnK!)RQRBoOvM?ft$ zSCuqiD&)4eHtDeb`y_ighm;BKuM(#8iJ0yGJIMwpPgkPk32oayk=)XTp1q^Aw8~`8 z1I00y-`J97`h+^AoNA&xi2xA{gVOdQ zoWS)xun&rlr##UgW~_bA+0;lST>V=D8F{(3KMCBZjOvlpMU9abPkdF#WCo$DJ?IY+ z2J>zE@BS~6(En=cfbW^7@+SND{_h>W=hhZD=^F&pujQ6T^$=~!9Q9NNbh&XRY*E9j#Av+^-Hi1fnYIOWcE=r3B^ELact~m z01LrZrV|E^GOQrCApkNw`o_Qiz??xnPJaxVE^FiJ7t;Zw{s~=g%h?ZCW4?#~Y4P~? zLYFZ8^~~nkR8ET!sHyh+kO>>V0$g?yDGVFbl7%si-n%&kkt>;w&7IBKb0rCOC`+;^AvU;SlnKUCb(P*^_J-W)5uEg83#(sGXT^dzU;)LBopV>1m za#U)7k-%(2>-DG0NRkm)`PW)ADQ5to#GQkqF&$v^3~A);?F>#^0`CCM#D6>&JkX=5 znf0?K>%Ve^x$fqG?|&*bN^5Tz-XMeS8b>PNhzZ6MQ(C;psx=y&@nsrT`TwYTtAMt; zaP1bSxNCqyad(&EE(MA^!QI{6-Mz)#-7UCN+$FeEDAxY@_CEXK+~*>hS!>Gsj%Q2( zSHVB*O%bQ($;^_iKm1A?nTFk5?;($@F5)PC`O|mWarG{(2$?9zdUya`z;@R0lRVQ+ zoZFUP^%uKa>{&2bl6A%$@IApyqPMxhrA(40{7T+B*&2SjH8-G4AyAl7X=*u<{(o1l zQwI#YCDF^_S52LI#$e%U`5yNUWMN}8!&>wN+px&i5=p7>_n=pf)~+Tk`z)#t8%d zbnebry7&OIG}j_EmWYRp(Ls7`uFBLWai1b0<=w!w7O&LXK?tjcTk>!u4xFHYDQ4pAfR4u z7VCkQc}69^@xLNaaH&G(>-7ELPuj9QY!)CW?kxJ(C7$~|ys3RH^Sw^tm$VG0-apq$ z0+yjF6{w&!EA)$0E@7Y@{*}7AZ+D9{kBW6wkq{UmBOkGQh?pFUo5P_XzOD(BVY@W1 z4;$gIPBEukmsKxxAL>>NTyL>o>p}HVJWVEB)80*Zw#8nXpHIjsdw2ZfKefT$@FjTr ztqmw@{?})75~(L4ls@bz>{~MGSjY?w6XU{oPXjJ-uC5{*9uqApuTPqTirnp}KAj#HX$I!}nBgB#dC3?7)5 zHubyfr&^Mfekj8+y)uAI$%F#VI?eKafjMVUBch`om4c8M{?d%G%PqI00o-QOKA=}y zgg#+HCa`|1BFQ6P2}5R z@Ijm&%!g#B(AnnA_Io}iXdG15(dMk$a4*JMRAO0v+?r`5zLhs;U&L_`dm@VungeXqxqg@q?j=fE{#jK?wRPK~y#Z z!>(2`G6M+f3Em{5kH?phijcC$x5zS%3ms^~CN0Di@Qv7Y8}1RNgnSoFw3e>H7k2~U zjLjxf4CWyWm_C~pQKAEmY}}FuL_BD_2WO&3tg4~Pq7wBn-T26SNJLU#laq&2R98m^ zkV>rV=+K90bb9&5pd?9vRkiqQWd4BpC!&w2ELzx@L}k5wM(fAD(bW!Q2>m~;pB5($XONy0(2xiCaf4028!^$ zB$*jV;7pbR8u>ovPmxXzm%9Go4E%7{?? z#4m7y+ikNPhVF&3IUkVH(^KpGYEnYod{vbHQxl<4*IO-QMT7Ex_C|Eeup|j)D%xzH zP&O!xB3Thp2{FyaIxd2LnpLgq{LnQpC2sO);aZW$T#1Ph!7g!cLPJ3rYT*;KWEwAX z?VKihYY+)9(W}Fs>zVIzviW51!Z`t-hM%E68#OTt#$gXO2vR1ZNq0|M;zD$R7aCz6 z9*Xw|B<^2rz;fSXE-|SjXlSGpijen{$01G|$KNj(i(KL6J(e(OH#))hifC}+dPbAY z!IIQM*?_~j<=&QzMNCREnollo4qy#_YLJ1=Qu@3*fV};-LfX<<-2UXKhode3tqCL; zPRfKQLC2|dGB12mzT`T(zYyh=E%1muwk5#PcW?I0%umoY8W@)~An>)`Yvj>ySMi2BT#GKGHo`XLKOkr|!U z>J4&#_6tfB(Pch~b*c2!Xc{N8N)uSJ zUJoApn8munK#cOlmU7FQA^+5JV8SiJXHNtW`c4p{q{qU3suTE=CC61)`_15xt(5Wk zwzjYH4pW}TK$Cv6iPijCT|o)+fR*^{O0f`)|$9x zFfe*^W^Agy-;cLDZJ^(xTO?*jO*saTZuFC2o?=!#yD;=W%nJTFQwfZLv{?bG2A=s7L}|SrZHg}L zsm%2)HJy^muK|mW1btwf?RyXk%_qtQ#ZLF)nu|cMVk88er)`XS&<)F1)T}oE)8>Kt zO>)#5`9!(&ipuqt16&$YbsAk0{BI?A=_ahm%CBKyEK?DV>XCw|W9+!v3GBFaCHnma zB{YDJ-e9_xNII-tA|Bk(QAi6PKC+Mf+mPqFc|{(^piyfBaF2h!st`D?o{k}E;BxIY zB>SU^^e&}#`1g>muCBQa+$zcxYqlX$Oq;wQ^>B*acpCUoJ1P4w{O@2TSC`=wr0XF< zcIKy`W9R}}!JD3DDSAvh{fHZ~Wdc}FVW?(9%xx@c!y6@=U+R1}%6kA$)={A6RwA0h z4SulTT{G=YvSEsO2gGt@x=f8>G7NkM%FS?06TKjlu1kmpxH03(kJyIT>6^6Z5U}M)b6C9QF}%Ci5-25S}L}UIJUSw;p@8Iw6r}|_zODwV0t@Gt%dsg)VdPo=il$trt>{8&~sn-Kx@T0 z1=4dcDSq%8>Z)?^Rkc!1IHRTaF*eYi7~E8yq+#@SCt*ZfI<>W>SBUF$YL93-mX}K( z3hW*FePpz7_60<76SRzj#?zSb+gyb!YYUd1@~7gP)7JX-sw;)=2Rp0;_sk1QPpI^_ASyA z`X+*E>G!q?dek$YJ0QT8wbpI+Lvk9CTdUTm*Wf#%iXH*?C2X9fHrlQ05ekivW~NSD z_4mIxpQ#E?WFyiDTV%%dlI&{V@+52?Vi`+4!<*`MJ4{4gCoa`P(QN%?Vj=V85czun z%i(CpP{;4a%G8W}#0D1ToE;R#p9!j7G0um=9{PPcLRhA!wv1DX0JOv1oat$KkFji? z5RDNA0&+L}9)<~9tk|UaX_lrZXOGY)tP|7Axen@5ayvl2-Gacn$@Aqr8ZU7W!SGBA73qA9XHRm7@yG z9AFwhOfr*@;LOQ2m*p5o<#$?{n1(Gb{SJ$5&r!LnSZSO@4H}7}m+@$^G(PX(Q?g*B zt-AVYmxP%$gUv+GaO$(0u}}l^2Bt zd(^-b&J8o?_q1zqr_Dk>b@dy5Rbk!-J)qgGn0lRa&;ey+5jykVKz;$6r&Uvutm3p) z{R%P?Xob7YTfw&BhxvU7d;2jr5x^+Z@{p*ZG0CANT8$cs@ICXve$Klr%Ax9BODPFqv(+$S$T%wt&qruaB#QW-M3z7G^YN1D)w@Y=BYAR|- zf7##?W7NY>`;;5ml_}b|CTW=h9ij+a%FEw2j;RAm8Jl+z6yX`ySU_9y5L}P5k$m#l zR`N?C_cLoDNUOun7Ney_))@TxPC|I>!t8biY1Za$%l^c4b>Z+XR=sYR@n$=b5|Mi0 z&&o&EJIY?p-N)UAZTirmP3rL=c{K@MnE@=CTRf zwDy7)){SE&mqX;jwy(=10v2CMl>d6n6P?y~-V}A=$cVI(s^HqVT*s;@OU9 zoo!3_p(?{78z8gj=9z2AoQ^)XzB)P(OTX}?*92S1SvEyA{kg4VoNe62XJ*m;R{@J4 z6iUWV4l$oN2>Q7}M%eVMO{AtDl-^3PC%S}SH?$k@03)66!TmZ#dR=Lo0FwJk8n;;( z2q?d{#pu)6{}jC!;0kfa1xj_T(8lYIG?XWoCH!HCq-eQcfo0k}=$P(0vg2#do>BIid)%&8IpcLlklHBwew(jS zQf~Cp>Vv+b!+I=)eMPiXz$PkLNh7ans5iEP*7 z!fx{etEQfj3F%s8ui>@0n7PzLE@R+$#IhC2SpZgof7E<^)J+N)y}?2Qi=TcZm(YKH zW5`X8T;t(TeME%~2r*#&TJBV%KBnR2EG!>d$ZeB>;aR@%3OufI*Z#XBpwsM#DblWo z^{N-!bKfkDIy7EyYc(=%650@(w@HZr*-@U#Z9%&hR3RQYj%cz&Vmdeq{f_TvkQ~RK|HP}rM ztOSUJ8TuEKpDP$P>)$r3>CESoJr|^!y0@ETE58#8q#@0{G^4FB3C|7khfxt12Aw7x zk&jB8JMEch!%{%zc0@h~yhu$almSU-Hiu@dZny$VC!BhjBJ^&S-|Zlx^GUwvL57~g zU=$W*j}I;~TL(ibf0H6*zgO3z!_3&}6v+FbcYJk(-}He+1dYQfTe+BKf2G{QwB`}} z>9J+TW}LT}@G-6INFB-iz7kGHG;feFw8jrRlBR=d0QrSvQ3Q61!xuDydcp^BXrhBI zp{7IWDRb$w1;wHOAy6#QxT$tqr=K)_#~19ip{CctwVo^0F z=TZ9U$a_Qb?n@`K!&uGg2tas`=2$lQS@oSrJtY=29j2HTHWN7lt>*q6;iY`!C=c?A zn?7Vo1%S7ln?Q00JttCW6(Njb^NQrNvx2bc}`&cndh3*-S;)zm5Xj?E_C< zAsGW=BEo~mqi!fd5x)+kk&b}XDc1ft-W@O4-IrNU0lcsurl{8$-iC(6T=*E99f@C| z+L3N}RJ`6`--EMI33%GaCI2*GbH=UaM;6B$im&{Wo2))bFU77_*xXbb=waun(Es?S z^lU%*H@JYkZJ&k^hyR9#yn!?*n@7h(VA(1mTXIKutE4FL5^|Jnd0;V}!m?;O=1Nj4 zNOUa8Hz3@dH!J^LYOomRkI@iEmldxS6*mda_8rSF_jAPC^tB{nab!$|0@C(8?+f%$ zOWcn}+mO%=rv>`MI z;SeJ2l{8pi>(rpAkAgIRilp$}?ZGszl54q!R9M+(9|t4v-;39du<=Z#;shm9W&tV0 zH4A;~Bv|T*ZWv018sK$r>-|LGo62%B1yfWZEVVl+BAnM&G4$Wc4UX&IkH$uh|H+HT;KDn}yme_TKS(nBwiBWO$e^0v*`e&NCXbv#xjFSH4q{ zD=ug1_bqa-#%M<#sBh-Ts#HjLe!gKGWj!{K-2CRfL`wmTKgbI7>(D1&={ zty#bI)1xr=#v%X+Px%tdsX@5|&kX1PaGr}Q2Wlf$0-Jwoak5q5`RANTs=Vi>bt zTUMEarAGn#=|oMK{u$ZJIqbB1)fqXt##D4l%+1L^EhI1F-uex219h2COFF;3^Ii9dcrwE-ps9n@7j-)> z|A@LAT7vONulH>3O}kNf_;G5@Z}@ z81wf%rQ5rw9Bk0}37Fc=4=oQDBt7p1Z8rr*NRiD{*1$8lcY}zZ&4eB9=`El0%r(}; zvL{Tl|1dbm_T-bt|7g+D*AxeUR#q&Ci0P8O0sdyPqARb-LA6q#%Hu&?W;AyzyYvWE zFDZ`B>K}%hqZt9TI*MD-Oig@gXmkKgT1?y2@C&n_4&H!`qr=0QToFm%e+H^7gM`Ih zxRLbSLldT{OiwPYvbZncSLw@Mb@zGgT6_%Aa z+yc|Xr((p%mm~Ld!%dGMvj-&gh>7M>d31i-UA)-oxXz#%*?n}5o-WUC{q5E1RGW(P z8oG-F{%`5V<19@(YemFKecMzQGCU`4lB4zoo!~8;EwyK^ba0H98!VlAlBu^BV@kL~ zD&GAScJ}h_tTzy>k_8qo3vaF{m-weQ^H9=pu+^n(uf zXS@No-ED0vevZvX{Q)jUtQ@XmgnoCxQvk2S$nE~{F`3Z;FBwn-gR0ZYOu@c4F-tn; z8$~m0YMBzFl(%zgPt0zFTDJBtx~d+nu-1h8smA5rVsY=>1OWM69Ks?@h!7> zOKLrNLGCyWqTJS(^!aU<EL?%@FaIG7EYnXu9viMS zWAb$ z-1)J3%;FuA`4`gfQ(VhplTpy-Uat$gz^yx@v!d{!W#sG{qpafs#w!$CrV*I@NyJak z%g7nxqyFfh&R?^5zFf&Sc53HwE_hd|%;6PVwbA--en)*1##C8(exn3=C}K<({`*9u zBp_Di{Og5ek77;k+1fClVW1wqx?Vvgt zW0mWu{BdQBo|HL!3R-Sbg$@vg6-&s(Vmw|q67EhBDf-K!PEpw_|T49_LzM&PWqgtDzWax0Ccfd(KWxO=gnSsl=U_c6rp6t{;vsf8C-i3 zY^L7(Q5#fY!S?NkB)i!w9g>NE;?A&D~cs@MQWnBvvSOh zO@2xGhtbK6k-yS9T8b+u=k1)6CDYRMGAl=O#0?cn;7c*v3^~)ORh~W0ZrM5Q=zhyM zzgZ$%XN=rNL@}^MDybu`ybA0WW9mf5g?s23H1W&sQ2^eCX_GbjXl3M(iQjND!{K_9 zRn_O|2TY_Yv%O^Z$)ro+Fj!sliSsMwv*?9rpEt!nnE$+OVlexdO@|HfU^q(Nj{IbE z%8x2s6IZp>Hd4Q=bHQ&GlGnL7lidy&MuxR1Kv$B5wlUg6d(W(4JQImjN|I5+9 zdkyHI{e*&7X{itgt7NN?CsD;~xVx8f##yf5RwoU}q$)<&)@0z_$|aXFnvGtVzHnjD z9%yJiC-c(FJd;*$CYon-8JVm6bBlb{hUPcM|Gi zXh(*ni&Tg>MaR_~ribFWIobG=Z{&R#VF{wMd-8{wTsA6yY(){+hB7O4uJV0mF@TK? zg@uR|5h#{8>h&Mb817ZXX)mj4z#K_as>Q??&0vdmgr1)w_uF01EIt!o2T+dXe(&E= zp+dP1O*n(#%+p!|Aqagzgh}a>P58%nm!zrtb2*9gZRYtnadKYco~6igqo)007PqV) z4d{AD>2rJg*sSUC&?q>Z1dmQ%joEf*GoIPuknTggzKJjvNM$oMON~n=HRBU-0{`og zQ0D8)nO%~{9;n)w^a6>R@PmsSI;-~K%oY`B#B{0+ZaEnNdw)WoT$w?!X5v4^)-kE0oq*E2fyQ0SJ27hrwc<$4e6vi2 zgORGWPOjp-LP3X9vi`fIfc7))_u?GOeM^%{kDX4f!X9qZ!JR$mzt@AVoV$kytqzF5 z<=7_6+4>;A2s;Fd4a0_n@Ak=*aub?VpEJxwHL36}FV!6y@(2?la7__}^1FiLt@}H_ zkY-8vOZ8#>Hy63WSMU2EK1n&@x1zjJ!$Az_DQI4Mzg<80q6(KHCYD^uR6ja>fD&_Z zylpiT6o_KNMGLj@~n4BElFTksE#hg=JN9B;;H zvYKxsAuD5%4Q_4}ES)LFx1677#A|2(@lw5|= zW+N(LFs3F@j&3cFF)W9o)TSmn(9m=Xdq7mt8915Xo*>`HHx(&qeWWs{X7^XxbYczm z#V3e1kN=D`94e_t8 z)LrD_z*NMrm7V<+T`FR}Y+7^2R=0G`J!yQ8BGfij~TOLm1wnv+uxwQnl^pscyW! zUwSMg4`2Z4#Pti^+{=mZe@^L-Z*cJvo`_wsvU1=S(+=#LIHW0OmOqqFgnY6Q(Wf8L z>*K*zbgS#jr{b}c*UBHYS0ZF_G~wChyycdP=6O-6hYfPx!_68i#Ek5p3G840kd`3$ z!${%%vY1`l6S-RJ)zv)7TqV~#cBR#12jSLoKrI=vtqj>U0hPNZc-{{1ir$7iZn4(EMDVX(1>u)auxxG6N=?&Bp>}qOuj90Q zB{T7U=U10YPEW+6TmSvWwpK(h6-(REryyuTbxUv<5$p}elGe_Koz9!%_p46c2(${xbgmrK0$r{}>@2hEF(HMN#3g3IAF_o)*%NKWfSx83!*IoQS<;a^p{sq@Yy0#C$N@XUq@RU66Ch%*Ardnyh-6 z-ltzm%l0uP-kDhHq3w%9f(g#VayI@;en9@eNJOuAS0EI~tAtU#sTvJmjo*H)0w*l` z0)(%czc*zr4N2t?z5cES1qJ)ZxpMtIFw?V-Q^Fubp@_e#KI#c3>_fq%SvZ2hN16_b z<+HEaw9l&A>fr2*&6U>ko@VYV>MMB_G5z%ONkZE?h1x9mY%;n;<{3(6y9hdm*y3Xt zd*ZyF?QdJro!^SRURwWl#(MB)4vEn(+QwxHVML>Ia-Q%UM@%7*gIwF0k31mf^2mD@ zRf4DW)>@0~-R+0iKAs#9+s<QKE~B^Sj~(@XaulzY})2TpZL&z zL`W!$s%jX7PgXJDcGs35pl(QVB;ALw5xeRc*@w}qWVs*%*fZZg6f6|QQ?>O1rfqNSKiO(>f^?J}3nzCDFBU3Il$je{rAgqbL51r49$7h%hW zlR!um(sY(%h90@4@DSjg;N*Y5RMh={Wa3YTQa1!k$MN@9VjPSe%0tXtP2tGy8-FqlM1Q>Uc)+GXun^el}h^wl#s!fRJP$iCR`hA|Ggy2SS%EwbzKQ* zfj7wQ;{ZW4CHj_IYbC428;6Y1I}{w(0Ms_&&X7jM?W`2t-$GR6&gJww?oX66*3z~5pX65y*f2bg@t!l2NH3z4Jz}%B8UV^=-?^yE1C)cU zHhc5c+uv9Du5B~-{%Y}rk=fWBBI|ojDRrDr8yyY@NiI!}ISpzwJ8%BRFfI1m;$G;2 z?l0s9tO~y&{C&9Iw0PTW-W~QV^Fu<^Z=HX}#A5qZ{jI=3wLI@f_cUa0w-@6T(5OwO z1dX6Z5>aC-Yog#Ei!>yQvhmG(=0$W|Q{waKyW6Pb7rG>itE6u>Q}SDG`&5ekuXETt zB})*m!+>QX)+=Y=AnelYkcsb2Fno1hJz2ldvn`+3keOoOAEGUWp2mONsL#yqExSH$ z2u~t*UucZ{QOJ7TiD}5%cpbdW4K^B3nE$?*^PMzVdmSisFSlqFPyp@HWdtFoD?9zSM~)r{tzzN(az>Qpu>$9JJ{f-I$o)1mqJ0_M zBRo$D!@i;kTW>rgcam}BNz2GMBl%H;>WpCcw3$@Wc*Z3M6`l`X9&DZYo-?`8dC%pE z`jpb^{@gea7s}aV2SY^Mo0Q~($Q$21PNMB@RDecNSu#nz6PB6bc!$*U_b8M_L~`dE zZ~iK_?3 zEdtE5yv$vk>^cZ%iJ8GUF*nop1s&w#Gl?V1#WI#Ig9@6*iZprpLV>}W{;=cz1nS?@ z%bXc2;a4%a+HT+9{}szFC+QG)uJr9DgRyYnPj({kYS{BIytV!Sd4K!$z2CeaYtHa1 zMwT0+X78U**WP!e)7en^zHiM|-#5Rs9>>2qy<-$$eyZ>gDKRzn&7}L~(8TYxkM^(i zbz^9^>!(XCwoCml2-8F9(6Nuuy!~-&^L~9l9MsuA$kE?rpon@iKsNv9%V&Z|h%B$J z2EkkzQ!@-ZJIUzFaI$>6xwnEDD`DgpBu@5c<6Pyn(cUd9zHYXhQJ$iW-={=yiK)EC ztrXs84g6ClfA={xqr}tfaJRL--ALja1wvg5oppEYIa!|qC`lG}OwkKq*>-ya5$rWl9n4apkS@uu9TF)w z49{Mj8TpQs@h#P3vWwSf1R1H9h2K5yk!RvLCUuzIcH-gBooaWqVKbJ{$Da?y0$EfL zc_)}F+q@U?D$d2aMh6r%his{1-=)RSioN^QMPRo7jHW?5pp8X{|2PgC{P?!G$^bjq z9ne5{IJeiTd!ufDfHtJ?Kgg2TM_0v&7o~f6eb;AS_=r?8N&FP?wv*?lZUhgB>;f_Ox+C3WL_~l1#b0v)c&YV;WtzHcP64wBW$y3G+bl}g z82XX&gJG6wg)-ejD`3?1jOY?o+~oHK-r{1e`;7DI-p}3ofm0DYZ3lstFCf8b=vC7{ zC(0wZ(;$gJgZPERSKu9~OMAy92BGkgeW3ya{M(g=(XgZccd?y+-)In~XuCol$r2vi zkd&aMp|}}{=P~c@3`S&7CJ9l_@^Ppp*r;IH>X1O>F`A*$iwx@&oli6VhQ!F_1%AvW#-x?utKnL$0ZJ_o)PLzmcOyN?N6?)cAbnGs9f@IM!4w5QJ9g<;6;; zoK{cXfe;qK{Ad-l z2T*OIe`|uwR*OkHRm_$qKvUgMCer%4gp7{eo6&m@Ux^ueb#RU1Wi z{&8fm1hSfn_e$D)h=k)<#0?p=_eE_eO*vhp4kXf&MOEQjo~mJd0HN#rUJYvAoqF4u zeNM|cWG-#JPJiFZfvPrv_d?1rdLt3us3YkX!{9$*m?hqP!J?)~W)T$TJb&@C5j9zH z?l()IPrqZ*m^)c5S{H9UjdC$q>lP8S=M2NnT;)OWL!;DZhxB^xk^*V;qr$b~hYk?` z1uNCYSJc|$25Rm9(RnuB?$Y?P{SV^znpoXO>%69!+-l-<^hdWf@*>3OZy-joP#WrS z)Q{KVsT;wdHAGQNrx^9jI5;l<8xyWJxuo)eG_|{ns|vBNza@^)t3CA;GE2`y1ezw$ z&G7F-eQy_#$gJv+4$7YU3$QJ1S8iV=&}VfWnH_Z8B0&1i1L4)@VdG5hKU`E3KaF5F zp=&#-7RuTYdFt^)&vxWn#!TA>6-2||N8s$puwj3Y5q3y<4Yd`F@pcAi3*m-M~U2gVI@iNM%)1fms)uH7M-MEu7R7g!=oR*`Bqj%s z2F|W^riV2_)9!D*-yn|9fPbvtwHb(|<~)KniEjQB3dJ4v3alRR%G^YM&3h6G`1rj* z#{DTvTHk?2OP*2qp^t#=E+U(d>1$QrCwij=_Gs4;O=g2QbLI~|OC92WGhSzH>UUak zL%dIENQ|4R2bGwLJTnpWmQL&NXAuPC3{}DDp8nqo6)Cv5%BDdog?Dn_&8_Pn=(mB6 z0>jgIlN{QqwH2U2zhxLLa-8XH9 zvwv;xuGXLT>tg#q`Q38Vy$z)gROqbv_7Bf&rl06@VyMjUAqlqk1Q!+#2iYDN)f zzk|GMt9MDU%#0euiMIVV>YAQH*4ymX%5g$)zW{z3vQ6~1yXnty7zbPX{*cTh9c4@_ zV5wadjh1Bh_?t(fyb}FbD2i8K_4JqT{DQz3{L`H81*Ndj@7pnx5e4onR`-Qq`2kC8 ztZMmQ1g*tELw?(KskIg@NWg*Gf5soX?XQf9pvLW>@6+=vb79U}db*n7zZiHRZ z?*TJ$5fxLMAR;L(y?8=uu`f>l=yN-pMEZ5~7FOc0U;fx7D~ba7-=C;l)yoJyjBE4t z2ngKG7JCTgeaVxp(oD==K2q>17%+A))GX?>)x3_0guHRuk`*+=&PuPwzCo;UxBn-v zFe462a6V!Q?>)?81w94js|6d{E(dD0~C<#DUO}c_L$04PMKr`v9p$&>r68wSlckV)_Bi? zOdL7pkCGlTS1DL_rG#r#Fh@_yeOa=^P{#g3iE)vQ=sb>1#w{&#%3%e0bQ)6C6?S(a zMVV7oLf+syW~c3yilDeSvLDB{9xr);u*Z58sSSn*r~_+i)EjEDB{@`I9-dd&2$wGy ztNQY5K9#{??cISDV5sos*mY+SILPL;Rr}M?NZS1*XPQ`r z{YdZZGjfkKKHa<78@&1KT*|o`@6Oq9nZ>!zPpN$1fO$SZ!BJJ-L_@2ZvM99nt=5H( zT+Y3PDc2%PdUCy!0bgq1n<>6`e;Y>gg{X9z^?yJ;(PtY9{8J>0d6I;{!ptP2(r$;lk?ahH4)JIa&wyu(Q|9JJHfMq=?i z!l}J5`l9g*Nn@_bpYldiM)zhFK?E>}=-4yv;?`2#Lb7cN#~av-Hm%MMhn65=DjrgTNmNSIHyM*>KUOg@ zn?@O8$Pz^Q=T`b)Sf>Oz7iOy~`TBqcWgJdt#Q(lc6bgNXV&Lgpy)4G9wsnwDS;J8C z9SO5#VSQdL&hYjL^oKAq-Jtqi(AK1wYC&d6_KN|uJ0)XxnjfIaFoGhtqYvs>$qXO! z8fN(nnzNMHwrtzRT2!?gRY4vTtT=6nN9fc@_E$W#qYwc6-fDVO(VxB5b_G_nTmg9>xgz-OE=i@MZ=lJ)X$9rXru{G@eVn>_%Mn4Pqm zmCkI7y1=jcoYd&9Oj^bTbCl@Pd*pC2{y`r8ErE#Do z2Q$>|^R>jH4bitg7owO2xPrMZDTS-OJW)2)C|)5A3^wPKxiAD;22+=H`dKI@rccFK zb+9Ys!%1iys1vU3+9IAADvfO1536pbe+9F9$H_W)3HT!>2xPg_&pf<$mZU%SnM8eR9h7k`2idxoA z2z_s6J0z&5%ch8LK>P(-Cwr445>3x1UO&qEi6fimo7c2Pm_S&oKv;aO8f z$-P)rW=_1+-tW-`XPzOYZiOrDQFHHeJ31z$^L@I=_)O13>}!m8FPe#H+UYljkQ7g( z-rED;YAV6`mlAq?FNVq^Jt(f%T+sxYNKXarr#_DK%B8FmEG!C_dGd77w7K9_d1MET zKDEj!?7JTUXB!tGrP63Nj)^x9gj}m6K?~Oiw+Im^S(m%oY$4A}M0MvlQiKo3s>w45 zDm4pEkQ8~fVU*Aza^5K=o8K)_hzIk4)akUjtW5^BH8irb4_CjSkb77=rr^r@_U$DS z(9<53n?)nv|4~bR&xVTYHO5Zj7pUo7LIIORyK-$L96yONVf{C8UItrXxapCD3fOtt z*0BK`4obCG+SG$T>nhgVG2k{Fb$A(8``HdC(DDAMDVUhqsV zASp#duluJ~99XG7LjygObzGlK`GYm(1*c248ePySAPZ?o@u*BJ%YICod+f)~&mJ0p zrtbgeHX)yeH6V_Xf(S-gP$ z!ZrdDtI!*)uv!LGySS=qN5bz~c@4zBQD0tY_L`4+p}tvFnYwHy*bcS)sw0WzkUNUA zN@7uz$TVQ9aOL(VGS_inBl5vr!cM@Y2&JFy7?u;%b{3qIF*>GX`~l-^*nqhF51!FO zIk-Gls|7=Dle;|avWHOG7y!{wxGi~&6%Vy-IYv(c($G9|Exem!tC%C&4+#LpYcZURLaCZpq?gZzMC-?iEtN%c+-Q9cD zs;XY?Co{$zQ_+fjzVLYnug(xTE~g@%<%vAaZxqN;vc!c4;GiY{W@9(A_4GjY{YAZE zYm{Y}NDtW1pT&I*R}_JC1fyR>gr$n(m~v(chBx?9OUr=3ROc$~rl}^!55wpZbXH&P zK+jT!{O&v}CA3(aJ9zI?G;SikyT#iK_`S~CtWWUKeR+%eBL>R!Xd{{M+98?Wr=8Hc zF4+n7))|&PI-NLie4P);6GWrsVHk_!?)u!whq7H}xv~)NU6;N?6t&^lakV-s>+)3| z#a0gmCt?0SVL~tk))2?*yU@Ea?2bAcLijedUc!-QaFVw7)49!emfmC@DMt2h!L&~) zL(eF2Q~IIYpy{z(qYxB64r|I&q91i_1wpM$lkj0bKX9fYE zxUx<^$qR(W>kuZfH^JIRsMM*B_0~fQ;p)EBQHx%9wF&hKWqRFrLnAE{ozbvL6BX^= z_`PCs!CrqlXyAHS{k66&7`K-go2gs;v+CX6epT*2g9L`cd$>y$O9RZ40YiujPh(}E zX#iMU)asrS8G>I{j|=O-d8Ijbkz9Ze0NrT9E$_de0smSs1;)??9TV2I!o!Mi7gr{a zc4qKGNGF2UKTcQxp)a^i2wR+PDb!LBgEmBliDNkR>(_WVL6) zSM(!!!G6R6{PAcA2MGg-MDDW0}l&x@`nPyklYSO32@g`ol9v>b*t4%pn|SxE_2aietP&YypnO ztD&P3OPSP1<`CNN6!&Teyv#G8c9hmQ7nfPqsP<{E(2w}UD0wG25gY&%JgdduUk8mo z_R*~&?7=9o@leK@xDA;w8!=Zff_m@n_}ybb_;zC+!a^C5jG$tD$eX~@a&KBpf#O^* z#9?tTJxg%=8uT*?qBJkL@Z1lBKjFKGV7GuYgJFv_mZm}`USL8%1ILK6Qe;!JB!hZ= z1rk_4f={2~z~SA;&y>yjijdizuoN0WN13X~O~-xXWFu+6i?{eKEtoj!Z$z+j$8=r&jJeFLdI;1vg z$m~^?8$vwc?e@9h#e{qEwR8C@_FdIws-Z}y^ss~d? zVK0l0#NW6axcDwv3erTGCJli{!TAr`&t4|eDpACb4dsehi&x|Br3pQtdXSCM=62lK zXS$w#W`Tz6Lu|(YreFnWib0YS#OCy7;^QFF2nng0{+tLd*vJYPsl9%py}Iw{VjWF1 zhk}vh1&4jCT+HEN%6LBtGe3y@T~Lf2e|nU@0P<^GYpd+VNf&X$*uG$9^4*Fm>+XSD zI-t6$mFmg4T9$63UI;MIS^s*p;JWYRo7nLf3H*pS)F_M(%4o?x-xAUU&)2v)0|Cx}VN$2(+oYG+gw;YG9*xIPq#To}21>~Rv}75m|6AJ3 zKZ1YY3?0toKmqYbD6gXLvykBetXtuCsjDFyID>s=EVud3k}G;h7(vGu*DX-jE`jz#TN z71Ctm@G$F2jb>Fg1_S_fL6Y*ZvK|>32Bn2iCr?HWj_NGSrowY${g}po6g~U@ehqX4sK#H;ej5Naq~O4p zUlyz%CHwy!*4U|hH}eJ!SYseUePRfZN(fJAOT(!z@fzmO+ktYnsZSxE&lA`*O%t}N zs{-0O&Ydr>%Uz2T5QDmS+lI(Y{>f=M(d6K75MtG|?>8#OkAg~NbPiFJ<3By*(H@!j zl%~KA;VyqpMv@X@R#5qb=4RgKQgE1WwcrMwDI}uchCks=B~gjeR7Bi*)D!08dACAk zEU>t@5#sJw&)d)``Ry5hkq|q!mM2+;_wZsM6ru7Ac0SmLa{%i7_34^E5+7&{A`Qw| z(TNjiaSsk`c;;tuYhUWkm4ap8D2OZu-lIE8wp-1;~hl#xlQ}6Ld ztP7}{d}+|dUMX}PzQZX!L;GABuKnulxdJ@5iVL!;|A=9SOoL=8zZXxvMs8rDe`5OR zcKKuxO(YMizU7U^?du0 zXgc9X`~=s~Ymbu7r{(L25bLrNX$$?)WOxkk(P*>PbOztwIzPRUJgdZI^pQL~aO&2x zpm?v8s&L?W`eKS6%(2a}IlsaY;D<5|&a{`GvFXw|@O!V~LqE{k75;*wYVU?x;e{aF zvSPpA(CcN%0j_!66I9DTz8;CV1_zn=Ugpo7nN{yw>YoVNUj}63eHFliF-*@FhEb(J zlO(f_4HpZN;omhjV>c1d7y{(=WDa1QkjqtA>0IMGlUS2x;hCWM1F1ZeKW- z2E`~o2U=Zcpy@Q-|0Y?Z!FeUi6R@N-O$<{VleN&d;_k)e;D5_&_xQudnj^C>sI9wH zyN~@bf0T4mT3zu%pkh(s%dWKgQnGHj7M$k$Ac%*oRPqgtscib`mr2LamT=r$#M7%+ zRb5nnR=@4;3NB73YJRE`Nv)eZ_r`ET*qb@|Nufu7)|Rm3f#`O*zaJa)a;j)y(S9|3 zZ@4;HWGZejG;#WM$3@gN-+Q|Fmv$>fpPqLY5zwQ+?v@z7^R{U(ydgFXIP`#u}N5yGkd553&bV|eo3R5#+lb*)wv>Bvx zv;B%sxs4}k7Wewv`e>koc}U(YVxNSqjOc#DCI&brMAg{Y)W}>!txb9}9cG^pXUT!q zFo$tCU8gzaVsQ~>H1!OQQ^Lrj_m;+hj#(?kG&w%)akOkgZg?NORM2Q}hUp%z=oCck zhtZHN5-WCbuBn{AOE;)2H!fnec32`1+{g(1Zq?4A^6$maUa73%Dk`~C)@XAOs_*&+FLp9 z%o~PlA{RpU*P5xutfkYx@9)iGH_2xBGv^XBpWdp#y>xGlpXIrKxaeAN7P+bmql z%KMtBZj4*mG{;$DjrfGOC}Chliwak`uGn0Z@JO#RAe=`ag`8`ub!F(8jy5#nQ?cz7 zD;rJfg8o^;HePg9=QeN5u`nrTABS+;;|K7;Gj;_s3a)nAZvgl)y8zJ)9IgASrwOy8 zz2m;p=KWloW4l#hb5fzx$W22om8Cm0t9ZJ^;k+Jws5<5Zi(WrIwrTx*SvWg;5^yQ! z5ICe@Kp2GhJq^%e=O%)t+73z;#j>UHGIZP45T^F(UFor)%I!$7DY4eLm81TA z_N2V7UYEH*GDPI?+J?{hgy*JN#w6WKtLMR!%6r!BhP1=tl4{a6i8mR+6l}_%>l879 z6x#Z$zv@?uH_v}t%LEP;s*m*(xJwGeJ05@#sW6Vsye5{qyQ6^4yj!tKAhQ7C$=prW0`S#PoF6X;+w_1 zl?89VhG#shD?nsuNQqFv<_1J$$(aj*cvo-DKjX#`+<$Hn^CS8&`f?Yf=RA+iS`g<$ z8LQI0xD;`AhFHyK81`l^y@b!*p55=d>tgk9<=T+(U_$45J`)+yf%K)V0Y(WnwOt@a zzq4^lTUL>rYzZ?2tsgD6;K3tuTpKtAlPrtGaIG z*Jcc6?mFrXIRN*~AdS6!yj^*2t8-eUOz|iGn4J6$v14y1@k~5<`K(z;o%3A_DLmYMbelvh|H$|7 zkgkOiI!TvHlP7)jIA^=mT|M9!U6QONwI0l!{~fG>;jV7K)Gkc9uTB+1`=hC+KHfjl z=tsj3Mf})xXi;Lv_92YfMOQ>;_js|fZWx$?>WGL| z>V#+^SEPQf9aJ~cM|Kw&VqMZTgeBzNs3>6`?v!aJ1%7K_!A5N#4d0#m_G_?qId^ZP z0U>fK(S#1u3@zG(qgLmdbelE;PJ#+M9aBU!q^_jda!46VnZAW`ACT2vxe(=d1W;1Q|y6Z?p^Xe)d(utlUKDHk=cOR

(1ib00c7Uh`P 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%0D`!``7%Iy`oE2(Ay6%F`o0ngQ6nw&sA0b06X z#*NT^_<661=B>ryy_TG&ojwav{C937;%VT-*;bVL@H)6uv=;cdL1@U`ib>mgq>tlq zRLm`S;U#M7-f@lK%ih$?6zvQSQh>5Z#%eDB+ji1R?K_sQuY0#ILSdM%c~ERN@zc23DNg%Hi@;j(4xdQcdT8 z8ATxNc}f9tmr*fnvw<7Gyvp;*p^R%JR`GBepg|`pLN-b#<{-bjOfZ$PMAj`^C}cW7 z0hB9`39BuN+2rgUEqZhk!9!eFW}s)UM9`pKz+)AFng94a-uS47N4q;a-%d9MPuD)s zF;YK2AJpGclUmyEA1rN|+6`Yh9t=f&vcqUqHyQQ1vFZ21B3ozY;73!;HbH8lLU!U| znY=D;O$`Hb^EQTv%-Si?CZgOiwGFxQD<=RF!?2tY<#C3eY|$2-6q|(=vsy&b?QRnl zvl(#Lj9jw_hLh$KGLl057$*Wm6K-Tqmn*o5fbQPhp3*MTkg` z8l_awv!@b##NkRh3u!i4Ags@kGy`=C-4&+Yn5f1!xT>w~*%;DwM$4C1*g}B*+~AQ7 z1r7G$Vrf&Z2z1C!K--6zo8z#@48M6$yPD?t=cl(2HbMa6lA9-bg4P1K$9pY0h_WV z*CdApo>O0IG^~1xMT$=+REliexO4p-^k)d0aZwM^6}a-XbxFd~ft94F=6EU;&BC6{ zVK}l9JwQuYzs_N8vm}H&p%kW*^IB>4mqh4uPhS7D8;_hPgk&v6Sk~c#H12Jh!%5eD zJFkFBMGe^p`~@z{Pyh?Pu*cPySDVa)o^e4LTLkBe2NcZ-;aEiz;Xuv>A8ZETgoZx7 z61rNZ*@C|h4iMb6fFfi8X4w+xH{Vn_>eZ~fm(PNp8ayY17rf4V>y*V((1WJ&j|ci+ zjK2y93(Xv6;ST;J&8C4pd*U2C%v~jL-Ef%!lqtE09UC0ZYf*5VR^DExnXc1L-D>_s zQ6E+SqvbY2JEP%?Br>tAgF-qP&4tOL*!d5e1rs9_MjQWU zyx^jd(V~uxO{dMxM<29^n}clZcnGN_(w5DM6+RaYyr^^b3Mbl3Mq%+q!Le*WJ9iXM zR60^-IM67E>d2^!wD1lp*(N9&mpjS5S4%4LKhdo@@FVF5FZ7F3lAa%exTA1WD*b1ry{fjU=!M(3QjJFo5l0Cn6@>{ zu>rWZ>f0BW{IrQZ*G4SLRth7jmPrMs{{PR$3b1O%jd>M zcFP{)H;0qt9c^l4Z_MVD3H6XZKyWe+HdaK%#Dq5_n8%)~L_^WZ3)8gH#BHbE5dhr_ zQDQ#TdxW7bnMPr!C32A&CybM25+H$x%_+Co&XUc}VvHPA)J;>RKONmDv4~26hY0ya zW~k5jjAoO?myc}G3b(v!$t(*JZqZoJFvMK#RmV&YdnAp&c$mO`H ztfpQD=a1u)s>RdPJm^J!1ieAy8O})vvy6z5_XRUVOz^bk?oSnrB8R;}QLofUhl|=I zq!47JRB(XdynP9&4J#GrE(tu(ZL;4qK8F?WQNY^W3o|)6oN3`xo-w9rv`_d@-S_hI zoX^8d+Lm8hS|l&n(p0w>2vAb!cnA>??1iSbN%RQ$5hWtZhB)25z3c>2cz)TPv^ex- zKw|tPNE;L0@VvozIywG570c^Hw~D2*_E4mu{*9$;Qj@U0-(3spJmL%V|3ApncUg3N zNhCSQACBeKHnn9>Un(iSj!WRRRZ?L5G1WwG&OIonbrGTVVcndgCp)wG$4ilFl+wEg z5_-dT)aB(iDn&TR1F034CcUDJf7>el1uqKn^ddY6baQNhf=I;i8WFXSdMd_*)9XpS zwzKmsQYw5QIhCspBO+#+^1s`~7NCiN8~Jmb+=;awk)krbbZtBxc|6+_{~w3<-~2_C z-~Qm>8|FEx$geaa6G&)ren1>5||m>&pKN`KYk&$l$bjvv=6VYbbw~ Nih`zmjjYA{{{SC4x1s<5 From cd0910b7874f9e6fbb6b15115d054a25e3abbe68 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 1 Aug 2016 12:40:38 -0400 Subject: [PATCH 0952/1223] Fix p2p-feefilter.py for changed tx relay behavior Github-Pull: #8444 Rebased-From: 2c517b3928a68c6e36b18262081a401a741cd4cd --- qa/rpc-tests/p2p-feefilter.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index cd0501a31..96d99d38a 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -62,6 +62,7 @@ class FeeFilterTest(BitcoinTestFramework): def run_test(self): node1 = self.nodes[1] + node0 = self.nodes[0] # Get out of IBD node1.generate(1) sync_blocks(self.nodes) @@ -91,8 +92,17 @@ class FeeFilterTest(BitcoinTestFramework): node1.settxfee(Decimal("0.00010000")) [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] sync_mempools(self.nodes) # must be sure node 0 has received all txs - time.sleep(10) # wait 10 secs to be sure its doesn't relay any - assert(allInvsMatch([], test_node)) + + # Send one transaction from node0 that should be received, so that we + # we can sync the test on receipt (if node1's txs were relayed, they'd + # be received by the time this node0 tx is received). This is + # unfortunately reliant on the current relay behavior where we batch up + # to 35 entries in an inv, which means that when this next transaction + # is eligible for relay, the prior transactions from node1 are eligible + # as well. + node0.settxfee(Decimal("0.00020000")) + txids = [node0.sendtoaddress(node0.getnewaddress(), 1)] + assert(allInvsMatch(txids, test_node)) test_node.clear_invs() # Remove fee filter and check that txs are received again From d485a6c5a8d238cac5ad732ce9e744f4b121143c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Aug 2016 14:37:49 +0200 Subject: [PATCH 0953/1223] doc: Add list of new and removed RPC commands to release notes Finish up the RPC part of #7678. --- doc/release-notes.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index aa9b48d72..de2e73d24 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -289,6 +289,14 @@ Low-level RPC changes - The sorting of the output of the `getrawmempool` output has changed. +- New RPC commands: `generatetoaddress`, `importprunedfunds`, `removeprunedfunds`, `signmessagewithprivkey`, + `getmempoolancestors`, `getmempooldescendants`, `getmempoolentry`, + `createwitnessaddress`, `addwitnessaddress`. + +- Removed RPC commands: `setgenerate`, `getgenerate`. + +- New options were added to `fundrawtransaction`: `includeWatching`, `changeAddress`, `changePosition` and `feeRate`. + Low-level ZMQ changes ---------------------- From b49d963cf7c5feeb90666749171b752731f70061 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 5 Aug 2016 21:01:33 +0200 Subject: [PATCH 0954/1223] Document reindexing changes --- doc/release-notes.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index de2e73d24..2c9ff299c 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -214,6 +214,24 @@ no longer optimized for this metric. Feedback is requested on whether to deprecate or keep this command line option in future releases. +Reindexing changes +------------------ + +In earlier versions, reindexing did validation while reading through the block +files on disk. These two have now been split up, so that all blocks are known +before validation starts. This was necessary to make certain optimizations that +are available during normal synchronizations also available during reindexing. + +The two phases are distinct in the Bitcoin-Qt GUI. During the first one, +"Reindexing blocks on disk" is shown. During the second (slower) one, +"Processing blocks on disk" is shown. + +It is possible to only redo validation now, without rebuilding the block index, +using the command line option `-reindex-chainstate` (in addition to +`-reindex` which does both). This new option is useful when the blocks on disk +are assumed to be fine, but the chainstate is still corrupted. It is also +useful for benchmarks. + Removal of internal miner -------------------------- From 8b0eee66e9c9057b6e53bb1f4a0a3821083e5df0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 8 Aug 2016 21:16:40 +0000 Subject: [PATCH 0955/1223] Bugfix: Use pre-BIP141 sigops until segwit activates qa/rpc-tests/segwit: Test GBT sigops before and after activation Github-Pull: #8489 Rebased-From: 160f895a80660e4e3904a2624e4110960d051902 239cbd2e5c2a36843b45b356e9aea6e8d35f0968 --- qa/rpc-tests/segwit.py | 50 +++++++++++++++++++++++++++++++++++++----- src/rpc/mining.cpp | 17 ++++++++++++-- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index d4c9a8afe..097e119f3 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -69,6 +69,11 @@ def getutxo(txid): utxo["txid"] = txid return utxo +def find_unspent(node, min_value): + for utxo in node.listunspent(): + if utxo['amount'] >= min_value: + return utxo + class SegWitTest(BitcoinTestFramework): def setup_chain(self): @@ -117,8 +122,21 @@ class SegWitTest(BitcoinTestFramework): sync_blocks(self.nodes) def run_test(self): - self.nodes[0].generate(160) #block 160 + self.nodes[0].generate(161) #block 161 + print("Verify sigops are counted in GBT with pre-BIP141 rules before the fork") + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + tmpl = self.nodes[0].getblocktemplate({}) + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + self.nodes[0].generate(1) #block 162 + + balance_presetup = self.nodes[0].getbalance() self.pubkey = [] p2sh_ids = [] # p2sh_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE embedded in p2sh wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness @@ -137,18 +155,18 @@ class SegWitTest(BitcoinTestFramework): for i in range(5): for n in range(3): for v in range(2): - wit_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], False, Decimal("49.999"))) - p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], True, Decimal("49.999"))) + wit_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], False, Decimal("49.999"))) + p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], True, Decimal("49.999"))) - self.nodes[0].generate(1) #block 161 + self.nodes[0].generate(1) #block 163 sync_blocks(self.nodes) # Make sure all nodes recognize the transactions as theirs - assert_equal(self.nodes[0].getbalance(), 60*50 - 60*50 + 20*Decimal("49.999") + 50) + assert_equal(self.nodes[0].getbalance(), balance_presetup - 60*50 + 20*Decimal("49.999") + 50) assert_equal(self.nodes[1].getbalance(), 20*Decimal("49.999")) assert_equal(self.nodes[2].getbalance(), 20*Decimal("49.999")) - self.nodes[0].generate(262) #block 423 + self.nodes[0].generate(260) #block 423 sync_blocks(self.nodes) print("Verify default node can't accept any witness format txs before fork") @@ -205,5 +223,25 @@ class SegWitTest(BitcoinTestFramework): self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True) #block 434 self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True) #block 435 + print("Verify sigops are counted in GBT with BIP141 rules after the fork") + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sigoplimit'] == 80000) + assert(tmpl['transactions'][0]['txid'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 8) + + print("Verify non-segwit miners get a valid GBT response after the fork") + send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.998")) + try: + tmpl = self.nodes[0].getblocktemplate({}) + assert(len(tmpl['transactions']) == 1) # Doesn't include witness tx + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + assert(('!segwit' in tmpl['rules']) or ('segwit' not in tmpl['rules'])) + except JSONRPCException: + # This is an acceptable outcome + pass + if __name__ == '__main__': SegWitTest().main() diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 92ca4bab6..2479e5d59 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -546,6 +546,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; + // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration + const bool fPreSegWit = (THRESHOLD_ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); @@ -574,7 +577,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) int index_in_template = i - 1; entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOpsCost[index_in_template])); + int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template]; + if (fPreSegWit) { + assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0); + nTxSigOps /= WITNESS_SCALE_FACTOR; + } + entry.push_back(Pair("sigops", nTxSigOps)); entry.push_back(Pair("weight", GetTransactionWeight(tx))); transactions.push_back(entry); @@ -657,7 +665,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_COST)); + int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; + if (fPreSegWit) { + assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); + nSigOpLimit /= WITNESS_SCALE_FACTOR; + } + result.push_back(Pair("sigoplimit", nSigOpLimit)); result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); result.push_back(Pair("curtime", pblock->GetBlockTime())); From 9058617afb24594f09848d2a53403760bd64470a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 Aug 2016 21:10:28 +0000 Subject: [PATCH 0956/1223] qt: translations update pre-rc3 --- src/qt/bitcoinstrings.cpp | 3 +- src/qt/locale/bitcoin_da.ts | 4 +++ src/qt/locale/bitcoin_de.ts | 2 +- src/qt/locale/bitcoin_en.ts | 46 ++++++++++++++-------------- src/qt/locale/bitcoin_es.ts | 4 +++ src/qt/locale/bitcoin_es_CO.ts | 4 +++ src/qt/locale/bitcoin_it.ts | 42 ++++++++++++++++++++++++- src/qt/locale/bitcoin_ja.ts | 4 +++ src/qt/locale/bitcoin_pt_BR.ts | 10 +++++- src/qt/locale/bitcoin_ro.ts | 14 ++++++++- src/qt/locale/bitcoin_ru.ts | 54 +++++++++++++++++++++++++++++++- src/qt/locale/bitcoin_tr.ts | 4 +++ src/qt/locale/bitcoin_vi_VN.ts | 56 ++++++++++++++++++++++++++++++++++ src/qt/locale/bitcoin_zh_TW.ts | 4 +++ 14 files changed, 222 insertions(+), 29 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 22d3e0824..fefaaf8cd 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -60,6 +60,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Do not keep transactions in the mempool longer than hours (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Error loading %s: You can't enable HD on a already existing non-HD wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error reading %s! All keys read correctly, but transaction data or address " @@ -284,7 +286,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most connections to peers (de QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, *1000 bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, *1000 bytes (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Minimum bytes per sigop in transactions we relay and mine (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."), diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index db52367ef..5fc6733b5 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -2098,6 +2098,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d) + + Set maximum BIP141 block weight (default: %d) + Sæt maksimal BIP141-blokvægt (standard: %d) + Set maximum block size in bytes (default: %d) Sæt maksimum blokstørrelse i byte (standard: %d) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 502d02b7f..dc632a246 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1892,7 +1892,7 @@ Change index out of range - Änderungsindex außerhalb des Bereichs + Position des Wechselgelds außerhalb des Bereichs Connect only to the specified node(s) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 2785ed929..14126f2d6 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -2226,7 +2226,7 @@ bitcoin-core - + Options: Options: @@ -2236,17 +2236,17 @@ Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands @@ -2286,7 +2286,7 @@ - + Pruning blockstore... @@ -2301,12 +2301,12 @@ - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -2352,6 +2352,11 @@ + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + + + + Error loading %s: You can't enable HD on a already existing non-HD wallet @@ -2631,12 +2636,7 @@ - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - - - - + Not enough file descriptors available. Not enough file descriptors available. @@ -2766,7 +2766,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -2791,7 +2791,7 @@ - + Error: Listening for incoming connections failed (listen returned error %s) @@ -2911,7 +2911,7 @@ - + Need to specify a port with -whitebind: '%s' @@ -3046,7 +3046,7 @@ Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) @@ -3061,7 +3061,7 @@ Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3081,7 +3081,7 @@ - + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) @@ -3206,7 +3206,7 @@ - + Prepend debug output with timestamp (default: %u) @@ -3261,7 +3261,7 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds @@ -3291,12 +3291,12 @@ Cannot write default address - + Rescanning... Rescanning... - + Done loading Done loading diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 1a367c276..5e1187301 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -2097,6 +2097,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) + + Set maximum BIP141 block weight (default: %d) + Establecer peso máximo bloque BIP141 (predeterminado: %d) + Set maximum block size in bytes (default: %d) Establecer tamaño máximo de bloque en bytes (predeterminado: %d) diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts index df189190f..7d10e0320 100644 --- a/src/qt/locale/bitcoin_es_CO.ts +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -197,6 +197,10 @@ Intro + + Welcome + bienvenido + Error Error diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 752c4f4fe..0ed0fc442 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -114,6 +114,10 @@ &About %1 &Informazioni su %1 + + Show information about %1 + Mostra informazioni su %1 + About &Qt Informazioni su &Qt @@ -126,6 +130,10 @@ &Options... &Opzioni... + + Modify configuration options for %1 + Modifica le opzioni di configurazione per %1 + &Encrypt Wallet... &Cifra il portamonete... @@ -254,6 +262,14 @@ %n active connection(s) to Bitcoin network %n connessione attiva alla rete Bitcoin%n connessioni alla rete Bitcoin attive + + Indexing blocks on disk... + Indicizzando i blocchi su disco... + + + Processing blocks on disk... + Processando i blocchi su disco... + No block source available... Nessuna fonte di blocchi disponibile... @@ -310,6 +326,14 @@ Up to date Aggiornato + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra il messaggio di aiuto di %1 per ottenere una lista di opzioni di comando per Bitcoin + + + %1 client + %1 client + Catching up... In aggiornamento... @@ -532,13 +556,25 @@ Show splash screen on startup (default: %u) Mostra schermata iniziale all'avvio (default: %u) - + + Reset all settings changed in the GUI + Reimposta tutti i campi dell'interfaccia grafica + + Intro Welcome Benvenuto + + Welcome to %1. + Benvenuto su %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Dato che questa è la prima volta che il programma viene lanciato, puoi scegliere dove %1 salverà i suoi dati. + Use the default data directory Usa la cartella dati predefinita @@ -593,6 +629,10 @@ &Main &Principale + + Automatically start %1 after logging in to the system. + Avvia automaticamente %1 una volta effettuato l'accesso al sistema. + Size of &database cache Dimensione della cache del &database. diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 4d866ce94..52f18c118 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -2099,6 +2099,10 @@ Set database cache size in megabytes (%d to %d, default: %d) データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d) + + Set maximum BIP141 block weight (default: %d) + BIP141ブロック重みの最大値を設定 (初期値: %d) + Set maximum block size in bytes (default: %d) 最大ブロックサイズをバイトで設定 (初期値: %d) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 5e7f47cda..bc7ee034d 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1567,7 +1567,7 @@ 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. - A taxa será deduzida da quantia sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se varios destinatários estão selecionados, a taxa é dividida igualmente. + A taxa será deduzida da quantia que está sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se vários destinatários estão selecionados, a taxa é dividida igualmente. S&ubtract fee from amount @@ -1866,6 +1866,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Este pode ser um build de teste pré-lançamento - use por sua conta e risco - não use para mineração ou aplicações de comércio. + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Não foi possível reanalisar o banco de dados para o estado pre-fork. Você precisa rebaixar o blockchain + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy) @@ -2050,6 +2054,10 @@ Prune mode is incompatible with -txindex. O modo Prune é incompatível com -txindex. + + Rewinding blocks... + Reanalizando blocos... + Set database cache size in megabytes (%d to %d, default: %d) Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d) diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index 270a4ba06..cf85cf44c 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -63,9 +63,21 @@ BanTableModel - + + Banned Until + Blocat până + + BitcoinGUI + + Synchronizing with network... + Se sincronizează cu rețeaua + + + &Options... + &Opțiuni... + CoinControlDialog diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index db9d37c8c..271b11122 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -655,7 +655,7 @@ Accept connections from outside - Разрешать соединения извне + Принимать входящие соединения Allow incoming connections @@ -1802,6 +1802,10 @@ -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. Установлено очень большое значение -fallbackfee! Это комиссия за транзацию, которую вы можете заплатить, если оценка размера комиссии не доступна. + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Принимать транзакции пересылаемые от узлов из белого списка даже если они не удовлетворяют требованиям ретрансляции (по умолчанию: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6 @@ -1818,6 +1822,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Ошибка загрузки %s: Вы не можете включить HD в уже существующем не-HD кошельке + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Ошибка чтения %s! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. @@ -1846,6 +1854,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Невозможно отмотать базу данных до пред-форкового состояния. Вам будет необходимо перекачать цепочку блоков. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy) @@ -1862,6 +1874,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Вам необходимо пересобрать базы данных с помощью -reindex-chainstate, чтобы изменить -txindex + %s corrupt, salvage failed %s поврежден, восстановить не удалось @@ -1886,6 +1902,14 @@ Block creation options: Параметры создания блоков: + + Cannot resolve -%s address: '%s' + Не удаётся разрешить адрес в параметре -%s: '%s' + + + Change index out of range + Изменение индекса вне диапазона + Connect only to the specified node(s) Подключаться только к указанному узлу(ам) @@ -1950,6 +1974,10 @@ Error loading %s: Wallet requires newer version of %s Ошибка загрузки %s: Для бумажника требуется более новая версия %s + + Error loading %s: You can't disable HD on a already existing HD wallet + Ошибка загрузки %s: Вы не можете включить HD в уже существующем не-HD кошельке + Error loading block database Ошибка чтения базы данных блоков @@ -1974,6 +2002,10 @@ Incorrect or no genesis block found. Wrong datadir for network? Неверный или отсутствующий начальный блок. Неправильный каталог данных для сети? + + Initialization sanity check failed. %s is shutting down. + Начальная проверка исправности не удалась. %s завершает работу. + Invalid -onion address: '%s' Неверный -onion адрес: '%s' @@ -1994,6 +2026,10 @@ Location of the auth cookie (default: data dir) Расположение куки входы(по умолчанию: data dir) + + Minimum bytes per sigop in transactions we relay and mine (default: %u) + Минимально байт на sigop в транзакциях, которые мы ретранслируем и добываем (по умолчанию: %u) + Not enough file descriptors available. Недостаточно файловых дескрипторов. @@ -2022,10 +2058,18 @@ Rebuild chain state from the currently indexed blocks Перестроить индекс цепи из текущих индексированных блоков + + Rewinding blocks... + Перемотка блоков... + Set database cache size in megabytes (%d to %d, default: %d) Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d) + + Set maximum BIP141 block weight (default: %d) + Задать максимальное BIP141 значение блока (по умолчанию: %d) + Set maximum block size in bytes (default: %d) Задать максимальный размер блока в байтах (по умолчанию: %d) @@ -2150,6 +2194,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Использовать иерархическую детерминированную генерацию ключей (HD) после BIP32. Применяется в процессе создания бумажника / первого запуска + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза. @@ -2370,6 +2418,10 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Обнаружен не поддерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Не поддерживаемый аргумент -whitelistalwaysrelay игнорируется, используйте -whitelistrelay и/или -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index ccf570b53..21a91a86f 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -2098,6 +2098,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d) + + Set maximum BIP141 block weight (default: %d) + Azami BIP141 blok ağırlığını ayarla (varsayılan: %d) + Set maximum block size in bytes (default: %d) Azami blok boyutunu bayt olarak ayarla (varsayılan: %d) diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index 8b92a3a2e..e5f955eb4 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -74,6 +74,10 @@ BitcoinGUI + + Sign &message... + Chứ ký & Tin nhắn... + Synchronizing with network... Đồng bộ hóa với mạng @@ -86,6 +90,10 @@ Node Node + + Show general overview of wallet + Hiện thỉ thông tin sơ lược chung về Ví + &Transactions &Giao dịch @@ -150,6 +158,10 @@ Open &URI... Mở &URI... + + Reindexing blocks on disk... + Đánh chỉ số (indexing) lại các khối (blocks) trên ổ đĩa ... + Send coins to a Bitcoin address Gửi coins đến tài khoản Bitcoin @@ -158,6 +170,14 @@ Backup wallet to another location Sao lưu ví tiền ở vị trí khác + + Change the passphrase used for wallet encryption + Thay đổi cụm mật mã dùng cho mã hoá Ví + + + &Debug window + &Cửa sổ xử lý lỗi (debug) + &Verify message... &Tin nhắn xác thực @@ -186,6 +206,18 @@ Show or hide the main Window Hiện hoặc ẩn cửa sổ chính + + Encrypt the private keys that belong to your wallet + Mã hoá các khoá bí mật trong Ví của bạn. + + + Sign messages with your Bitcoin addresses to prove you own them + Dùng địa chỉ Bitcoin của bạn ký các tin nhắn để xác minh những nội dung tin nhắn đó là của bạn. + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Kiểm tra các tin nhắn để chắc chắn rằng chúng được ký bằng các địa chỉ Bitcoin xác định. + &File &File @@ -198,10 +230,22 @@ &Help Trợ &giúp + + Tabs toolbar + Thanh công cụ (toolbar) + Request payments (generates QR codes and bitcoin: URIs) Yêu cầu thanh toán(tạo mã QR và địa chỉ Bitcoin: URLs) + + Show the list of used sending addresses and labels + Hiện thỉ danh sách các địa chỉ và nhãn đã dùng để gửi. + + + Show the list of used receiving addresses and labels + Hiện thỉ danh sách các địa chỉ và nhãn đã dùng để nhận. + Open a bitcoin: URI or payment request Mở bitcoin:URL hoặc yêu cầu thanh toán @@ -234,6 +278,14 @@ %1 behind %1 chậm trễ + + Last received block was generated %1 ago. + Khối (block) cuối cùng nhận được cách đây %1 + + + Transactions after this will not yet be visible. + Những giao dịch sau đó sẽ không hiện thị. + Error Lỗi @@ -250,6 +302,10 @@ Up to date Đã cập nhật + + Catching up... + Bắt kịp... + Date: %1 diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 1fd8d6df8..21ca417ac 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -2099,6 +2099,10 @@ Set database cache size in megabytes (%d to %d, default: %d) 設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d) + + Set maximum BIP141 block weight (default: %d) + 設定 BIP141 區塊重量的最大值(預設值: %d) + Set maximum block size in bytes (default: %d) 設定區塊大小上限成多少位元組(預設值: %d) From b52c67c4b188c274de60fbd5e26441e9a644dba6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 11 Aug 2016 23:27:24 +0200 Subject: [PATCH 0957/1223] doc: Update changelog for rc3 --- doc/release-notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 2c9ff299c..ea6e56927 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -392,6 +392,7 @@ git merge commit are mentioned. - #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) - #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) - #8381 `f84ee3d` Make witness v0 outputs non-standard (jl2012) +- #8364 `3f65ba2` Treat high-sigop transactions as larger rather than rejecting them (sipa) ### P2P protocol and network code @@ -644,6 +645,7 @@ git merge commit are mentioned. - #7951 `5c7df70` Test_framework: Properly print exception (MarcoFalke) - #8070 `7771aa5` Remove non-determinism which is breaking net_tests #8069 (EthanHeilman) - #8309 `bb2646a` Add wallet-hd test (MarcoFalke) +- #8444 `cd0910b` Fix p2p-feefilter.py for changed tx relay behavior (sdaftuar) ### Mining @@ -656,6 +658,7 @@ git merge commit are mentioned. - #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) - #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) - #8362 `86edc20` Scale legacy sigop count in CreateNewBlock (sdaftuar) +- #8489 `8b0eee6` Bugfix: Use pre-BIP141 sigops until segwit activates (GBT) (luke-jr) ### Documentation and miscellaneous From 7f84015352808776175f686f256d037eb40b08ba Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 16 Aug 2016 11:15:13 +0200 Subject: [PATCH 0958/1223] Inline mempool RPCs and feefilter into misc sections --- doc/release-notes.md | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index ea6e56927..3d6abcde0 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -54,6 +54,7 @@ For nodes on low-memory systems, the database cache can be changed back to Note that the database cache setting has the most performance impact during initial sync of a node, and when catching up after downtime. + bitcoin-cli: arguments privacy -------------------------------- @@ -71,6 +72,7 @@ It is recommended to use this for sensitive information such as wallet passphrases, as command-line arguments can usually be read from the process table by any user on the system. + C++11 and Python 3 ------------------- @@ -84,6 +86,7 @@ When cross-compiling for a target that doesn't have C++11 libraries, configure w For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now required. + Linux ARM builds ------------------ @@ -104,20 +107,6 @@ possible to resolve them. Note that Android is not considered ARM Linux in this context. The executables are not expected to work out of the box on Android. -New mempool information RPC calls ---------------------------------- - -RPC calls have been added to output detailed statistics for individual mempool -entries, as well as to calculate the in-mempool ancestors or descendants of a -transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. - -Fee filtering of invs (BIP 133) ------------------------------------- - -The optional new p2p message "feefilter" is implemented and the protocol -version is bumped to 70013. Upon receiving a feefilter message from a peer, -a node will not send invs for any transactions which do not meet the filter -feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) Compact Block support (BIP 152) ------------------------------- @@ -130,6 +119,7 @@ cases it also reduces propagation delay. It is automatically enabled between compatible peers. [BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) + Hierarchical Deterministic Key Generation ----------------------------------------- Newly created wallets will use hierarchical deterministic key generation @@ -152,6 +142,7 @@ HD wallets are incompatible with older versions of Bitcoin Core. [Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + Segregated Witness ------------------ @@ -174,6 +165,7 @@ BIP 141 activation, mine segwit blocks, fully validate segwit blocks, relay segwit blocks to other segwit nodes, and use segwit transactions in the wallet, etc). + Mining transaction selection ("Child Pays For Parent") ------------------------------------------------------ @@ -232,6 +224,7 @@ using the command line option `-reindex-chainstate` (in addition to are assumed to be fine, but the chainstate is still corrupted. It is also useful for benchmarks. + Removal of internal miner -------------------------- @@ -246,9 +239,15 @@ For testing, the `generate` call can still be used to mine a block, and a new RPC call `generatetoaddress` has been added to mine to a specific address. This works with wallet disabled. + Low-level P2P changes ---------------------- +- The optional new p2p message "feefilter" is implemented and the protocol + version is bumped to 70013. Upon receiving a feefilter message from a peer, + a node will not send invs for any transactions which do not meet the filter + feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) + - The P2P alert system has been removed in PR #7692 and the `alert` P2P message is no longer supported. @@ -276,9 +275,14 @@ Low-level P2P changes - Connections to peers who have recently been the first one to give us a valid new block or transaction are protected from disconnections since PR #8084. + Low-level RPC changes ---------------------- +- RPC calls have been added to output detailed statistics for individual mempool + entries, as well as to calculate the in-mempool ancestors or descendants of a + transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. + - `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been fixed, but this means that the output will be different than from previous versions. @@ -315,6 +319,7 @@ Low-level RPC changes - New options were added to `fundrawtransaction`: `includeWatching`, `changeAddress`, `changePosition` and `feeRate`. + Low-level ZMQ changes ---------------------- @@ -324,6 +329,7 @@ Low-level ZMQ changes therefore backward compatible. Each message type has its own counter. PR [#7762](https://github.com/bitcoin/bitcoin/pull/7762). + 0.13.0 Change log ================= From fe20b83ca94c5ad2af10c45465bad9521b5c447c Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 16 Aug 2016 11:15:56 +0200 Subject: [PATCH 0959/1223] Remove refactors from list of changes --- doc/release-notes.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3d6abcde0..e3331adec 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -547,10 +547,8 @@ git merge commit are mentioned. - #7649 `4900641` Prevent multiple calls to CWallet::AvailableCoins (promag) - #7646 `e5c3511` Fix lockunspent help message (promag) - #7558 `b35a591` Add import/removeprunedfunds rpc call (instagibbs) -- #7691 `30c2dd8` Refactor wallet/init interaction (jonasschnelli) - #6215 `48c5adf` add bip32 pub key serialization (jonasschnelli) - #7913 `bafd075` Fix for incorrect locking in GetPubKey() (keystore.cpp) (yurizhykin) -- #7816 `0c95ebc` Slighly refactor GetOldestKeyPoolTime() (jonasschnelli) - #8036 `41138f9` init: Move berkeleydb version reporting to wallet (laanwj) - #8028 `373b50d` Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk (pstratem) - #8061 `f6b7df3` Improve Wallet encapsulation (pstratem) @@ -595,11 +593,9 @@ git merge commit are mentioned. - #7764 `a65b36c` Don't run pruning.py twice (MarcoFalke) - #7773 `7c80e72` Fix comments in tests (btcdrak) - #7489 `e9723cb` tests: Make proxy_test work on travis servers without IPv6 (laanwj) -- #7778 `ff5874b` Bug fixes and refactor (MarcoFalke) - #7801 `70ac71b` Remove misleading "errorString syntax" (MarcoFalke) - #7803 `401c65c` maxblocksinflight: Actually enable test (MarcoFalke) - #7802 `3bc71e1` httpbasics: Actually test second connection (MarcoFalke) -- #7818 `3911a0a` Refactor script tests (sipa) - #7849 `ab8586e` tests: add varints_bitpatterns test (laanwj) - #7846 `491171f` Clean up lockorder data of destroyed mutexes (sipa) - #7853 `6ef5e00` py2: Unfiddle strings into bytes explicitly (MarcoFalke) @@ -615,7 +611,6 @@ git merge commit are mentioned. - #7814 `77b637f` Switch to py3 (MarcoFalke) - #8030 `409a8a1` Revert fatal-ness of missing python-zmq (laanwj) - #8018 `3e90fe6` Autofind rpc tests --srcdir (jonasschnelli) -- #7971 `4e14afe` Refactor test_framework and pull tester (MarcoFalke) - #8016 `5767e80` Fix multithread CScheduler and reenable test (paveljanik) - #7972 `423ca30` pull-tester: Run rpc test in parallel (MarcoFalke) - #8039 `69b3a6d` Bench: Add crypto hash benchmarks (laanwj) @@ -659,7 +654,6 @@ git merge commit are mentioned. - #7663 `c87f51e` Make the generate RPC call function for non-regtest (sipa) - #7671 `e2ebd25` Add generatetoaddress RPC to mine to an address (achow101) - #7935 `66ed450` Versionbits: GBT support (luke-jr) -- #7598 `e1486eb` Refactor CreateNewBlock to be a method of the BlockAssembler class (morcos) - #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) - #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) - #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) From 2f5858952e968ff0d93eeb704a480a095f7c9adf Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 16 Aug 2016 11:17:47 +0200 Subject: [PATCH 0960/1223] Mention dump/import support for HD wallets --- doc/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index e3331adec..ba8ad71be 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -132,6 +132,10 @@ ones which haven't already been generated during the time of the backup. **Attention:** Encrypting the wallet will create a new seed which requires a new backup! +Wallet dumps (created using the `dumpwallet` RPC) will contain the deterministic +seed. This is expected to allow future versions to import the seed and all +associated funds, but this is not yet implemented. + HD key generation for new wallets can be disabled by `-usehd=0`. Keep in mind that this flag only has affect on newly created wallets. You can't disable HD key generation once you have created a HD wallet. From 4f5529351f94026a8e206b3df0476f7c6a492bbf Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 8 Aug 2016 21:07:38 +0000 Subject: [PATCH 0961/1223] doc/release-notes: Misc --- doc/release-notes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index ba8ad71be..6c7385c98 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -56,7 +56,7 @@ during initial sync of a node, and when catching up after downtime. bitcoin-cli: arguments privacy --------------------------------- +------------------------------ The RPC command line client gained a new argument, `-stdin` to read extra arguments from standard input, one per line until EOF/Ctrl-D. @@ -74,7 +74,7 @@ table by any user on the system. C++11 and Python 3 -------------------- +------------------ Various code modernizations have been done. The Bitcoin Core code base has started using C++11. This means that a C++11-capable compiler is now needed for @@ -88,7 +88,7 @@ required. Linux ARM builds ------------------- +---------------- Due to popular request, Linux ARM builds have been added to the uploaded executables. From 40d705cb70efddee3568576ed1c88b0f89403e9e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 8 Aug 2016 22:13:21 +0000 Subject: [PATCH 0962/1223] doc/release-notes: Mention the relevance of Compact Blocks on non-mining nodes' influence on network policy --- doc/release-notes.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6c7385c98..23687eccc 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -119,6 +119,15 @@ cases it also reduces propagation delay. It is automatically enabled between compatible peers. [BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) +As a side-effect, ordinary non-mining nodes will download and upload blocks +faster if those blocks were produced by miners using similar transaction +filtering policies. This means that a miner who produces a block with many +transactions discouraged by your node will be relayed slower than one with +only transactions already in your memory pool. The overall effect of such +relay differences on the network may result in blocks which include widely- +discouraged transactions losing a stale block race, and therefore miners may +wish to configure their node to take common relay policies into consideration. + Hierarchical Deterministic Key Generation ----------------------------------------- From 5e499e7a56b2e343e0a9b169cd95f181bdd3e334 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Aug 2016 03:07:03 +0000 Subject: [PATCH 0963/1223] doc/release-notes: Document changed bytespersigop behaviour --- doc/release-notes.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 23687eccc..5dd3f5a65 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -253,6 +253,19 @@ RPC call `generatetoaddress` has been added to mine to a specific address. This works with wallet disabled. +New bytespersigop implementation +-------------------------------- + +The former implementation of the bytespersigop filter accidentally broke bare +multisig (which is meant to be controlled by the `permitbaremultisig` option), +since the consensus protocol always counts these older transaction forms as 20 +sigops for backwards compatibility. Simply fixing this bug by counting more +accurately would have reintroduced a vulnerability. It has therefore been +replaced with a new implementation that rather than filter such transactions, +instead treats them (for fee purposes only) as if they were in fact the size +of a transaction actually using all 20 sigops. + + Low-level P2P changes ---------------------- From f2306fbe01426ce11c4df6a5c1b837106bc2c702 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 25 Aug 2016 09:56:12 +0200 Subject: [PATCH 0964/1223] doc: Clean out release notes after 0.13.0 release --- doc/release-notes.md | 814 +------------------------------------------ 1 file changed, 6 insertions(+), 808 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 5dd3f5a65..77d35315f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 0.13.0 is now available from: +Bitcoin Core version 0.13.x is now available from: - + This is a new major version release, including new features, various bugfixes and performance improvements, as well as updated translations. @@ -38,323 +38,8 @@ report issues about Windows XP to the issue tracker. Notable changes =============== -Database cache memory increased --------------------------------- - -As a result of growth of the UTXO set, performance with the prior default -database cache of 100 MiB has suffered. -For this reason the default was changed to 300 MiB in this release. - -For nodes on low-memory systems, the database cache can be changed back to -100 MiB (or to another value) by either: - -- Adding `dbcache=100` in bitcoin.conf -- Changing it in the GUI under `Options → Size of database cache` - -Note that the database cache setting has the most performance impact -during initial sync of a node, and when catching up after downtime. - - -bitcoin-cli: arguments privacy ------------------------------- - -The RPC command line client gained a new argument, `-stdin` -to read extra arguments from standard input, one per line until EOF/Ctrl-D. -For example: - - $ src/bitcoin-cli -stdin walletpassphrase - mysecretcode - 120 - ..... press Ctrl-D here to end input - $ - -It is recommended to use this for sensitive information such as wallet -passphrases, as command-line arguments can usually be read from the process -table by any user on the system. - - -C++11 and Python 3 ------------------- - -Various code modernizations have been done. The Bitcoin Core code base has -started using C++11. This means that a C++11-capable compiler is now needed for -building. Effectively this means GCC 4.7 or higher, or Clang 3.3 or higher. - -When cross-compiling for a target that doesn't have C++11 libraries, configure with -`./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++`. - -For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now -required. - - -Linux ARM builds ----------------- - -Due to popular request, Linux ARM builds have been added to the uploaded -executables. - -The following extra files can be found in the download directory or torrent: - -- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries for the most - common 32-bit ARM architecture. -- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries for the most - common 64-bit ARM architecture. - -ARM builds are still experimental. If you have problems on a certain device or -Linux distribution combination please report them on the bug tracker, it may be -possible to resolve them. - -Note that Android is not considered ARM Linux in this context. The executables -are not expected to work out of the box on Android. - - -Compact Block support (BIP 152) -------------------------------- - -Support for block relay using the Compact Blocks protocol has been implemented -in PR 8068. - -The primary goal is reducing the bandwidth spikes at relay time, though in many -cases it also reduces propagation delay. It is automatically enabled between -compatible peers. -[BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) - -As a side-effect, ordinary non-mining nodes will download and upload blocks -faster if those blocks were produced by miners using similar transaction -filtering policies. This means that a miner who produces a block with many -transactions discouraged by your node will be relayed slower than one with -only transactions already in your memory pool. The overall effect of such -relay differences on the network may result in blocks which include widely- -discouraged transactions losing a stale block race, and therefore miners may -wish to configure their node to take common relay policies into consideration. - - -Hierarchical Deterministic Key Generation ------------------------------------------ -Newly created wallets will use hierarchical deterministic key generation -according to BIP32 (keypath m/0'/0'/k'). -Existing wallets will still use traditional key generation. - -Backups of HD wallets, regardless of when they have been created, can -therefore be used to re-generate all possible private keys, even the -ones which haven't already been generated during the time of the backup. -**Attention:** Encrypting the wallet will create a new seed which requires -a new backup! - -Wallet dumps (created using the `dumpwallet` RPC) will contain the deterministic -seed. This is expected to allow future versions to import the seed and all -associated funds, but this is not yet implemented. - -HD key generation for new wallets can be disabled by `-usehd=0`. Keep in -mind that this flag only has affect on newly created wallets. -You can't disable HD key generation once you have created a HD wallet. - -There is no distinction between internal (change) and external keys. - -HD wallets are incompatible with older versions of Bitcoin Core. - -[Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) - - -Segregated Witness ------------------- - -The code preparations for Segregated Witness ("segwit"), as described in [BIP -141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP -143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP -144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki), and [BIP -145](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki) are -finished and included in this release. However, BIP 141 does not yet specify -activation parameters on mainnet, and so this release does not support segwit -use on mainnet. Testnet use is supported, and after BIP 141 is updated with -proposed parameters, a future release of Bitcoin Core is expected that -implements those parameters for mainnet. - -Furthermore, because segwit activation is not yet specified for mainnet, -version 0.13.0 will behave similarly as other pre-segwit releases even after a -future activation of BIP 141 on the network. Upgrading from 0.13.0 will be -required in order to utilize segwit-related features on mainnet (such as signal -BIP 141 activation, mine segwit blocks, fully validate segwit blocks, relay -segwit blocks to other segwit nodes, and use segwit transactions in the -wallet, etc). - - -Mining transaction selection ("Child Pays For Parent") ------------------------------------------------------- - -The mining transaction selection algorithm has been replaced with an algorithm -that selects transactions based on their feerate inclusive of unconfirmed -ancestor transactions. This means that a low-fee transaction can become more -likely to be selected if a high-fee transaction that spends its outputs is -relayed. - -With this change, the `-blockminsize` command line option has been removed. - -The command line option `-blockmaxsize` remains an option to specify the -maximum number of serialized bytes in a generated block. In addition, the new -command line option `-blockmaxweight` has been added, which specifies the -maximum "block weight" of a generated block, as defined by [BIP 141 (Segregated -Witness)] (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki). - -In preparation for Segregated Witness, the mining algorithm has been modified -to optimize transaction selection for a given block weight, rather than a given -number of serialized bytes in a block. In this release, transaction selection -is unaffected by this distinction (as BIP 141 activation is not supported on -mainnet in this release, see above), but in future releases and after BIP 141 -activation, these calculations would be expected to differ. - -For optimal runtime performance, miners using this release should specify -`-blockmaxweight` on the command line, and not specify `-blockmaxsize`. -Additionally (or only) specifying `-blockmaxsize`, or relying on default -settings for both, may result in performance degradation, as the logic to -support `-blockmaxsize` performs additional computation to ensure that -constraint is met. (Note that for mainnet, in this release, the equivalent -parameter for `-blockmaxweight` would be four times the desired -`-blockmaxsize`. See [BIP 141] -(https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) for additional -details.) - -In the future, the `-blockmaxsize` option may be removed, as block creation is -no longer optimized for this metric. Feedback is requested on whether to -deprecate or keep this command line option in future releases. - - -Reindexing changes ------------------- - -In earlier versions, reindexing did validation while reading through the block -files on disk. These two have now been split up, so that all blocks are known -before validation starts. This was necessary to make certain optimizations that -are available during normal synchronizations also available during reindexing. - -The two phases are distinct in the Bitcoin-Qt GUI. During the first one, -"Reindexing blocks on disk" is shown. During the second (slower) one, -"Processing blocks on disk" is shown. - -It is possible to only redo validation now, without rebuilding the block index, -using the command line option `-reindex-chainstate` (in addition to -`-reindex` which does both). This new option is useful when the blocks on disk -are assumed to be fine, but the chainstate is still corrupted. It is also -useful for benchmarks. - - -Removal of internal miner --------------------------- - -As CPU mining has been useless for a long time, the internal miner has been -removed in this release, and replaced with a simpler implementation for the -test framework. - -The overall result of this is that `setgenerate` RPC call has been removed, as -well as the `-gen` and `-genproclimit` command-line options. - -For testing, the `generate` call can still be used to mine a block, and a new -RPC call `generatetoaddress` has been added to mine to a specific address. This -works with wallet disabled. - - -New bytespersigop implementation --------------------------------- - -The former implementation of the bytespersigop filter accidentally broke bare -multisig (which is meant to be controlled by the `permitbaremultisig` option), -since the consensus protocol always counts these older transaction forms as 20 -sigops for backwards compatibility. Simply fixing this bug by counting more -accurately would have reintroduced a vulnerability. It has therefore been -replaced with a new implementation that rather than filter such transactions, -instead treats them (for fee purposes only) as if they were in fact the size -of a transaction actually using all 20 sigops. - - -Low-level P2P changes ----------------------- - -- The optional new p2p message "feefilter" is implemented and the protocol - version is bumped to 70013. Upon receiving a feefilter message from a peer, - a node will not send invs for any transactions which do not meet the filter - feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) - -- The P2P alert system has been removed in PR #7692 and the `alert` P2P message - is no longer supported. - -- The transaction relay mechanism used to relay one quarter of all transactions - instantly, while queueing up the rest and sending them out in batch. As - this resulted in chains of dependent transactions being reordered, it - systematically hurt transaction relay. The relay code was redesigned in PRs - \#7840 and #8082, and now always batches transactions announcements while also - sorting them according to dependency order. This significantly reduces orphan - transactions. To compensate for the removal of instant relay, the frequency of - batch sending was doubled for outgoing peers. - -- Since PR #7840 the BIP35 `mempool` command is also subject to batch processing. - Also the `mempool` message is no longer handled for non-whitelisted peers when - `NODE_BLOOM` is disabled through `-peerbloomfilters=0`. - -- The maximum size of orphan transactions that are kept in memory until their - ancestors arrive has been raised in PR #8179 from 5000 to 99999 bytes. They - are now also removed from memory when they are included in a block, conflict - with a block, and time out after 20 minutes. - -- We respond at most once to a getaddr request during the lifetime of a - connection since PR #7856. - -- Connections to peers who have recently been the first one to give us a valid - new block or transaction are protected from disconnections since PR #8084. - - -Low-level RPC changes ----------------------- - -- RPC calls have been added to output detailed statistics for individual mempool - entries, as well as to calculate the in-mempool ancestors or descendants of a - transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. - -- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between - 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been - fixed, but this means that the output will be different than from previous versions. - -- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, - wallet labels have always been malformed because they weren't taken into account - properly in JSON RPC processing. This is no longer the case. This also affects - the GUI debug console. - -- Asm script outputs replacements for OP_NOP2 and OP_NOP3 - - - OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP -65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) - - - OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP -112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) - - - The following outputs are affected by this change: - - - RPC `getrawtransaction` (in verbose mode) - - RPC `decoderawtransaction` - - RPC `decodescript` - - REST `/rest/tx/` (JSON format) - - REST `/rest/block/` (JSON format when including extended tx details) - - `bitcoin-tx -json` - -- The sorting of the output of the `getrawmempool` output has changed. - -- New RPC commands: `generatetoaddress`, `importprunedfunds`, `removeprunedfunds`, `signmessagewithprivkey`, - `getmempoolancestors`, `getmempooldescendants`, `getmempoolentry`, - `createwitnessaddress`, `addwitnessaddress`. - -- Removed RPC commands: `setgenerate`, `getgenerate`. - -- New options were added to `fundrawtransaction`: `includeWatching`, `changeAddress`, `changePosition` and `feeRate`. - - -Low-level ZMQ changes ----------------------- - -- Each ZMQ notification now contains an up-counting sequence number that allows - listeners to detect lost notifications. - The sequence number is always the last element in a multi-part ZMQ notification and - therefore backward compatible. Each message type has its own counter. - PR [#7762](https://github.com/bitcoin/bitcoin/pull/7762). - +Example item +-------------- 0.13.0 Change log ================= @@ -364,500 +49,13 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -### RPC and other APIs - -- #7156 `9ee02cf` Remove cs_main lock from `createrawtransaction` (laanwj) -- #7326 `2cd004b` Fix typo, wrong information in gettxout help text (paveljanik) -- #7222 `82429d0` Indicate which transactions are signaling opt-in RBF (sdaftuar) -- #7480 `b49a623` Changed getnetworkhps value to double to avoid overflow (instagibbs) -- #7550 `8b958ab` Input-from-stdin mode for bitcoin-cli (laanwj) -- #7670 `c9a1265` Use cached block hash in blockToJSON() (rat4) -- #7726 `9af69fa` Correct importaddress help reference to importpubkey (CypherGrue) -- #7766 `16555b6` Register calls where they are defined (laanwj) -- #7797 `e662a76` Fix generatetoaddress failing to parse address (mruddy) -- #7774 `916b15a` Add versionHex in getblock and getblockheader JSON results (mruddy) -- #7863 `72c54e3` Getblockchaininfo: make bip9_softforks an object, not an array (rustyrussell) -- #7842 `d97101e` Do not print minping time in getpeerinfo when no ping received yet (paveljanik) -- #7518 `be14ca5` Add multiple options to fundrawtransaction (promag) -- #7756 `9e47fce` Add cursor to iterate over utxo set, use this in `gettxoutsetinfo` (laanwj) -- #7848 `88616d2` Divergence between 32- and 64-bit when hashing >4GB affects `gettxoutsetinfo` (laanwj) -- #7827 `4205ad7` Speed up `getchaintips` (mrbandrews) -- #7762 `a1eb344` Append a message sequence number to every ZMQ notification (jonasschnelli) -- #7688 `46880ed` List solvability in listunspent output and improve help (sipa) -- #7926 `5725807` Push back `getaddednodeinfo` dead value (instagibbs) -- #7953 `0630353` Create `signmessagewithprivkey` rpc (achow101) -- #8049 `c028c7b` Expose information on whether transaction relay is enabled in `getnetworkinfo` (laanwj) -- #7967 `8c1e49b` Add feerate option to `fundrawtransaction` (jonasschnelli) -- #8118 `9b6a48c` Reduce unnecessary hashing in `signrawtransaction` (jonasnick) -- #7957 `79004d4` Add support for transaction sequence number (jonasschnelli) -- #8153 `75ec320` `fundrawtransaction` feeRate: Use BTC/kB (MarcoFalke) -- #7292 `7ce9ac5` Expose ancestor/descendant information over RPC (sdaftuar) -- #8171 `62fcf27` Fix createrawtx sequence number unsigned int parsing (jonasschnelli) -- #7892 `9c3d0fa` Add full UTF-8 support to RPC (laanwj) -- #8317 `304eff3` Don't use floating point in rpcwallet (MarcoFalke) -- #8258 `5a06ebb` Hide softfork in `getblockchaininfo` if timeout is 0 (jl2012) -- #8244 `1922e5a` Remove unnecessary LOCK(cs_main) in getrawmempool (dcousens) - -### Block and transaction handling - -- #7056 `6a07208` Save last db read (morcos) -- #6842 `0192806` Limitfreerelay edge case bugfix (ptschip) -- #7084 `11d74f6` Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee in mempool (MarcoFalke) -- #7539 `9f33dba` Add tags to mempool's mapTx indices (sdaftuar) -- #7592 `26a2a72` Re-remove ERROR logging for mempool rejects (laanwj) -- #7187 `14d6324` Keep reorgs fast for SequenceLocks checks (morcos) -- #7594 `01f4267` Mempool: Add tracking of ancestor packages (sdaftuar) -- #7904 `fc9e334` Txdb: Fix assert crash in new UTXO set cursor (laanwj) -- #7927 `f9c2ac7` Minor changes to dbwrapper to simplify support for other databases (laanwj) -- #7933 `e26b620` Fix OOM when deserializing UTXO entries with invalid length (sipa) -- #8020 `5e374f7` Use SipHash-2-4 for various non-cryptographic hashes (sipa) -- #8076 `d720980` VerifyDB: don't check blocks that have been pruned (sdaftuar) -- #8080 `862fd24` Do not use mempool for GETDATA for tx accepted after the last mempool req (gmaxwell) -- #7997 `a82f033` Replace mapNextTx with slimmer setSpends (kazcw) -- #8220 `1f86d64` Stop trimming when mapTx is empty (sipa) -- #8273 `396f9d6` Bump `-dbcache` default to 300MiB (laanwj) -- #7225 `eb33179` Eliminate unnecessary call to CheckBlock (sdaftuar) -- #7907 `006cdf6` Optimize and Cleanup CScript::FindAndDelete (pstratem) -- #7917 `239d419` Optimize reindex (sipa) -- #7763 `3081fb9` Put hex-encoded version in UpdateTip (sipa) -- #8149 `d612837` Testnet-only segregated witness (sipa) -- #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) -- #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) -- #8381 `f84ee3d` Make witness v0 outputs non-standard (jl2012) -- #8364 `3f65ba2` Treat high-sigop transactions as larger rather than rejecting them (sipa) - -### P2P protocol and network code - -- #6589 `dc0305d` Log bytes recv/sent per command (jonasschnelli) -- #7164 `3b43cad` Do not download transactions during initial blockchain sync (ptschip) -- #7458 `898fedf` peers.dat, banlist.dat recreated when missing (kirkalx) -- #7637 `3da5d1b` Fix memleak in TorController (laanwj, jonasschnelli) -- #7553 `9f14e5a` Remove vfReachable and modify IsReachable to only use vfLimited (pstratem) -- #7708 `9426632` De-neuter NODE_BLOOM (pstratem) -- #7692 `29b2be6` Remove P2P alert system (btcdrak) -- #7542 `c946a15` Implement "feefilter" P2P message (morcos) -- #7573 `352fd57` Add `-maxtimeadjustment` command line option (mruddy) -- #7570 `232592a` Add IPv6 Link-Local Address Support (mruddy) -- #7874 `e6a4d48` Improve AlreadyHave (morcos) -- #7856 `64e71b3` Only send one GetAddr response per connection (gmaxwell) -- #7868 `7daa3ad` Split DNS resolving functionality out of net structures (theuni) -- #7919 `7617682` Fix headers announcements edge case (sdaftuar) -- #7514 `d9594bf` Fix IsInitialBlockDownload for testnet (jmacwhyte) -- #7959 `03cf6e8` fix race that could fail to persist a ban (kazcw) -- #7840 `3b9a0bf` Several performance and privacy improvements to inv/mempool handling (sipa) -- #8011 `65aecda` Don't run ThreadMessageHandler at lowered priority (kazcw) -- #7696 `5c3f8dd` Fix de-serialization bug where AddrMan is left corrupted (EthanHeilman) -- #7932 `ed749bd` CAddrMan::Deserialize handle corrupt serializations better (pstratem) -- #7906 `83121cc` Prerequisites for p2p encapsulation changes (theuni) -- #8033 `18436d8` Fix Socks5() connect failures to be less noisy and less unnecessarily scary (wtogami) -- #8082 `01d8359` Defer inserting into maprelay until just before relaying (gmaxwell) -- #7960 `6a22373` Only use AddInventoryKnown for transactions (sdaftuar) -- #8078 `2156fa2` Disable the mempool P2P command when bloom filters disabled (petertodd) -- #8065 `67c91f8` Addrman offline attempts (gmaxwell) -- #7703 `761cddb` Tor: Change auth order to only use password auth if -torpassword (laanwj) -- #8083 `cd0c513` Add support for dnsseeds with option to filter by servicebits (jonasschnelli) -- #8173 `4286f43` Use SipHash for node eviction (sipa) -- #8154 `1445835` Drop vAddrToSend after sending big addr message (kazcw) -- #7749 `be9711e` Enforce expected outbound services (sipa) -- #8208 `0a64777` Do not set extra flags for unfiltered DNS seed results (sipa) -- #8084 `e4bb4a8` Add recently accepted blocks and txn to AttemptToEvictConnection (gmaxwell) -- #8113 `3f89a53` Rework addnode behaviour (sipa) -- #8179 `94ab58b` Evict orphans which are included or precluded by accepted blocks (gmaxwell) -- #8068 `e9d76a1` Compact Blocks (TheBlueMatt) -- #8204 `0833894` Update petertodd's testnet seed (petertodd) -- #8247 `5cd35d3` Mark my dnsseed as supporting filtering (sipa) -- #8275 `042c323` Remove bad chain alert partition check (btcdrak) -- #8271 `1bc9c80` Do not send witnesses in cmpctblock (sipa) -- #8312 `ca40ef6` Fix mempool DoS vulnerability from malleated transactions (sdaftuar) -- #7180 `16ccb74` Account for `sendheaders` `verack` messages (laanwj) -- #8102 `425278d` Bugfix: use global ::fRelayTxes instead of CNode in version send (sipa) -- #8408 `b7e2011` Prevent fingerprinting, disk-DoS with compact blocks (sdaftuar) - -### Build system - -- #7302 `41f1a3e` C++11 build/runtime fixes (theuni) -- #7322 `fd9356b` c++11: add scoped enum fallbacks to CPPFLAGS rather than defining them locally (theuni) -- #7441 `a6771fc` Use Debian 8.3 in gitian build guide (fanquake) -- #7349 `152a821` Build against system UniValue when available (luke-jr) -- #7520 `621940e` LibreSSL doesn't define OPENSSL_VERSION, use LIBRESSL_VERSION_TEXT instead (paveljanik) -- #7528 `9b9bfce` autogen.sh: warn about needing autoconf if autoreconf is not found (knocte) -- #7504 `19324cf` Crystal clean make clean (paveljanik) -- #7619 `18b3f1b` Add missing sudo entry in gitian VM setup (btcdrak) -- #7616 `639ec58` [depends] Delete unused patches (MarcoFalke) -- #7658 `c15eb28` Add curl to Gitian setup instructions (btcdrak) -- #7710 `909b72b` [Depends] Bump miniupnpc and config.guess+sub (fanquake) -- #7723 `5131005` build: python 3 compatibility (laanwj) -- #7477 `28ad4d9` Fix quoting of copyright holders in configure.ac (domob1812) -- #7711 `a67bc5e` [build-aux] Update Boost & check macros to latest serials (fanquake) -- #7788 `4dc1b3a` Use relative paths instead of absolute paths in protoc calls (paveljanik) -- #7809 `bbd210d` depends: some base fixes/changes (theuni) -- #7603 `73fc922` Build System: Use PACKAGE_TARNAME in NSIS script (JeremyRand) -- #7905 `187186b` test: move accounting_tests and rpc_wallet_tests to wallet/test (laanwj) -- #7911 `351abf9` leveldb: integrate leveldb into our buildsystem (theuni) -- #7944 `a407807` Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035 (randy-waterhouse) -- #7920 `c3e3cfb` Switch Travis to Trusty (theuni) -- #7954 `08b37c5` build: quiet annoying warnings without adding new ones (theuni) -- #7165 `06162f1` build: Enable C++11 in build, require C++11 compiler (laanwj) -- #7982 `559fbae` build: No need to check for leveldb atomics (theuni) -- #8002 `f9b4582` [depends] Add -stdlib=libc++ to darwin CXX flags (fanquake) -- #7993 `6a034ed` [depends] Bump Freetype, ccache, ZeroMQ, miniupnpc, expat (fanquake) -- #8167 `19ea173` Ship debug tarballs/zips with debug symbols (theuni) -- #8175 `f0299d8` Add --disable-bench to config flags for windows (laanwj) -- #7283 `fd9881a` [gitian] Default reference_datetime to commit author date (MarcoFalke) -- #8181 `9201ce8` Get rid of `CLIENT_DATE` (laanwj) -- #8133 `fde0ac4` Finish up out-of-tree changes (theuni) -- #8188 `65a9d7d` Add armhf/aarch64 gitian builds (theuni) -- #8194 `cca1c8c` [gitian] set correct PATH for wrappers (MarcoFalke) -- #8198 `5201614` Sync ax_pthread with upstream draft4 (fanquake) -- #8210 `12a541e` [Qt] Bump to Qt5.6.1 (jonasschnelli) -- #8285 `da50997` windows: Add testnet link to installer (laanwj) -- #8304 `0cca2fe` [travis] Update SDK_URL (MarcoFalke) -- #8310 `6ae20df` Require boost for bench (theuni) -- #8315 `2e51590` Don't require sudo for Linux (theuni) -- #8314 `67caef6` Fix pkg-config issues for 0.13 (theuni) -- #8373 `1fe7f40` Fix OSX non-deterministic dmg (theuni) -- #8358 `cfd1280` Gbuild: Set memory explicitly (default is too low) (MarcoFalke) - -### GUI - -- #7154 `00b4b8d` Add InMempool() info to transaction details (jonasschnelli) -- #7068 `5f3c670` [RPC-Tests] add simple way to run rpc test over QT clients (jonasschnelli) -- #7218 `a1c185b` Fix misleading translation (MarcoFalke) -- #7214 `be9a9a3` qt5: Use the fixed font the system recommends (MarcoFalke) -- #7256 `08ab906` Add note to coin control dialog QT5 workaround (fanquake) -- #7255 `e289807` Replace some instances of formatWithUnit with formatHtmlWithUnit (fanquake) -- #7317 `3b57e9c` Fix RPCTimerInterface ordering issue (jonasschnelli) -- #7327 `c079d79` Transaction View: LastMonth calculation fixed (crowning-) -- #7334 `e1060c5` coincontrol workaround is still needed in qt5.4 (fixed in qt5.5) (MarcoFalke) -- #7383 `ae2db67` Rename "amount" to "requested amount" in receive coins table (jonasschnelli) -- #7396 `cdcbc59` Add option to increase/decrease font size in the console window (jonasschnelli) -- #7437 `9645218` Disable tab navigation for peers tables (Kefkius) -- #7604 `354b03d` build: Remove spurious dollar sign. Fixes #7189 (dooglus) -- #7605 `7f001bd` Remove openssl info from init/log and from Qt debug window (jonasschnelli) -- #7628 `87d6562` Add 'copy full transaction details' option (ericshawlinux) -- #7613 `3798e5d` Add autocomplete to bitcoin-qt's console window (GamerSg) -- #7668 `b24266c` Fix history deletion bug after font size change (achow101) -- #7680 `41d2dfa` Remove reflection from `about` icon (laanwj) -- #7686 `f034bce` Remove 0-fee from send dialog (MarcoFalke) -- #7506 `b88e0b0` Use CCoinControl selection in CWallet::FundTransaction (promag) -- #7732 `0b98dd7` Debug window: replace "Build date" with "Datadir" (jonasschnelli) -- #7761 `60db51d` remove trailing output-index from transaction-id (jonasschnelli) -- #7772 `6383268` Clear the input line after activating autocomplete (paveljanik) -- #7925 `f604bf6` Fix out-of-tree GUI builds (laanwj) -- #7939 `574ddc6` Make it possible to show details for multiple transactions (laanwj) -- #8012 `b33824b` Delay user confirmation of send (Tyler-Hardin) -- #8006 `7c8558d` Add option to disable the system tray icon (Tyler-Hardin) -- #8046 `169d379` Fix Cmd-Q / Menu Quit shutdown on OSX (jonasschnelli) -- #8042 `6929711` Don't allow to open the debug window during splashscreen & verification state (jonasschnelli) -- #8014 `77b49ac` Sort transactions by date (Tyler-Hardin) -- #8073 `eb2f6f7` askpassphrasedialog: Clear pass fields on accept (rat4) -- #8129 `ee1533e` Fix RPC console auto completer (UdjinM6) -- #7636 `fb0ac48` Add bitcoin address label to request payment QR code (makevoid) -- #8231 `760a6c7` Fix a bug where the SplashScreen will not be hidden during startup (jonasschnelli) -- #8256 `af2421c` BUG: bitcoin-qt crash (fsb4000) -- #8257 `ff03c50` Do not ask a UI question from bitcoind (sipa) -- #8288 `91abb77` Network-specific example address (laanwj) -- #7707 `a914968` UI support for abandoned transactions (jonasschnelli) -- #8207 `f7a403b` Add a link to the Bitcoin-Core repository and website to the About Dialog (MarcoFalke) -- #8281 `6a87eb0` Remove client name from debug window (laanwj) -- #8407 `45eba4b` Add dbcache migration path (jonasschnelli) - -### Wallet - -- #7262 `fc08994` Reduce inefficiency of GetAccountAddress() (dooglus) -- #7537 `78e81b0` Warn on unexpected EOF while salvaging wallet (laanwj) -- #7521 `3368895` Don't resend wallet txs that aren't in our own mempool (morcos) -- #7576 `86a1ec5` Move wallet help string creation to CWallet (jonasschnelli) -- #7577 `5b3b5a7` Move "load wallet phase" to CWallet (jonasschnelli) -- #7608 `0735c0c` Move hardcoded file name out of log messages (MarcoFalke) -- #7649 `4900641` Prevent multiple calls to CWallet::AvailableCoins (promag) -- #7646 `e5c3511` Fix lockunspent help message (promag) -- #7558 `b35a591` Add import/removeprunedfunds rpc call (instagibbs) -- #6215 `48c5adf` add bip32 pub key serialization (jonasschnelli) -- #7913 `bafd075` Fix for incorrect locking in GetPubKey() (keystore.cpp) (yurizhykin) -- #8036 `41138f9` init: Move berkeleydb version reporting to wallet (laanwj) -- #8028 `373b50d` Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk (pstratem) -- #8061 `f6b7df3` Improve Wallet encapsulation (pstratem) -- #7891 `950be19` Always require OS randomness when generating secret keys (sipa) -- #7689 `b89ef13` Replace OpenSSL AES with ctaes-based version (sipa) -- #7825 `f972b04` Prevent multiple calls to ExtractDestination (pedrobranco) -- #8137 `243ac0c` Improve CWallet API with new AccountMove function (pstratem) -- #8142 `52c3f34` Improve CWallet API with new GetAccountPubkey function (pstratem) -- #8035 `b67a472` Add simplest BIP32/deterministic key generation implementation (jonasschnelli) -- #7687 `a6ddb19` Stop treating importaddress'ed scripts as change (sipa) -- #8298 `aef3811` wallet: Revert input selection post-pruning (laanwj) -- #8324 `bc94b87` Keep HD seed during salvagewallet (jonasschnelli) -- #8323 `238300b` Add HD keypath to CKeyMetadata, report metadata in validateaddress (jonasschnelli) -- #8367 `3b38a6a` Ensure <0.13 clients can't open HD wallets (jonasschnelli) -- #8378 `ebea651` Move SetMinVersion for FEATURE_HD to SetHDMasterKey (pstratem) -- #8390 `73adfe3` Correct hdmasterkeyid/masterkeyid name confusion (jonasschnelli) -- #8206 `18b8ee1` Add HD xpriv to dumpwallet (jonasschnelli) -- #8389 `c3c82c4` Create a new HD seed after encrypting the wallet (jonasschnelli) - -### Tests and QA - -- #7320 `d3dfc6d` Test walletpassphrase timeout (MarcoFalke) -- #7208 `47c5ed1` Make max tip age an option instead of chainparam (laanwj) -- #7372 `21376af` Trivial: [qa] wallet: Print maintenance (MarcoFalke) -- #7280 `668906f` [travis] Fail when documentation is outdated (MarcoFalke) -- #7177 `93b0576` [qa] Change default block priority size to 0 (MarcoFalke) -- #7236 `02676c5` Use createrawtx locktime parm in txn_clone (dgenr8) -- #7212 `326ffed` Adds unittests for CAddrMan and CAddrinfo, removes source of non-determinism (EthanHeilman) -- #7490 `d007511` tests: Remove May15 test (laanwj) -- #7531 `18cb2d5` Add bip68-sequence.py to extended rpc tests (btcdrak) -- #7536 `ce5fc02` test: test leading spaces for ParseHex (laanwj) -- #7620 `1b68de3` [travis] Only run check-doc.py once (MarcoFalke) -- #7455 `7f96671` [travis] Exit early when check-doc.py fails (MarcoFalke) -- #7667 `56d2c4e` Move GetTempPath() to testutil (musalbas) -- #7517 `f1ca891` test: script_error checking in script_invalid tests (laanwj) -- #7684 `3d0dfdb` Extend tests (MarcoFalke) -- #7697 `622fe6c` Tests: make prioritise_transaction.py more robust (sdaftuar) -- #7709 `efde86b` Tests: fix missing import in mempool_packages (sdaftuar) -- #7702 `29e1131` Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke) -- #7720 `3b4324b` rpc-test: Normalize assert() (MarcoFalke) -- #7757 `26794d4` wallet: Wait for reindex to catch up (MarcoFalke) -- #7764 `a65b36c` Don't run pruning.py twice (MarcoFalke) -- #7773 `7c80e72` Fix comments in tests (btcdrak) -- #7489 `e9723cb` tests: Make proxy_test work on travis servers without IPv6 (laanwj) -- #7801 `70ac71b` Remove misleading "errorString syntax" (MarcoFalke) -- #7803 `401c65c` maxblocksinflight: Actually enable test (MarcoFalke) -- #7802 `3bc71e1` httpbasics: Actually test second connection (MarcoFalke) -- #7849 `ab8586e` tests: add varints_bitpatterns test (laanwj) -- #7846 `491171f` Clean up lockorder data of destroyed mutexes (sipa) -- #7853 `6ef5e00` py2: Unfiddle strings into bytes explicitly (MarcoFalke) -- #7878 `53adc83` [test] bctest.py: Revert faa41ee (MarcoFalke) -- #7798 `cabba24` [travis] Print the commit which was evaluated (MarcoFalke) -- #7833 `b1bf511` tests: Check Content-Type header returned from RPC server (laanwj) -- #7851 `fa9d86f` pull-tester: Don't mute zmq ImportError (MarcoFalke) -- #7822 `0e6fd5e` Add listunspent() test for spendable/unspendable UTXO (jpdffonseca) -- #7912 `59ad568` Tests: Fix deserialization of reject messages (sdaftuar) -- #7941 `0ea3941` Fixing comment in script_test.json test case (Christewart) -- #7807 `0ad1041` Fixed miner test values, gave constants for less error-prone values (instagibbs) -- #7980 `88b77c7` Smartfees: Properly use ordered dict (MarcoFalke) -- #7814 `77b637f` Switch to py3 (MarcoFalke) -- #8030 `409a8a1` Revert fatal-ness of missing python-zmq (laanwj) -- #8018 `3e90fe6` Autofind rpc tests --srcdir (jonasschnelli) -- #8016 `5767e80` Fix multithread CScheduler and reenable test (paveljanik) -- #7972 `423ca30` pull-tester: Run rpc test in parallel (MarcoFalke) -- #8039 `69b3a6d` Bench: Add crypto hash benchmarks (laanwj) -- #8041 `5b736dd` Fix bip9-softforks blockstore issue (MarcoFalke) -- #7994 `1f01443` Add op csv tests to script_tests.json (Christewart) -- #8038 `e2bf830` Various minor fixes (MarcoFalke) -- #8072 `1b87e5b` Travis: 'make check' in parallel and verbose (MarcoFalke) -- #8056 `8844ef1` Remove hardcoded "4 nodes" from test_framework (MarcoFalke) -- #8047 `37f9a1f` Test_framework: Set wait-timeout for bitcoind procs (MarcoFalke) -- #8095 `6700cc9` Test framework: only cleanup on successful test runs (sdaftuar) -- #8098 `06bd4f6` Test_framework: Append portseed to tmpdir (MarcoFalke) -- #8104 `6ff2c8d` Add timeout to sync_blocks() and sync_mempools() (sdaftuar) -- #8111 `61b8684` Benchmark SipHash (sipa) -- #8107 `52b803e` Bench: Added base58 encoding/decoding benchmarks (yurizhykin) -- #8115 `0026e0e` Avoid integer division in the benchmark inner-most loop (gmaxwell) -- #8090 `a2df115` Adding P2SH(p2pkh) script test case (Christewart) -- #7992 `ec45cc5` Extend #7956 with one more test (TheBlueMatt) -- #8139 `ae5575b` Fix interrupted HTTP RPC connection workaround for Python 3.5+ (sipa) -- #8164 `0f24eaf` [Bitcoin-Tx] fix missing test fixtures, fix 32bit atoi issue (jonasschnelli) -- #8166 `0b5279f` Src/test: Do not shadow local variables (paveljanik) -- #8141 `44c1b1c` Continuing port of java comparison tool (mrbandrews) -- #8201 `36b7400` fundrawtransaction: Fix race, assert amounts (MarcoFalke) -- #8214 `ed2cd59` Mininode: fail on send_message instead of silent return (MarcoFalke) -- #8215 `a072d1a` Don't use floating point in wallet tests (MarcoFalke) -- #8066 `65c2058` Test_framework: Use different rpc_auth_pair for each node (MarcoFalke) -- #8216 `0d41d70` Assert 'changePosition out of bounds' (MarcoFalke) -- #8222 `961893f` Enable mempool consistency checks in unit tests (sipa) -- #7751 `84370d5` test_framework: python3.4 authproxy compat (laanwj) -- #7744 `d8e862a` test_framework: detect failure of bitcoind startup (laanwj) -- #8280 `115735d` Increase sync_blocks() timeouts in pruning.py (MarcoFalke) -- #8340 `af9b7a9` Solve trivial merge conflict in p2p-segwit.py (MarcoFalke) -- #8067 `3e4cf8f` Travis: use slim generic image, and some fixups (theuni) -- #7951 `5c7df70` Test_framework: Properly print exception (MarcoFalke) -- #8070 `7771aa5` Remove non-determinism which is breaking net_tests #8069 (EthanHeilman) -- #8309 `bb2646a` Add wallet-hd test (MarcoFalke) -- #8444 `cd0910b` Fix p2p-feefilter.py for changed tx relay behavior (sdaftuar) - -### Mining - -- #7507 `11c7699` Remove internal miner (Leviathn) -- #7663 `c87f51e` Make the generate RPC call function for non-regtest (sipa) -- #7671 `e2ebd25` Add generatetoaddress RPC to mine to an address (achow101) -- #7935 `66ed450` Versionbits: GBT support (luke-jr) -- #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) -- #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) -- #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) -- #8362 `86edc20` Scale legacy sigop count in CreateNewBlock (sdaftuar) -- #8489 `8b0eee6` Bugfix: Use pre-BIP141 sigops until segwit activates (GBT) (luke-jr) - -### Documentation and miscellaneous - -- #7423 `69e2a40` Add example for building with constrained resources (jarret) -- #8254 `c2c69ed` Add OSX ZMQ requirement to QA readme (fanquake) -- #8203 `377d131` Clarify documentation for running a tor node (nathaniel-mahieu) -- #7428 `4b12266` Add example for listing ./configure flags (nathaniel-mahieu) -- #7847 `3eae681` Add arch linux build example (mruddy) -- #7968 `ff69aaf` Fedora build requirements (wtogami) -- #8013 `fbedc09` Fedora build requirements, add gcc-c++ and fix typo (wtogami) -- #8009 `fbd8478` Fixed invalid example paths in gitian-building.md (JeremyRand) -- #8240 `63fbdbc` Mention Windows XP end of support in release notes (laanwj) -- #8303 `5077d2c` Update bips.md for CSV softfork (fanquake) -- #7789 `e0b3e19` Add note about using the Qt official binary installer (paveljanik) -- #7791 `e30a5b0` Change Precise to Trusty in gitian-building.md (JeremyRand) -- #7838 `8bb5d3d` Update gitian build guide to debian 8.4.0 (fanquake) -- #7855 `b778e59` Replace precise with trusty (MarcoFalke) -- #7975 `fc23fee` Update bitcoin-core GitHub links (MarcoFalke) -- #8034 `e3a8207` Add basic git squash workflow (fanquake) -- #7813 `214ec0b` Update port in tor.md (MarcoFalke) -- #8193 `37c9830` Use Debian 8.5 in the gitian-build guide (fanquake) -- #8261 `3685e0c` Clarify help for `getblockchaininfo` (paveljanik) -- #7185 `ea0f5a2` Note that reviewers should mention the id of the commits they reviewed (pstratem) -- #7290 `c851d8d` [init] Add missing help for args (MarcoFalke) -- #7281 `f9fd4c2` Improve CheckInputs() comment about sig verification (petertodd) -- #7417 `1e06bab` Minor improvements to the release process (PRabahy) -- #7444 `4cdbd42` Improve block validity/ConnectBlock() comments (petertodd) -- #7527 `db2e1c0` Fix and cleanup listreceivedbyX documentation (instagibbs) -- #7541 `b6e00af` Clarify description of blockindex (pinheadmz) -- #7590 `f06af57` Improving wording related to Boost library requirements [updated] (jonathancross) -- #7635 `0fa88ef` Add dependency info to test docs (elliotolds) -- #7609 `3ba07bd` RPM spec file project (AliceWonderMiscreations) -- #7850 `229a17c` Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp` (alexreg) -- #7888 `ec870e1` Prevector: fix 2 bugs in currently unreached code paths (kazcw) -- #7922 `90653bc` CBase58Data::SetString: cleanse the full vector (kazcw) -- #7881 `c4e8390` Update release process (laanwj) -- #7952 `a9c8b74` Log invalid block hash to make debugging easier (paveljanik) -- #7974 `8206835` More comments on the design of AttemptToEvictConnection (gmaxwell) -- #7795 `47a7cfb` UpdateTip: log only one line at most per block (laanwj) -- #8110 `e7e25ea` Add benchmarking notes (fanquake) -- #8121 `58f0c92` Update implemented BIPs list (fanquake) -- #8029 `58725ba` Simplify OS X build notes (fanquake) -- #8143 `d46b8b5` comment nit: miners don't vote (instagibbs) -- #8136 `22e0b35` Log/report in 10% steps during VerifyDB (jonasschnelli) -- #8168 `d366185` util: Add ParseUInt32 and ParseUInt64 (laanwj) -- #8178 `f7b1bfc` Add git and github tips and tricks to developer notes (sipa) -- #8177 `67db011` developer notes: updates for C++11 (kazcw) -- #8229 `8ccdac1` [Doc] Update OS X build notes for 10.11 SDK (fanquake) -- #8233 `9f1807a` Mention Linux ARM executables in release process and notes (laanwj) -- #7540 `ff46dd4` Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY (btcdrak) -- #8289 `26316ff` bash-completion: Adapt for 0.12 and 0.13 (roques) -- #7453 `3dc3149` Missing patches from 0.12 (MarcoFalke) -- #7113 `54a550b` Switch to a more efficient rolling Bloom filter (sipa) -- #7257 `de9e5ea` Combine common error strings for different options so translations can be shared and reused (luke-jr) -- #7304 `b8f485c` [contrib] Add clang-format-diff.py (MarcoFalke) -- #7378 `e6f97ef` devtools: replace github-merge with python version (laanwj) -- #7395 `0893705` devtools: show pull and commit information in github-merge (laanwj) -- #7402 `6a5932b` devtools: github-merge get toplevel dir without extra whitespace (achow101) -- #7425 `20a408c` devtools: Fix utf-8 support in messages for github-merge (laanwj) -- #7632 `409f843` Delete outdated test-patches reference (Lewuathe) -- #7662 `386f438` remove unused NOBLKS_VERSION_{START,END} constants (rat4) -- #7737 `aa0d2b2` devtools: make github-merge.py use py3 (laanwj) -- #7781 `55db5f0` devtools: Auto-set branch to merge to in github-merge (laanwj) -- #7934 `f17032f` Improve rolling bloom filter performance and benchmark (sipa) -- #8004 `2efe38b` signal handling: fReopenDebugLog and fRequestShutdown should be type sig_atomic_t (catilac) -- #7713 `f6598df` Fixes for verify-commits script (petertodd) -- #8412 `8360d5b` libconsensus: Expose a flag for BIP112 (jtimon) + ... fill in here Credits ======= Thanks to everyone who directly contributed to this release: -- 21E14 -- accraze -- Adam Brown -- Alexander Regueiro -- Alex Morcos -- Alfie John -- Alice Wonder -- AlSzacrel -- Andrew Chow -- Andrés G. Aragoneses -- Bob McElrath -- BtcDrak -- calebogden -- Cédric Félizard -- Chirag Davé -- Chris Moore -- Chris Stewart -- Christian von Roques -- Chris Wheeler -- Cory Fields -- crowning- -- Daniel Cousens -- Daniel Kraft -- Denis Lukianov -- Elias Rohrer -- Elliot Olds -- Eric Shaw -- error10 -- Ethan Heilman -- face -- fanquake -- Francesco 'makevoid' Canessa -- fsb4000 -- Gavin Andresen -- gladoscc -- Gregory Maxwell -- Gregory Sanders -- instagibbs -- James O'Beirne -- Jannes Faber -- Jarret Dyrbye -- Jeremy Rand -- jloughry -- jmacwhyte -- Joao Fonseca -- Johnson Lau -- Jonas Nick -- Jonas Schnelli -- Jonathan Cross -- João Barbosa -- Jorge Timón -- Kaz Wesley -- Kefkius -- kirkalx -- Krzysztof Jurewicz -- Leviathn -- lewuathe -- Luke Dashjr -- Luv Khemani -- Marcel Krüger -- Marco Falke -- Mark Friedenbach -- Matt -- Matt Bogosian -- Matt Corallo -- Matthew English -- Matthew Zipkin -- mb300sd -- Mitchell Cash -- mrbandrews -- mruddy -- Murch -- Mustafa -- Nathaniel Mahieu -- Nicolas Dorier -- Patrick Strateman -- Paul Rabahy -- paveljanik -- Pavel Janík -- Pavel Vasin -- Pedro Branco -- Peter Todd -- Philip Kaufmann -- Pieter Wuille -- Prayag Verma -- ptschip -- Puru -- randy-waterhouse -- R E Broadley -- Rusty Russell -- Suhas Daftuar -- Suriyaa Kudo -- TheLazieR Yip -- Thomas Kerin -- Tom Harding -- Tyler Hardin -- UdjinM6 -- Warren Togami -- Will Binns -- Wladimir J. van der Laan -- Yuri Zhykin + ... fill in here As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 526d2b0472356a185bda316ab424e914ba56d9be Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 24 Aug 2016 19:21:27 +0200 Subject: [PATCH 0965/1223] [wallet] rpc: Drop misleading option Github-Pull: #8581 Rebased-From: fab5ecb7719063aa72751df1258dfa4cf4a9a4a9 --- doc/release-notes.md | 10 ++++++++- qa/rpc-tests/importprunedfunds.py | 35 ++++++++++++------------------- src/wallet/rpcdump.cpp | 6 +----- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 77d35315f..019031aed 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -41,7 +41,15 @@ Notable changes Example item -------------- -0.13.0 Change log +Low-level RPC changes +--------------------- + +- `importprunedfunds` only accepts two required arguments. Some versions accept + an optional third arg, which was always ignored. Make sure to never pass more + than two arguments. + + +0.13.1 Change log ================= Detailed release notes follow. This overview includes changes that affect diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index d86f51b7f..3287470c5 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -20,14 +20,10 @@ class ImportPrunedFundsTest(BitcoinTestFramework): self.is_network_split=False self.sync_all() - def run_test (self): - import time - begintime = int(time.time()) - + def run_test(self): print("Mining blocks...") self.nodes[0].generate(101) - # sync self.sync_all() # address @@ -72,7 +68,6 @@ class ImportPrunedFundsTest(BitcoinTestFramework): rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex'] proof2 = self.nodes[0].gettxoutproof([txnid2]) - txnid3 = self.nodes[0].sendtoaddress(address3, 0.025) self.nodes[0].generate(1) rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex'] @@ -82,28 +77,27 @@ class ImportPrunedFundsTest(BitcoinTestFramework): #Import with no affiliated address try: - result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "") + self.nodes[1].importprunedfunds(rawtxn1, proof1) except JSONRPCException as e: assert('No addresses' in e.error['message']) else: assert(False) - balance1 = self.nodes[1].getbalance("", 0, True) assert_equal(balance1, Decimal(0)) #Import with affiliated address with no rescan - self.nodes[1].importaddress(address2, "", False) - result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2, "") - balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + self.nodes[1].importaddress(address2, "add2", False) + result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2) + balance2 = self.nodes[1].getbalance("add2", 0, True) assert_equal(balance2, Decimal('0.05')) #Import with private key with no rescan - self.nodes[1].importprivkey(address3_privkey, "", False) - result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3, "") - balance3 = Decimal(self.nodes[1].getbalance("", 0, False)) + self.nodes[1].importprivkey(address3_privkey, "add3", False) + result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3) + balance3 = self.nodes[1].getbalance("add3", 0, False) assert_equal(balance3, Decimal('0.025')) - balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance3 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance3, Decimal('0.075')) #Addresses Test - after import @@ -118,7 +112,6 @@ class ImportPrunedFundsTest(BitcoinTestFramework): assert_equal(address_info['ismine'], True) #Remove transactions - try: self.nodes[1].removeprunedfunds(txnid1) except JSONRPCException as e: @@ -126,18 +119,16 @@ class ImportPrunedFundsTest(BitcoinTestFramework): else: assert(False) - - balance1 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance1 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance1, Decimal('0.075')) - self.nodes[1].removeprunedfunds(txnid2) - balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance2 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance2, Decimal('0.025')) self.nodes[1].removeprunedfunds(txnid3) - balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance3 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance3, Decimal('0.0')) if __name__ == '__main__': - ImportPrunedFundsTest ().main () + ImportPrunedFundsTest().main() diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 6647d3297..443441a36 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -257,6 +257,7 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; + // 0.13.x: Silently accept up to 3 params, but ignore the third: if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( "importprunedfunds\n" @@ -264,7 +265,6 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" - "3. \"label\" (string, optional) An optional label\n" ); CTransaction tx; @@ -277,10 +277,6 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - string strLabel = ""; - if (params.size() == 3) - strLabel = params[2].get_str(); - //Search partial merkle tree in proof for our transaction and index in valid block vector vMatch; vector vIndex; From 75f20652932361a176e72e2ba3477f4604810bb6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Aug 2016 11:16:21 +0200 Subject: [PATCH 0966/1223] build: Remove check for `openssl/ec.h` We don't use any elliptic curves from OpenSSL anymore, nor include this header anywhere but optionally in the tests of secp256k1 (which has its own autoconf setup). Reported by sinetek on IRC. --- configure.ac | 8 -------- 1 file changed, 8 deletions(-) diff --git a/configure.ac b/configure.ac index 19861d24c..01d20baef 100644 --- a/configure.ac +++ b/configure.ac @@ -861,14 +861,6 @@ AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$system_univalue = xno]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) -CXXFLAGS_TEMP="$CXXFLAGS" -LIBS_TEMP="$LIBS" -CXXFLAGS="$CXXFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" -LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS" -AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) -CXXFLAGS="$CXXFLAGS_TEMP" -LIBS="$LIBS_TEMP" - BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) AC_MSG_CHECKING([whether to build bitcoind]) From 1db3352cc663f6a25a39813c763a2f6263f55e6d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 18 Aug 2016 16:58:04 +0200 Subject: [PATCH 0967/1223] qt: Fix random segfault when closing "Choose data directory" dialog The `pickDataDirectory()` function was calling `exit(0)` to quit the application when the user closes the dialog without choosing a data directory. This is a bad idea because a background thread is created (to check free space on the drive of the currently selected datadir). The thread is not stopped and unwound properly, resulting in a potential race condition somewhere deep in Qt. So replace the `exit()` by a boolean return value, and let the stack unwind normally. --- src/qt/bitcoin.cpp | 3 ++- src/qt/intro.cpp | 7 ++++--- src/qt/intro.h | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 64b5c83d7..430e6dd0e 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -578,7 +578,8 @@ int main(int argc, char *argv[]) /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory - Intro::pickDataDirectory(); + if (!Intro::pickDataDirectory()) + return 0; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 6d6af5429..6a5740e21 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -165,14 +165,14 @@ QString Intro::getDefaultDataDirectory() return GUIUtil::boostPathToQString(GetDefaultDataDir()); } -void Intro::pickDataDirectory() +bool Intro::pickDataDirectory() { namespace fs = boost::filesystem; QSettings settings; /* If data directory provided on command line, no need to look at settings or show a picking dialog */ if(!GetArg("-datadir", "").empty()) - return; + return true; /* 1) Default data directory for operating system */ QString dataDir = getDefaultDataDirectory(); /* 2) Allow QSettings to override default dir */ @@ -190,7 +190,7 @@ void Intro::pickDataDirectory() if(!intro.exec()) { /* Cancel clicked */ - exit(0); + return false; } dataDir = intro.getDataDirectory(); try { @@ -211,6 +211,7 @@ void Intro::pickDataDirectory() */ if(dataDir != getDefaultDataDirectory()) SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting + return true; } void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable) diff --git a/src/qt/intro.h b/src/qt/intro.h index 9e2e96dc9..ee768a7ad 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -35,10 +35,13 @@ public: /** * Determine data directory. Let the user choose if the current one doesn't exist. * + * @returns true if a data directory was selected, false if the user cancelled the selection + * dialog. + * * @note do NOT call global GetDataDir() before calling this function, this * will cause the wrong path to be cached. */ - static void pickDataDirectory(); + static bool pickDataDirectory(); /** * Determine default data directory for operating system. From 2611ad79a5d53e2ce1535b342a9b72c2888a6c3f Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 17 Jun 2016 00:10:07 -0400 Subject: [PATCH 0968/1223] Added feeler connections increasing good addrs in the tried table. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests if addresses are online or offline by briefly connecting to them. These short lived connections are referred to as feeler connections. Feeler connections are designed to increase the number of fresh online addresses in tried by selecting and connecting to addresses in new. One feeler connection is attempted on average once every two minutes. This change was suggested as Countermeasure 4 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. --- src/main.cpp | 6 +++++ src/net.cpp | 59 ++++++++++++++++++++++++++++++++++++------ src/net.h | 5 +++- src/test/net_tests.cpp | 22 ++++++++++++++++ 4 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7ddf52fc5..e3be69ad2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4917,6 +4917,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (strCommand == NetMsgType::VERSION) { + // Feeler connections exist only to verify if address is online. + if (pfrom->fFeeler) { + assert(pfrom->fInbound == false); + pfrom->fDisconnect = true; + } + // Each connection can only send one version message if (pfrom->nVersion != 0) { diff --git a/src/net.cpp b/src/net.cpp index 4cbc43e4d..eb2c38dd1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -42,6 +42,9 @@ // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 +// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization. +#define FEELER_SLEEP_WINDOW 1 + #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif @@ -60,6 +63,7 @@ namespace { const int MAX_OUTBOUND_CONNECTIONS = 8; + const int MAX_FEELER_CONNECTIONS = 1; struct ListenSocket { SOCKET socket; @@ -1016,7 +1020,8 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); CAddress addr; int nInbound = 0; - int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; + int nMaxInbound = nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); + assert(nMaxInbound > 0); if (hSocket != INVALID_SOCKET) if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) @@ -1609,6 +1614,9 @@ void ThreadOpenConnections() // Initiate network connections int64_t nStart = GetTime(); + + // Minimum time before next feeler connection (in microseconds). + int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL); while (true) { ProcessOneShot(); @@ -1646,13 +1654,36 @@ void ThreadOpenConnections() } } } + assert(nOutbound <= (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS)); + + // Feeler Connections + // + // Design goals: + // * Increase the number of connectable addresses in the tried table. + // + // Method: + // * Choose a random address from new and attempt to connect to it if we can connect + // successfully it is added to tried. + // * Start attempting feeler connections only after node finishes making outbound + // connections. + // * Only make a feeler connection once every few minutes. + // + bool fFeeler = false; + if (nOutbound >= MAX_OUTBOUND_CONNECTIONS) { + int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds). + if (nTime > nNextFeeler) { + nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL); + fFeeler = true; + } else { + continue; + } + } int64_t nANow = GetAdjustedTime(); - int nTries = 0; while (true) { - CAddrInfo addr = addrman.Select(); + CAddrInfo addr = addrman.Select(fFeeler); // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) @@ -1688,8 +1719,17 @@ void ThreadOpenConnections() break; } - if (addrConnect.IsValid()) - OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant); + if (addrConnect.IsValid()) { + + if (fFeeler) { + // Add small amount of random noise before connection to avoid synchronization. + int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000); + MilliSleep(randsleep); + LogPrint("net", "Making feeler connection to %s\n", addrConnect.ToString()); + } + + OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, NULL, false, fFeeler); + } } } @@ -1771,7 +1811,7 @@ void ThreadOpenAddedConnections() } // if successful, this moves the passed grant to the constructed node -bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot) +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler) { // // Initiate outbound network connection @@ -1795,6 +1835,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSem pnode->fNetworkNode = true; if (fOneShot) pnode->fOneShot = true; + if (fFeeler) + pnode->fFeeler = true; return true; } @@ -2054,7 +2096,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); + int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } @@ -2096,7 +2138,7 @@ bool StopNode() LogPrintf("StopNode()\n"); MapPort(false); if (semOutbound) - for (int i=0; ipost(); if (fAddressesInitialized) @@ -2437,6 +2479,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa fWhitelisted = false; fOneShot = false; fClient = false; // set by version message + fFeeler = false; fInbound = fInboundIn; fNetworkNode = false; fSuccessfullyConnected = false; diff --git a/src/net.h b/src/net.h index 41315fc9b..63bb2c2ec 100644 --- a/src/net.h +++ b/src/net.h @@ -41,6 +41,8 @@ namespace boost { static const int PING_INTERVAL = 2 * 60; /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ static const int TIMEOUT_INTERVAL = 20 * 60; +/** Run the feeler connection loop once every 2 minutes or 120 seconds. **/ +static const int FEELER_INTERVAL = 120; /** The maximum number of entries in an 'inv' protocol message */ static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ @@ -89,7 +91,7 @@ CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); CNode* FindNode(const NodeId id); //TODO: Remove this -bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); @@ -350,6 +352,7 @@ public: // the network or wire types and the cleaned string used when displayed or logged. std::string strSubVer, cleanSubVer; bool fWhitelisted; // This peer can bypass DoS banning. + bool fFeeler; // If true this node is being used as a short lived feeler. bool fOneShot; bool fClient; bool fInbound; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index d005d6a16..72bca9bbb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -142,4 +142,26 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) BOOST_CHECK(addrman2.size() == 0); } +BOOST_AUTO_TEST_CASE(cnode_simple_test) +{ + SOCKET hSocket = INVALID_SOCKET; + + in_addr ipv4Addr; + ipv4Addr.s_addr = 0xa0b0c001; + + CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK); + std::string pszDest = ""; + bool fInboundIn = false; + + // Test that fFeeler is false by default. + CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn); + BOOST_CHECK(pnode1->fInbound == false); + BOOST_CHECK(pnode1->fFeeler == false); + + fInboundIn = true; + CNode* pnode2 = new CNode(hSocket, addr, pszDest, fInboundIn); + BOOST_CHECK(pnode2->fInbound == true); + BOOST_CHECK(pnode2->fFeeler == false); +} + BOOST_AUTO_TEST_SUITE_END() From f1c0d78b2d9cbd671413af98e7b081a3b71113ad Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 22 Feb 2016 16:21:27 +0100 Subject: [PATCH 0969/1223] [Qt] show network/chain errors in the GUI --- src/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e3be69ad2..6e784c508 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4647,6 +4647,7 @@ std::string GetWarnings(const std::string& strFor) string strStatusBar; string strRPC; string strGUI; + const string uiAlertSeperator = "


"; if (!CLIENT_VERSION_IS_RELEASE) { strStatusBar = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"; @@ -4659,18 +4660,19 @@ std::string GetWarnings(const std::string& strFor) // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { - strStatusBar = strGUI = strMiscWarning; + strStatusBar = strMiscWarning; + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + strMiscWarning; } if (fLargeWorkForkFound) { strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; - strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; - strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } if (strFor == "gui") From 0e6d7535845f98a080078525c4e3f4f9dce0ec22 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 29 Aug 2016 10:33:36 +0200 Subject: [PATCH 0970/1223] [doc] build: Mention curl --- doc/build-unix.md | 5 +++-- doc/build-windows.md | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index bd89978cc..62e3e793e 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -293,9 +293,10 @@ These steps can be performed on, for example, an Ubuntu VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. -First install the toolchain: +Make sure you install the build requirements mentioned above. +Then, install the toolchain and curl: - sudo apt-get install g++-arm-linux-gnueabihf + sudo apt-get install g++-arm-linux-gnueabihf curl To build executables for ARM: diff --git a/doc/build-windows.md b/doc/build-windows.md index 2b9233d1e..129774491 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -16,9 +16,11 @@ These steps can be performed on, for example, an Ubuntu VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. -First install the toolchains: +Make sure you install the build requirements mentioned in +[build-unix.md](/doc/build-unix.md). +Then, install the toolchains and curl: - sudo apt-get install g++-mingw-w64-i686 mingw-w64-i686-dev g++-mingw-w64-x86-64 mingw-w64-x86-64-dev + sudo apt-get install g++-mingw-w64-i686 mingw-w64-i686-dev g++-mingw-w64-x86-64 mingw-w64-x86-64-dev curl To build executables for Windows 32-bit: From b09e13cb6f3ca3b478afc6dea161463247ac5146 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 26 Aug 2016 16:26:02 +0200 Subject: [PATCH 0971/1223] build: Updates for OpenBSD - LevelDB platform was not guessed correctly (it ended up defining `-DOS_OPENBSD59` instead of `-DOS_OPENBSD`) - On OpenBSD there is no convenience link from `python3.5` to `python3`: add detection for other python interpreter names. - If it has to guess the LevelDB OS, print a autoconf warning so that the user can check. --- configure.ac | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 01d20baef..7b66b61eb 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,8 @@ AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(JAVA, java) -AC_PATH_PROGS([PYTHON], [python3 python2.7 python2 python]) +dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) +AC_PATH_PROGS([PYTHON], [python3.6 python3.5 python3.4 python3 python2.7 python2 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -366,8 +367,15 @@ case $host in TARGET_OS=linux LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; + *freebsd*) + LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" + ;; + *openbsd*) + LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" + ;; *) OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` + AC_MSG_WARN([Guessing LevelDB OS as OS_${OTHER_OS}, please check whether this is correct, if not add an entry to configure.ac.]) LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac From 32d75a7ffc718eff291978bc8c9406037e327c7e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 26 Aug 2016 16:26:09 +0200 Subject: [PATCH 0972/1223] doc: Update build-openbsd for 0.13.0+ and OpenBSD 5.9 - Python 3 now supported. - Bump boost version to 1.61 - one boost patch no longer needed. - All checked with OpenBSD 5.9, except for the clang part, I left this as-is for someone adventurous. - Mention overriding resource limits, OpenBSD's default ulimit does not suffice for building Bitcoin Core with gcc 4.9.3. --- doc/build-openbsd.md | 46 ++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index d92330146..55283d6dc 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 5.7) +(updated for OpenBSD 5.9) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -15,11 +15,10 @@ Run the following as root to install the base dependencies for building: pkg_add gmake libtool libevent pkg_add autoconf # (select highest version, e.g. 2.69) pkg_add automake # (select highest version, e.g. 1.15) -pkg_add python # (select version 2.7.x, not 3.x) -ln -sf /usr/local/bin/python2.7 /usr/local/bin/python2 +pkg_add python # (select highest version, e.g. 3.5) ``` -The default C++ compiler that comes with OpenBSD 5.7 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core. It is possible to patch it up to compile, but with the planned transition to C++11 this is a losing battle. So here we will be installing a newer compiler. +The default C++ compiler that comes with OpenBSD 5.9 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core, primarily as it has no C++11 support, but even before there were issues. So here we will be installing a newer compiler. GCC ------- @@ -27,7 +26,7 @@ GCC You can install a newer version of gcc with: ```bash -pkg_add g++ # (select newest 4.x version, e.g. 4.9.2) +pkg_add g++ # (select newest 4.x version, e.g. 4.9.3) ``` This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. @@ -49,18 +48,15 @@ BOOST_PREFIX="${BITCOIN_ROOT}/boost" mkdir -p $BOOST_PREFIX # Fetch the source and verify that it is not tampered with -wget http://heanet.dl.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.bz2 -echo '727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca boost_1_59_0.tar.bz2' | sha256 -c -# MUST output: (SHA256) boost_1_59_0.tar.bz2: OK -tar -xjf boost_1_59_0.tar.bz2 +curl -o boost_1_61_0.tar.bz2 http://heanet.dl.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2 +echo 'a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640 boost_1_61_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_61_0.tar.bz2: OK +tar -xjf boost_1_61_0.tar.bz2 -# Boost 1.59 needs two small patches for OpenBSD -cd boost_1_59_0 +# Boost 1.61 needs one small patch for OpenBSD +cd boost_1_61_0 # Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp -# https://github.com/boostorg/filesystem/commit/90517e459681790a091566dce27ca3acabf9a70c -sed 's/__OPEN_BSD__/__OpenBSD__/g' < libs/filesystem/src/path.cpp > libs/filesystem/src/path.cpp.tmp -mv libs/filesystem/src/path.cpp.tmp libs/filesystem/src/path.cpp # Build w/ minimum configuration necessary for bitcoin echo 'using gcc : : eg++ : "-fvisibility=hidden -fPIC" "" "ar" "strip" "ranlib" "" : ;' > user-config.jam @@ -84,7 +80,7 @@ BDB_PREFIX="${BITCOIN_ROOT}/db4" mkdir -p $BDB_PREFIX # Fetch the source and verify that it is not tampered with -wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' +curl -o db-4.8.30.NC.tar.gz 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256 -c # MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK tar -xzf db-4.8.30.NC.tar.gz @@ -93,9 +89,25 @@ tar -xzf db-4.8.30.NC.tar.gz cd db-4.8.30.NC/build_unix/ # Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp -make install +make install # do NOT use -jX, this is broken ``` +### Resource limits + +The standard ulimit restrictions in OpenBSD are very strict: + + data(kbytes) 1572864 + +This is, unfortunately, no longer enough to compile some `.cpp` files in the project, +at least with gcc 4.9.3 (see issue https://github.com/bitcoin/bitcoin/issues/6658). +If your user is in the `staff` group the limit can be raised with: + + ulimit -d 3000000 + +The change will only affect the current shell and processes spawned by it. To +make the change system-wide, change `datasize-cur` and `datasize-max` in +`/etc/login.conf`, and reboot. + ### Building Bitcoin Core **Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. @@ -123,7 +135,7 @@ To configure without wallet: Build and run the tests: ```bash -gmake +gmake # can use -jX here for parallelism gmake check ``` From a9874310c0f67c80a1f04854c5c9ed154e1bbf97 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 29 Jun 2016 23:38:33 +0200 Subject: [PATCH 0973/1223] [util] CopyrightHolders: Check for untranslated substitution Also, remove check which is always true --- src/util.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 9a9209c62..ee12f2b44 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -801,11 +801,10 @@ int GetNumCores() std::string CopyrightHolders(const std::string& strPrefix) { - std::string strCopyrightHolders = strPrefix + _(COPYRIGHT_HOLDERS); - if (strCopyrightHolders.find("%s") != strCopyrightHolders.npos) { - strCopyrightHolders = strprintf(strCopyrightHolders, _(COPYRIGHT_HOLDERS_SUBSTITUTION)); - } - if (strCopyrightHolders.find("Bitcoin Core developers") == strCopyrightHolders.npos) { + std::string strCopyrightHolders = strPrefix + strprintf(_(COPYRIGHT_HOLDERS), _(COPYRIGHT_HOLDERS_SUBSTITUTION)); + + // Check for untranslated substitution to make sure Bitcoin Core copyright is not removed by accident + if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Bitcoin Core") == std::string::npos) { strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; } return strCopyrightHolders; From b8c79a057c48c871a5e48bdcdf600fbfe68f656b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 16 Aug 2016 15:35:45 +0200 Subject: [PATCH 0974/1223] Precompute sighashes Original version by Nicolas Dorier. Precomputing version by Pieter Wuille. --- src/main.cpp | 22 +++++---- src/main.h | 9 ++-- src/script/bitcoinconsensus.cpp | 4 +- src/script/interpreter.cpp | 54 +++++++++++++------- src/script/interpreter.h | 13 ++++- src/script/sigcache.h | 2 +- src/test/script_P2SH_tests.cpp | 6 ++- src/test/transaction_tests.cpp | 87 ++++++++++++++++++++++++++++++++- src/txmempool.cpp | 6 ++- 9 files changed, 163 insertions(+), 40 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6e784c508..5a9691474 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1497,12 +1497,13 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true)) { + PrecomputedTransactionData txdata(tx); + if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, txdata)) { // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. - if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true) && - !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true)) { + if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, txdata) && + !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, txdata)) { // Only the witness is wrong, so the transaction itself may be fine. state.SetCorruptionPossible(); } @@ -1518,7 +1519,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // There is a similar check in CreateNewBlock() to prevent creating // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata)) { return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); @@ -1915,7 +1916,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; const CScriptWitness *witness = (nIn < ptxTo->wit.vtxinwit.size()) ? &ptxTo->wit.vtxinwit[nIn].scriptWitness : NULL; - if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), &error)) { return false; } return true; @@ -1974,7 +1975,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins } }// namespace Consensus -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector *pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector *pvChecks) { if (!tx.IsCoinBase()) { @@ -2001,7 +2002,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags, cacheStore); + CScriptCheck check(*coins, tx, i, flags, cacheStore, &txdata); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -2014,7 +2015,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check2(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &txdata); if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } @@ -2412,6 +2413,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector > vPos; vPos.reserve(block.vtx.size()); blockundo.vtxundo.reserve(block.vtx.size() - 1); + std::vector txdata; + txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; @@ -2458,13 +2461,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): too many sigops"), REJECT_INVALID, "bad-blk-sigops"); + txdata.emplace_back(tx); if (!tx.IsCoinBase()) { nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector vChecks; bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ - if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : NULL)) return error("ConnectBlock(): CheckInputs on %s failed with %s", tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); diff --git a/src/main.h b/src/main.h index 631dc00d0..cbce34290 100644 --- a/src/main.h +++ b/src/main.h @@ -39,6 +39,7 @@ class CTxMemPool; class CValidationInterface; class CValidationState; +struct PrecomputedTransactionData; struct CNodeStateStats; struct LockPoints; @@ -347,7 +348,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i * instead of being performed inline. */ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, - unsigned int flags, bool cacheStore, std::vector *pvChecks = NULL); + unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector *pvChecks = NULL); /** Apply the effects of this transaction on the UTXO set represented by view */ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); @@ -408,12 +409,13 @@ private: unsigned int nFlags; bool cacheStore; ScriptError error; + PrecomputedTransactionData *txdata; public: CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, PrecomputedTransactionData* txdataIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), amount(txFromIn.vout[txToIn.vin[nInIn].prevout.n].nValue), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { } bool operator()(); @@ -425,6 +427,7 @@ public: std::swap(nFlags, check.nFlags); std::swap(cacheStore, check.cacheStore); std::swap(error, check.error); + std::swap(txdata, check.txdata); } ScriptError GetScriptError() const { return error; } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 62fd9031f..b629f4278 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -84,8 +84,8 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, amount), NULL); + PrecomputedTransactionData txdata(tx); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index bc027e9f0..47ea261e3 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1108,9 +1108,40 @@ public: } }; +uint256 GetPrevoutHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + return ss.GetHash(); +} + +uint256 GetSequenceHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + return ss.GetHash(); +} + +uint256 GetOutputsHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + return ss.GetHash(); +} + } // anon namespace -uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion) +PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo) +{ + hashPrevouts = GetPrevoutHash(txTo); + hashSequence = GetSequenceHash(txTo); + hashOutputs = GetOutputsHash(txTo); +} + +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) { if (sigversion == SIGVERSION_WITNESS_V0) { uint256 hashPrevouts; @@ -1118,27 +1149,16 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig uint256 hashOutputs; if (!(nHashType & SIGHASH_ANYONECANPAY)) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].prevout; - } - hashPrevouts = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo); } if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].nSequence; - } - hashSequence = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo); } + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vout.size(); n++) { - ss << txTo.vout[n]; - } - hashOutputs = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo); } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { CHashWriter ss(SER_GETHASH, 0); ss << txTo.vout[nIn]; @@ -1209,7 +1229,7 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn int nHashType = vchSig.back(); vchSig.pop_back(); - uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); if (!VerifySignature(vchSig, pubkey, sighash)) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index bd2f21166..e5d7865cd 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -98,13 +98,20 @@ enum bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); +struct PrecomputedTransactionData +{ + uint256 hashPrevouts, hashSequence, hashOutputs; + + PrecomputedTransactionData(const CTransaction& tx); +}; + enum SigVersion { SIGVERSION_BASE = 0, SIGVERSION_WITNESS_V0 = 1, }; -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion); +uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = NULL); class BaseSignatureChecker { @@ -133,12 +140,14 @@ private: const CTransaction* txTo; unsigned int nIn; const CAmount amount; + const PrecomputedTransactionData* txdata; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const; bool CheckLockTime(const CScriptNum& nLockTime) const; bool CheckSequence(const CScriptNum& nSequence) const; diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 050bf8cc4..44551ec2b 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -22,7 +22,7 @@ private: bool store; public: - CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, nInIn, amount), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 5224b57ca..1a01593a8 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -107,18 +107,20 @@ BOOST_AUTO_TEST_CASE(sign) } // All of the above should be OK, and the txTos have valid signatures // Check to make sure signature verification fails if we use the wrong ScriptSig: - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { + PrecomputedTransactionData txdata(txTo[i]); for (int j = 0; j < 8; j++) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j)); txTo[i].vin[0].scriptSig = sigSave; } + } } BOOST_AUTO_TEST_CASE(norecurse) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index fd4f174b4..b5af400bc 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -7,6 +7,7 @@ #include "test/test_bitcoin.h" #include "clientversion.h" +#include "checkqueue.h" #include "consensus/validation.h" #include "core_io.h" #include "key.h" @@ -153,6 +154,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest); BOOST_CHECK(state.IsValid()); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size(); i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) @@ -168,7 +170,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err), + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -237,6 +239,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) CValidationState state; fValid = CheckTransaction(tx, state) && state.IsValid(); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) @@ -252,7 +255,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err); + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -419,6 +422,86 @@ void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) script = PushAll(stack); } +BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { + CMutableTransaction mtx; + mtx.nVersion = 1; + + CKey key; + key.MakeNewKey(false); + CBasicKeyStore keystore; + keystore.AddKeyPubKey(key, key.GetPubKey()); + CKeyID hash = key.GetPubKey().GetID(); + CScript scriptPubKey = CScript() << OP_0 << std::vector(hash.begin(), hash.end()); + + vector sigHashes; + sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_NONE); + sigHashes.push_back(SIGHASH_SINGLE); + sigHashes.push_back(SIGHASH_ALL); + + // create a big transaction of 4500 inputs signed by the same key + for(uint32_t ij = 0; ij < 4500; ij++) { + uint32_t i = mtx.vin.size(); + uint256 prevId; + prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100"); + COutPoint outpoint(prevId, i); + + mtx.vin.resize(mtx.vin.size() + 1); + mtx.vin[i].prevout = outpoint; + mtx.vin[i].scriptSig = CScript(); + + mtx.vout.resize(mtx.vout.size() + 1); + mtx.vout[i].nValue = 1000; + mtx.vout[i].scriptPubKey = CScript() << OP_1; + } + + // sign all inputs + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size())); + assert(hashSigned); + } + + CTransaction tx; + CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); + WithOrVersion(&ssout, 0) << mtx; + WithOrVersion(&ssout, 0) >> tx; + + // check all inputs concurrently, with the cache + PrecomputedTransactionData txdata(tx); + boost::thread_group threadGroup; + CCheckQueue scriptcheckqueue(128); + CCheckQueueControl control(&scriptcheckqueue); + + for (int i=0; i<20; i++) + threadGroup.create_thread(boost::bind(&CCheckQueue::Thread, boost::ref(scriptcheckqueue))); + + CCoins coins; + coins.nVersion = 1; + coins.fCoinBase = false; + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + CTxOut txout; + txout.nValue = 1000; + txout.scriptPubKey = scriptPubKey; + coins.vout.push_back(txout); + } + + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + std::vector vChecks; + CScriptCheck check(coins, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata); + vChecks.push_back(CScriptCheck()); + check.swap(vChecks.back()); + control.Add(vChecks); + } + + bool controlCheck = control.Wait(); + assert(controlCheck); + + threadGroup.interrupt_all(); + threadGroup.join_all(); +} + BOOST_AUTO_TEST_CASE(test_witness) { CBasicKeyStore keystore, keystore2; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 82827b8e4..8b974d731 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -737,7 +737,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const waitingOnDependants.push_back(&(*it)); else { CValidationState state; - assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); + PrecomputedTransactionData txdata(tx); + assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, txdata, NULL)); UpdateCoins(tx, mempoolDuplicate, 1000000); } } @@ -751,7 +752,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const stepsSinceLastRemove++; assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { - assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL)); + PrecomputedTransactionData txdata(entry->GetTx()); + assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, txdata, NULL)); UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000); stepsSinceLastRemove = 0; } From 2215c22a00116d210dcfd95d3369035a8d2fd6c2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 26 Aug 2016 21:44:44 +0200 Subject: [PATCH 0975/1223] Check for compatibility with download in FindNextBlocksToDownload --- src/main.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5a9691474..6a82f3d19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -537,7 +537,7 @@ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) { /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has * at most count entries. */ -void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller) { +void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller, const Consensus::Params& consensusParams) { if (count == 0) return; @@ -594,6 +594,10 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vectorfHaveWitness && IsWitnessEnabled(pindex->pprev, consensusParams)) { + // We wouldn't download this block or its descendants from this peer. + return; + } if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) { if (pindex->nChainTx) state->pindexLastCommonBlock = pindex; @@ -6726,15 +6730,13 @@ bool SendMessages(CNode* pto) if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vector vToDownload; NodeId staller = -1; - FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); + FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams); BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { - if (State(pto->GetId())->fHaveWitness || !IsWitnessEnabled(pindex->pprev, consensusParams)) { - uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams); - vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); - MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); - LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), - pindex->nHeight, pto->id); - } + uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams); + vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); + MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); + LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), + pindex->nHeight, pto->id); } if (state.nBlocksInFlight == 0 && staller != -1) { if (State(staller)->nStallingSince == 0) { From bbf379b0552c357088e349dd6608730489696b80 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 26 Aug 2016 21:07:05 +0200 Subject: [PATCH 0976/1223] Fix some locks This makes sure that cs_filter is never held while taking cs_main or CNode::cs_vSend. --- src/main.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6a82f3d19..0b8588efa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4803,10 +4803,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam pfrom->PushMessage(NetMsgType::BLOCK, block); else if (inv.type == MSG_FILTERED_BLOCK) { - LOCK(pfrom->cs_filter); - if (pfrom->pfilter) + bool send = false; + CMerkleBlock merkleBlock; { - CMerkleBlock merkleBlock(block, *pfrom->pfilter); + LOCK(pfrom->cs_filter); + if (pfrom->pfilter) { + send = true; + merkleBlock = CMerkleBlock(block, *pfrom->pfilter); + } + } + if (send) { pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip @@ -6074,8 +6080,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBloomFilter filter; vRecv >> filter; - LOCK(pfrom->cs_filter); - if (!filter.IsWithinSizeConstraints()) { // There is no excuse for sending a too-large filter @@ -6084,11 +6088,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else { + LOCK(pfrom->cs_filter); delete pfrom->pfilter; pfrom->pfilter = new CBloomFilter(filter); pfrom->pfilter->UpdateEmptyFull(); + pfrom->fRelayTxes = true; } - pfrom->fRelayTxes = true; } @@ -6099,20 +6104,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object, // and thus, the maximum size any matched object can have) in a filteradd message - if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) - { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), 100); + bool bad = false; + if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) { + bad = true; } else { LOCK(pfrom->cs_filter); - if (pfrom->pfilter) + if (pfrom->pfilter) { pfrom->pfilter->insert(vData); - else - { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), 100); + } else { + bad = true; } } + if (bad) { + LOCK(cs_main); + Misbehaving(pfrom->GetId(), 100); + } } From ab295bb4be26939e4853b9d95a9938c5ed8afa57 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Thu, 25 Aug 2016 23:42:40 +0000 Subject: [PATCH 0977/1223] Do not add random inbound peers to addrman. We should learn about new peers via address messages. An inbound peer connecting to us tells us nothing about its ability to accept incoming connections from us, so we shouldn't assume that we can connect to it based on this. The vast majority of nodes on the network do not accept incoming connections, adding them will only slow down the process of making a successful connection in the future. Nodes which have configured themselves to not announce would prefer we not violate their privacy by announcing them in GETADDR responses. --- src/main.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0b8588efa..40f2fffe7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5057,12 +5057,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fGetAddr = true; } addrman.Good(pfrom->addr); - } else { - if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom) - { - addrman.Add(addrFrom, addrFrom); - addrman.Good(addrFrom); - } } pfrom->fSuccessfullyConnected = true; From a9429ca26dd8f4555def2dc8bd8ea7fc4e32fce6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 27 Aug 2016 15:28:20 +0200 Subject: [PATCH 0978/1223] Reduce default number of blocks to check at startup Github-Pull: #8611 Rebased-From: 203f2121be0a84e85f7dff9cca9a30387005954f --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index cbce34290..8cae9c953 100644 --- a/src/main.h +++ b/src/main.h @@ -192,7 +192,7 @@ extern uint64_t nPruneTarget; /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ static const unsigned int MIN_BLOCKS_TO_KEEP = 288; -static const signed int DEFAULT_CHECKBLOCKS = MIN_BLOCKS_TO_KEEP; +static const signed int DEFAULT_CHECKBLOCKS = 6; static const unsigned int DEFAULT_CHECKLEVEL = 3; // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) From 41fd852d3fcb84b87fefb2a4f7290c53519c78f3 Mon Sep 17 00:00:00 2001 From: rodasmith Date: Sat, 10 Sep 2016 11:41:01 -0700 Subject: [PATCH 0979/1223] fix op order to append first alert Github-Pull: #8697 Rebased-From: 1d635ae61b26d1dd613c1cc1cac796627af2a31e --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 40f2fffe7..8f519dee1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4675,12 +4675,12 @@ std::string GetWarnings(const std::string& strFor) if (fLargeWorkForkFound) { strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; - strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; - strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } if (strFor == "gui") From d9f0d4e0737a1f29173ee5407ba701496ba9f46b Mon Sep 17 00:00:00 2001 From: adlawren Date: Sat, 6 Aug 2016 23:58:30 -0700 Subject: [PATCH 0980/1223] Fix minimize and close bugs refs #8225 To ensure the GUI closes when the "Minimize on close" window option is disabled, and the "Minimize to the tray instead of the taskbar" window option is enbaled, remove a check made against the "Minimize to the tray instead of the taskbar" value, made during GUI closure. To ensure the GUI minimizes to the taskbar when the "Minimize on close" window option is enabled, and the "Minimize to the tray instead of the taskbar" window option is disabled, minimize the GUI and ignore the closure event. Github-Pull: #8481 Rebased-From: 05242e937d3fc0144029ccf3b14f98662400dd60 --- src/qt/bitcoingui.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 9042e3b56..2afefb733 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -902,17 +902,22 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) #ifndef Q_OS_MAC // Ignored on Mac if(clientModel && clientModel->getOptionsModel()) { - if(!clientModel->getOptionsModel()->getMinimizeToTray() && - !clientModel->getOptionsModel()->getMinimizeOnClose()) + if(!clientModel->getOptionsModel()->getMinimizeOnClose()) { // close rpcConsole in case it was open to make some space for the shutdown window rpcConsole->close(); QApplication::quit(); } + else + { + QMainWindow::showMinimized(); + event->ignore(); + } } -#endif +#else QMainWindow::closeEvent(event); +#endif } void BitcoinGUI::showEvent(QShowEvent *event) From a37cec537b70254a5587dd2aee6cfaad46349bcf Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Mon, 8 Aug 2016 14:17:23 -0400 Subject: [PATCH 0981/1223] Persist the datadir after option reset Github-Pull: #8487 Rebased-From: 15df3c196b2359505980a2b0217133e0bb550565 57acb82e7014f3214229349485fa3f57842b10ae --- src/qt/intro.cpp | 3 ++- src/qt/optionsmodel.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 6a5740e21..1a241ae0f 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -178,7 +178,7 @@ bool Intro::pickDataDirectory() /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || GetBoolArg("-resetguisettings", false)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -204,6 +204,7 @@ bool Intro::pickDataDirectory() } settings.setValue("strDataDir", dataDir); + settings.setValue("fReset", false); } /* Only override -datadir if different from the default, to make it possible to * override -datadir in the bitcoin.conf file in the default data directory diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 684db71a8..5538a2841 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -16,6 +16,7 @@ #include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS #include "net.h" #include "txdb.h" // for -dbcache defaults +#include "intro.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" @@ -98,6 +99,9 @@ void OptionsModel::Init(bool resetSettings) if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) addOverriddenOption("-par"); + if (!settings.contains("strDataDir")) + settings.setValue("strDataDir", Intro::getDefaultDataDirectory()); + // Wallet #ifdef ENABLE_WALLET if (!settings.contains("bSpendZeroConfChange")) @@ -150,9 +154,19 @@ void OptionsModel::Reset() { QSettings settings; + // Save the strDataDir setting + QString dataDir = Intro::getDefaultDataDirectory(); + dataDir = settings.value("strDataDir", dataDir).toString(); + // Remove all entries from our QSettings object settings.clear(); + // Set strDataDir + settings.setValue("strDataDir", dataDir); + + // Set that this was reset + settings.setValue("fReset", true); + // default setting for OptionsModel::StartAtStartup - disabled if (GUIUtil::GetStartOnSystemStartup()) GUIUtil::SetStartOnSystemStartup(false); From 63462c2b4bcd250402b040bc19f2ae39771a62f7 Mon Sep 17 00:00:00 2001 From: whythat Date: Fri, 2 Sep 2016 12:38:04 +0300 Subject: [PATCH 0982/1223] [qa] remove root test directory for RPC tests Github-Pull: #8652 Rebased-From: 438e94dc330a37600ec1d86f2ba8502385b5262d c62cc4ec759a8487373f158b3cbb888efcdd753a --- qa/rpc-tests/test_framework/test_framework.py | 5 ++++- qa/rpc-tests/wallet-hd.py | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 0dfece6b2..306f31102 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -123,7 +123,8 @@ class BitcoinTestFramework(object): self.add_options(parser) (self.options, self.args) = parser.parse_args() - self.options.tmpdir += '/' + str(self.options.port_seed) + # backup dir variable for removal at cleanup + self.options.root, self.options.tmpdir = self.options.tmpdir, self.options.tmpdir + '/' + str(self.options.port_seed) if self.options.trace_rpc: logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) @@ -174,6 +175,8 @@ class BitcoinTestFramework(object): if not self.options.nocleanup and not self.options.noshutdown and success: print("Cleaning up") shutil.rmtree(self.options.tmpdir) + if not os.listdir(self.options.root): + os.rmdir(self.options.root) else: print("Not cleaning up dir %s" % self.options.tmpdir) diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index c11da1e9a..a49d91f6f 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -39,8 +39,8 @@ class WalletHDTest(BitcoinTestFramework): self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) # This should be enough to keep the master key and the non-HD key - self.nodes[1].backupwallet(tmpdir + "hd.bak") - #self.nodes[1].dumpwallet(tmpdir + "hd.dump") + self.nodes[1].backupwallet(tmpdir + "/hd.bak") + #self.nodes[1].dumpwallet(tmpdir + "/hd.dump") # Derive some HD addresses and remember the last # Also send funds to each add @@ -63,7 +63,7 @@ class WalletHDTest(BitcoinTestFramework): print("Restore backup ...") self.stop_node(1) os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") - shutil.copyfile(tmpdir + "hd.bak", tmpdir + "/node1/regtest/wallet.dat") + shutil.copyfile(tmpdir + "/hd.bak", tmpdir + "/node1/regtest/wallet.dat") self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1]) #connect_nodes_bi(self.nodes, 0, 1) From ae8c7df7a5725e812586f2c2d653578b8fd55a37 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 13 Sep 2016 19:35:35 +0200 Subject: [PATCH 0983/1223] [qa] create_cache: Delete temp dir when done Github-Pull: #8713 Rebased-From: fa27d990ee38a9dce1da71098be010e4a81b18c3 --- qa/rpc-tests/create_cache.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py index b6161e091..1ace6310d 100755 --- a/qa/rpc-tests/create_cache.py +++ b/qa/rpc-tests/create_cache.py @@ -12,9 +12,15 @@ from test_framework.test_framework import BitcoinTestFramework class CreateCache(BitcoinTestFramework): + def __init__(self): + super().__init__() + + # Test network and test nodes are not required: + self.num_nodes = 0 + self.nodes = [] + def setup_network(self): - # Don't setup any test nodes - self.options.noshutdown = True + pass def run_test(self): pass From d6ebe1369fca30a914e72cbe9da7367de80d8f8a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 17 Sep 2016 11:47:51 +0200 Subject: [PATCH 0984/1223] [qa] Refactor RPCTestHandler to prevent TimeoutExpired Github-Pull: #8750 Rebased-From: dddd04f979392a8c69cc11f5c54d817702eeed3e --- qa/pull-tester/rpc-tests.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 11b83bac1..a99149e52 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -248,21 +248,27 @@ class RPCTestHandler: self.num_running += 1 t = self.test_list.pop(0) port_seed = ["--portseed=%s" % len(self.test_list)] + log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) + log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, time.time(), subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed, universal_newlines=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE))) + stdout=log_stdout, + stderr=log_stderr), + log_stdout, + log_stderr)) if not self.jobs: raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) for j in self.jobs: - (name, time0, proc) = j + (name, time0, proc, log_out, log_err) = j if proc.poll() is not None: - (stdout, stderr) = proc.communicate(timeout=3) + log_out.seek(0), log_err.seek(0) + [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] + log_out.close(), log_err.close() passed = stderr == "" and proc.returncode == 0 self.num_running -= 1 self.jobs.remove(j) From c6a629100b4b2afa1ad0cf71ba7ef21908ceda02 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 9 Sep 2016 12:13:18 -0400 Subject: [PATCH 0985/1223] add witness address to address book Github-Pull: #8693 Rebased-From: 62ffbbdec30699941069baeae61716ff12155ba6 --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a90807e51..901e6a5d1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1088,6 +1088,8 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet"); } + pwalletMain->SetAddressBook(w.result, "", "receive"); + return CBitcoinAddress(w.result).ToString(); } From 733760a700ac97e59a3e3ae5565ba45616aa079e Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 2 Sep 2016 23:05:29 +0100 Subject: [PATCH 0986/1223] Update btcdrak signing key Github-Pull: #8662 Rebased-From: 46606af200db563ca742b56f291cee2311a27491 --- contrib/gitian-keys/btcdrak-key.pgp | Bin 8954 -> 4916 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/gitian-keys/btcdrak-key.pgp b/contrib/gitian-keys/btcdrak-key.pgp index 60d76c0ec7ab86635637ee9f49948e004fadfee4..f00dc729d57a2e7b7848324177c605dac9dc8e45 100644 GIT binary patch literal 4916 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 z%0A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 Date: Tue, 16 Aug 2016 14:11:10 -0400 Subject: [PATCH 0987/1223] Update p2p-segwit.py to reflect correct AskFor behavior Github-Pull: #8528 Rebased-From: bc1d1f266046ec79e87c7bf90aaf279f43266cf5 --- qa/rpc-tests/p2p-segwit.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index cd02692b1..3813743e5 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -946,8 +946,7 @@ class SegWitTest(BitcoinTestFramework): self.test_node.test_transaction_acceptance(tx, with_witness=True, accepted=False) # Verify that removing the witness succeeds. - # Re-announcing won't result in a getdata for ~2.5 minutes, so just - # deliver the modified transaction. + self.test_node.announce_tx_and_wait_for_getdata(tx) self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) # Now try to add extra witness data to a valid witness tx. From a114a0208b2c01d85f413e48569edc4f5ec0951a Mon Sep 17 00:00:00 2001 From: instagibbs Date: Tue, 16 Aug 2016 15:45:42 -0400 Subject: [PATCH 0988/1223] p2psegwit.py transaction is rejected due to premature witness not size Github-Pull: #8528 Rebased-From: 5547aeb0159027912069b4773184963f54c672af --- qa/rpc-tests/p2p-segwit.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 3813743e5..68d8b9a00 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -302,13 +302,18 @@ class SegWitTest(BitcoinTestFramework): sync_blocks(self.nodes) # We'll add an unnecessary witness to this transaction that would cause - # it to be too large according to IsStandard. + # it to be non-standard, to test that violating policy with a witness before + # segwit activation doesn't blind a node to a transaction. Transactions + # rejected for having a witness before segwit activation shouldn't be added + # to the rejection cache. tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptPubKey)) tx3.wit.vtxinwit.append(CTxInWitness()) tx3.wit.vtxinwit[0].scriptWitness.stack = [b'a'*400000] tx3.rehash() + # Note that this should be rejected for the premature witness reason, + # rather than a policy check, since segwit hasn't activated yet. self.std_node.test_transaction_acceptance(tx3, True, False, b'no-witness-yet') # If we send without witness, it should be accepted. From 6b07362b375feab71f0d0d3ed00a5b16944f4d12 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Tue, 6 Sep 2016 00:50:23 +0800 Subject: [PATCH 0989/1223] Fix SIGHASH_SINGLE bug in test_framework SignatureHash The value for "other" inputs should be -1 (0xffffffffffffffff) instead of 0 Github-Pull: #8667 Rebased-From: 2f2548d5e0ccea6879eb7b0b851d61ad2f544423 --- qa/rpc-tests/test_framework/script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index b46c643cc..83bbf2047 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -882,7 +882,7 @@ def SignatureHash(script, txTo, inIdx, hashtype): tmp = txtmp.vout[outIdx] txtmp.vout = [] for i in range(outIdx): - txtmp.vout.append(CTxOut()) + txtmp.vout.append(CTxOut(-1)) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): From 8e0338227979eb619da2dcacc505f4f229b67da0 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 7 Sep 2016 16:03:08 +0200 Subject: [PATCH 0990/1223] [Qt][CoinControl] fix UI bug that could result in paying unexpected fee Github-Pull: #8678 Rebased-From: 04802930d4e1f565b3c36e1a806fbe9cd4809937 --- src/qt/sendcoinsdialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 6d50be56e..546003622 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -592,6 +592,9 @@ void SendCoinsDialog::updateGlobalFeeVariables() { nTxConfirmTarget = defaultConfirmTarget - ui->sliderSmartFee->value(); payTxFee = CFeeRate(0); + + // set nMinimumTotalFee to 0 to not accidentally pay a custom fee + CoinControlDialog::coinControl->nMinimumTotalFee = 0; } else { @@ -790,7 +793,7 @@ void SendCoinsDialog::coinControlUpdateLabels() ui->radioCustomAtLeast->setVisible(true); // only enable the feature if inputs are selected - ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected()); + ui->radioCustomAtLeast->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() &&CoinControlDialog::coinControl->HasSelected()); } else { From 091cdebfb823734559f9694c4c45eba1598b05ff Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Sun, 4 Sep 2016 20:02:40 -0400 Subject: [PATCH 0991/1223] Clear witness with vin/vout in CWallet::CreateTransaction() Github-Pull: #8664 Rebased-From: c40b034327bf8a30d3af1eeeef84bc4ccd57e685 --- src/wallet/wallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e5ee5063a..32a01d2db 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2202,6 +2202,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt nChangePosInOut = nChangePosRequest; txNew.vin.clear(); txNew.vout.clear(); + txNew.wit.SetNull(); wtxNew.fFromMe = true; bool fFirst = true; From 147003c73edb5a949ca403ecf8883c1b8bfaa6c1 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 23 Aug 2016 16:55:15 +1000 Subject: [PATCH 0992/1223] Add configure check for -latomic Github-Pull: #8563 Rebased-From: 878faacd7b3daac437cc689b13422f6432fb5cd0 --- build-aux/m4/l_atomic.m4 | 40 ++++++++++++++++++++++++++++++++++++++++ configure.ac | 3 +++ 2 files changed, 43 insertions(+) create mode 100644 build-aux/m4/l_atomic.m4 diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 new file mode 100644 index 000000000..906724b64 --- /dev/null +++ b/build-aux/m4/l_atomic.m4 @@ -0,0 +1,40 @@ +# Some versions of gcc/libstdc++ require linking with -latomic if +# using the C++ atomic library. +# +# Sourced from http://bugs.debian.org/797228 + +m4_define([_CHECK_ATOMIC_testbody], [[ + #include + #include + + int main() { + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } +]]) + +AC_DEFUN([CHECK_ATOMIC], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether std::atomic can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -latomic" + AC_MSG_CHECKING([whether std::atomic needs -latomic]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure our how to use std::atomic]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/configure.ac b/configure.ac index 7b66b61eb..55578c886 100644 --- a/configure.ac +++ b/configure.ac @@ -57,6 +57,9 @@ case $host in esac dnl Require C++11 compiler (no GNU extensions) AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +dnl Check if -latomic is required for +CHECK_ATOMIC + dnl Libtool init checks. LT_INIT([pic-only]) From 8a7d7ffe650d719b0a0ab17d60607e4400dc5408 Mon Sep 17 00:00:00 2001 From: Gaurav Rana Date: Thu, 8 Sep 2016 17:43:55 +0545 Subject: [PATCH 0993/1223] update name of file bitcoin.qrc Github-Pull: #8683 Rebased-From: df2d2e70cac8d15ecc30bc5c46930fd27c8afac0 --- doc/translation_process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/translation_process.md b/doc/translation_process.md index 310d560b3..361579a73 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -94,7 +94,7 @@ When new plurals are added to the source file, it's important to do the followin 7. Save the source file ### Translating a new language -To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin.qrc` and add a new entry. Below is an example of the english language entry. +To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin_locale.qrc` and add a new entry. Below is an example of the english language entry. ```xml From 03b01966fa4b864c82a7543de0ed52a2c69ed38a Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Tue, 6 Sep 2016 16:22:13 -0400 Subject: [PATCH 0994/1223] Fix obvious assignment/equality error in test Github-Pull: #8673 Rebased-From: 426e7bce0e365e0947f932ca46bcc48ca3a2f10e --- src/test/arith_uint256_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 53ab7e95e..b19d2faea 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); BOOST_CHECK(ZeroL == arith_uint256(0)); BOOST_CHECK(OneL == arith_uint256(1)); - BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); + BOOST_CHECK(arith_uint256("0xffffffffffffffff") == arith_uint256(0xffffffffffffffffULL)); // Assignment (from base_uint) arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); From 1f21d161a590d5f0aaf77ea01cd9d80c33be0a54 Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Wed, 27 Jul 2016 16:27:07 -0700 Subject: [PATCH 0995/1223] prepend license statement to indirectmap Add statement about MIT licensing to indirectmap.h. I forgot the license preamble when I originally wrote the file. Github-Pull: #8414 Rebased-From: d3af342276f29d2bd162628eb4b669599633e39e --- src/indirectmap.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/indirectmap.h b/src/indirectmap.h index 28e1e8ded..76da4a6bd 100644 --- a/src/indirectmap.h +++ b/src/indirectmap.h @@ -1,3 +1,7 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_INDIRECTMAP_H #define BITCOIN_INDIRECTMAP_H From f70be14f8fe4fd72f77d57d05c6c4d4f1e28b7f9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 28 Jul 2016 14:59:13 +0200 Subject: [PATCH 0996/1223] [QA] Add walletdump RPC test (including HD- & encryption-tests) Github-Pull: #8417 Rebased-From: 54af51d98d0b38f08c58dd589bff81883aee2854 --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/wallet-dump.py | 120 ++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100755 qa/rpc-tests/wallet-dump.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index a99149e52..05fee5179 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -107,6 +107,7 @@ testScripts = [ 'bip68-112-113-p2p.py', 'wallet.py', 'wallet-hd.py', + 'wallet-dump.py', 'listtransactions.py', 'receivedby.py', 'mempool_resurrect_test.py', diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py new file mode 100755 index 000000000..dd675f57f --- /dev/null +++ b/qa/rpc-tests/wallet-dump.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import os +import shutil + + +class WalletDumpTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 + + def setup_network(self, split=False): + extra_args = [["-keypool=100"]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + + def run_test (self): + tmpdir = self.options.tmpdir + + #generate 20 addresses to compare against the dump + test_addr_count = 20 + addrs = [] + for i in range(0,test_addr_count): + addr = self.nodes[0].getnewaddress() + vaddr= self.nodes[0].validateaddress(addr) #required to get hd keypath + addrs.append(vaddr) + + # dump unencrypted wallet + self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.unencrypted.dump") + + #open file + inputfile = open(tmpdir + "/node0/wallet.unencrypted.dump") + found_addr = 0 + found_addr_chg = 0 + found_addr_rsv = 0 + hdmasteraddr = "" + for line in inputfile: + #only read non comment lines + if line[0] != "#" and len(line) > 10: + #split out some data + keyLabel, comment = line.split("#") + key = keyLabel.split(" ")[0] + keytype = keyLabel.split(" ")[2] + if len(comment) > 1: + addrKeypath = comment.split(" addr=")[1] + addr = addrKeypath.split(" ")[0] + keypath = "" + if keytype != "hdmaster=1": + keypath = addrKeypath.rstrip().split("hdkeypath=")[1] + else: + #keep hd master for later comp. + hdmasteraddr = addr + + #count key types + for addrObj in addrs: + if (addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label="): + found_addr+=1 + break + elif (keytype == "change=1"): + found_addr_chg+=1 + break + elif (keytype == "reserve=1"): + found_addr_rsv+=1 + break + assert(found_addr == test_addr_count) #all keys must be in the dump + assert(found_addr_chg == 50) #50 blocks where mined + assert(found_addr_rsv == 100) #100 reserve keys (keypool) + + #encrypt wallet, restart, unlock and dump + self.nodes[0].encryptwallet('test') + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0, self.options.tmpdir) + self.nodes[0].walletpassphrase('test', 10) + self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump") + + #open dump done with an encrypted wallet + inputfile = open(tmpdir + "/node0/wallet.encrypted.dump") + found_addr = 0 + found_addr_chg = 0 + found_addr_rsv = 0 + for line in inputfile: + if line[0] != "#" and len(line) > 10: + keyLabel, comment = line.split("#") + key = keyLabel.split(" ")[0] + keytype = keyLabel.split(" ")[2] + if len(comment) > 1: + addrKeypath = comment.split(" addr=")[1] + addr = addrKeypath.split(" ")[0] + keypath = "" + if keytype != "hdmaster=1": + keypath = addrKeypath.rstrip().split("hdkeypath=")[1] + else: + #ensure we have generated a new hd master key + assert(hdmasteraddr != addr) + if keytype == "inactivehdmaster=1": + #ensure the old master is still available + assert(hdmasteraddr == addr) + for addrObj in addrs: + if (addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label="): + found_addr+=1 + break + elif (keytype == "change=1"): + found_addr_chg+=1 + break + elif (keytype == "reserve=1"): + found_addr_rsv+=1 + break + + assert(found_addr == test_addr_count) + assert(found_addr_chg == 150) #old reserve keys are marked as change now + assert(found_addr_rsv == 100) #keypool size + +if __name__ == '__main__': + WalletDumpTest().main () From 69d1cd202d432bd6b8a6cda2187c148bcf1f6c2e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 29 Jul 2016 17:42:12 +0200 Subject: [PATCH 0997/1223] net: Ignore `notfound` P2P messages Github-Pull: #8427 Rebased-From: 5c9e49d12c931f9c7ddaac0144739dcd7263e554 --- src/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 8f519dee1..01cd410da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6161,6 +6161,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + else if (strCommand == NetMsgType::NOTFOUND) { + // We do not care about the NOTFOUND message, but logging an Unknown Command + // message would be undesirable as we transmit it ourselves. + } + else { // Ignore unknown commands for extensibility LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id); From e111904a76774c9912189f29ad82ad3424905507 Mon Sep 17 00:00:00 2001 From: whythat Date: Mon, 25 Jul 2016 01:30:28 +0300 Subject: [PATCH 0998/1223] [qa]: add parsing for ':' argument form to rpc_url() Github-Pull: #8400 Rebased-From: 0ff4375c93bd159233282de5a33ad2e6c1e79841 --- qa/rpc-tests/test_framework/util.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 32fe79efc..8aa34265c 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -171,7 +171,15 @@ def rpc_auth_pair(n): def rpc_url(i, rpchost=None): rpc_u, rpc_p = rpc_auth_pair(i) - return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) + host = '127.0.0.1' + port = rpc_port(i) + if rpchost: + parts = rpchost.split(':') + if len(parts) == 2: + host, port = parts + else: + host = rpchost + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, host, int(port)) def wait_for_bitcoind_start(process, url, i): ''' From bea02dc3b664d77745f6701ba7c425b1f9f737cd Mon Sep 17 00:00:00 2001 From: whythat Date: Mon, 25 Jul 2016 01:31:05 +0300 Subject: [PATCH 0999/1223] [qa]: enable rpcbind_test Github-Pull: #8400 Rebased-From: 9bbb414b800cf71f93f15d2cb5d4cf32c72294e6 --- qa/pull-tester/rpc-tests.py | 2 +- qa/rpc-tests/rpcbind_test.py | 209 +++++++++++++++-------------------- 2 files changed, 88 insertions(+), 123 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 05fee5179..d3b4ebb8e 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -159,7 +159,7 @@ testScriptsExt = [ 'txn_clone.py --mineblock', 'forknotify.py', 'invalidateblock.py', -# 'rpcbind_test.py', #temporary, bug in libevent, see #6655 + 'rpcbind_test.py', 'smartfees.py', 'maxblocksinflight.py', 'p2p-acceptblock.py', diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 572273566..bf1cc8712 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -5,143 +5,108 @@ # Test for -rpcbind, as well as -rpcallowip and -rpcconnect -# TODO extend this test from the test framework (like all other tests) - import tempfile import traceback +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.netutil import * -def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected): - ''' - Start a node with requested rpcallowip and rpcbind parameters, - then try to connect, and check if the set of bound addresses - matches the expected set. - ''' - expected = [(addr_to_hex(addr), port) for (addr, port) in expected] - base_args = ['-disablewallet', '-nolisten'] - if allow_ips: - base_args += ['-rpcallowip=' + x for x in allow_ips] - binds = ['-rpcbind='+addr for addr in addresses] - nodes = start_nodes(self.num_nodes, tmpdir, [base_args + binds], connect_to) - try: - pid = bitcoind_processes[0].pid - assert_equal(set(get_bind_addrs(pid)), set(expected)) - finally: - stop_nodes(nodes) - wait_bitcoinds() +class RPCBindTest(BitcoinTestFramework): -def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport): - ''' - Start a node with rpcwallow IP, and request getinfo - at a non-localhost IP. - ''' - base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] - nodes = start_nodes(self.num_nodes, tmpdir, [base_args]) - try: - # connect to node through non-loopback interface - url = "http://rt:rt@%s:%d" % (rpchost, rpcport,) - node = get_rpc_proxy(url, 1) - node.getinfo() - finally: - node = None # make sure connection will be garbage collected and closed - stop_nodes(nodes) - wait_bitcoinds() + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 - -def run_test(tmpdir): - assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux - # find the first non-loopback interface for testing - non_loopback_ip = None - for name,ip in all_interfaces(): - if ip != '127.0.0.1': - non_loopback_ip = ip - break - if non_loopback_ip is None: - assert(not 'This test requires at least one non-loopback IPv4 interface') - print("Using interface %s for testing" % non_loopback_ip) - - defaultport = rpc_port(0) - - # check default without rpcallowip (IPv4 and IPv6 localhost) - run_bind_test(tmpdir, None, '127.0.0.1', [], - [('127.0.0.1', defaultport), ('::1', defaultport)]) - # check default with rpcallowip (IPv6 any) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', [], - [('::0', defaultport)]) - # check only IPv4 localhost (explicit) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1'], - [('127.0.0.1', defaultport)]) - # check only IPv4 localhost (explicit) with alternative port - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'], - [('127.0.0.1', 32171)]) - # check only IPv4 localhost (explicit) with multiple alternative ports on same host - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'], - [('127.0.0.1', 32171), ('127.0.0.1', 32172)]) - # check only IPv6 localhost (explicit) - run_bind_test(tmpdir, ['[::1]'], '[::1]', ['[::1]'], - [('::1', defaultport)]) - # check both IPv4 and IPv6 localhost (explicit) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'], - [('127.0.0.1', defaultport), ('::1', defaultport)]) - # check only non-loopback interface - run_bind_test(tmpdir, [non_loopback_ip], non_loopback_ip, [non_loopback_ip], - [(non_loopback_ip, defaultport)]) - - # Check that with invalid rpcallowip, we are denied - run_allowip_test(tmpdir, [non_loopback_ip], non_loopback_ip, defaultport) - try: - run_allowip_test(tmpdir, ['1.1.1.1'], non_loopback_ip, defaultport) - assert(not 'Connection not denied by rpcallowip as expected') - except ValueError: + def setup_network(self): pass -def main(): - import optparse + def setup_nodes(self): + pass - parser = optparse.OptionParser(usage="%prog [options]") - parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", - help="Leave bitcoinds and test.* datadir on exit or error") - parser.add_option("--srcdir", dest="srcdir", default="../../src", - help="Source directory containing bitcoind/bitcoin-cli (default: %default%)") - parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), - help="Root directory for datadirs") - (options, args) = parser.parse_args() + def run_bind_test(self, allow_ips, connect_to, addresses, expected): + ''' + Start a node with requested rpcallowip and rpcbind parameters, + then try to connect, and check if the set of bound addresses + matches the expected set. + ''' + expected = [(addr_to_hex(addr), port) for (addr, port) in expected] + base_args = ['-disablewallet', '-nolisten'] + if allow_ips: + base_args += ['-rpcallowip=' + x for x in allow_ips] + binds = ['-rpcbind='+addr for addr in addresses] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) + try: + pid = bitcoind_processes[0].pid + assert_equal(set(get_bind_addrs(pid)), set(expected)) + finally: + stop_nodes(self.nodes) + wait_bitcoinds() - os.environ['PATH'] = options.srcdir+":"+os.environ['PATH'] + def run_allowip_test(self, allow_ips, rpchost, rpcport): + ''' + Start a node with rpcwallow IP, and request getinfo + at a non-localhost IP. + ''' + base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) + try: + # connect to node through non-loopback interface + node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) + node.getinfo() + finally: + node = None # make sure connection will be garbage collected and closed + stop_nodes(self.nodes) + wait_bitcoinds() - check_json_precision() + def run_test(self): + # due to OS-specific network stats queries, this test works only on Linux + assert(sys.platform.startswith('linux')) + # find the first non-loopback interface for testing + non_loopback_ip = None + for name,ip in all_interfaces(): + if ip != '127.0.0.1': + non_loopback_ip = ip + break + if non_loopback_ip is None: + assert(not 'This test requires at least one non-loopback IPv4 interface') + print("Using interface %s for testing" % non_loopback_ip) - success = False - nodes = [] - try: - print("Initializing test directory "+options.tmpdir) - if not os.path.isdir(options.tmpdir): - os.makedirs(options.tmpdir) - initialize_chain(options.tmpdir) + defaultport = rpc_port(0) - run_test(options.tmpdir) + # check default without rpcallowip (IPv4 and IPv6 localhost) + self.run_bind_test(None, '127.0.0.1', [], + [('127.0.0.1', defaultport), ('::1', defaultport)]) + # check default with rpcallowip (IPv6 any) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', [], + [('::0', defaultport)]) + # check only IPv4 localhost (explicit) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1'], + [('127.0.0.1', defaultport)]) + # check only IPv4 localhost (explicit) with alternative port + self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'], + [('127.0.0.1', 32171)]) + # check only IPv4 localhost (explicit) with multiple alternative ports on same host + self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'], + [('127.0.0.1', 32171), ('127.0.0.1', 32172)]) + # check only IPv6 localhost (explicit) + self.run_bind_test(['[::1]'], '[::1]', ['[::1]'], + [('::1', defaultport)]) + # check both IPv4 and IPv6 localhost (explicit) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'], + [('127.0.0.1', defaultport), ('::1', defaultport)]) + # check only non-loopback interface + self.run_bind_test([non_loopback_ip], non_loopback_ip, [non_loopback_ip], + [(non_loopback_ip, defaultport)]) - success = True - - except AssertionError as e: - print("Assertion failed: "+e.message) - except Exception as e: - print("Unexpected exception caught during testing: "+str(e)) - traceback.print_tb(sys.exc_info()[2]) - - if not options.nocleanup: - print("Cleaning up") - wait_bitcoinds() - shutil.rmtree(options.tmpdir) - - if success: - print("Tests successful") - sys.exit(0) - else: - print("Failed") - sys.exit(1) + # Check that with invalid rpcallowip, we are denied + self.run_allowip_test([non_loopback_ip], non_loopback_ip, defaultport) + try: + self.run_allowip_test(['1.1.1.1'], non_loopback_ip, defaultport) + assert(not 'Connection not denied by rpcallowip as expected') + except JSONRPCException: + pass if __name__ == '__main__': - main() + RPCBindTest ().main () From a7aa3ccc4f6a80bc23a8f7a419d72d0f1a33dfe1 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 28 Jul 2016 14:27:19 -0400 Subject: [PATCH 1000/1223] Enable size accounting in mining unit tests Github-Pull: #8419 Rebased-From: 8bfd70817bf8b8b07b81660e47c88dd122b7423f --- src/test/miner_tests.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index fd581db52..15fceb963 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -181,9 +181,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { - // Disable size accounting (CPFP does not support it) - mapArgs["-blockmaxsize"] = strprintf("%u", MAX_BLOCK_SERIALIZED_SIZE); - + // Note that by default, these tests run with size accounting enabled. const CChainParams& chainparams = Params(CBaseChainParams::MAIN); CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; From 8bb1efd9859726e992e4bf21de19f954d2bb2ab0 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 31 Jul 2016 15:35:46 +0200 Subject: [PATCH 1001/1223] [qa] Rework hd wallet dump test Github-Pull: #8442 Rebased-From: fa4439d3554435bdf0ef47861835f10d41bcdc1a --- qa/rpc-tests/wallet-dump.py | 144 ++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 80 deletions(-) diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py index dd675f57f..6028d2c20 100755 --- a/qa/rpc-tests/wallet-dump.py +++ b/qa/rpc-tests/wallet-dump.py @@ -4,9 +4,52 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil +from test_framework.util import (start_nodes, start_node, assert_equal, bitcoind_processes) + + +def read_dump(file_name, addrs, hd_master_addr_old): + """ + Read the given dump, count the addrs that match, count change and reserve. + Also check that the old hd_master is inactive + """ + with open(file_name) as inputfile: + found_addr = 0 + found_addr_chg = 0 + found_addr_rsv = 0 + hd_master_addr_ret = None + for line in inputfile: + # only read non comment lines + if line[0] != "#" and len(line) > 10: + # split out some data + key_label, comment = line.split("#") + # key = key_label.split(" ")[0] + keytype = key_label.split(" ")[2] + if len(comment) > 1: + addr_keypath = comment.split(" addr=")[1] + addr = addr_keypath.split(" ")[0] + keypath = None + if keytype == "inactivehdmaster=1": + # ensure the old master is still available + assert(hd_master_addr_old == addr) + elif keytype == "hdmaster=1": + # ensure we have generated a new hd master key + assert(hd_master_addr_old != addr) + hd_master_addr_ret = addr + else: + keypath = addr_keypath.rstrip().split("hdkeypath=")[1] + + # count key types + for addrObj in addrs: + if addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label=": + found_addr += 1 + break + elif keytype == "change=1": + found_addr_chg += 1 + break + elif keytype == "reserve=1": + found_addr_rsv += 1 + break + return found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret class WalletDumpTest(BitcoinTestFramework): @@ -15,106 +58,47 @@ class WalletDumpTest(BitcoinTestFramework): super().__init__() self.setup_clean_chain = False self.num_nodes = 1 + self.extra_args = [["-keypool=90"]] def setup_network(self, split=False): - extra_args = [["-keypool=100"]] - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) def run_test (self): tmpdir = self.options.tmpdir - #generate 20 addresses to compare against the dump + # generate 20 addresses to compare against the dump test_addr_count = 20 addrs = [] for i in range(0,test_addr_count): addr = self.nodes[0].getnewaddress() vaddr= self.nodes[0].validateaddress(addr) #required to get hd keypath addrs.append(vaddr) + # Should be a no-op: + self.nodes[0].keypoolrefill() # dump unencrypted wallet self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.unencrypted.dump") - #open file - inputfile = open(tmpdir + "/node0/wallet.unencrypted.dump") - found_addr = 0 - found_addr_chg = 0 - found_addr_rsv = 0 - hdmasteraddr = "" - for line in inputfile: - #only read non comment lines - if line[0] != "#" and len(line) > 10: - #split out some data - keyLabel, comment = line.split("#") - key = keyLabel.split(" ")[0] - keytype = keyLabel.split(" ")[2] - if len(comment) > 1: - addrKeypath = comment.split(" addr=")[1] - addr = addrKeypath.split(" ")[0] - keypath = "" - if keytype != "hdmaster=1": - keypath = addrKeypath.rstrip().split("hdkeypath=")[1] - else: - #keep hd master for later comp. - hdmasteraddr = addr - - #count key types - for addrObj in addrs: - if (addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label="): - found_addr+=1 - break - elif (keytype == "change=1"): - found_addr_chg+=1 - break - elif (keytype == "reserve=1"): - found_addr_rsv+=1 - break - assert(found_addr == test_addr_count) #all keys must be in the dump - assert(found_addr_chg == 50) #50 blocks where mined - assert(found_addr_rsv == 100) #100 reserve keys (keypool) + found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc = \ + read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, None) + assert_equal(found_addr, test_addr_count) # all keys must be in the dump + assert_equal(found_addr_chg, 50) # 50 blocks where mined + assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one) #encrypt wallet, restart, unlock and dump self.nodes[0].encryptwallet('test') bitcoind_processes[0].wait() - self.nodes[0] = start_node(0, self.options.tmpdir) + self.nodes[0] = start_node(0, self.options.tmpdir, self.extra_args[0]) self.nodes[0].walletpassphrase('test', 10) + # Should be a no-op: + self.nodes[0].keypoolrefill() self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump") - #open dump done with an encrypted wallet - inputfile = open(tmpdir + "/node0/wallet.encrypted.dump") - found_addr = 0 - found_addr_chg = 0 - found_addr_rsv = 0 - for line in inputfile: - if line[0] != "#" and len(line) > 10: - keyLabel, comment = line.split("#") - key = keyLabel.split(" ")[0] - keytype = keyLabel.split(" ")[2] - if len(comment) > 1: - addrKeypath = comment.split(" addr=")[1] - addr = addrKeypath.split(" ")[0] - keypath = "" - if keytype != "hdmaster=1": - keypath = addrKeypath.rstrip().split("hdkeypath=")[1] - else: - #ensure we have generated a new hd master key - assert(hdmasteraddr != addr) - if keytype == "inactivehdmaster=1": - #ensure the old master is still available - assert(hdmasteraddr == addr) - for addrObj in addrs: - if (addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label="): - found_addr+=1 - break - elif (keytype == "change=1"): - found_addr_chg+=1 - break - elif (keytype == "reserve=1"): - found_addr_rsv+=1 - break - - assert(found_addr == test_addr_count) - assert(found_addr_chg == 150) #old reserve keys are marked as change now - assert(found_addr_rsv == 100) #keypool size + found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_enc = \ + read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, hd_master_addr_unenc) + assert_equal(found_addr, test_addr_count) + assert_equal(found_addr_chg, 90 + 1 + 50) # old reserve keys are marked as change now + assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one) if __name__ == '__main__': WalletDumpTest().main () From 9b0097976f4e593103cdf4594eb68de9bf9d60b3 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Fri, 29 Jul 2016 11:52:48 -0500 Subject: [PATCH 1002/1223] Update README.md Updating documentation for adding new unit test files Removing unneeded sentence from README Removing uint160_tests.cpp as it DNE Formatting command line instructions to use `` fixing 80 char formatting issue in README fixing more nits Github-Pull: #8428 Rebased-From: b8db185952c815444b7052092472ef9af3a42e89 --- src/test/README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/test/README.md b/src/test/README.md index b2d6be14f..61462642b 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -5,18 +5,15 @@ sense to simply use this framework rather than require developers to configure some other framework (we want as few impediments to creating unit tests as possible). -The build system is setup to compile an executable called "test_bitcoin" +The build system is setup to compile an executable called `test_bitcoin` that runs all of the unit tests. The main source file is called -test_bitcoin.cpp, which simply includes other files that contain the -actual unit tests (outside of a couple required preprocessor -directives). The pattern is to create one test file for each class or -source file for which you want to create unit tests. The file naming -convention is "_tests.cpp" and such files should wrap -their tests in a test suite called "_tests". For an -examples of this pattern, examine uint160_tests.cpp and -uint256_tests.cpp. - -Add the source files to /src/Makefile.test.include to add them to the build. +test_bitcoin.cpp. To add a new unit test file to our test suite you need +to add the file to `src/Makefile.test.include`. The pattern is to create +one test file for each class or source file for which you want to create +unit tests. The file naming convention is `_tests.cpp` +and such files should wrap their tests in a test suite +called `_tests`. For an example of this pattern, +examine `uint256_tests.cpp`. For further reading, I found the following website to be helpful in explaining how the boost unit test framework works: @@ -31,5 +28,5 @@ example, to run just the getarg_tests verbosely: test_bitcoin --run_test=getarg_tests/doubledash -Run test_bitcoin --help for the full list. +Run `test_bitcoin --help` for the full list. From 30eac2d79a05b4d7bcb708f59ff6b92c742c02f4 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 22 Jul 2016 15:57:25 +0200 Subject: [PATCH 1003/1223] Use a signal to continue init after genesis activation Github-Pull: #8392 Rebased-From: 0fd2a33648ccde4b989f1d69529daea4d88b14a2 --- src/init.cpp | 40 +++++++++++++++++++++++++++++---------- src/main.cpp | 2 -- src/test/test_bitcoin.cpp | 5 +++++ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 8d4a2cafb..4458c8331 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -510,6 +510,21 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex boost::thread t(runCommand, strCmd); // thread runs free } +static bool fHaveGenesis = false; +static boost::mutex cs_GenesisWait; +static CConditionVariable condvar_GenesisWait; + +static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex) +{ + if (pBlockIndex != NULL) { + { + boost::unique_lock lock_GenesisWait(cs_GenesisWait); + fHaveGenesis = true; + } + condvar_GenesisWait.notify_all(); + } +} + struct CImportingNow { CImportingNow() { @@ -1286,7 +1301,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } - if (!fReindex) { + if (!fReindex && chainActive.Tip() != NULL) { uiInterface.InitMessage(_("Rewinding blocks...")); if (!RewindBlockIndex(chainparams)) { strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain"); @@ -1403,6 +1418,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 10: import blocks + // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. + // No locking, as this happens before any background thread is started. + if (chainActive.Tip() == NULL) { + uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); + } else { + fHaveGenesis = true; + } + if (mapArgs.count("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); @@ -1412,19 +1435,16 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) vImportFiles.push_back(strFile); } + threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); // Wait for genesis block to be processed - bool fHaveGenesis = false; - while (!fHaveGenesis && !fRequestShutdown) { - { - LOCK(cs_main); - fHaveGenesis = (chainActive.Tip() != NULL); - } - - if (!fHaveGenesis) { - MilliSleep(10); + { + boost::unique_lock lock(cs_GenesisWait); + while (!fHaveGenesis) { + condvar_GenesisWait.wait(lock); } + uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait); } // ********************************************************* Step 11: start node diff --git a/src/main.cpp b/src/main.cpp index 01cd410da..3392a2075 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4339,8 +4339,6 @@ bool InitBlockIndex(const CChainParams& chainparams) CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("LoadBlockIndex(): genesis block not accepted"); - if (!ActivateBestChain(state, chainparams, &block)) - return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); } catch (const std::runtime_error& e) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 856f9b842..056f2982c 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -60,6 +60,11 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(chainparams); + { + CValidationState state; + bool ok = ActivateBestChain(state, chainparams); + BOOST_CHECK(ok); + } nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); From 3b354d213f99b89a1baf9a2c5895f172e4b351c3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 22 Jul 2016 16:01:12 +0200 Subject: [PATCH 1004/1223] Add extra message to avoid a long 'Loading banlist' Github-Pull: #8392 Rebased-From: aa59f2ed3f378c02159e41ff3ae2df76ef850577 --- src/net.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index eb2c38dd1..a15b0403b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2092,6 +2092,8 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) DumpBanlist(); } + uiInterface.InitMessage(_("Starting network threads...")); + fAddressesInitialized = true; if (semOutbound == NULL) { From fc349288cbcfe3df20d91cc16149b973eb14e272 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 22 Jul 2016 16:01:51 +0200 Subject: [PATCH 1005/1223] Do diskspace check before import thread is started Github-Pull: #8392 Rebased-From: 9d4eb9ad99f7c3abf7abaeaf7ea51f98f9445e75 --- src/init.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 4458c8331..44d8c16d9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1418,6 +1418,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 10: import blocks + if (!CheckDiskSpace()) + return false; + // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // No locking, as this happens before any background thread is started. if (chainActive.Tip() == NULL) { @@ -1449,9 +1452,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 11: start node - if (!CheckDiskSpace()) - return false; - if (!strErrors.str().empty()) return InitError(strErrors.str()); From 749c8a565532ee4480d8f3edd83ca08f437767a4 Mon Sep 17 00:00:00 2001 From: Justin Camarena Date: Fri, 12 Aug 2016 15:30:11 -0700 Subject: [PATCH 1006/1223] [doc] typos, READMEs, comments Just a quick run through some docs and fixing some text errors. Github-Pull: #8503 Rebased-From: e11f9a2f0244f1d6e34b50293b2ecca61a356bed --- doc/README_osx.md | 2 +- doc/release-notes.md | 2 +- doc/translation_process.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/README_osx.md b/doc/README_osx.md index aed3cd97e..6a5c67227 100644 --- a/doc/README_osx.md +++ b/doc/README_osx.md @@ -22,7 +22,7 @@ These tools inject timestamps by default, which produce non-deterministic binaries. The ZERO_AR_DATE environment variable is used to disable that. This version of cctools has been patched to use the current version of clang's -headers and and its libLTO.so rather than those from llvmgcc, as it was +headers and its libLTO.so rather than those from llvmgcc, as it was originally done in toolchain4. To complicate things further, all builds must target an Apple SDK. These SDKs diff --git a/doc/release-notes.md b/doc/release-notes.md index 019031aed..4478f872a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -28,7 +28,7 @@ libraries such as Qt are no longer being tested on XP. We do not have time nor resources to provide support for an OS that is end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are -suggested to upgrade to a newer verion of Windows, or install an alternative OS +suggested to upgrade to a newer version of Windows, or install an alternative OS that is supported. No attempt is made to prevent installing or running the software on Windows XP, diff --git a/doc/translation_process.md b/doc/translation_process.md index 361579a73..a443a16fe 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -94,7 +94,7 @@ When new plurals are added to the source file, it's important to do the followin 7. Save the source file ### Translating a new language -To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin_locale.qrc` and add a new entry. Below is an example of the english language entry. +To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin_locale.qrc` and add a new entry. Below is an example of the English language entry. ```xml From 8b0bdd392317851b47bb62e90e1f6d28b47427ec Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 9 Aug 2016 05:07:28 +0000 Subject: [PATCH 1007/1223] configure: Allow building bench_bitcoin by itself Github-Pull: #8492 Rebased-From: 216d796ce006df36427c03f0c209c48472d65bef --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 55578c886..4c7ef8b3a 100644 --- a/configure.ac +++ b/configure.ac @@ -1006,8 +1006,8 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then - AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests]) +if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) From fa5b2498cac2c3c036ea89d07284aa5095ed1ced Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 30 Jun 2016 01:51:09 +0000 Subject: [PATCH 1008/1223] Bugfix: Allow building libbitcoinconsensus without any univalue Github-Pull: #8293 Rebased-From: 8a270b25fc90495ce4b98b6d6e954fce92135dc1 --- configure.ac | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4c7ef8b3a..a545bc57b 100644 --- a/configure.ac +++ b/configure.ac @@ -836,6 +836,12 @@ fi dnl univalue check +need_bundled_univalue=yes + +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then + need_bundled_univalue=no +else + if test x$system_univalue != xno ; then found_univalue=no if test x$use_pkgconfig = xyes; then @@ -857,6 +863,7 @@ if test x$system_univalue != xno ; then if test x$found_univalue = xyes ; then system_univalue=yes + need_bundled_univalue=no elif test x$system_univalue = xyes ; then AC_MSG_ERROR([univalue not found]) else @@ -864,11 +871,14 @@ if test x$system_univalue != xno ; then fi fi -if test x$system_univalue = xno ; then +if test x$need_bundled_univalue = xyes ; then UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' UNIVALUE_LIBS='univalue/libunivalue.la' fi -AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$system_univalue = xno]) + +fi + +AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) @@ -1099,7 +1109,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" -if test x$system_univalue = xno; then +if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi From 156e305dc17b952dd869f76863d3ee70364c9234 Mon Sep 17 00:00:00 2001 From: Sev Date: Sun, 14 Aug 2016 15:35:27 +0300 Subject: [PATCH 1009/1223] Corrected JSON typo on setban of net.cpp Github-Pull: #8512 Rebased-From: 6ffd996b8ee5f36ed4490410385f9b072da5889b --- src/rpc/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index b85c7b2e1..89035aaa8 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -484,7 +484,7 @@ UniValue setban(const UniValue& params, bool fHelp) "\nExamples:\n" + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") - + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400") + + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400") ); CSubNet subNet; From 4e5fc31ae69076224c58dbe41bbd62497510de7d Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Sun, 14 Aug 2016 20:45:46 -0400 Subject: [PATCH 1010/1223] Fix a type error that would not compile on Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) Github-Pull: #8513 Rebased-From: 8194a6e525514d5cda85ac08273a6ffb6d5b6cac --- src/httpserver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/httpserver.h b/src/httpserver.h index 20a119cc5..42a142dde 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -35,7 +35,7 @@ void InterruptHTTPServer(); void StopHTTPServer(); /** Handler for requests to a certain HTTP path */ -typedef boost::function HTTPRequestHandler; +typedef boost::function HTTPRequestHandler; /** Register handler for prefix. * If multiple handlers match a prefix, the first-registered one will * be invoked. From befe654f0f6a4384f25bd8af317ef95919a0ece9 Mon Sep 17 00:00:00 2001 From: leijurv Date: Sat, 13 Aug 2016 11:21:13 -0600 Subject: [PATCH 1011/1223] various typos Github-Pull: #8505 Rebased-From: 1aacfc2da521a8e0d718e9ac561d9b2d7916eb0b --- src/blockencodings.cpp | 2 +- src/init.cpp | 2 +- src/main.cpp | 6 +++--- src/main.h | 2 +- src/net.cpp | 2 +- src/rpc/mining.cpp | 2 +- src/wallet/wallet.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 5c4c3bd27..df237f8f2 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -75,7 +75,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c } prefilled_count = cmpctblock.prefilledtxn.size(); - // Calculate map of txids -> positions and check mempool to see what we have (or dont) + // Calculate map of txids -> positions and check mempool to see what we have (or don't) // Because well-formed cmpctblock messages will have a (relatively) uniform distribution // of short IDs, any highly-uneven distribution of elements can be safely treated as a // READ_STATUS_FAILED. diff --git a/src/init.cpp b/src/init.cpp index 44d8c16d9..7f856e407 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1231,7 +1231,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache - nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache + nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; nBlockTreeDBCache = std::min(nBlockTreeDBCache, (GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20); nTotalCache -= nBlockTreeDBCache; diff --git a/src/main.cpp b/src/main.cpp index 3392a2075..45af5138c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1183,7 +1183,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // nSequence >= maxint-1 on all inputs. // // maxint-1 is picked to still allow use of nLockTime by - // non-replacable transactions. All inputs rather than just one + // non-replaceable transactions. All inputs rather than just one // is for the sake of multi-party protocols, where we don't // want a single party to be able to disable replacement. // @@ -1998,7 +1998,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // is safe because block merkle hashes are still computed and checked, // and any change will be caught at the next checkpoint. Of course, if // the checkpoint is for a chain that's invalid due to false scriptSigs - // this optimisation would allow an invalid chain to be accepted. + // this optimization would allow an invalid chain to be accepted. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -4829,7 +4829,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam { // If a peer is asking for old blocks, we're almost guaranteed // they wont have a useful mempool to match against a compact block, - // and we dont feel like constructing the object for them, so + // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. if (mi->second->nHeight >= chainActive.Height() - 10) { CBlockHeaderAndShortTxIDs cmpctblock(block); diff --git a/src/main.h b/src/main.h index 8cae9c953..0ca13d82d 100644 --- a/src/main.h +++ b/src/main.h @@ -215,7 +215,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! * - * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. + * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganization; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. diff --git a/src/net.cpp b/src/net.cpp index a15b0403b..fb85bedff 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1707,7 +1707,7 @@ void ThreadOpenConnections() if (nANow - addr.nLastTry < 600 && nTries < 30) continue; - // only consider nodes missing relevant services after 40 failed attemps + // only consider nodes missing relevant services after 40 failed attempts if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) continue; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 2479e5d59..6d88d4bec 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -650,7 +650,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here - // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks + // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 32a01d2db..2fea5ed39 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3140,7 +3140,7 @@ void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) const { mapKeyBirth[it->first] = it->second.nCreateTime; // map in which we'll infer heights of other keys - CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin + CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin std::map mapKeyFirstBlock; std::set setKeys; GetKeys(setKeys); From a27cdd8edf9083dd38cdb39b4067286ea20e15ea Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 17 Aug 2016 13:28:09 +0200 Subject: [PATCH 1012/1223] [qa] abandonconflict: Use assert_equal Github-Pull: #8531 Rebased-From: fa64306520156af1d1fe90e92f6cc22ffa097c02 --- qa/rpc-tests/abandonconflict.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index c50c3cc56..874df4877 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -68,7 +68,7 @@ class AbandonConflictTest(BitcoinTestFramework): # In mempool txs from self should increase balance from change newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("30") + Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("30") + Decimal("24.9996")) balance = newbalance # Restart the node with a higher min relay fee so the parent tx is no longer in mempool @@ -78,16 +78,16 @@ class AbandonConflictTest(BitcoinTestFramework): self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) # Verify txs no longer in mempool - assert(len(self.nodes[0].getrawmempool()) == 0) + assert_equal(len(self.nodes[0].getrawmempool()), 0) # Not in mempool txs from self should only reduce balance # inputs are still spent, but change not received newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("24.9996")) # Unconfirmed received funds that are not in mempool, also shouldn't show # up in unconfirmed balance unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance() - assert(unconfbalance == newbalance) + assert_equal(unconfbalance, newbalance) # Also shouldn't show up in listunspent assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)]) balance = newbalance @@ -96,35 +96,35 @@ class AbandonConflictTest(BitcoinTestFramework): # including that the child tx was also abandoned self.nodes[0].abandontransaction(txAB1) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance + Decimal("30")) + assert_equal(newbalance, balance + Decimal("30")) balance = newbalance # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned stop_node(self.nodes[0],0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]) - assert(len(self.nodes[0].getrawmempool()) == 0) - assert(self.nodes[0].getbalance() == balance) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + assert_equal(self.nodes[0].getbalance(), balance) # But if its received again then it is unabandoned # And since now in mempool, the change is available # But its child tx remains abandoned self.nodes[0].sendrawtransaction(signed["hex"]) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("20") + Decimal("14.99998")) + assert_equal(newbalance, balance - Decimal("20") + Decimal("14.99998")) balance = newbalance # Send child tx again so its unabandoned self.nodes[0].sendrawtransaction(signed2["hex"]) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) balance = newbalance # Remove using high relay fee again stop_node(self.nodes[0],0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) - assert(len(self.nodes[0].getrawmempool()) == 0) + assert_equal(len(self.nodes[0].getrawmempool()), 0) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("24.9996")) balance = newbalance # Create a double spend of AB1 by spending again from only A's 10 output @@ -143,7 +143,7 @@ class AbandonConflictTest(BitcoinTestFramework): # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted newbalance = self.nodes[0].getbalance() - assert(newbalance == balance + Decimal("20")) + assert_equal(newbalance, balance + Decimal("20")) balance = newbalance # There is currently a minor bug around this and so this test doesn't work. See Issue #7315 @@ -151,7 +151,7 @@ class AbandonConflictTest(BitcoinTestFramework): # Don't think C's should either self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) newbalance = self.nodes[0].getbalance() - #assert(newbalance == balance - Decimal("10")) + #assert_equal(newbalance, balance - Decimal("10")) print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer") print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315") print(str(balance) + " -> " + str(newbalance) + " ?") From b17a3f9e5af0a97a4d744bcbdac11fcb19de546c Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Thu, 4 Aug 2016 17:33:59 -0400 Subject: [PATCH 1013/1223] document return value of networkhashps for getmininginfo RPC endpoint Github-Pull: #8461 Rebased-From: 65f4532f13a89cacc4909072601d71ee7ebae5c5 --- src/rpc/mining.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 6d88d4bec..a26340f3e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -227,10 +227,11 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"currentblockweight\": nnn, (numeric) The last block weight\n" " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" - " \"errors\": \"...\" (string) Current errors\n" + " \"errors\": \"...\" (string) Current errors\n" + " \"networkhashps\": nnn, (numeric) The network hashes per second\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmininginfo", "") From 464dedd6ab496bb520cc8a5b1b69ca7ebdcdf815 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 1 Aug 2016 15:18:15 +0200 Subject: [PATCH 1014/1223] [Wallet] Trivial cleanup of HD wallet changes Github-Pull: #8443 Rebased-From: 7e5d94df1fb09ed7ee7ed50032f876972ef39489 --- src/wallet/wallet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2fea5ed39..12b83e54c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1199,7 +1199,7 @@ CPubKey CWallet::GenerateNewHDMasterKey() // write the key&metadata to the database if (!AddKeyPubKey(key, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + throw std::runtime_error(std::string(__func__)+": AddKeyPubKey failed"); } return pubkey; @@ -3331,7 +3331,6 @@ bool CWallet::InitLoadWallet() // Create new keyUser and set as default key if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { // generate a new master key - CKey key; CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); if (!walletInstance->SetHDMasterKey(masterPubKey)) throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); From 305d8ac90b5c1301ec243024a5c68880f7a27ccc Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 19 Aug 2016 18:31:35 +0200 Subject: [PATCH 1015/1223] Use __func__ to get function name for output printing Github-Pull: #8548 Rebased-From: fa785d121152c652d0704ac32ce8611262e609d2 --- src/main.cpp | 2 +- src/primitives/transaction.cpp | 2 +- src/wallet/wallet.cpp | 34 +++++++++++++++++----------------- src/wallet/walletdb.cpp | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 45af5138c..8d8fb1502 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3962,7 +3962,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); + throw runtime_error(std::string(__func__) + ": new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 8d6380564..2fdc59ea0 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -100,7 +100,7 @@ CAmount CTransaction::GetValueOut() const { nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) - throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nValueOut; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 12b83e54c..6ce8d19bf 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -108,7 +108,7 @@ CPubKey CWallet::GenerateNewKey() // try to get the master key if (!GetKey(hdChain.masterKeyID, key)) - throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); + throw std::runtime_error(std::string(__func__) + ": Master key not found"); masterKey.SetMaster(key.begin(), key.size()); @@ -135,7 +135,7 @@ CPubKey CWallet::GenerateNewKey() // update the chain model in the database if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) - throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); + throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed"); } else { secret.MakeNewKey(fCompressed); } @@ -152,7 +152,7 @@ CPubKey CWallet::GenerateNewKey() nTimeFirstKey = nCreationTime; if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + throw std::runtime_error(std::string(__func__) + ": AddKey failed"); return pubkey; } @@ -1093,7 +1093,7 @@ isminetype CWallet::IsMine(const CTxOut& txout) const CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return ((IsMine(txout) & filter) ? txout.nValue : 0); } @@ -1122,7 +1122,7 @@ bool CWallet::IsChange(const CTxOut& txout) const CAmount CWallet::GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return (IsChange(txout) ? txout.nValue : 0); } @@ -1146,7 +1146,7 @@ CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) co { nDebit += GetDebit(txin, filter); if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nDebit; } @@ -1158,7 +1158,7 @@ CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) c { nCredit += GetCredit(txout, filter); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nCredit; } @@ -1170,7 +1170,7 @@ CAmount CWallet::GetChange(const CTransaction& tx) const { nChange += GetChange(txout); if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nChange; } @@ -1199,7 +1199,7 @@ CPubKey CWallet::GenerateNewHDMasterKey() // write the key&metadata to the database if (!AddKeyPubKey(key, pubkey)) - throw std::runtime_error(std::string(__func__)+": AddKeyPubKey failed"); + throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed"); } return pubkey; @@ -1226,7 +1226,7 @@ bool CWallet::SetHDChain(const CHDChain& chain, bool memonly) { LOCK(cs_wallet); if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain)) - throw runtime_error("AddHDChain(): writing chain failed"); + throw runtime_error(std::string(__func__) + ": writing chain failed"); hdChain = chain; return true; @@ -2714,7 +2714,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("TopUpKeyPool(): writing generated key failed"); + throw runtime_error(std::string(__func__) + ": writing generated key failed"); setKeyPool.insert(nEnd); LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); } @@ -2741,9 +2741,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); LogPrintf("keypool reserve %d\n", nIndex); } @@ -2802,7 +2802,7 @@ int64_t CWallet::GetOldestKeyPoolTime() CWalletDB walletdb(strWalletFile); int64_t nIndex = *(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("GetOldestKeyPoolTime(): read oldest key in keypool failed"); + throw runtime_error(std::string(__func__) + ": read oldest key in keypool failed"); assert(keypool.vchPubKey.IsValid()); return keypool.nTime; } @@ -3029,11 +3029,11 @@ void CWallet::GetAllReserveKeys(set& setAddress) const { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) - throw runtime_error("GetAllReserveKeyHashes(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); assert(keypool.vchPubKey.IsValid()); CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) - throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); setAddress.insert(keyID); } } @@ -3333,7 +3333,7 @@ bool CWallet::InitLoadWallet() // generate a new master key CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); if (!walletInstance->SetHDMasterKey(masterPubKey)) - throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); + throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 72af8ab7b..31aec0f9e 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -215,7 +215,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, listclose(); - throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB"); + throw runtime_error(std::string(__func__) + ": error scanning DB"); } // Unserialize From 75d548475dcf74fc0e69c4e5a4a6a0c213950cde Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 22 Aug 2016 09:24:50 +0200 Subject: [PATCH 1016/1223] Add copyright header to wallet_text_fixture.cpp I created the file but forgot to add this header. Github-Pull: #8558 Rebased-From: 653bb3d64057f11c5c9a8f539ba57be549097cee --- src/wallet/test/wallet_test_fixture.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 9036ee26d..a76db3761 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "wallet/test/wallet_test_fixture.h" #include "rpc/server.h" From cb07f19e90951fc47604a12b500514ff08742c31 Mon Sep 17 00:00:00 2001 From: crowning- Date: Thu, 18 Aug 2016 16:52:38 +0200 Subject: [PATCH 1017/1223] CDB: fix debug output It doesn't really help to clear a variable before printing it to the debug log. Github-Pull: #8539 Rebased-From: fab2e26d2033ca3c7a24f6a0ad6529fceda52ebc --- src/wallet/db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index c906785e9..cfd007ca1 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -284,7 +284,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose pdb = NULL; --bitdb.mapFileUseCount[strFile]; strFile = ""; - throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile)); + throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); } if (fCreate && !Exists(string("version"))) { From c493f436218b473e11eac3786222b53430ef592b Mon Sep 17 00:00:00 2001 From: Christian Barcenas Date: Mon, 22 Aug 2016 20:49:36 -0400 Subject: [PATCH 1018/1223] Trivial: Fix two VarInt examples in serialize.h Github-Pull: #8560 Rebased-From: 7bd5ff46237b06b3cf223176c1c71ef66383fa92 --- src/serialize.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index 378ed3907..04ab9aa2e 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -322,8 +322,8 @@ uint64_t ReadCompactSize(Stream& is) * 0: [0x00] 256: [0x81 0x00] * 1: [0x01] 16383: [0xFE 0x7F] * 127: [0x7F] 16384: [0xFF 0x00] - * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] - * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] + * 128: [0x80 0x00] 16511: [0xFF 0x7F] + * 255: [0x80 0x7F] 65535: [0x82 0xFE 0x7F] * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] */ From 863ae74a1fdc11aec2e94167b30c1d7f7b6fd1e7 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 13 Jun 2016 12:10:46 +0200 Subject: [PATCH 1019/1223] [doc] Update git-subtree-check.sh README Github-Pull: #8545 Rebased-From: fa3d9740099c8513f9942983f135f58890e62cb5 --- contrib/devtools/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index bb8b9246b..af5c000b0 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -51,8 +51,9 @@ maintained: * for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master) * for `src/leveldb`: https://github.com/bitcoin-core/leveldb.git (branch bitcoin-fork) * for `src/univalue`: https://github.com/bitcoin-core/univalue.git (branch master) +* for `src/crypto/ctaes`: https://github.com/bitcoin-core/ctaes.git (branch master) -Usage: `git-subtree-check.sh DIR COMMIT` +Usage: `git-subtree-check.sh DIR (COMMIT)` `COMMIT` may be omitted, in which case `HEAD` is used. From 4f84082a74fcddda425344cb3444418856ea75e4 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 24 Aug 2016 09:06:56 +0200 Subject: [PATCH 1020/1223] Set jonasschnellis dns-seeder filter flag Github-Pull: #8573 Rebased-From: 40a95cfd8f21bedbf35016b920f26c19bfb25c69 --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 86bef1e10..0cb0fccd1 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -119,7 +119,7 @@ public: vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik - vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch")); // Jonas Schnelli + vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); From 9556745dc2f3bda3a91be799fd4d92ba50ed3c95 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 3 May 2016 18:02:46 +0200 Subject: [PATCH 1021/1223] init: Fix typo in help message for -whitelistforcerelay Reported by pryds on Transifex in the Danish translation. Github-Pull: #8607 Rebased-From: 67a55025a1ea5d0461139cd6764686a77524feed --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 7f856e407..9b6eca2e1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -379,7 +379,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); - strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); + strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET From c18a9ca7886ada5dfc43787631c578a32f7dc5bf Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 29 Jun 2016 11:53:07 +0200 Subject: [PATCH 1022/1223] [qa] pull-tester: Don't mute zmq ImportError Github-Pull: #8607 Rebased-From: fabfd5dae28cbe26e71d50dbfb6feab03673f27a --- qa/pull-tester/rpc-tests.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index d3b4ebb8e..634d67589 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -94,12 +94,12 @@ if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): if ENABLE_ZMQ: try: import zmq - except ImportError as e: - print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ - "to run zmq tests, see dependency info in /qa/README.md.") - ENABLE_ZMQ=0 + except ImportError: + print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " + "to run zmq tests, see dependency info in /qa/README.md.") + # ENABLE_ZMQ=0 + raise -#Tests testScripts = [ # longest test should go first, to favor running tests in parallel 'p2p-fullblocktest.py', From 486650ae6a8ab44c0ac4f8a935b51629c04c1282 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 29 Jun 2016 11:48:51 +0200 Subject: [PATCH 1023/1223] [doc] Fix typos in comments, doxygen: Fix comment syntax Github-Pull: #8607 Rebased-From: fa27c0a2c4545a579bf339e816c3fa785252b7dc --- src/chain.h | 10 +++---- src/consensus/validation.h | 6 ++-- src/rpc/protocol.h | 54 ++++++++++++++++++------------------ src/script/sign.h | 2 +- src/zmq/zmqpublishnotifier.h | 2 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/chain.h b/src/chain.h index 76a774c12..6588e8f57 100644 --- a/src/chain.h +++ b/src/chain.h @@ -137,15 +137,15 @@ enum BlockStatus: uint32_t { BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, - BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat - BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat + BLOCK_HAVE_DATA = 8, //!< full block available in blk*.dat + BLOCK_HAVE_UNDO = 16, //!< undo data available in rev*.dat BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, - BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed - BLOCK_FAILED_CHILD = 64, //! descends from failed block + BLOCK_FAILED_VALID = 32, //!< stage after last reached validness failed + BLOCK_FAILED_CHILD = 64, //!< descends from failed block BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, - BLOCK_OPT_WITNESS = 128, //! block data in blk*.data was received with a witness-enforcing client + BLOCK_OPT_WITNESS = 128, //!< block data in blk*.data was received with a witness-enforcing client }; /** The block chain is a tree shaped structure starting with the diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 000b19727..3e24294a6 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -22,9 +22,9 @@ static const unsigned char REJECT_CHECKPOINT = 0x43; class CValidationState { private: enum mode_state { - MODE_VALID, //! everything ok - MODE_INVALID, //! network rule violation (DoS value may be set) - MODE_ERROR, //! run-time error + MODE_VALID, //!< everything ok + MODE_INVALID, //!< network rule violation (DoS value may be set) + MODE_ERROR, //!< run-time error } mode; int nDoS; std::string strRejectReason; diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 55d0aac68..988e0fc5f 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -38,18 +38,18 @@ enum RPCErrorCode RPC_PARSE_ERROR = -32700, //! General application defined errors - RPC_MISC_ERROR = -1, //! std::exception thrown in command handling - RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode - RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter - RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key - RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation - RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter - RPC_DATABASE_ERROR = -20, //! Database error - RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format - RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission - RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules - RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain - RPC_IN_WARMUP = -28, //! Client still warming up + RPC_MISC_ERROR = -1, //!< std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, //!< Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, //!< Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, //!< Invalid address or key + RPC_OUT_OF_MEMORY = -7, //!< Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, //!< Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, //!< Database error + RPC_DESERIALIZATION_ERROR = -22, //!< Error parsing or validating structure in raw format + RPC_VERIFY_ERROR = -25, //!< General error during transaction or block submission + RPC_VERIFY_REJECTED = -26, //!< Transaction or block was rejected by network rules + RPC_VERIFY_ALREADY_IN_CHAIN = -27, //!< Transaction already in chain + RPC_IN_WARMUP = -28, //!< Client still warming up //! Aliases for backward compatibility RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR, @@ -57,23 +57,23 @@ enum RPCErrorCode RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN, //! P2P client errors - RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected - RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks - RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added - RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before - RPC_CLIENT_NODE_NOT_CONNECTED = -29, //! Node to disconnect not found in connected nodes - RPC_CLIENT_INVALID_IP_OR_SUBNET = -30, //! Invalid IP/Subnet + RPC_CLIENT_NOT_CONNECTED = -9, //!< Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //!< Still downloading initial blocks + RPC_CLIENT_NODE_ALREADY_ADDED = -23, //!< Node is already added + RPC_CLIENT_NODE_NOT_ADDED = -24, //!< Node has not been added before + RPC_CLIENT_NODE_NOT_CONNECTED = -29, //!< Node to disconnect not found in connected nodes + RPC_CLIENT_INVALID_IP_OR_SUBNET = -30, //!< Invalid IP/Subnet //! Wallet errors - RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.) - RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name - RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first - RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first - RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect - RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) - RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet - RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked + RPC_WALLET_ERROR = -4, //!< Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, //!< Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //!< Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, //!< Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, //!< Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, //!< The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, //!< Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, //!< Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, //!< Wallet is already unlocked }; std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); diff --git a/src/script/sign.h b/src/script/sign.h index 6404b4523..f9aa6fca2 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -51,7 +51,7 @@ public: MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {} }; -/** A signature creator that just produces 72-byte empty signatyres. */ +/** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 22f02a3d0..751ded395 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -12,7 +12,7 @@ class CBlockIndex; class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { private: - uint32_t nSequence; //! upcounting per message sequence number + uint32_t nSequence; //!< upcounting per message sequence number public: From 752fbae697db0a255999695e83d163f21d2ebc15 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 1 Jul 2016 12:39:04 +0200 Subject: [PATCH 1024/1223] contrib: Make fix-copyright-headers.py more portable Github-Pull: #8607 Rebased-From: fafe7b3432d5117e3f207eafe2fca1f9637b24f6 --- contrib/devtools/fix-copyright-headers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index b6414a551..31a81ae4f 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -16,7 +16,7 @@ import time import re year = time.gmtime()[0] -CMD_GIT_DATE = 'git log --format=@%%at -1 %s | date +"%%Y" -u -f -' +CMD_GIT_DATE = 'git log --format=%%ad --date=short -1 %s | cut -d"-" -f 1' CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s" REGEX_CURRENT= re.compile("%s The Bitcoin" % year) CMD_LIST_FILES= "find %s | grep %s" From 0a35573534ee81d98d7389a1fc8c6f1c5856f07e Mon Sep 17 00:00:00 2001 From: isle2983 Date: Mon, 29 Aug 2016 21:01:38 -0600 Subject: [PATCH 1025/1223] [doc] - clarify statement about parallel jobs in rpc-tests.py Github-Pull: #8625 Rebased-From: 14675610245e951f2b922a0eaad6eb7d011ae87e --- qa/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/README.md b/qa/README.md index 723660c6c..225207cc1 100644 --- a/qa/README.md +++ b/qa/README.md @@ -41,8 +41,8 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended -By default, tests will be run in parallel if you want to specify how many -tests should be run in parallel, append `-parallel=n` (default n=4). +By default, tests will be run in parallel. To specify how many jobs to run, +append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. From ea51b0f5ddd705dd955eb5220253c6e325279609 Mon Sep 17 00:00:00 2001 From: Alexey Vesnin Date: Tue, 30 Aug 2016 09:00:55 +0300 Subject: [PATCH 1026/1223] Berkeley DB v6 compatibility fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes building error looking like this: CXX wallet/libbitcoin_wallet_a-db.o wallet/db.cpp: In member function ‘void CDBEnv::EnvShutdown()’: wallet/db.cpp:46:16: error: call of overloaded ‘DbEnv(int)’ is ambiguous DbEnv(0).remove(strPath.c_str(), 0); ^ wallet/db.cpp:46:16: note: candidates are: In file included from wallet/db.h:21:0, from wallet/db.cpp:6: /usr/include/db_cxx.h:916:2: note: DbEnv::DbEnv(const DbEnv&) DbEnv(const DbEnv &); ^ /usr/include/db_cxx.h:518:2: note: DbEnv::DbEnv(DB_ENV) DbEnv(DB_ENV *dbenv); ^ /usr/include/db_cxx.h:516:2: note: DbEnv::DbEnv(u_int32_t) DbEnv(u_int32_t flags); ^ Makefile:5780: recipe for target 'wallet/libbitcoin_wallet_a-db.o' failed make[2]: ** [wallet/libbitcoin_wallet_a-db.o] Error 1 Github-Pull: #8626 Rebased-From: 323a5fe06af43d3922a435e696d6c52acc6fade1 --- src/wallet/db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index cfd007ca1..236c1d324 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -43,7 +43,7 @@ void CDBEnv::EnvShutdown() if (ret != 0) LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) - DbEnv(0).remove(strPath.c_str(), 0); + DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); } void CDBEnv::Reset() From 42ea51a65fdacc9a0bf687474bc3839b854c726f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 15 Sep 2016 23:32:45 +0200 Subject: [PATCH 1027/1223] net: No longer send local address in addrMe After #8594 the addrFrom sent by a node is not used anymore at all, so don't bother sending it. Also mitigates the privacy issue in (#8616). It doesn't completely solve the issue as GetLocalAddress is also called in AdvertiseLocal, but at least when advertising addresses it stands out less as *our* address. Github-Pull: #8740 Rebased-From: d9c99c3058c90f4f7075cf5c495b8dcd2e7519a7 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index fb85bedff..a0ab544f5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -499,7 +499,7 @@ void CNode::PushVersion() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0), addr.nServices)); - CAddress addrMe = GetLocalAddress(&addr); + CAddress addrMe = CAddress(CService(), nLocalServices); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); From da94272e3c3f344660c274b41cbff2f402b5ae0c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 14 Sep 2016 16:28:50 +0200 Subject: [PATCH 1028/1223] [qa] walletbackup: Sync blocks inside the loop Github-Pull: #8724 Rebased-From: fad41f308f5e0e0650e3eed96c8c8575b3f7c33e --- qa/rpc-tests/walletbackup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index b991d5c76..e12cb10a5 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -45,12 +45,12 @@ class WalletBackupTest(BitcoinTestFramework): super().__init__() self.setup_clean_chain = True self.num_nodes = 4 + # nodes 1, 2,3 are spenders, let's give them a keypool=100 + self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] # This mirrors how the network was setup in the bash test def setup_network(self, split=False): - # nodes 1, 2,3 are spenders, let's give them a keypool=100 - extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) connect_nodes(self.nodes[0], 3) connect_nodes(self.nodes[1], 3) connect_nodes(self.nodes[2], 3) @@ -79,6 +79,7 @@ class WalletBackupTest(BitcoinTestFramework): # Must sync mempools before mining. sync_mempools(self.nodes) self.nodes[3].generate(1) + sync_blocks(self.nodes) # As above, this mirrors the original bash test. def start_three(self): From 0e2c6bdf78d5ddb374061f5b6b5c62a15ee53940 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sun, 18 Sep 2016 19:53:02 +0800 Subject: [PATCH 1029/1223] [Doc] Target protobuf 2.6 in OS X build notes. Homebrew now installs Protobuf version 3 by default, which doesn't currently compile. Install Protobuf 2.6.x from the versions tap instead. Github-Pull: #8754 Rebased-From: b16a7f609fdb2efa9a8a1b82f09748b95b5ae4f6 --- doc/build-osx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index c9eb4225a..bc90a3056 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -16,7 +16,7 @@ Then install [Homebrew](http://brew.sh). Dependencies ---------------------- - brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent + brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config homebrew/versions/protobuf260 --c++11 qt5 libevent NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended. From 5e15fce30c7b406c1ace6f5f6df5c24b8050a8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98yvind=20Urke-S=C3=A6tre?= Date: Wed, 14 Sep 2016 13:05:18 +0200 Subject: [PATCH 1030/1223] Minor change in section name Changed 'build' to 'create', as the section name have changed in newer versions of release-process.md Github-Pull: #8720 Rebased-From: dad932c241a3fe9ef8e4dc36596381666ab4f879 --- doc/gitian-building.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 938f92ff1..84dce3f08 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -337,7 +337,7 @@ Getting and building the inputs -------------------------------- Follow the instructions in [doc/release-process.md](release-process.md#fetch-and-build-inputs-first-time-or-when-dependency-versions-change) -in the bitcoin repository under 'Fetch and build inputs' to install sources which require +in the bitcoin repository under 'Fetch and create inputs' to install sources which require manual intervention. Also optionally follow the next step: 'Seed the Gitian sources cache and offline git repositories' which will fetch the remaining files required for building offline. From d31ac725cfab15d086362124c3c18f5bcccebca7 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 16 Sep 2016 11:45:08 +0800 Subject: [PATCH 1031/1223] Specify Protobuf version 2 in paymentrequest.proto Github-Pull: #8742 Rebased-From: c4084c208509c42f796ebaa3eaded5f1cd40c506 --- src/qt/paymentrequest.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto index b2281c4c7..d2721a34b 100644 --- a/src/qt/paymentrequest.proto +++ b/src/qt/paymentrequest.proto @@ -6,6 +6,8 @@ // https://en.bitcoin.it/wiki/Payment_Request // +syntax = "proto2"; + package payments; option java_package = "org.bitcoin.protocols.payments"; option java_outer_classname = "Protos"; From e34374e252b2545eb510d26b752c5d00bba1f2f6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 13 Sep 2016 22:00:55 +0200 Subject: [PATCH 1032/1223] [qa] wallet: Check legacy wallet as well Github-Pull: #8716 Rebased-From: fa644d0053ca40740b9e7b8982ff6c5d5640e4af --- qa/rpc-tests/wallet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 5d96e7a6e..3420be1a2 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -18,9 +18,10 @@ class WalletTest (BitcoinTestFramework): super().__init__() self.setup_clean_chain = True self.num_nodes = 4 + self.extra_args = [['-usehd={:d}'.format(i%2==0)] for i in range(4)] def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(3, self.options.tmpdir, self.extra_args[:3]) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) @@ -154,7 +155,7 @@ class WalletTest (BitcoinTestFramework): txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) sync_mempools(self.nodes) - self.nodes.append(start_node(3, self.options.tmpdir)) + self.nodes.append(start_node(3, self.options.tmpdir, self.extra_args[3])) connect_nodes_bi(self.nodes, 0, 3) sync_blocks(self.nodes) From 084cae9ca57a263d7b768b2854614bc9a2c26a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 15 Sep 2016 12:40:09 +0200 Subject: [PATCH 1033/1223] UndoReadFromDisk works on undo files (rev), not on block files. Github-Pull: #8737 Rebased-From: b4fb51271905f9ef39e5c2bc7e8c15e7489394a1 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8d8fb1502..82f9e147e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2073,7 +2073,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin // Open history file to read CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("%s: OpenBlockFile failed", __func__); + return error("%s: OpenUndoFile failed", __func__); // Read block uint256 hashChecksum; From 9a903f9f003d743242d4ac41b4a4045559f1ff4c Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 11 Sep 2016 15:26:53 -0600 Subject: [PATCH 1034/1223] [copyright] add MIT License copyright header to zmq_sub.py Github-Pull: #8701 Rebased-From: 37a7fe9e440b83e2364d5498931253937abe9294 --- contrib/zmq/zmq_sub.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 6268123dd..3dea5e3c1 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,4 +1,7 @@ #!/usr/bin/env python2 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import array import binascii From ea2a6bef858049a5fc47a1f67bbfc8ab78d7348d Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 11 Sep 2016 15:32:22 -0600 Subject: [PATCH 1035/1223] [copyright] add MIT License copyright header to remaining Python files Github-Pull: #8702 Rebased-From: 4677b197f7aa8d35bfc20a5961c3e1c41bb7de39 --- contrib/devtools/security-check.py | 3 +++ contrib/devtools/test-security-check.py | 3 +++ share/qt/extract_strings_qt.py | 3 +++ 3 files changed, 9 insertions(+) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 301fea85c..d774b7fea 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,4 +1,7 @@ #!/usr/bin/python2 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Perform basic ELF security checks on a series of executables. Exit status will be 0 if successful, and the program will be silent. diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index fed7626aa..58817089c 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,4 +1,7 @@ #!/usr/bin/python2 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Test script for security-check.py ''' diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 2ba8bb9b3..f0f6a4f47 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -1,4 +1,7 @@ #!/usr/bin/python +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Extract _("...") strings for translation and convert to Qt stringdefs so that they can be picked up by Qt linguist. From a60d7cc97d5f91b4157bdc8af0451f44149436fd Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 11 Sep 2016 15:25:51 -0600 Subject: [PATCH 1036/1223] [copyright] Add missing copyright headers Github-Pull: #8676 Rebased-From: 783e930e68a312bc7654d833053cceead18dd688 --- contrib/devtools/optimize-pngs.py | 3 +++ contrib/qt_translations.py | 3 +++ contrib/seeds/makeseeds.py | 3 +++ contrib/spendfrom/setup.py | 3 +++ contrib/spendfrom/spendfrom.py | 3 +++ contrib/testgen/base58.py | 3 +++ contrib/testgen/gen_base58_test_vectors.py | 3 +++ qa/rpc-tests/test_framework/blockstore.py | 3 +++ 8 files changed, 24 insertions(+) diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py index 799e0cc7d..b7b8dc008 100755 --- a/contrib/devtools/optimize-pngs.py +++ b/contrib/devtools/optimize-pngs.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Run this script every time you change one of the png files. Using pngcrush, it will optimize the png files, remove various color profiles, remove ancillary chunks (alla) and text chunks (text). #pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text diff --git a/contrib/qt_translations.py b/contrib/qt_translations.py index fd8a8b712..cfdeed41a 100755 --- a/contrib/qt_translations.py +++ b/contrib/qt_translations.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2011 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # Helpful little script that spits out a comma-separated list of # language codes for Qt icons that should be included diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 4072405ef..041f224f4 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2013-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # # Generate seeds.txt from Pieter's DNS seeder # diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py index 01b9768a5..f80736752 100644 --- a/contrib/spendfrom/setup.py +++ b/contrib/spendfrom/setup.py @@ -1,3 +1,6 @@ +# Copyright (c) 2013 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. from distutils.core import setup setup(name='btcspendfrom', version='1.0', diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py index 72ee0425e..086b91b26 100755 --- a/contrib/spendfrom/spendfrom.py +++ b/contrib/spendfrom/spendfrom.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2013 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # # Use the raw transactions API to spend bitcoins received on particular addresses, # and send any change back to that same address. diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py index b71649514..72b288b2d 100644 --- a/contrib/testgen/base58.py +++ b/contrib/testgen/base58.py @@ -1,3 +1,6 @@ +# Copyright (c) 2012 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Bitcoin base58 encoding and decoding. diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py index 181343695..8518774db 100755 --- a/contrib/testgen/gen_base58_test_vectors.py +++ b/contrib/testgen/gen_base58_test_vectors.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2012 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Generate valid and invalid base58 address and private key test vectors. diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 6120dd574..1e2bbb277 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # BlockStore: a helper class that keeps a map of blocks and implements # helper functions for responding to getheaders and getdata, # and for constructing a getheaders message From 702fd2ee21c17bfbc56d2fe6d3fad982fb8412a0 Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sun, 11 Sep 2016 13:36:22 -0600 Subject: [PATCH 1037/1223] [copyright] add MIT license headers to .sh scripts where missing Years are set according to 'git log' history Github-Pull: #8700 Rebased-From: 0766d1cac38d7ea27a6323d7ca206154b2686f9b --- contrib/devtools/git-subtree-check.sh | 3 +++ contrib/macdeploy/detached-sig-apply.sh | 4 ++++ contrib/macdeploy/detached-sig-create.sh | 4 ++++ contrib/qos/tc.sh | 4 ++++ contrib/tidy_datadir.sh | 3 +++ contrib/verify-commits/gpg.sh | 4 ++++ contrib/verify-commits/pre-push-hook.sh | 4 ++++ contrib/verify-commits/verify-commits.sh | 4 ++++ contrib/verifybinaries/verify.sh | 3 +++ src/qt/res/movies/makespinner.sh | 4 ++++ 10 files changed, 37 insertions(+) diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh index 1cb82fe68..2384d66ca 100755 --- a/contrib/devtools/git-subtree-check.sh +++ b/contrib/devtools/git-subtree-check.sh @@ -1,4 +1,7 @@ #!/bin/sh +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. DIR="$1" COMMIT="$2" diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh index 781fe315e..91674a92e 100755 --- a/contrib/macdeploy/detached-sig-apply.sh +++ b/contrib/macdeploy/detached-sig-apply.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + set -e UNSIGNED="$1" diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index 89a2da32f..5022ea88b 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + set -e ROOTDIR=dist diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh index f62060421..aaf5e1fa1 100644 --- a/contrib/qos/tc.sh +++ b/contrib/qos/tc.sh @@ -1,3 +1,7 @@ +# Copyright (c) 2013 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + #network interface on which to limit traffic IF="eth0" #limit of the network interface in question diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh index 5d6d82644..8960f8811 100755 --- a/contrib/tidy_datadir.sh +++ b/contrib/tidy_datadir.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Copyright (c) 2013 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. if [ -d "$1" ]; then cd "$1" diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 375d71172..09ff23754 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + INPUT=$(cat /dev/stdin) VALID=false REVSIG=false diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh index c57222818..c21febb9e 100755 --- a/contrib/verify-commits/pre-push-hook.sh +++ b/contrib/verify-commits/pre-push-hook.sh @@ -1,4 +1,8 @@ #!/bin/bash +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + if ! [[ "$2" =~ ^(git@)?(www.)?github.com(:|/)bitcoin/bitcoin(.git)?$ ]]; then exit 0 fi diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 5219331e2..cfe4f11a0 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + # Not technically POSIX-compliant due to use of "local", but almost every # shell anyone uses today supports it, so its probably fine diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh index 657c3bd33..6b6b28184 100755 --- a/contrib/verifybinaries/verify.sh +++ b/contrib/verifybinaries/verify.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org ### It first checks if the signature passes, and then downloads the files specified in diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh index a4c2fddbb..d0deb1238 100755 --- a/src/qt/res/movies/makespinner.sh +++ b/src/qt/res/movies/makespinner.sh @@ -1,3 +1,7 @@ +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + FRAMEDIR=$(dirname $0) for i in {0..35} do From b70b4a24e645e4602df310263390964ceda64a8f Mon Sep 17 00:00:00 2001 From: Marty Jones Date: Mon, 19 Sep 2016 21:17:27 -0500 Subject: [PATCH 1038/1223] Trivial: Fix typo Github-Pull: #8762 Rebased-From: 12a721b45e16124f48ea85f96079feec18e948ca --- doc/translation_process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/translation_process.md b/doc/translation_process.md index a443a16fe..9e9ced245 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -6,7 +6,7 @@ The Bitcoin-Core project has been designed to support multiple localisations. Th ### Helping to translate (using Transifex) Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface. -Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated. +Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated. See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below. From 1672225670cd34e21e397968433d47e6997f9a5f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 16 Aug 2016 17:38:57 +0200 Subject: [PATCH 1039/1223] Do not store witness txn in rejection cache Github-Pull: #8525 Rebased-From: 34521e4d7d176109dedf52ec8ef2b5052b9a30f3 --- src/main.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 82f9e147e..a664bf2de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1506,9 +1506,9 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. - if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, txdata) && + if (tx.wit.IsNull() && CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, txdata) && !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, txdata)) { - // Only the witness is wrong, so the transaction itself may be fine. + // Only the witness is missing, so the transaction itself may be fine. state.SetCorruptionPossible(); } return false; @@ -5505,7 +5505,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (!fMissingInputs2) { int nDos = 0; - if (stateDummy.IsInvalid(nDos) && nDos > 0 && (!state.CorruptionPossible() || State(fromPeer)->fHaveWitness)) + if (stateDummy.IsInvalid(nDos) && nDos > 0) { // Punish peer that gave us an invalid orphan tx Misbehaving(fromPeer, nDos); @@ -5516,7 +5516,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Probably non-standard or insufficient fee/priority LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString()); vEraseQueue.push_back(orphanHash); - if (!stateDummy.CorruptionPossible()) { + if (orphanTx.wit.IsNull() && !stateDummy.CorruptionPossible()) { + // Do not use rejection cache for witness transactions or + // witness-stripped transactions, as they can have been malleated. + // See https://github.com/bitcoin/bitcoin/issues/8279 for details. assert(recentRejects); recentRejects->insert(orphanHash); } @@ -5554,7 +5557,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); } } else { - if (!state.CorruptionPossible()) { + if (tx.wit.IsNull() && !state.CorruptionPossible()) { + // Do not use rejection cache for witness transactions or + // witness-stripped transactions, as they can have been malleated. + // See https://github.com/bitcoin/bitcoin/issues/8279 for details. assert(recentRejects); recentRejects->insert(tx.GetHash()); } @@ -5586,9 +5592,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); - if (nDoS > 0 && (!state.CorruptionPossible() || State(pfrom->id)->fHaveWitness)) { - // When a non-witness-supporting peer gives us a transaction that would - // be accepted if witness validation was off, we can't blame them for it. + if (nDoS > 0) { Misbehaving(pfrom->GetId(), nDoS); } } From b394a96396ce166bf2b519190fdc2a124f57eb5e Mon Sep 17 00:00:00 2001 From: instagibbs Date: Thu, 18 Aug 2016 12:04:33 -0400 Subject: [PATCH 1040/1223] Add basic test for IsStandard witness transaction blinding Github-Pull: #8525 Rebased-From: ca10a03addf70421893791c2c499e82fc494d60b --- qa/rpc-tests/p2p-segwit.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 68d8b9a00..8af46f031 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -965,8 +965,24 @@ class SegWitTest(BitcoinTestFramework): tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) - tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE]))) tx3.wit.vtxinwit.append(CTxInWitness()) + + # Add too-large for IsStandard witness and check that it does not enter reject filter + p2sh_program = CScript([OP_TRUE]) + p2sh_pubkey = hash160(p2sh_program) + witness_program2 = CScript([b'a'*400000]) + tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]))) + tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program2] + tx3.rehash() + + # Node will not be blinded to the transaction + self.std_node.announce_tx_and_wait_for_getdata(tx3) + self.std_node.test_transaction_acceptance(tx3, True, False, b'tx-size') + self.std_node.announce_tx_and_wait_for_getdata(tx3) + self.std_node.test_transaction_acceptance(tx3, True, False, b'tx-size') + + # Remove witness stuffing, instead add extra witness push on stack + tx3.vout[0] = CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE])) tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program ] tx3.rehash() From a5ec2483235d5585e985715a5f66d41dbe1c424e Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Mon, 12 Sep 2016 02:03:55 +0800 Subject: [PATCH 1041/1223] Remove createwitnessaddress This RPC command is unsafe as it will return an address even if the script is invalid. Github-Pull: #8699 Rebased-From: 86c3f8db0bf64693313a81d5fe92ef603499030a --- src/rpc/misc.cpp | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a8c5bcd17..06489566b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -320,43 +320,6 @@ UniValue createmultisig(const UniValue& params, bool fHelp) return result; } -UniValue createwitnessaddress(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 1) - { - string msg = "createwitnessaddress \"script\"\n" - "\nCreates a witness address for a particular script.\n" - "It returns a json object with the address and witness script.\n" - - "\nArguments:\n" - "1. \"script\" (string, required) A hex encoded script\n" - - "\nResult:\n" - "{\n" - " \"address\":\"multisigaddress\", (string) The value of the new address (P2SH of witness script).\n" - " \"witnessScript\":\"script\" (string) The string value of the hex-encoded witness script.\n" - "}\n" - ; - throw runtime_error(msg); - } - - if (!IsHex(params[0].get_str())) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Script must be hex-encoded"); - } - - std::vector code = ParseHex(params[0].get_str()); - CScript script(code.begin(), code.end()); - CScript witscript = GetScriptForWitness(script); - CScriptID witscriptid(witscript); - CBitcoinAddress address(witscriptid); - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("address", address.ToString())); - result.push_back(Pair("witnessScript", HexStr(witscript.begin(), witscript.end()))); - - return result; -} - UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) @@ -490,7 +453,6 @@ static const CRPCCommand commands[] = { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, - { "util", "createwitnessaddress", &createwitnessaddress, true }, { "util", "verifymessage", &verifymessage, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, From 23feab1f38cd63f55631a1b5125ef1bd5ce049df Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 13 Sep 2016 18:08:17 +0200 Subject: [PATCH 1042/1223] Remove maxuploadtargets recommended minimum Github-Pull: #8712 Rebased-From: 1b6bcdd3aa379a50c960e23d7c55db8294e76f7f --- doc/reduce-traffic.md | 3 +-- src/net.cpp | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/doc/reduce-traffic.md b/doc/reduce-traffic.md index 2d86588eb..697099bea 100644 --- a/doc/reduce-traffic.md +++ b/doc/reduce-traffic.md @@ -19,8 +19,7 @@ This is *not* a hard limit; only a threshold to minimize the outbound traffic. When the limit is about to be reached, the uploaded data is cut by no longer serving historic blocks (blocks older than one week). Keep in mind that new nodes require other nodes that are willing to serve -historic blocks. **The recommended minimum is 144 blocks per day (max. 144MB -per day)** +historic blocks. Whitelisted peers will never be disconnected, although their traffic counts for calculating the target. diff --git a/src/net.cpp b/src/net.cpp index a0ab544f5..5e38ec077 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2226,11 +2226,7 @@ void CNode::RecordBytesSent(uint64_t bytes) void CNode::SetMaxOutboundTarget(uint64_t limit) { LOCK(cs_totalBytesSent); - uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SERIALIZED_SIZE; nMaxOutboundLimit = limit; - - if (limit > 0 && limit < recommendedMinimum) - LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum); } uint64_t CNode::GetMaxOutboundTarget() From 198494ce5323cafbf90a7b543d1b07355eb3db6c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 25 Jul 2016 17:22:37 -0400 Subject: [PATCH 1043/1223] Allow changing BIP9 parameters on regtest Github-Pull: #8418 Rebased-From: 56c87e92110f05d7452f1e85bf755246ffc77206 --- src/chainparams.cpp | 11 +++++++++++ src/chainparams.h | 5 +++++ src/init.cpp | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 0cb0fccd1..7b493ed8a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -303,6 +303,12 @@ public: base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); } + + void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) + { + consensus.vDeployments[d].nStartTime = nStartTime; + consensus.vDeployments[d].nTimeout = nTimeout; + } }; static CRegTestParams regTestParams; @@ -330,4 +336,9 @@ void SelectParams(const std::string& network) SelectBaseParams(network); pCurrentParams = &Params(network); } + +void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) +{ + regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout); +} diff --git a/src/chainparams.h b/src/chainparams.h index 638893e9a..0c3820b7c 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -112,4 +112,9 @@ CChainParams& Params(const std::string& chain); */ void SelectParams(const std::string& chain); +/** + * Allows modifying the BIP9 regtest parameters. + */ +void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/init.cpp b/src/init.cpp index 9b6eca2e1..f2b13b627 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -410,6 +410,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); + strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified bip9 deployment (regtest-only)"); } string debugCategories = "addrman, alert, bench, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) @@ -990,6 +991,41 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } + if (!mapMultiArgs["-bip9params"].empty()) { + // Allow overriding bip9 parameters for testing + if (!Params().MineBlocksOnDemand()) { + return InitError("BIP9 parameters may only be overridden on regtest."); + } + const vector& deployments = mapMultiArgs["-bip9params"]; + for (auto i : deployments) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, i, boost::is_any_of(":")); + if (vDeploymentParams.size() != 3) { + return InitError("BIP9 parameters malformed, expecting deployment:start:end"); + } + int64_t nStartTime, nTimeout; + if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); + } + if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + return InitError(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); + } + bool found = false; + for (int i=0; i<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) + { + if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[i].name) == 0) { + UpdateRegtestBIP9Parameters(Consensus::DeploymentPos(i), nStartTime, nTimeout); + found = true; + LogPrintf("Setting BIP9 activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); + break; + } + } + if (!found) { + return InitError(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); + } + } + } + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize elliptic curve code From ff893aa5574f5c422b72dd10b00eac805fc737e5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 27 Jun 2016 16:06:17 +0200 Subject: [PATCH 1044/1223] Implement SipHash in Python Github-Pull: #8418 Rebased-From: 9c8593d2b4e25ef628172ceadbedf0ef078d01ef --- qa/rpc-tests/test_framework/siphash.py | 64 ++++++++++++++++++++++++++ src/test/hash_tests.cpp | 4 ++ 2 files changed, 68 insertions(+) create mode 100644 qa/rpc-tests/test_framework/siphash.py diff --git a/qa/rpc-tests/test_framework/siphash.py b/qa/rpc-tests/test_framework/siphash.py new file mode 100644 index 000000000..9c0574bd9 --- /dev/null +++ b/qa/rpc-tests/test_framework/siphash.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# siphash.py - Specialized SipHash-2-4 implementations +# +# This implements SipHash-2-4 for 256-bit integers. + +def rotl64(n, b): + return n >> (64 - b) | (n & ((1 << (64 - b)) - 1)) << b + +def siphash_round(v0, v1, v2, v3): + v0 = (v0 + v1) & ((1 << 64) - 1) + v1 = rotl64(v1, 13) + v1 ^= v0 + v0 = rotl64(v0, 32) + v2 = (v2 + v3) & ((1 << 64) - 1) + v3 = rotl64(v3, 16) + v3 ^= v2 + v0 = (v0 + v3) & ((1 << 64) - 1) + v3 = rotl64(v3, 21) + v3 ^= v0 + v2 = (v2 + v1) & ((1 << 64) - 1) + v1 = rotl64(v1, 17) + v1 ^= v2 + v2 = rotl64(v2, 32) + return (v0, v1, v2, v3) + +def siphash256(k0, k1, h): + n0 = h & ((1 << 64) - 1) + n1 = (h >> 64) & ((1 << 64) - 1) + n2 = (h >> 128) & ((1 << 64) - 1) + n3 = (h >> 192) & ((1 << 64) - 1) + v0 = 0x736f6d6570736575 ^ k0 + v1 = 0x646f72616e646f6d ^ k1 + v2 = 0x6c7967656e657261 ^ k0 + v3 = 0x7465646279746573 ^ k1 ^ n0 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n0 + v3 ^= n1 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n1 + v3 ^= n2 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n2 + v3 ^= n3 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n3 + v3 ^= 0x2000000000000000 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= 0x2000000000000000 + v2 ^= 0xFF + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + return v0 ^ v1 ^ v2 ^ v3 diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index 82d61209b..fa9624f13 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -122,6 +122,10 @@ BOOST_AUTO_TEST_CASE(siphash) hasher3.Write(uint64_t(x)|(uint64_t(x+1)<<8)|(uint64_t(x+2)<<16)|(uint64_t(x+3)<<24)| (uint64_t(x+4)<<32)|(uint64_t(x+5)<<40)|(uint64_t(x+6)<<48)|(uint64_t(x+7)<<56)); } + + CHashWriter ss(SER_DISK, CLIENT_VERSION); + ss << CTransaction(); + BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); } BOOST_AUTO_TEST_SUITE_END() From 4295a7aea55be34c95a0624e95ea0b9587e644b6 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 17 Jun 2016 21:17:25 -0400 Subject: [PATCH 1045/1223] Tests: refactor compact size serialization in mininode Github-Pull: #8418 Rebased-From: a8689fdf8e10300b73750161a73a23467ecd1efe --- qa/rpc-tests/test_framework/mininode.py | 97 +++++++------------------ 1 file changed, 25 insertions(+), 72 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index cdd5292cd..67aaab698 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -74,8 +74,19 @@ def ripemd160(s): def hash256(s): return sha256(sha256(s)) +def ser_compact_size(l): + r = b"" + if l < 253: + r = struct.pack("B", l) + elif l < 0x10000: + r = struct.pack(" Date: Tue, 12 Jul 2016 16:04:38 -0400 Subject: [PATCH 1046/1223] Add support for compactblocks to mininode Github-Pull: #8418 Rebased-From: 9a22a6c0891256f02f4906c1c13fb22a9722ec7c --- qa/rpc-tests/test_framework/mininode.py | 276 +++++++++++++++++++++++- 1 file changed, 272 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 67aaab698..caffab353 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -36,9 +36,10 @@ from threading import RLock from threading import Thread import logging import copy +from test_framework.siphash import siphash256 BIP0031_VERSION = 60000 -MY_VERSION = 60001 # past bip-31 for ping/pong +MY_VERSION = 70014 # past bip-31 for ping/pong MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" MAX_INV_SZ = 50000 @@ -52,7 +53,7 @@ NODE_BLOOM = (1 << 2) NODE_WITNESS = (1 << 3) # Keep our own socket map for asyncore, so that we can track disconnects -# ourselves (to workaround an issue with closing an asyncore socket when +# ourselves (to workaround an issue with closing an asyncore socket when # using select) mininode_socket_map = dict() @@ -247,7 +248,8 @@ class CInv(object): 1: "TX", 2: "Block", 1|MSG_WITNESS_FLAG: "WitnessTx", - 2|MSG_WITNESS_FLAG : "WitnessBlock" + 2|MSG_WITNESS_FLAG : "WitnessBlock", + 4: "CompactBlock" } def __init__(self, t=0, h=0): @@ -734,6 +736,187 @@ class CAlert(object): % (len(self.vchMsg), len(self.vchSig)) +class PrefilledTransaction(object): + def __init__(self, index=0, tx = None): + self.index = index + self.tx = tx + + def deserialize(self, f): + self.index = deser_compact_size(f) + self.tx = CTransaction() + self.tx.deserialize(f) + + def serialize(self, with_witness=False): + r = b"" + r += ser_compact_size(self.index) + if with_witness: + r += self.tx.serialize_with_witness() + else: + r += self.tx.serialize_without_witness() + return r + + def __repr__(self): + return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) + +# This is what we send on the wire, in a cmpctblock message. +class P2PHeaderAndShortIDs(object): + def __init__(self): + self.header = CBlockHeader() + self.nonce = 0 + self.shortids_length = 0 + self.shortids = [] + self.prefilled_txn_length = 0 + self.prefilled_txn = [] + + def deserialize(self, f): + self.header.deserialize(f) + self.nonce = struct.unpack(" Date: Tue, 12 Jul 2016 16:05:02 -0400 Subject: [PATCH 1047/1223] Add p2p test for BIP 152 (compact blocks) Github-Pull: #8418 Rebased-From: 45c7ddd109465e03551f5b39c2e650c243b4a078 --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/p2p-compactblocks.py | 608 ++++++++++++++++++++++++++++++ 2 files changed, 609 insertions(+) create mode 100755 qa/rpc-tests/p2p-compactblocks.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 634d67589..1e57a3fc2 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -142,6 +142,7 @@ testScripts = [ 'segwit.py', 'importprunedfunds.py', 'signmessages.py', + 'p2p-compactblocks.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py new file mode 100755 index 000000000..7fe7ecc16 --- /dev/null +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -0,0 +1,608 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.blocktools import create_block, create_coinbase +from test_framework.siphash import siphash256 +from test_framework.script import CScript, OP_TRUE + +''' +CompactBlocksTest -- test compact blocks (BIP 152) +''' + + +# TestNode: A peer we use to send messages to bitcoind, and store responses. +class TestNode(SingleNodeConnCB): + def __init__(self): + SingleNodeConnCB.__init__(self) + self.last_sendcmpct = None + self.last_headers = None + self.last_inv = None + self.last_cmpctblock = None + self.block_announced = False + self.last_getdata = None + self.last_getblocktxn = None + self.last_block = None + self.last_blocktxn = None + + def on_sendcmpct(self, conn, message): + self.last_sendcmpct = message + + def on_block(self, conn, message): + self.last_block = message + + def on_cmpctblock(self, conn, message): + self.last_cmpctblock = message + self.block_announced = True + + def on_headers(self, conn, message): + self.last_headers = message + self.block_announced = True + + def on_inv(self, conn, message): + self.last_inv = message + self.block_announced = True + + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_getblocktxn(self, conn, message): + self.last_getblocktxn = message + + def on_blocktxn(self, conn, message): + self.last_blocktxn = message + + # Requires caller to hold mininode_lock + def received_block_announcement(self): + return self.block_announced + + def clear_block_announcement(self): + with mininode_lock: + self.block_announced = False + self.last_inv = None + self.last_headers = None + self.last_cmpctblock = None + + def get_headers(self, locator, hashstop): + msg = msg_getheaders() + msg.locator.vHave = locator + msg.hashstop = hashstop + self.connection.send_message(msg) + + def send_header_for_blocks(self, new_blocks): + headers_message = msg_headers() + headers_message.headers = [CBlockHeader(b) for b in new_blocks] + self.send_message(headers_message) + + +class CompactBlocksTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + self.utxos = [] + + def setup_network(self): + self.nodes = [] + + # Turn off segwit in this test, as compact blocks don't currently work + # with segwit. (After BIP 152 is updated to support segwit, we can + # test behavior with and without segwit enabled by adding a second node + # to the test.) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0"]]) + + def build_block_on_tip(self): + height = self.nodes[0].getblockcount() + tip = self.nodes[0].getbestblockhash() + mtp = self.nodes[0].getblockheader(tip)['mediantime'] + block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1) + block.solve() + return block + + # Create 10 more anyone-can-spend utxo's for testing. + def make_utxos(self): + block = self.build_block_on_tip() + self.test_node.send_and_ping(msg_block(block)) + assert(int(self.nodes[0].getbestblockhash(), 16) == block.sha256) + self.nodes[0].generate(100) + + total_value = block.vtx[0].vout[0].nValue + out_value = total_value // 10 + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(block.vtx[0].sha256, 0), b'')) + for i in range(10): + tx.vout.append(CTxOut(out_value, CScript([OP_TRUE]))) + tx.rehash() + + block2 = self.build_block_on_tip() + block2.vtx.append(tx) + block2.hashMerkleRoot = block2.calc_merkle_root() + block2.solve() + self.test_node.send_and_ping(msg_block(block2)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256) + self.utxos.extend([[tx.sha256, i, out_value] for i in range(10)]) + return + + # Test "sendcmpct": + # - No compact block announcements or getdata(MSG_CMPCT_BLOCK) unless + # sendcmpct is sent. + # - If sendcmpct is sent with version > 0, the message is ignored. + # - If sendcmpct is sent with boolean 0, then block announcements are not + # made with compact blocks. + # - If sendcmpct is then sent with boolean 1, then new block announcements + # are made with compact blocks. + def test_sendcmpct(self): + print("Testing SENDCMPCT p2p message... ") + + # Make sure we get a version 0 SENDCMPCT message from our peer + def received_sendcmpct(): + return (self.test_node.last_sendcmpct is not None) + got_message = wait_until(received_sendcmpct, timeout=30) + assert(got_message) + assert_equal(self.test_node.last_sendcmpct.version, 1) + + tip = int(self.nodes[0].getbestblockhash(), 16) + + def check_announcement_of_new_block(node, peer, predicate): + self.test_node.clear_block_announcement() + node.generate(1) + got_message = wait_until(peer.received_block_announcement, timeout=30) + assert(got_message) + with mininode_lock: + assert(predicate) + + # We shouldn't get any block announcements via cmpctblock yet. + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + + # Try one more time, this time after requesting headers. + self.test_node.clear_block_announcement() + self.test_node.get_headers(locator=[tip], hashstop=0) + wait_until(self.test_node.received_block_announcement, timeout=30) + self.test_node.clear_block_announcement() + + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None and self.test_node.last_inv is not None) + + # Now try a SENDCMPCT message with too-high version + sendcmpct = msg_sendcmpct() + sendcmpct.version = 2 + self.test_node.send_message(sendcmpct) + + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + + # Now try a SENDCMPCT message with valid version, but announce=False + self.test_node.send_message(msg_sendcmpct()) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + + # Finally, try a SENDCMPCT message with announce=True + sendcmpct.version = 1 + sendcmpct.announce = True + self.test_node.send_message(sendcmpct) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + + # Try one more time + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + + # Try one more time, after turning on sendheaders + self.test_node.send_message(msg_sendheaders()) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + + # Now turn off announcements + sendcmpct.announce = False + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None and self.test_node.last_headers is not None) + + # This test actually causes bitcoind to (reasonably!) disconnect us, so do this last. + def test_invalid_cmpctblock_message(self): + print("Testing invalid index in cmpctblock message...") + self.nodes[0].generate(101) + block = self.build_block_on_tip() + + cmpct_block = P2PHeaderAndShortIDs() + cmpct_block.header = CBlockHeader(block) + cmpct_block.prefilled_txn_length = 1 + # This index will be too high + prefilled_txn = PrefilledTransaction(1, block.vtx[0]) + cmpct_block.prefilled_txn = [prefilled_txn] + self.test_node.send_and_ping(msg_cmpctblock(cmpct_block)) + assert(int(self.nodes[0].getbestblockhash(), 16) == block.hashPrevBlock) + + # Compare the generated shortids to what we expect based on BIP 152, given + # bitcoind's choice of nonce. + def test_compactblock_construction(self): + print("Testing compactblock headers and shortIDs are correct...") + + # Generate a bunch of transactions. + self.nodes[0].generate(101) + num_transactions = 25 + address = self.nodes[0].getnewaddress() + for i in range(num_transactions): + self.nodes[0].sendtoaddress(address, 0.1) + + # Now mine a block, and look at the resulting compact block. + self.test_node.clear_block_announcement() + block_hash = int(self.nodes[0].generate(1)[0], 16) + + # Store the raw block in our internal format. + block = FromHex(CBlock(), self.nodes[0].getblock("%02x" % block_hash, False)) + [tx.calc_sha256() for tx in block.vtx] + block.rehash() + + # Don't care which type of announcement came back for this test; just + # request the compact block if we didn't get one yet. + wait_until(self.test_node.received_block_announcement, timeout=30) + + with mininode_lock: + if self.test_node.last_cmpctblock is None: + self.test_node.clear_block_announcement() + inv = CInv(4, block_hash) # 4 == "CompactBlock" + self.test_node.send_message(msg_getdata([inv])) + + wait_until(self.test_node.received_block_announcement, timeout=30) + + # Now we should have the compactblock + header_and_shortids = None + with mininode_lock: + assert(self.test_node.last_cmpctblock is not None) + # Convert the on-the-wire representation to absolute indexes + header_and_shortids = HeaderAndShortIDs(self.test_node.last_cmpctblock.header_and_shortids) + + # Check that we got the right block! + header_and_shortids.header.calc_sha256() + assert_equal(header_and_shortids.header.sha256, block_hash) + + # Make sure the prefilled_txn appears to have included the coinbase + assert(len(header_and_shortids.prefilled_txn) >= 1) + assert_equal(header_and_shortids.prefilled_txn[0].index, 0) + + # Check that all prefilled_txn entries match what's in the block. + for entry in header_and_shortids.prefilled_txn: + entry.tx.calc_sha256() + assert_equal(entry.tx.sha256, block.vtx[entry.index].sha256) + + # Check that the cmpctblock message announced all the transactions. + assert_equal(len(header_and_shortids.prefilled_txn) + len(header_and_shortids.shortids), len(block.vtx)) + + # And now check that all the shortids are as expected as well. + # Determine the siphash keys to use. + [k0, k1] = header_and_shortids.get_siphash_keys() + + index = 0 + while index < len(block.vtx): + if (len(header_and_shortids.prefilled_txn) > 0 and + header_and_shortids.prefilled_txn[0].index == index): + # Already checked prefilled transactions above + header_and_shortids.prefilled_txn.pop(0) + else: + shortid = calculate_shortid(k0, k1, block.vtx[index].sha256) + assert_equal(shortid, header_and_shortids.shortids[0]) + header_and_shortids.shortids.pop(0) + index += 1 + + # Test that bitcoind requests compact blocks when we announce new blocks + # via header or inv, and that responding to getblocktxn causes the block + # to be successfully reconstructed. + def test_compactblock_requests(self): + print("Testing compactblock requests... ") + + # Try announcing a block with an inv or header, expect a compactblock + # request + for announce in ["inv", "header"]: + block = self.build_block_on_tip() + with mininode_lock: + self.test_node.last_getdata = None + + if announce == "inv": + self.test_node.send_message(msg_inv([CInv(2, block.sha256)])) + else: + self.test_node.send_header_for_blocks([block]) + success = wait_until(lambda: self.test_node.last_getdata is not None, timeout=30) + assert(success) + assert_equal(len(self.test_node.last_getdata.inv), 1) + assert_equal(self.test_node.last_getdata.inv[0].type, 4) + assert_equal(self.test_node.last_getdata.inv[0].hash, block.sha256) + + # Send back a compactblock message that omits the coinbase + comp_block = HeaderAndShortIDs() + comp_block.header = CBlockHeader(block) + comp_block.nonce = 0 + comp_block.shortids = [1] # this is useless, and wrong + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) + # Expect a getblocktxn message. + with mininode_lock: + assert(self.test_node.last_getblocktxn is not None) + absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [0]) # should be a coinbase request + + # Send the coinbase, and verify that the tip advances. + msg = msg_blocktxn() + msg.block_transactions.blockhash = block.sha256 + msg.block_transactions.transactions = [block.vtx[0]] + self.test_node.send_and_ping(msg) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + # Create a chain of transactions from given utxo, and add to a new block. + def build_block_with_transactions(self, utxo, num_transactions): + block = self.build_block_on_tip() + + for i in range(num_transactions): + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(utxo[0], utxo[1]), b'')) + tx.vout.append(CTxOut(utxo[2] - 1000, CScript([OP_TRUE]))) + tx.rehash() + utxo = [tx.sha256, 0, tx.vout[0].nValue] + block.vtx.append(tx) + + block.hashMerkleRoot = block.calc_merkle_root() + block.solve() + return block + + # Test that we only receive getblocktxn requests for transactions that the + # node needs, and that responding to them causes the block to be + # reconstructed. + def test_getblocktxn_requests(self): + print("Testing getblocktxn requests...") + + # First try announcing compactblocks that won't reconstruct, and verify + # that we receive getblocktxn messages back. + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block) + + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + with mininode_lock: + assert(self.test_node.last_getblocktxn is not None) + absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [1, 2, 3, 4, 5]) + msg = msg_blocktxn() + msg.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) + self.test_node.send_and_ping(msg) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + # Now try interspersing the prefilled transactions + comp_block.initialize_from_block(block, prefill_list=[0, 1, 5]) + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + with mininode_lock: + assert(self.test_node.last_getblocktxn is not None) + absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [2, 3, 4]) + msg.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) + self.test_node.send_and_ping(msg) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + # Now try giving one transaction ahead of time. + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + self.test_node.send_and_ping(msg_tx(block.vtx[1])) + assert(block.vtx[1].hash in self.nodes[0].getrawmempool()) + + # Prefill 4 out of the 6 transactions, and verify that only the one + # that was not in the mempool is requested. + comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4]) + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + with mininode_lock: + assert(self.test_node.last_getblocktxn is not None) + absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [5]) + + msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]]) + self.test_node.send_and_ping(msg) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + # Now provide all transactions to the node before the block is + # announced and verify reconstruction happens immediately. + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(utxo, 10) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + for tx in block.vtx[1:]: + self.test_node.send_message(msg_tx(tx)) + self.test_node.sync_with_ping() + # Make sure all transactions were accepted. + mempool = self.nodes[0].getrawmempool() + for tx in block.vtx[1:]: + assert(tx.hash in mempool) + + # Clear out last request. + with mininode_lock: + self.test_node.last_getblocktxn = None + + # Send compact block + comp_block.initialize_from_block(block, prefill_list=[0]) + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + with mininode_lock: + # Shouldn't have gotten a request for any transaction + assert(self.test_node.last_getblocktxn is None) + # Tip should have updated + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + # Incorrectly responding to a getblocktxn shouldn't cause the block to be + # permanently failed. + def test_incorrect_blocktxn_response(self): + print("Testing handling of incorrect blocktxn responses...") + + if (len(self.utxos) == 0): + self.make_utxos() + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(utxo, 10) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + # Relay the first 5 transactions from the block in advance + for tx in block.vtx[1:6]: + self.test_node.send_message(msg_tx(tx)) + self.test_node.sync_with_ping() + # Make sure all transactions were accepted. + mempool = self.nodes[0].getrawmempool() + for tx in block.vtx[1:6]: + assert(tx.hash in mempool) + + # Send compact block + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, prefill_list=[0]) + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + absolute_indexes = [] + with mininode_lock: + assert(self.test_node.last_getblocktxn is not None) + absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [6, 7, 8, 9, 10]) + + # Now give an incorrect response. + # Note that it's possible for bitcoind to be smart enough to know we're + # lying, since it could check to see if the shortid matches what we're + # sending, and eg disconnect us for misbehavior. If that behavior + # change were made, we could just modify this test by having a + # different peer provide the block further down, so that we're still + # verifying that the block isn't marked bad permanently. This is good + # enough for now. + msg = msg_blocktxn() + msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]] + block.vtx[7:]) + self.test_node.send_and_ping(msg) + + # Tip should not have updated + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) + + # We should receive a getdata request + success = wait_until(lambda: self.test_node.last_getdata is not None, timeout=10) + assert(success) + assert_equal(len(self.test_node.last_getdata.inv), 1) + assert_equal(self.test_node.last_getdata.inv[0].type, 2) + assert_equal(self.test_node.last_getdata.inv[0].hash, block.sha256) + + # Deliver the block + self.test_node.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + + def test_getblocktxn_handler(self): + print("Testing getblocktxn handler...") + + # bitcoind won't respond for blocks whose height is more than 15 blocks + # deep. + MAX_GETBLOCKTXN_DEPTH = 15 + chain_height = self.nodes[0].getblockcount() + current_height = chain_height + while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): + block_hash = self.nodes[0].getblockhash(current_height) + block = FromHex(CBlock(), self.nodes[0].getblock(block_hash, False)) + + msg = msg_getblocktxn() + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), []) + num_to_request = random.randint(1, len(block.vtx)) + msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request))) + self.test_node.send_message(msg) + success = wait_until(lambda: self.test_node.last_blocktxn is not None, timeout=10) + assert(success) + + [tx.calc_sha256() for tx in block.vtx] + with mininode_lock: + assert_equal(self.test_node.last_blocktxn.block_transactions.blockhash, int(block_hash, 16)) + all_indices = msg.block_txn_request.to_absolute() + for index in all_indices: + tx = self.test_node.last_blocktxn.block_transactions.transactions.pop(0) + tx.calc_sha256() + assert_equal(tx.sha256, block.vtx[index].sha256) + self.test_node.last_blocktxn = None + current_height -= 1 + + # Next request should be ignored, as we're past the allowed depth. + block_hash = self.nodes[0].getblockhash(current_height) + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0]) + self.test_node.send_and_ping(msg) + with mininode_lock: + assert_equal(self.test_node.last_blocktxn, None) + + def test_compactblocks_not_at_tip(self): + print("Testing compactblock requests/announcements not at chain tip...") + + # Test that requesting old compactblocks doesn't work. + MAX_CMPCTBLOCK_DEPTH = 11 + new_blocks = [] + for i in range(MAX_CMPCTBLOCK_DEPTH): + self.test_node.clear_block_announcement() + new_blocks.append(self.nodes[0].generate(1)[0]) + wait_until(self.test_node.received_block_announcement, timeout=30) + + self.test_node.clear_block_announcement() + self.test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: self.test_node.last_cmpctblock is not None, timeout=30) + assert(success) + + self.test_node.clear_block_announcement() + self.nodes[0].generate(1) + wait_until(self.test_node.received_block_announcement, timeout=30) + self.test_node.clear_block_announcement() + self.test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: self.test_node.last_block is not None, timeout=30) + assert(success) + with mininode_lock: + self.test_node.last_block.block.calc_sha256() + assert_equal(self.test_node.last_block.block.sha256, int(new_blocks[0], 16)) + + # Generate an old compactblock, and verify that it's not accepted. + cur_height = self.nodes[0].getblockcount() + hashPrevBlock = int(self.nodes[0].getblockhash(cur_height-5), 16) + block = self.build_block_on_tip() + block.hashPrevBlock = hashPrevBlock + block.solve() + + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block) + self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + + tips = self.nodes[0].getchaintips() + found = False + for x in tips: + if x["hash"] == block.hash: + assert_equal(x["status"], "headers-only") + found = True + break + assert(found) + + # Requesting this block via getblocktxn should silently fail + # (to avoid fingerprinting attacks). + msg = msg_getblocktxn() + msg.block_txn_request = BlockTransactionsRequest(block.sha256, [0]) + with mininode_lock: + self.test_node.last_blocktxn = None + self.test_node.send_and_ping(msg) + with mininode_lock: + assert(self.test_node.last_blocktxn is None) + + def run_test(self): + # Setup the p2p connections and start up the network thread. + self.test_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.test_node)) + self.test_node.add_connection(connections[0]) + + NetworkThread().start() # Start up network handling in another thread + + # Test logic begins here + self.test_node.wait_for_verack() + + # We will need UTXOs to construct transactions in later tests. + self.make_utxos() + + self.test_sendcmpct() + self.test_compactblock_construction() + self.test_compactblock_requests() + self.test_getblocktxn_requests() + self.test_getblocktxn_handler() + self.test_compactblocks_not_at_tip() + self.test_incorrect_blocktxn_response() + self.test_invalid_cmpctblock_message() + + +if __name__ == '__main__': + CompactBlocksTest().main() From cef633ce63937eea37048fe07da2488fefb4ec7c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 14 Sep 2016 21:00:53 -0400 Subject: [PATCH 1048/1223] Fix broken sendcmpct test in p2p-compactblocks.py Python lambda use was incorrect. sendcmpct messages need to be synchronized with RPC calls to generate(). Headers need to be synced (eg with getheaders) for cmpctblock announcements to start. Last test omitted sending a sendcmpct message. Github-Pull: #8739 Rebased-From: 157254a4bfdfc4ca3ad5bf2d84e82f290bd0c7f2) --- qa/rpc-tests/p2p-compactblocks.py | 58 ++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 7fe7ecc16..bf4fb43ad 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -78,6 +78,13 @@ class TestNode(SingleNodeConnCB): headers_message.headers = [CBlockHeader(b) for b in new_blocks] self.send_message(headers_message) + def request_headers_and_sync(self, locator, hashstop=0): + self.clear_block_announcement() + self.get_headers(locator, hashstop) + assert(wait_until(self.received_block_announcement, timeout=30)) + assert(self.received_block_announcement()) + self.clear_block_announcement() + class CompactBlocksTest(BitcoinTestFramework): def __init__(self): @@ -130,7 +137,7 @@ class CompactBlocksTest(BitcoinTestFramework): # Test "sendcmpct": # - No compact block announcements or getdata(MSG_CMPCT_BLOCK) unless # sendcmpct is sent. - # - If sendcmpct is sent with version > 0, the message is ignored. + # - If sendcmpct is sent with version > 1, the message is ignored. # - If sendcmpct is sent with boolean 0, then block announcements are not # made with compact blocks. # - If sendcmpct is then sent with boolean 1, then new block announcements @@ -142,57 +149,66 @@ class CompactBlocksTest(BitcoinTestFramework): def received_sendcmpct(): return (self.test_node.last_sendcmpct is not None) got_message = wait_until(received_sendcmpct, timeout=30) + assert(received_sendcmpct()) assert(got_message) assert_equal(self.test_node.last_sendcmpct.version, 1) tip = int(self.nodes[0].getbestblockhash(), 16) def check_announcement_of_new_block(node, peer, predicate): - self.test_node.clear_block_announcement() + peer.clear_block_announcement() node.generate(1) - got_message = wait_until(peer.received_block_announcement, timeout=30) + got_message = wait_until(lambda: peer.block_announced, timeout=30) + assert(peer.block_announced) assert(got_message) with mininode_lock: - assert(predicate) + assert(predicate(peer)) # We shouldn't get any block announcements via cmpctblock yet. - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) # Try one more time, this time after requesting headers. - self.test_node.clear_block_announcement() - self.test_node.get_headers(locator=[tip], hashstop=0) - wait_until(self.test_node.received_block_announcement, timeout=30) - self.test_node.clear_block_announcement() + self.test_node.request_headers_and_sync(locator=[tip]) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None and p.last_inv is not None) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None and self.test_node.last_inv is not None) + # Test a few ways of using sendcmpct that should NOT + # result in compact block announcements. + # Before each test, sync the headers chain. + self.test_node.request_headers_and_sync(locator=[tip]) # Now try a SENDCMPCT message with too-high version sendcmpct = msg_sendcmpct() sendcmpct.version = 2 - self.test_node.send_message(sendcmpct) + self.test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + # Headers sync before next test. + self.test_node.request_headers_and_sync(locator=[tip]) # Now try a SENDCMPCT message with valid version, but announce=False - self.test_node.send_message(msg_sendcmpct()) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None) + self.test_node.send_and_ping(msg_sendcmpct()) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) + + # Headers sync before next test. + self.test_node.request_headers_and_sync(locator=[tip]) # Finally, try a SENDCMPCT message with announce=True sendcmpct.version = 1 sendcmpct.announce = True - self.test_node.send_message(sendcmpct) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + self.test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) - # Try one more time - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + # Try one more time (no headers sync should be needed!) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) # Try one more time, after turning on sendheaders - self.test_node.send_message(msg_sendheaders()) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is not None) + self.test_node.send_and_ping(msg_sendheaders()) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) # Now turn off announcements sendcmpct.announce = False - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda: self.test_node.last_cmpctblock is None and self.test_node.last_headers is not None) + self.test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None and p.last_headers is not None) # This test actually causes bitcoind to (reasonably!) disconnect us, so do this last. def test_invalid_cmpctblock_message(self): From 9dfa0c8d90177a12c3a3b1ac59c32727077d6803 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Wed, 31 Aug 2016 19:38:23 +0800 Subject: [PATCH 1049/1223] Implement NULLDUMMY softfork Github-Pull: #8636 Rebased-From: 482f852da65457eb2fbea6b259e7568133fb81c4 --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/nulldummy.py | 148 ++++++++++++++++++++++++++++++++++++ src/main.cpp | 1 + 3 files changed, 150 insertions(+) create mode 100755 qa/rpc-tests/nulldummy.py diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 1e57a3fc2..dbd6de559 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -143,6 +143,7 @@ testScripts = [ 'importprunedfunds.py', 'signmessages.py', 'p2p-compactblocks.py', + 'nulldummy.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py new file mode 100755 index 000000000..eaed7a8c7 --- /dev/null +++ b/qa/rpc-tests/nulldummy.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.mininode import CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment +from test_framework.comptool import TestManager +from test_framework.script import CScript +from io import BytesIO +import time + +NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)" + +def trueDummy(tx): + scriptSig = CScript(tx.vin[0].scriptSig) + newscript = [] + for i in scriptSig: + if (len(newscript) == 0): + assert(len(i) == 0) + newscript.append(b'\x51') + else: + newscript.append(i) + tx.vin[0].scriptSig = CScript(newscript) + tx.rehash() + +''' +This test is meant to exercise NULLDUMMY softfork. +Connect to a single node. +Generate 2 blocks (save the coinbases for later). +Generate 427 more blocks. +[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block. +[Policy] Check that non-NULLDUMMY transactions are rejected before activation. +[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block. +[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. +''' + +class NULLDUMMYTest(ComparisonTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + + def setup_network(self): + # Must set the blockversion for this test + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1', '-walletprematurewitness']]) + + def run_test(self): + self.address = self.nodes[0].getnewaddress() + self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address]) + self.wit_address = self.nodes[0].addwitnessaddress(self.address) + self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address) + + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 + coinbase_txid = [] + for i in self.coinbase_blocks: + coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0]) + self.nodes[0].generate(427) # Block 429 + self.lastblockhash = self.nodes[0].getbestblockhash() + self.tip = int("0x" + self.lastblockhash, 0) + self.lastblockheight = 429 + self.lastblocktime = int(time.time()) + 429 + + print ("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") + test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] + txid1 = self.tx_submit(self.nodes[0], test1txs[0]) + test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) + txid2 = self.tx_submit(self.nodes[0], test1txs[1]) + test1txs.append(self.create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49)) + txid3 = self.tx_submit(self.nodes[0], test1txs[2]) + self.block_submit(self.nodes[0], test1txs, False, True) + + print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") + test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48) + trueDummy(test2tx) + txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR) + + print ("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") + self.block_submit(self.nodes[0], [test2tx], False, True) + + print ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") + test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 47) + test6txs=[CTransaction(test4tx)] + trueDummy(test4tx) + self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR) + self.block_submit(self.nodes[0], [test4tx]) + + print ("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation") + test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48) + test6txs.append(CTransaction(test5tx)) + test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01' + self.tx_submit(self.nodes[0], test5tx, NULLDUMMY_ERROR) + self.block_submit(self.nodes[0], [test5tx], True) + + print ("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]") + for i in test6txs: + self.tx_submit(self.nodes[0], i) + self.block_submit(self.nodes[0], test6txs, True, True) + + + def create_transaction(self, node, txid, to_address, amount): + inputs = [{ "txid" : txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + f = BytesIO(hex_str_to_bytes(signresult['hex'])) + tx.deserialize(f) + return tx + + + def tx_submit(self, node, tx, msg = ""): + tx.rehash() + try: + node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True) + except JSONRPCException as exp: + assert_equal(exp.error["message"], msg) + return tx.hash + + + def block_submit(self, node, txs, witness = False, accept = False): + block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1) + block.nVersion = 4 + for tx in txs: + tx.rehash() + block.vtx.append(tx) + block.hashMerkleRoot = block.calc_merkle_root() + witness and add_witness_commitment(block) + block.rehash() + block.solve() + node.submitblock(bytes_to_hex_str(block.serialize(True))) + if (accept): + assert_equal(node.getbestblockhash(), block.hash) + self.tip = block.sha256 + self.lastblockhash = block.hash + self.lastblocktime += 1 + self.lastblockheight += 1 + else: + assert_equal(node.getbestblockhash(), self.lastblockhash) + +if __name__ == '__main__': + NULLDUMMYTest().main() \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a664bf2de..c9869d04f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2399,6 +2399,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Start enforcing WITNESS rules using versionbits logic. if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) { flags |= SCRIPT_VERIFY_WITNESS; + flags |= SCRIPT_VERIFY_NULLDUMMY; } int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; From 375437c26bba95e9c25b758a186a3370f1d5e15d Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 24 Sep 2016 16:26:26 +0800 Subject: [PATCH 1050/1223] Ping regularly in p2p-segwit.py to keep connection alive This pings regularly while building a big block in p2p-segwit.py, to prevent timeout Github-Pull: #8803 Rebased-From: 0637b02fce04c800acc6747687c91c9b22f642e5 --- qa/rpc-tests/p2p-segwit.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 8af46f031..ada5fba7f 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -1389,6 +1389,9 @@ class SegWitTest(BitcoinTestFramework): block = self.build_next_block() used_sighash_single_out_of_bounds = False for i in range(NUM_TESTS): + # Ping regularly to keep the connection alive + if (not i % 100): + self.test_node.sync_with_ping() # Choose random number of inputs to use. num_inputs = random.randint(1, 10) # Create a slight bias for producing more utxos From 9bbe66e5929b47f3990a916787f1b145556fd665 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 28 Sep 2016 11:08:08 -0400 Subject: [PATCH 1051/1223] [qa] Split up slow RPC calls to avoid pruning test timeouts Github-Pull: #8827 Rebased-From: a0f8482f3e9b07e37c3f1b6fa09683b448810955 --- qa/rpc-tests/pruning.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 7cbe69c29..287dbc776 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -157,7 +157,10 @@ class PruneTest(BitcoinTestFramework): print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") - self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects + for i in range(22): + # This can be slow, so do this in multiple RPC calls to avoid + # RPC timeouts. + self.nodes[0].generate(10) #node 0 has many large tx's in its mempool from the disconnects sync_blocks(self.nodes[0:3], timeout=300) usage = calc_usage(self.prunedir) From 2a8bca465dfd24cb7722d63d41bd67b0ba3dcb5c Mon Sep 17 00:00:00 2001 From: jnewbery Date: Wed, 28 Sep 2016 13:36:36 -0400 Subject: [PATCH 1052/1223] Add bitcoin-tx JSON tests Github-Pull: #8829 Rebased-From: 54e5d7c1b81e1b76f5789abfa2cb1f5963cd9d72 --- src/test/data/bitcoin-util-test.json | 85 ++++++++- src/test/data/blanktx.json | 10 + src/test/data/tt-delin1-out.json | 216 ++++++++++++++++++++++ src/test/data/tt-delout1-out.json | 212 +++++++++++++++++++++ src/test/data/tt-locktime317000-out.json | 225 +++++++++++++++++++++++ src/test/data/txcreate1.json | 63 +++++++ src/test/data/txcreate2.json | 0 src/test/data/txcreatedata1.json | 41 +++++ src/test/data/txcreatedata2.json | 41 +++++ src/test/data/txcreatedata_seq0.json | 32 ++++ src/test/data/txcreatedata_seq1.json | 41 +++++ src/test/data/txcreatesign.json | 32 ++++ 12 files changed, 997 insertions(+), 1 deletion(-) create mode 100644 src/test/data/blanktx.json create mode 100644 src/test/data/tt-delin1-out.json create mode 100644 src/test/data/tt-delout1-out.json create mode 100644 src/test/data/tt-locktime317000-out.json create mode 100644 src/test/data/txcreate1.json create mode 100644 src/test/data/txcreate2.json create mode 100644 src/test/data/txcreatedata1.json create mode 100644 src/test/data/txcreatedata2.json create mode 100644 src/test/data/txcreatedata_seq0.json create mode 100644 src/test/data/txcreatedata_seq1.json create mode 100644 src/test/data/txcreatesign.json diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 5cb383de8..9df61a7e7 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,18 +1,32 @@ [ - { "exec": "././bitcoin-tx", + { "exec": "./bitcoin-tx", "args": ["-create"], "output_cmp": "blanktx.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json","-create"], + "output_cmp": "blanktx.json" + }, { "exec": "./bitcoin-tx", "args": ["-"], "input": "blanktx.hex", "output_cmp": "blanktx.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json","-"], + "input": "blanktx.hex", + "output_cmp": "blanktx.json" + }, { "exec": "./bitcoin-tx", "args": ["-", "delin=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delin1-out.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-", "delin=1"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-delin1-out.json" + }, { "exec": "./bitcoin-tx", "args": ["-", "delin=31"], "input": "tx394b54bb.hex", @@ -23,6 +37,11 @@ "input": "tx394b54bb.hex", "output_cmp": "tt-delout1-out.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-", "delout=1"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-delout1-out.json" + }, { "exec": "./bitcoin-tx", "args": ["-", "delout=2"], "input": "tx394b54bb.hex", @@ -33,6 +52,11 @@ "input": "tx394b54bb.hex", "output_cmp": "tt-locktime317000-out.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-", "locktime=317000"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-locktime317000-out.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", @@ -43,10 +67,25 @@ "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], "output_cmp": "txcreate1.hex" }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", + "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], + "output_cmp": "txcreate1.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:"], + "output_cmp": "txcreate2.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", @@ -57,6 +96,17 @@ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], "output_cmp": "txcreatesign.hex" }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", + "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", + "sign=ALL", + "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], + "output_cmp": "txcreatesign.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", @@ -79,6 +129,15 @@ "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "output_cmp": "txcreatedata1.hex" }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata1.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", @@ -87,6 +146,15 @@ "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "output_cmp": "txcreatedata2.hex" }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata2.json" + }, { "exec": "./bitcoin-tx", "args": ["-create", @@ -94,10 +162,25 @@ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], "output_cmp": "txcreatedata_seq0.hex" }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], + "output_cmp": "txcreatedata_seq0.json" + }, { "exec": "./bitcoin-tx", "args": ["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], "output_cmp": "txcreatedata_seq1.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], + "output_cmp": "txcreatedata_seq1.json" } ] diff --git a/src/test/data/blanktx.json b/src/test/data/blanktx.json new file mode 100644 index 000000000..f6d6ab588 --- /dev/null +++ b/src/test/data/blanktx.json @@ -0,0 +1,10 @@ +{ + "txid": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + ], + "hex": "01000000000000000000" +} diff --git a/src/test/data/tt-delin1-out.json b/src/test/data/tt-delin1-out.json new file mode 100644 index 000000000..2c7a68636 --- /dev/null +++ b/src/test/data/tt-delin1-out.json @@ -0,0 +1,216 @@ +{ + "txid": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb" + ] + } + } + ], + "hex": "0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000" +} diff --git a/src/test/data/tt-delout1-out.json b/src/test/data/tt-delout1-out.json new file mode 100644 index 000000000..9cf8cbb16 --- /dev/null +++ b/src/test/data/tt-delout1-out.json @@ -0,0 +1,212 @@ +{ + "txid": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000" +} diff --git a/src/test/data/tt-locktime317000-out.json b/src/test/data/tt-locktime317000-out.json new file mode 100644 index 000000000..65b6a4451 --- /dev/null +++ b/src/test/data/tt-locktime317000-out.json @@ -0,0 +1,225 @@ +{ + "txid": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", + "version": 1, + "locktime": 317000, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400" +} diff --git a/src/test/data/txcreate1.json b/src/test/data/txcreate1.json new file mode 100644 index 000000000..3890dbaf6 --- /dev/null +++ b/src/test/data/txcreate1.json @@ -0,0 +1,63 @@ +{ + "txid": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c", + "vout": 18, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 4.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46" + ] + } + } + ], + "hex": "01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000" +} diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/data/txcreatedata1.json b/src/test/data/txcreatedata1.json new file mode 100644 index 000000000..2fed22810 --- /dev/null +++ b/src/test/data/txcreatedata1.json @@ -0,0 +1,41 @@ +{ + "txid": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 4.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "type": "nulldata" + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" +} diff --git a/src/test/data/txcreatedata2.json b/src/test/data/txcreatedata2.json new file mode 100644 index 000000000..3d4d367f3 --- /dev/null +++ b/src/test/data/txcreatedata2.json @@ -0,0 +1,41 @@ +{ + "txid": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 0.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "type": "nulldata" + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" +} diff --git a/src/test/data/txcreatedata_seq0.json b/src/test/data/txcreatedata_seq0.json new file mode 100644 index 000000000..f25aa43c2 --- /dev/null +++ b/src/test/data/txcreatedata_seq0.json @@ -0,0 +1,32 @@ +{ + "txid": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967293 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" +} diff --git a/src/test/data/txcreatedata_seq1.json b/src/test/data/txcreatedata_seq1.json new file mode 100644 index 000000000..33585d6df --- /dev/null +++ b/src/test/data/txcreatedata_seq1.json @@ -0,0 +1,41 @@ +{ + "txid": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967293 + }, + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 1 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + } + ], + "hex": "01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" +} diff --git a/src/test/data/txcreatesign.json b/src/test/data/txcreatesign.json new file mode 100644 index 000000000..057fe9b01 --- /dev/null +++ b/src/test/data/txcreatesign.json @@ -0,0 +1,32 @@ +{ + "txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485", + "vout": 0, + "scriptSig": { + "asm": "304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e2[ALL] 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "hex": "48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.001, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7" + ] + } + } + ], + "hex": "01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000" +} From 62886598dbed82a6ce2d987ad345ebf710751d26 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 20 Sep 2016 16:18:24 +0200 Subject: [PATCH 1053/1223] [Wallet] remove "unused" ThreadFlushWalletDB from removeprunedfunds Github-Pull: #8765 Rebased-From: c6f5ca822f1308983431bf1b3c91f8aaccff51a0 --- src/wallet/rpcdump.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 443441a36..34b8c1fb7 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -346,8 +346,6 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); } - ThreadFlushWalletDB(pwalletMain->strWalletFile); - return NullUniValue; } From 83ad563ade3c7db887b12f7aaf6d5ad9c20f208a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 28 Sep 2016 21:05:11 +0200 Subject: [PATCH 1054/1223] [rpc] throw JSONRPCError when utxo set can not be read Github-Pull: #8832 Rebased-From: fa05cfdf256f3bc13b89ea80231e342f4302d204 --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9dc896b7a..d95be05c3 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -704,6 +704,8 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } return ret; } From 1dd1783873db0a438a0141e908a9d08f1774e6e3 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 29 Sep 2016 11:21:33 +0200 Subject: [PATCH 1055/1223] [qa] blockstore: Switch to dumb dbm Github-Pull: #8834 Rebased-From: fa9cd25ed0587078e3218965606c79ebf8138d53 --- qa/rpc-tests/test_framework/blockstore.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 1e2bbb277..28a6b92b8 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -9,11 +9,11 @@ from .mininode import * from io import BytesIO -import dbm.ndbm +import dbm.dumb as dbmd class BlockStore(object): def __init__(self, datadir): - self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') + self.blockDB = dbmd.open(datadir + "/blocks", 'c') self.currentBlock = 0 self.headers_map = dict() @@ -123,7 +123,7 @@ class BlockStore(object): class TxStore(object): def __init__(self, datadir): - self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') + self.txDB = dbmd.open(datadir + "/transactions", 'c') def close(self): self.txDB.close() From d87227d6d2d6e06af1ef4ad13e2b15f1d4d43600 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 29 Sep 2016 15:34:04 +0200 Subject: [PATCH 1056/1223] [qa] nulldummy: Don't run unused code Github-Pull: #8835 Rebased-From: fa156c604e7d86d84f7731b05d7530bc91d2736b --- qa/rpc-tests/nulldummy.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index eaed7a8c7..6488a9236 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -3,11 +3,10 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from test_framework.test_framework import ComparisonTestFramework +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment -from test_framework.comptool import TestManager from test_framework.script import CScript from io import BytesIO import time @@ -37,11 +36,12 @@ Generate 427 more blocks. [Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. ''' -class NULLDUMMYTest(ComparisonTestFramework): +class NULLDUMMYTest(BitcoinTestFramework): def __init__(self): super().__init__() self.num_nodes = 1 + self.setup_clean_chain = True def setup_network(self): # Must set the blockversion for this test @@ -54,8 +54,6 @@ class NULLDUMMYTest(ComparisonTestFramework): self.wit_address = self.nodes[0].addwitnessaddress(self.address) self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address) - test = TestManager(self, self.options.tmpdir) - test.add_all_connections(self.nodes) NetworkThread().start() # Start up network handling in another thread self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 coinbase_txid = [] @@ -145,4 +143,4 @@ class NULLDUMMYTest(ComparisonTestFramework): assert_equal(node.getbestblockhash(), self.lastblockhash) if __name__ == '__main__': - NULLDUMMYTest().main() \ No newline at end of file + NULLDUMMYTest().main() From eb18cc1272e1f29b2caccf08aedee3de6fc3c437 Mon Sep 17 00:00:00 2001 From: jnewbery Date: Thu, 29 Sep 2016 10:13:16 -0400 Subject: [PATCH 1057/1223] bitcoin-util-test.py should fail if the output file is empty Github-Pull: #8836 Rebased-From: da9469770847df56e67e629986129a087b5bd7a5 --- src/test/bctest.py | 3 +++ src/test/data/txcreate2.json | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/test/bctest.py b/src/test/bctest.py index 8105b87ff..39a27fcd0 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -24,6 +24,9 @@ def bctest(testDir, testObj, exeext): if "output_cmp" in testObj: outputFn = testObj['output_cmp'] outputData = open(testDir + "/" + outputFn).read() + if not outputData: + print("Output data missing for " + outputFn) + sys.exit(1) proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) try: outs = proc.communicate(input=inputData) diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json index e69de29bb..c56293eaf 100644 --- a/src/test/data/txcreate2.json +++ b/src/test/data/txcreate2.json @@ -0,0 +1,19 @@ +{ + "txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "", + "hex": "", + "type": "nonstandard" + } + } + ], + "hex": "01000000000100000000000000000000000000" +} From 31ab2f862ad48e89314611faa0debc916317cb16 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 29 Sep 2016 15:02:08 +0000 Subject: [PATCH 1058/1223] test: Avoid ConnectionResetErrors during RPC tests This is necessary on FreeBSD and MacOSX, at least. See https://github.com/bitcoin/bitcoin/pull/8834#issuecomment-250450213 Github-Pull: #8839 Rebased-From: 1d28faf9e94fcf240ece7336d61ec297b064bc37 --- qa/rpc-tests/test_framework/authproxy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index d095a56ce..1a94bf5fe 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -126,8 +126,9 @@ class AuthServiceProxy(object): return self._get_response() else: raise - except BrokenPipeError: - # Python 3.5+ raises this instead of BadStatusLine when the connection was reset + except (BrokenPipeError,ConnectionResetError): + # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset + # ConnectionResetError happens on FreeBSD with Python 3.4 self.__conn.close() self.__conn.request(method, path, postdata, headers) return self._get_response() From 3e4abb5025f4b7415fa57d576efebe1d45fd204e Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 30 Sep 2016 00:18:13 +0800 Subject: [PATCH 1059/1223] Fix nulldummy.py test Github-Pull: #8841 Rebased-From: 46a4774d2bb9cc863e43507212ef989fa10d56d4 --- qa/rpc-tests/nulldummy.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 6488a9236..54b7eac37 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -119,6 +119,8 @@ class NULLDUMMYTest(BitcoinTestFramework): node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True) except JSONRPCException as exp: assert_equal(exp.error["message"], msg) + else: + assert_equal('', msg) return tx.hash From 624a007f476027457b32e0bd42584e67bb003317 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 30 Sep 2016 20:54:30 -0400 Subject: [PATCH 1060/1223] [qa] Fix race condition in p2p-compactblocks test Also fix a bug in the sync_with_ping() helper function Github-Pull: #8854 Rebased-From: b5fd666984fdb7125cb809c773b36034f32128cc --- qa/rpc-tests/p2p-compactblocks.py | 2 ++ qa/rpc-tests/test_framework/mininode.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index bf4fb43ad..ac4655a84 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -237,6 +237,8 @@ class CompactBlocksTest(BitcoinTestFramework): for i in range(num_transactions): self.nodes[0].sendtoaddress(address, 0.1) + self.test_node.sync_with_ping() + # Now mine a block, and look at the resulting compact block. self.test_node.clear_block_announcement() block_hash = int(self.nodes[0].generate(1)[0], 16) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index caffab353..0b7b17cdb 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1536,7 +1536,7 @@ class SingleNodeConnCB(NodeConnCB): def received_pong(): return (self.last_pong.nonce == self.ping_counter) self.send_message(msg_ping(nonce=self.ping_counter)) - success = wait_until(received_pong, timeout) + success = wait_until(received_pong, timeout=timeout) self.ping_counter += 1 return success From 1f60d455048b7c0af6a5fdc032022d3fac37e790 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 1 Oct 2016 11:36:25 +0200 Subject: [PATCH 1061/1223] [qa] mininode: Only allow named args in wait_until Github-Pull: #8857 Rebased-From: fa666094cf5b9ac4a7c1732a7ffa001afffcd938 --- qa/rpc-tests/maxuploadtarget.py | 2 +- qa/rpc-tests/p2p-mempool.py | 2 +- qa/rpc-tests/test_framework/mininode.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 125d4eb27..d0e9fe9a3 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -75,7 +75,7 @@ class TestNode(NodeConnCB): def received_pong(): return (self.last_pong.nonce == self.ping_counter) self.connection.send_message(msg_ping(nonce=self.ping_counter)) - success = wait_until(received_pong, timeout) + success = wait_until(received_pong, timeout=timeout) self.ping_counter += 1 return success diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py index 5d2daf39f..80948426d 100755 --- a/qa/rpc-tests/p2p-mempool.py +++ b/qa/rpc-tests/p2p-mempool.py @@ -63,7 +63,7 @@ class TestNode(NodeConnCB): def received_pong(): return (self.last_pong.nonce == self.ping_counter) self.connection.send_message(msg_ping(nonce=self.ping_counter)) - success = wait_until(received_pong, timeout) + success = wait_until(received_pong, timeout=timeout) self.ping_counter += 1 return success diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 0b7b17cdb..88a3b7e0f 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1320,7 +1320,7 @@ class msg_reject(object): % (self.message, self.code, self.reason, self.data) # Helper function -def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): +def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf')): attempt = 0 elapsed = 0 From 794b007896aae7b180bdfc771bb4e1656a3e3329 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 25 Sep 2016 15:01:31 +0200 Subject: [PATCH 1062/1223] [qa] Add getinfo smoke tests and rework versionbits test Github-Pull: #8780 Rebased-From: fa6e71b27d00766897f3e69775d450924a58a153 --- qa/rpc-tests/p2p-versionbits-warning.py | 42 ++++++++++++++----------- qa/rpc-tests/rpcbind_test.py | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 962cafef0..00dbbc02c 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -6,6 +6,7 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +import re import time from test_framework.blocktools import create_block, create_coinbase @@ -21,6 +22,10 @@ VB_THRESHOLD = 108 # versionbits activation threshold for regtest VB_TOP_BITS = 0x20000000 VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment +WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect" +WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT) +VB_PATTERN = re.compile("^Warning.*versionbit") + # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. class TestNode(NodeConnCB): @@ -65,16 +70,12 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.num_nodes = 1 def setup_network(self): - self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w') as _: pass - self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""] - self.nodes.append(start_node(0, self.options.tmpdir, self.node_options)) - - import re - self.vb_pattern = re.compile("^Warning.*versionbit") + self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Send numblocks blocks via peer with nVersionToUse set. def send_blocks_with_version(self, peer, numblocks, nVersionToUse): @@ -83,7 +84,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): block_time = self.nodes[0].getblockheader(tip)["time"]+1 tip = int(tip, 16) - for i in range(numblocks): + for _ in range(numblocks): block = create_block(tip, create_coinbase(height+1), block_time) block.nVersion = nVersionToUse block.solve() @@ -96,7 +97,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): def test_versionbits_in_alert_file(self): with open(self.alert_filename, 'r') as f: alert_text = f.read() - assert(self.vb_pattern.match(alert_text)) + assert(VB_PATTERN.match(alert_text)) def run_test(self): # Setup the p2p connection and start up the network thread. @@ -122,8 +123,10 @@ class VersionBitsWarningTest(BitcoinTestFramework): # Fill rest of period with regular version blocks self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) # Check that we're not getting any versionbit-related errors in - # getinfo() - assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"])) + # get*info() + assert(not VB_PATTERN.match(self.nodes[0].getinfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"])) # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling # some unknown bit @@ -132,8 +135,10 @@ class VersionBitsWarningTest(BitcoinTestFramework): # Might not get a versionbits-related alert yet, as we should # have gotten a different alert due to more than 51/100 blocks # being of unexpected version. - # Check that getinfo() shows some kind of error. - assert(len(self.nodes[0].getinfo()["errors"]) != 0) + # Check that get*info() shows some kind of error. + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"]) # Mine a period worth of expected blocks so the generic block-version warning # is cleared, and restart the node. This should move the versionbit state @@ -142,20 +147,21 @@ class VersionBitsWarningTest(BitcoinTestFramework): stop_node(self.nodes[0], 0) wait_bitcoinds() # Empty out the alert file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w') as _: pass - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Connecting one block should be enough to generate an error. self.nodes[0].generate(1) - assert(len(self.nodes[0].getinfo()["errors"]) != 0) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) stop_node(self.nodes[0], 0) wait_bitcoinds() self.test_versionbits_in_alert_file() # Test framework expects the node to still be running... - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) - + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) if __name__ == '__main__': VersionBitsWarningTest().main() diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index bf1cc8712..b6407b91a 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -46,7 +46,7 @@ class RPCBindTest(BitcoinTestFramework): def run_allowip_test(self, allow_ips, rpchost, rpcport): ''' - Start a node with rpcwallow IP, and request getinfo + Start a node with rpcallow IP, and request getinfo at a non-localhost IP. ''' base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] From 0bee740845b9c7599e041b0be7111c8debaff63b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 1 Oct 2016 21:07:31 +0200 Subject: [PATCH 1063/1223] [qa] util: Move wait_bitcoinds() into stop_nodes() Github-Pull: #8860 Rebased-From: fa7c35c4ec630838178b4674288da33561a66f08 --- qa/rpc-tests/bip9-softforks.py | 1 - qa/rpc-tests/fundrawtransaction.py | 1 - qa/rpc-tests/p2p-versionbits-warning.py | 6 ++---- qa/rpc-tests/reindex.py | 16 +++++++++------- qa/rpc-tests/rpcbind_test.py | 2 -- qa/rpc-tests/test_framework/test_framework.py | 4 ---- qa/rpc-tests/test_framework/util.py | 2 +- qa/rpc-tests/wallet.py | 3 --- 8 files changed, 12 insertions(+), 23 deletions(-) diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 979d1410c..be6ddde11 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -195,7 +195,6 @@ class BIP9SoftForksTest(ComparisonTestFramework): # Restart all self.test.block_store.close() stop_nodes(self.nodes) - wait_bitcoinds() shutil.rmtree(self.options.tmpdir) self.setup_chain() self.setup_network() diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index eeb847663..8c45578fc 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -470,7 +470,6 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[1].encryptwallet("test") self.nodes.pop(1) stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 00dbbc02c..1fb4870e1 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -144,8 +144,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): # is cleared, and restart the node. This should move the versionbit state # to ACTIVE. self.nodes[0].generate(VB_PERIOD) - stop_node(self.nodes[0], 0) - wait_bitcoinds() + stop_nodes(self.nodes) # Empty out the alert file with open(self.alert_filename, 'w') as _: pass @@ -156,8 +155,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"]) assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"]) assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) - stop_node(self.nodes[0], 0) - wait_bitcoinds() + stop_nodes(self.nodes) self.test_versionbits_in_alert_file() # Test framework expects the node to still be running... diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index abbbb1033..25cf4c167 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -7,7 +7,11 @@ # Test -reindex and -reindex-chainstate with CheckBlockIndex # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import ( + start_nodes, + stop_nodes, + assert_equal, +) import time class ReindexTest(BitcoinTestFramework): @@ -18,16 +22,14 @@ class ReindexTest(BitcoinTestFramework): self.num_nodes = 1 def setup_network(self): - self.nodes = [] - self.is_network_split = False - self.nodes.append(start_node(0, self.options.tmpdir)) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) def reindex(self, justchainstate=False): self.nodes[0].generate(3) blockcount = self.nodes[0].getblockcount() - stop_node(self.nodes[0], 0) - wait_bitcoinds() - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) + stop_nodes(self.nodes) + extra_args = [["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) while self.nodes[0].getblockcount() < blockcount: time.sleep(0.1) assert_equal(self.nodes[0].getblockcount(), blockcount) diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index b6407b91a..308945553 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -42,7 +42,6 @@ class RPCBindTest(BitcoinTestFramework): assert_equal(set(get_bind_addrs(pid)), set(expected)) finally: stop_nodes(self.nodes) - wait_bitcoinds() def run_allowip_test(self, allow_ips, rpchost, rpcport): ''' @@ -58,7 +57,6 @@ class RPCBindTest(BitcoinTestFramework): finally: node = None # make sure connection will be garbage collected and closed stop_nodes(self.nodes) - wait_bitcoinds() def run_test(self): # due to OS-specific network stats queries, this test works only on Linux diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 306f31102..9d15d8745 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -21,7 +21,6 @@ from .util import ( sync_mempools, stop_nodes, stop_node, - wait_bitcoinds, enable_coverage, check_json_precision, initialize_chain_clean, @@ -81,7 +80,6 @@ class BitcoinTestFramework(object): """ assert not self.is_network_split stop_nodes(self.nodes) - wait_bitcoinds() self.setup_network(True) def sync_all(self): @@ -100,7 +98,6 @@ class BitcoinTestFramework(object): """ assert self.is_network_split stop_nodes(self.nodes) - wait_bitcoinds() self.setup_network(False) def main(self): @@ -168,7 +165,6 @@ class BitcoinTestFramework(object): if not self.options.noshutdown: print("Stopping nodes") stop_nodes(self.nodes) - wait_bitcoinds() else: print("Note: bitcoinds were not stopped and may still be running") diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 8aa34265c..53db1cc49 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -262,7 +262,6 @@ def initialize_chain(test_dir, num_nodes): # Shut them down, and clean up cache directories: stop_nodes(rpcs) - wait_bitcoinds() disable_mocktime() for i in range(MAX_NODES): os.remove(log_filename("cache", i, "debug.log")) @@ -361,6 +360,7 @@ def stop_nodes(nodes): except http.client.CannotSendRequest as e: print("WARN: Unable to stop node: " + repr(e)) del nodes[:] # Emptying array closes connections as a side effect + wait_bitcoinds() def set_node_times(nodes, t): for node in nodes: diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 3420be1a2..e43f6ea5d 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -199,7 +199,6 @@ class WalletTest (BitcoinTestFramework): #do some -walletbroadcast tests stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -225,7 +224,6 @@ class WalletTest (BitcoinTestFramework): #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -335,7 +333,6 @@ class WalletTest (BitcoinTestFramework): for m in maintenance: print("check " + m) stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: # reindex will leave rpc warm up "early"; Wait for it to finish From cbc3fe59c4d92784411f5d40207ddde61fa5a892 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 29 Sep 2016 15:34:44 +0000 Subject: [PATCH 1064/1223] test: Explicitly set encoding to utf8 when opening text files These are text files but their encoding does not depend on the locale. Not all of them require utf8 but it is better to fix it at something to remove potential unpredictability. This is necessary on FreeBSD where no locale is set by default, and apparently Python defaults not only the terminal encoding to the locale but that of every text file. So without LOCALE environment it defaults text file encoding to ASCII. This causes problems with e.g. `bitcoin.conf`. Luckily the locale doesn't affect the default encoding for str.encode() and bytes.decode() on Python 3, so this is the only change necessary. Github-Pull: #8840 Rebased-From: 30930e847e2483c7c8163cc581b392bc288250e9 --- qa/rpc-tests/forknotify.py | 6 +++--- qa/rpc-tests/multi_rpc.py | 2 +- qa/rpc-tests/p2p-versionbits-warning.py | 6 +++--- qa/rpc-tests/test_framework/coverage.py | 4 ++-- qa/rpc-tests/test_framework/netutil.py | 2 +- qa/rpc-tests/test_framework/util.py | 2 +- qa/rpc-tests/wallet-dump.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 5a3f75c80..a1901aeda 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -22,7 +22,7 @@ class ForkNotifyTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w', encoding='utf8') as f: pass # Just open then close to create zero-length file self.nodes.append(start_node(0, self.options.tmpdir, ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) @@ -44,7 +44,7 @@ class ForkNotifyTest(BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text = f.read() if len(alert_text) == 0: @@ -56,7 +56,7 @@ class ForkNotifyTest(BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text2 = f.read() if alert_text != alert_text2: diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 24373b257..cdeb94caa 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -26,7 +26,7 @@ class HTTPBasicsTest (BitcoinTestFramework): #Append rpcauth to bitcoin.conf before initialization rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" - with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a') as f: + with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a', encoding='utf8') as f: f.write(rpcauth+"\n") f.write(rpcauth2+"\n") diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 1fb4870e1..fc3edddde 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -72,7 +72,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): def setup_network(self): self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file - with open(self.alert_filename, 'w') as _: + with open(self.alert_filename, 'w', encoding='utf8') as _: pass self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) @@ -95,7 +95,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): peer.sync_with_ping() def test_versionbits_in_alert_file(self): - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text = f.read() assert(VB_PATTERN.match(alert_text)) @@ -146,7 +146,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.nodes[0].generate(VB_PERIOD) stop_nodes(self.nodes) # Empty out the alert file - with open(self.alert_filename, 'w') as _: + with open(self.alert_filename, 'w', encoding='utf8') as _: pass self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index 23fce6101..13b33869f 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -50,7 +50,7 @@ class AuthServiceProxyWrapper(object): rpc_method = self.auth_service_proxy_instance._service_name if self.coverage_logfile: - with open(self.coverage_logfile, 'a+') as f: + with open(self.coverage_logfile, 'a+', encoding='utf8') as f: f.write("%s\n" % rpc_method) return return_val @@ -100,7 +100,7 @@ def write_all_rpc_commands(dirname, node): if line and not line.startswith('='): commands.add("%s\n" % line.split()[0]) - with open(filename, 'w') as f: + with open(filename, 'w', encoding='utf8') as f: f.writelines(list(commands)) return True diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index 573b06772..b92a9f6e1 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -58,7 +58,7 @@ def netstat(typ='tcp'): To get pid of all network process running on system, you must run this script as superuser ''' - with open('/proc/net/'+typ,'r') as f: + with open('/proc/net/'+typ,'r',encoding='utf8') as f: content = f.readlines() content.pop(0) result = [] diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 53db1cc49..47cebf4f6 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -157,7 +157,7 @@ def initialize_datadir(dirname, n): if not os.path.isdir(datadir): os.makedirs(datadir) rpc_u, rpc_p = rpc_auth_pair(n) - with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: + with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f: f.write("regtest=1\n") f.write("rpcuser=" + rpc_u + "\n") f.write("rpcpassword=" + rpc_p + "\n") diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py index 6028d2c20..a37096a40 100755 --- a/qa/rpc-tests/wallet-dump.py +++ b/qa/rpc-tests/wallet-dump.py @@ -12,7 +12,7 @@ def read_dump(file_name, addrs, hd_master_addr_old): Read the given dump, count the addrs that match, count change and reserve. Also check that the old hd_master is inactive """ - with open(file_name) as inputfile: + with open(file_name, encoding='utf8') as inputfile: found_addr = 0 found_addr_chg = 0 found_addr_rsv = 0 From b98734843520bc09d11ab76842de420479468801 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 4 Oct 2016 22:20:07 +0000 Subject: [PATCH 1065/1223] Bugfix: Trivial: RPC: getblockchaininfo help: pruneheight is the lowest, not highest, block Github-Pull: #8884 Rebased-From: a78e5428acb862bfb47e6faff39f4889f5c73269 --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d95be05c3..6f97671f5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -894,7 +894,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" - " \"pruneheight\": xxxxxx, (numeric) heighest block available\n" + " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" " \"softforks\": [ (array) status of softforks in progress\n" " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" From b73f0653f30168db84b4521e5f315e53804feced Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 4 Oct 2016 15:17:19 -0400 Subject: [PATCH 1066/1223] [qa] Another attempt to fix race condition in p2p-compactblocks.py sync_with_ping() only guarantees that the node has processed messages it's received from the peer, not that block announcements from the node have made it back to the peer. Replace sync_with_ping() with an explicit check that the node's tip has been announced. Github-Pull: #8882 Rebased-From: 6976db2f4687d575e1b4bee5aaf1d93a794f23c3 --- qa/rpc-tests/p2p-compactblocks.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index ac4655a84..cd6804376 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -28,6 +28,10 @@ class TestNode(SingleNodeConnCB): self.last_getblocktxn = None self.last_block = None self.last_blocktxn = None + # Store the hashes of blocks we've seen announced. + # This is for synchronizing the p2p message traffic, + # so we can eg wait until a particular block is announced. + self.set_announced_blockhashes = set() def on_sendcmpct(self, conn, message): self.last_sendcmpct = message @@ -38,14 +42,22 @@ class TestNode(SingleNodeConnCB): def on_cmpctblock(self, conn, message): self.last_cmpctblock = message self.block_announced = True + self.last_cmpctblock.header_and_shortids.header.calc_sha256() + self.set_announced_blockhashes.add(self.last_cmpctblock.header_and_shortids.header.sha256) def on_headers(self, conn, message): self.last_headers = message self.block_announced = True + for x in self.last_headers.headers: + x.calc_sha256() + self.set_announced_blockhashes.add(x.sha256) def on_inv(self, conn, message): self.last_inv = message - self.block_announced = True + for x in self.last_inv.inv: + if x.type == 2: + self.block_announced = True + self.set_announced_blockhashes.add(x.hash) def on_getdata(self, conn, message): self.last_getdata = message @@ -85,6 +97,12 @@ class TestNode(SingleNodeConnCB): assert(self.received_block_announcement()) self.clear_block_announcement() + # Block until a block announcement for a particular block hash is + # received. + def wait_for_block_announcement(self, block_hash, timeout=30): + def received_hash(): + return (block_hash in self.set_announced_blockhashes) + return wait_until(received_hash, timeout=timeout) class CompactBlocksTest(BitcoinTestFramework): def __init__(self): @@ -237,7 +255,9 @@ class CompactBlocksTest(BitcoinTestFramework): for i in range(num_transactions): self.nodes[0].sendtoaddress(address, 0.1) - self.test_node.sync_with_ping() + # Wait until we've seen the block announcement for the resulting tip + tip = int(self.nodes[0].getbestblockhash(), 16) + assert(self.test_node.wait_for_block_announcement(tip)) # Now mine a block, and look at the resulting compact block. self.test_node.clear_block_announcement() From d6c83b95cff2ff290533593719d6501ecf128f13 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 6 Oct 2016 14:21:11 -0400 Subject: [PATCH 1067/1223] [qa] Fix race condition in sendheaders.py Also de-duplicates code that has been moved to mininode Github-Pull: #8882 Rebased-From: b55d9411e7e1aa36ddabba3b942f2e1c736c1bd9 --- qa/rpc-tests/sendheaders.py | 68 ++++++++++++++----------------------- 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index c3f3180b6..81b2442e6 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -80,20 +80,19 @@ e. Announce one more that doesn't connect. Expect: disconnect. ''' -class BaseNode(NodeConnCB): +direct_fetch_response_time = 0.05 + +class BaseNode(SingleNodeConnCB): def __init__(self): - NodeConnCB.__init__(self) - self.connection = None + SingleNodeConnCB.__init__(self) self.last_inv = None self.last_headers = None self.last_block = None - self.ping_counter = 1 - self.last_pong = msg_pong(0) self.last_getdata = None - self.sleep_time = 0.05 self.block_announced = False self.last_getheaders = None self.disconnected = False + self.last_blockhash_announced = None def clear_last_announcement(self): with mininode_lock: @@ -101,9 +100,6 @@ class BaseNode(NodeConnCB): self.last_inv = None self.last_headers = None - def add_connection(self, conn): - self.connection = conn - # Request data for a list of block hashes def get_data(self, block_hashes): msg = msg_getdata() @@ -122,17 +118,17 @@ class BaseNode(NodeConnCB): msg.inv = [CInv(2, blockhash)] self.connection.send_message(msg) - # Wrapper for the NodeConn's send_message function - def send_message(self, message): - self.connection.send_message(message) - def on_inv(self, conn, message): self.last_inv = message self.block_announced = True + self.last_blockhash_announced = message.inv[-1].hash def on_headers(self, conn, message): self.last_headers = message - self.block_announced = True + if len(message.headers): + self.block_announced = True + message.headers[-1].calc_sha256() + self.last_blockhash_announced = message.headers[-1].sha256 def on_block(self, conn, message): self.last_block = message.block @@ -141,9 +137,6 @@ class BaseNode(NodeConnCB): def on_getdata(self, conn, message): self.last_getdata = message - def on_pong(self, conn, message): - self.last_pong = message - def on_getheaders(self, conn, message): self.last_getheaders = message @@ -157,7 +150,7 @@ class BaseNode(NodeConnCB): expect_headers = headers if headers != None else [] expect_inv = inv if inv != None else [] test_function = lambda: self.block_announced - self.sync(test_function) + assert(wait_until(test_function, timeout=60)) with mininode_lock: self.block_announced = False @@ -180,30 +173,14 @@ class BaseNode(NodeConnCB): return success # Syncing helpers - def sync(self, test_function, timeout=60): - while timeout > 0: - with mininode_lock: - if test_function(): - return - time.sleep(self.sleep_time) - timeout -= self.sleep_time - raise AssertionError("Sync failed to complete") - - def sync_with_ping(self, timeout=60): - self.send_message(msg_ping(nonce=self.ping_counter)) - test_function = lambda: self.last_pong.nonce == self.ping_counter - self.sync(test_function, timeout) - self.ping_counter += 1 - return - def wait_for_block(self, blockhash, timeout=60): test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_getheaders(self, timeout=60): test_function = lambda: self.last_getheaders != None - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_getdata(self, hash_list, timeout=60): @@ -211,12 +188,17 @@ class BaseNode(NodeConnCB): return test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_disconnect(self, timeout=60): test_function = lambda: self.disconnected - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) + return + + def wait_for_block_announcement(self, block_hash, timeout=60): + test_function = lambda: self.last_blockhash_announced == block_hash + assert(wait_until(test_function, timeout=timeout)) return def send_header_for_blocks(self, new_blocks): @@ -266,7 +248,9 @@ class SendHeadersTest(BitcoinTestFramework): def mine_reorg(self, length): self.nodes[0].generate(length) # make sure all invalidated blocks are node0's sync_blocks(self.nodes, wait=0.1) - [x.clear_last_announcement() for x in self.p2p_connections] + for x in self.p2p_connections: + x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16)) + x.clear_last_announcement() tip_height = self.nodes[1].getblockcount() hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1)) @@ -495,7 +479,7 @@ class SendHeadersTest(BitcoinTestFramework): test_node.send_header_for_blocks(blocks) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=direct_fetch_response_time) [ test_node.send_message(msg_block(x)) for x in blocks ] @@ -526,13 +510,13 @@ class SendHeadersTest(BitcoinTestFramework): # both blocks (same work as tip) test_node.send_header_for_blocks(blocks[1:2]) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=direct_fetch_response_time) # Announcing 16 more headers should trigger direct fetch for 14 more # blocks test_node.send_header_for_blocks(blocks[2:18]) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=direct_fetch_response_time) # Announcing 1 more header should not trigger any response test_node.last_getdata = None From 49be9f0c88b2bb8d1409c138f92e0cf753807353 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Fri, 7 Oct 2016 13:05:53 +0200 Subject: [PATCH 1068/1223] Fix wake from sleep issue with Boost 1.59.0 --- depends/packages/boost.mk | 2 ++ .../boost/fix-win-wake-from-sleep.patch | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 depends/patches/boost/fix-win-wake-from-sleep.patch diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index ef1307c24..2bedbc6f1 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -3,6 +3,7 @@ $(package)_version=1_59_0 $(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.59.0 $(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca +$(package)_patches=fix-win-wake-from-sleep.patch define $(package)_set_vars $(package)_config_opts_release=variant=release @@ -25,6 +26,7 @@ $(package)_cxxflags_linux=-fPIC endef define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/fix-win-wake-from-sleep.patch && \ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$(boost_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef diff --git a/depends/patches/boost/fix-win-wake-from-sleep.patch b/depends/patches/boost/fix-win-wake-from-sleep.patch new file mode 100644 index 000000000..8fb4d3028 --- /dev/null +++ b/depends/patches/boost/fix-win-wake-from-sleep.patch @@ -0,0 +1,31 @@ +--- old/libs/thread/src/win32/thread.cpp ++++ new/libs/thread/src/win32/thread.cpp +@@ -645,7 +645,7 @@ + } Detailed; + } Reason; + } REASON_CONTEXT, *PREASON_CONTEXT; +- static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"}; ++ //static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"}; + typedef BOOL (WINAPI *setwaitabletimerex_t)(HANDLE, const LARGE_INTEGER *, LONG, PTIMERAPCROUTINE, LPVOID, PREASON_CONTEXT, ULONG); + static inline BOOL WINAPI SetWaitableTimerEx_emulation(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay) + { +@@ -715,7 +715,8 @@ + if(time_left.milliseconds/20>tolerable) // 5% + tolerable=time_left.milliseconds/20; + LARGE_INTEGER due_time=get_due_time(target_time); +- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; +@@ -799,7 +800,8 @@ + if(time_left.milliseconds/20>tolerable) // 5% + tolerable=time_left.milliseconds/20; + LARGE_INTEGER due_time=get_due_time(target_time); +- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; From 5e0dd9e07c02422a263cc14a173d4ee21a7c1393 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 5 Oct 2016 16:47:57 +0800 Subject: [PATCH 1069/1223] [Doc] Update bips.md for Segregated Witness Github-Pull: #8891 Rebased-From: ef28d8a899aeb4487ef7fbfbfca9c0f2b60bdaf6 --- doc/bips.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/bips.md b/doc/bips.md index 039d5114f..040439fbc 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -26,4 +26,9 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). +* [`BIP 141`](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki): Segregated Witness (Consensus Layer) as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 143`](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki): Transaction Signature Verification for Version 0 Witness Program as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 144`](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki): Segregated Witness as of **0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 145`](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki): getblocktemplate updates for Segregated Witness as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636)). * [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)). From 7634d8eac4a5a727b77b4a7e2521bc2b95f53e5a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 11 Oct 2016 17:41:45 +0200 Subject: [PATCH 1070/1223] qt: Translate all files, even if wallet disabled This passes all QT cpp files to the lupdate executable which extracts translations, no matter what conditional functionality is enabled. Rebased-From: 8aed5f6c23cbaae6bf56be04f2b8d861eacf588d Github-Pull: #8911 --- src/Makefile.qt.include | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 7730aba37..7b01be9ab 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -280,7 +280,7 @@ RES_ICONS = \ qt/res/icons/verify.png \ qt/res/icons/transaction_abandoned.png -BITCOIN_QT_CPP = \ +BITCOIN_QT_BASE_CPP = \ qt/bantablemodel.cpp \ qt/bitcoinaddressvalidator.cpp \ qt/bitcoinamountfield.cpp \ @@ -303,12 +303,9 @@ BITCOIN_QT_CPP = \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp -if TARGET_WINDOWS -BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp -endif +BITCOIN_QT_WINDOWS_CPP = qt/winshutdownmonitor.cpp -if ENABLE_WALLET -BITCOIN_QT_CPP += \ +BITCOIN_QT_WALLET_CPP = \ qt/addressbookpage.cpp \ qt/addresstablemodel.cpp \ qt/askpassphrasedialog.cpp \ @@ -335,6 +332,13 @@ BITCOIN_QT_CPP += \ qt/walletmodel.cpp \ qt/walletmodeltransaction.cpp \ qt/walletview.cpp + +BITCOIN_QT_CPP = $(BITCOIN_QT_BASE_CPP) +if TARGET_WINDOWS +BITCOIN_QT_CPP += $(BITCOIN_QT_WINDOWS_CPP) +endif +if ENABLE_WALLET +BITCOIN_QT_CPP += $(BITCOIN_QT_WALLET_CPP) endif RES_IMAGES = @@ -403,7 +407,7 @@ $(srcdir)/qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wal @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^ -translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) +translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/bitcoin_en.ts From 633c4a1f3690152bdda4b0ac7bcfde22c237183e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 13 Oct 2016 10:26:44 +0000 Subject: [PATCH 1071/1223] qt: Periodic translations update Added languages: - `ne` - Niger --- src/Makefile.qt.include | 3 +- src/qt/bitcoin_locale.qrc | 3 +- src/qt/bitcoinstrings.cpp | 5 +- src/qt/locale/bitcoin_af.ts | 464 ++++++++- src/qt/locale/bitcoin_ar.ts | 2 +- src/qt/locale/bitcoin_cs.ts | 4 - src/qt/locale/bitcoin_da.ts | 10 +- src/qt/locale/bitcoin_de.ts | 58 +- src/qt/locale/bitcoin_en.ts | 1590 ++++++++++++++++++++++++++++- src/qt/locale/bitcoin_en_GB.ts | 12 +- src/qt/locale/bitcoin_es.ts | 8 +- src/qt/locale/bitcoin_fa.ts | 82 +- src/qt/locale/bitcoin_fi.ts | 202 +++- src/qt/locale/bitcoin_fr.ts | 194 ++-- src/qt/locale/bitcoin_it.ts | 218 +++- src/qt/locale/bitcoin_it_IT.ts | 4 + src/qt/locale/bitcoin_ja.ts | 8 +- src/qt/locale/bitcoin_ko_KR.ts | 218 +++- src/qt/locale/bitcoin_nb.ts | 36 + src/qt/locale/bitcoin_ne.ts | 548 ++++++++++ src/qt/locale/bitcoin_nl.ts | 44 +- src/qt/locale/bitcoin_pl.ts | 4 + src/qt/locale/bitcoin_pt_BR.ts | 48 +- src/qt/locale/bitcoin_pt_PT.ts | 4 - src/qt/locale/bitcoin_ro.ts | 598 ++++++++++- src/qt/locale/bitcoin_ru.ts | 28 +- src/qt/locale/bitcoin_ru_RU.ts | 14 +- src/qt/locale/bitcoin_sk.ts | 64 ++ src/qt/locale/bitcoin_sl_SI.ts | 42 +- src/qt/locale/bitcoin_sr@latin.ts | 182 +++- src/qt/locale/bitcoin_sv.ts | 12 +- src/qt/locale/bitcoin_tr.ts | 8 +- src/qt/locale/bitcoin_zh_CN.ts | 43 +- src/qt/locale/bitcoin_zh_TW.ts | 8 +- 34 files changed, 4556 insertions(+), 212 deletions(-) create mode 100644 src/qt/locale/bitcoin_ne.ts diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 7b01be9ab..bbef64176 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -7,8 +7,8 @@ QT_TS = \ qt/locale/bitcoin_af_ZA.ts \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ - qt/locale/bitcoin_bg.ts \ qt/locale/bitcoin_bg_BG.ts \ + qt/locale/bitcoin_bg.ts \ qt/locale/bitcoin_ca_ES.ts \ qt/locale/bitcoin_ca.ts \ qt/locale/bitcoin_ca@valencia.ts \ @@ -60,6 +60,7 @@ QT_TS = \ qt/locale/bitcoin_mn.ts \ qt/locale/bitcoin_ms_MY.ts \ qt/locale/bitcoin_nb.ts \ + qt/locale/bitcoin_ne.ts \ qt/locale/bitcoin_nl.ts \ qt/locale/bitcoin_pam.ts \ qt/locale/bitcoin_pl.ts \ diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index 8dd07c3d4..aae07ffb7 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -4,8 +4,8 @@ locale/bitcoin_af_ZA.qm locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm - locale/bitcoin_bg.qm locale/bitcoin_bg_BG.qm + locale/bitcoin_bg.qm locale/bitcoin_ca_ES.qm locale/bitcoin_ca.qm locale/bitcoin_ca@valencia.qm @@ -57,6 +57,7 @@ locale/bitcoin_mn.qm locale/bitcoin_ms_MY.qm locale/bitcoin_nb.qm + locale/bitcoin_ne.qm locale/bitcoin_nl.qm locale/bitcoin_pam.qm locale/bitcoin_pl.qm diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index fefaaf8cd..b64ae5c70 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -84,8 +84,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Fees (in %s/kB) smaller than this are considered zero fee for transaction " "creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Force relay of transactions from whitelisted peers even they violate local " -"relay policy (default: %d)"), +"Force relay of transactions from whitelisted peers even if they violate " +"local relay policy (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -325,6 +325,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Starting network threads..."), QT_TRANSLATE_NOOP("bitcoin-core", "The source code is available from %s."), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 97ada8dd5..8305b7060 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -21,6 +21,10 @@ &Copy &Dupliseer
+ + C&lose + S&luit + Delete the currently selected address from the list Verwyder die adres wat u gekies het van die lys @@ -86,14 +90,42 @@ &Transactions &Transaksies + + Browse transaction history + Blaai deur transaksiegeskiedenis + + + E&xit + &Sluit + Quit application Stop en verlaat die applikasie + + &About %1 + &Oor %1 + + + Show information about %1 + Wys inligting oor %1 + + + About &Qt + Oor &Qt + + + Show information about Qt + Wys inligting oor Qt + &Options... &Opsies + + Modify configuration options for %1 + Verander konfigurasie-opsies vir %1 + &Encrypt Wallet... &Kodifiseer Beursie @@ -170,6 +202,10 @@ &Help &Help + + Tabs toolbar + Orebalk + Request payments (generates QR codes and bitcoin: URIs) Versoek betalings (genereer QR-kodes en bitcoin: URI's) @@ -186,39 +222,383 @@ Open a bitcoin: URI or payment request Skep 'n bitcoin: URI of betalingsversoek + + Indexing blocks on disk... + Blokke op skyf word geïndekseer... + + + Processing blocks on disk... + Blokke op skyf word geprosesseer... + + + No block source available... + Geen blokbron beskikbaar... + + + Processed %n block(s) of transaction history. + %n blok van transaksiegeskiedenis geprosesseer.%n blokke van transaksiegeskiedenis geprosesseer. + + + %n hour(s) + %n uur%n ure + + + %n day(s) + %n dag%n dae + + + %n week(s) + %n week%n weke + + + %1 and %2 + %1 en %2 + + + %n year(s) + %n jaar%n jare + + + %1 behind + %1 agter + + + Last received block was generated %1 ago. + Laaste ontvange blok is %1 gelede gegenereer. + + + Transactions after this will not yet be visible. + Transaksies hierna sal nog nie sigbaar wees nie. + + + Error + Fout + + + Warning + Waarskuwing + + + Information + Inligting + + + Up to date + Op datum + + + Catching up... + Word op datum gebring... + + + Date: %1 + + Datum: %1 + + + + Address: %1 + + Adres: %1 + + + + Sent transaction + Gestuurde transaksie + + + Incoming transaction + Inkomende transaksie +
CoinControlDialog - + + Bytes: + Grepe: + + + Priority: + Prioriteit: + + + Fee: + Fooi: + + + Dust: + Stof: + + + After Fee: + Na Fooi: + + + (un)select all + (de)selekteer alle + + + List mode + Lysmodus + + + Date + Datum + + + Confirmations + Bevestigings + + + Confirmed + Bevestig + + + Priority + Prioriteit + + EditAddressDialog + + Edit Address + Wysig Adres + FreespaceChecker + + name + naam + HelpMessageDialog - + + version + weergawe + + + About %1 + Ongeveer %1 + + + UI Options: + Gebruikerkoppelvlakopsies: + + + Start minimized + Begin geminimeer + + + Reset all settings changed in the GUI + Alle instellings wat in die grafiese gebruikerkoppelvlak gewysig is, terugstel + + Intro + + Welcome + Welkom + + + Welcome to %1. + Welkom by %1. + + + Error + Fout + OpenURIDialog OptionsDialog + + Options + Opsies + + + MB + MG + + + Accept connections from outside + Verbindings van buite toelaat + + + Allow incoming connections + Inkomende verbindings toelaat + + + Reset all client options to default. + Alle kliëntopsies na verstek terugstel. + + + Expert + Kenner + + + IPv6 + IPv6 + + + Tor + Tor + + + default + verstek + + + none + geen + + + Confirm options reset + Bevestig terugstel van opsies + + + Client restart required to activate changes. + Kliënt moet herbegin word om veranderinge te aktiveer. + OverviewPage + + Available: + Beskikbaar: + + + Pending: + Hangend: + + + Immature: + Onvolwasse: + + + Balances + Balanse + + + Total: + Totaal: + + + Your current total balance + U huidige totale balans + + + Spendable: + Besteebaar: + + + Recent transactions + Onlangse transaksies + PeerTableModel + + User Agent + Gebruikeragent + QObject - + + %1 d + %1 d + + + %1 h + %1 u + + + %1 m + %1 m + + + %1 s + %1 s + + + None + Geen + + + N/A + n.v.t. + + + %1 ms + %1 ms + + RPCConsole + + N/A + n.v.t. + + + Client version + Kliëntweergawe + + + General + Algemeen + + + Network + Netwerk + + + Name + Naam + + + Number of connections + Aantal verbindings + + + Block chain + Blokketting + + + Current number of blocks + Huidige aantal blokke + + + Received + Ontvang + + + Sent + Gestuur + + + Banned peers + Verbanne porture + + + Whitelisted + Gewitlys + + + Direction + Rigting + + + Version + Weergawe + + + User Agent + Gebruikeragent + ReceiveCoinsDialog @@ -228,6 +608,50 @@ SendCoinsDialog + + Bytes: + Grepe: + + + Priority: + Prioriteit: + + + Fee: + Fooi: + + + After Fee: + Na Fooi: + + + Transaction Fee: + Transaksiefooi: + + + Choose... + Kies... + + + per kilobyte + per kilogreep + + + Hide + Versteek + + + total at least + totaal ten minste + + + Dust: + Stof: + + + Balance: + Balans: + SendCoinsEntry @@ -256,9 +680,41 @@ Bitcoin Core Bitcoin Kern + + Information + Inligting + + + Warning + Waarskuwing + Do not keep transactions in the mempool longer than <n> hours (default: %u) Moenie transaksies vir langer as <n> ure in die geheuepoel hou nie (verstek: %u) - + + Insufficient funds + Onvoldoende fondse + + + Loading block index... + Blokindeks word gelaai... + + + Loading wallet... + Beursie word gelaai... + + + Rescanning... + Word herskandeer... + + + Done loading + Klaar met laai + + + Error + Fout + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index af62207df..2e1603bb8 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -23,7 +23,7 @@ C&lose - &اغلاق + ا&غلاق Delete the currently selected address from the list diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 4f198c9ae..0b28956ff 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -1810,10 +1810,6 @@ Location of the auth cookie (default: data dir) Místo pro autentizační cookie (výchozí: adresář pro data) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimální počet bajtů na každý sigop v transakcích, které přeposíláme a těžíme (výchozí: %u) - Not enough file descriptors available. Je nedostatek deskriptorů souborů. diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 5fc6733b5..8675f8aa6 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -605,7 +605,7 @@ (of %n GB needed) - (ud af %n GB behøvet)(ud af %n GB behøvet) + (ud af %n GB nødvendig)(ud af %n GB nødvendig) @@ -1830,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Tilsvarende bytes pr. sigop i transaktioner, som videresendes og mines (standard: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Fejl under indlæsning af %s: Du kan ikke aktivere HD på en allerede eksisterende ikke-HD-tegnebog @@ -2054,10 +2058,6 @@ Location of the auth cookie (default: data dir) Placering for autentificerings-cookie (standard: datamappe) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum bytes pr. sigop i transaktioner, vi videresender og miner (standard: %u) - Not enough file descriptors available. For få tilgængelige fildeskriptorer. diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index dc632a246..498baf97e 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -112,7 +112,7 @@ &About %1 - &Über %1 + Über %1 Show information about %1 @@ -1758,10 +1758,18 @@ Prune configured below the minimum of %d MiB. Please use a higher number. Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert. + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune (Kürzung): Die letzte Syncronisation der Wallet liegt vor gekürzten (gelöschten) Blöcken. Es ist ein -reindex (download der gesamten Blockkette) notwendig. + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus ist nicht mit -txindex und -rescan kompatibel. Warnung: Die Umkehr dieser Einstellung erfordert das erneute Herunterladen der gesamten Blockkette. (Standard: 0 = deaktiviert das Kürzen von Blöcken, >%u = Zielgröße in MiB, die für Blockdateien verwendet werden darf) + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Rescans sind im pruned mode nicht möglich. Ein -reindex ist notwendig, welcher die gesmate Blockkette erneut herunterlädt. + Error: A fatal internal error occurred, see debug.log for details Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details. @@ -1798,6 +1806,10 @@ A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) Eine Transaktionsgebühr (in %s/kB) wird genutzt, wenn für die Gebührenschützung zu wenig Daten vorliegen (Standardwert: %s) + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Geben Sie immer die Transaktionen, die Sie von freigegebenen Peers erhalten haben, weiter (Voreinstellung: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden @@ -1814,6 +1826,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u) + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt) @@ -1822,6 +1838,14 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da %s ansonsten nicht ordnungsgemäß funktionieren wird. @@ -1842,6 +1866,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen! + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um zum ungekürzten Modus zurückzukehren. Dies erfordert, dass die gesamte Blockkette erneut heruntergeladen wird. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist) @@ -1938,6 +1966,10 @@ Enable publish raw transaction in <address> Aktiviere das Veröffentlichen der Roh-Transaktion in <address> + + Enable transaction replacement in the memory pool (default: %u) + Maximal <n> nicht-verbindbare Transaktionen im Speicher halten (Standard: %u) + Error initializing block database Fehler beim Initialisieren der Blockdatenbank @@ -2030,10 +2062,26 @@ Prune mode is incompatible with -txindex. Kürzungsmodus ist nicht mit -txindex kompatibel. + + Rebuild chain state and block index from the blk*.dat files on disk + Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen + + + Rebuild chain state from the currently indexed blocks + Blockkettenindex aus aktuellen Dateien blk000??.dat wiederaufbauen + + + Rewinding blocks... + Verifiziere Blöcke... + Set database cache size in megabytes (%d to %d, default: %d) Größe des Datenbankcaches in Megabyte festlegen (%d bis %d, Standard: %d) + + Set maximum BIP141 block weight (default: %d) + Maximales BIP141 Blockgewicht festlegen (Standard: %d) + Set maximum block size in bytes (default: %d) Maximale Blockgröße in Byte festlegen (Standard: %d) @@ -2082,6 +2130,10 @@ Wallet %s resides outside data directory %s Wallet %s liegt außerhalb des Datenverzeichnisses %s + + Wallet debugging/testing options: + Wallet Debugging-/Testoptionen: + Wallet options: Wallet-Optionen: @@ -2150,6 +2202,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Dieses Produkt enthält Software, die vom OpenSSL-Projekt zur Verwendung im OpenSSL-Toolkit <https://www.openssl.org/> entwickelt wird, sowie von Eric Young geschriebene kryptographische Software und von Thomas Bernard geschriebene UPnP-Software. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Erlaubte Gegenstellen werden nicht für DoS-Attacken gesperrt und ihre Transkationen werden immer weitergeleitet, auch wenn sie sich bereits im Speicherpool befinden, was z.B. für Gateways sinnvoll ist. diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 14126f2d6..7631a666c 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -53,6 +53,94 @@ &Delete &Delete + + + Choose the address to send coins to + + + + + Choose the address to receive coins with + + + + + C&hoose + + + + + Sending addresses + + + + + Receiving addresses + + + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + + + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + + + + + &Copy Address + + + + + Copy &Label + + + + + &Edit + + + + + Export Address List + + + + + Comma separated file (*.csv) + + + + + Exporting Failed + + + + + There was an error trying to save the address list to %1. Please try again. + + + + + AddressTableModel + + + Label + + + + + Address + + + + + (no label) + + AskPassphraseDialog @@ -76,6 +164,124 @@ Repeat new passphrase Repeat new passphrase + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old passphrase and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + + + + + Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was successfully changed. + + + + + + Warning: The Caps Lock key is on! + + BanTableModel @@ -442,7 +648,7 @@ Catching up... - + Date: %1 @@ -589,6 +795,189 @@ Priority + + + Copy address + + + + + Copy label + + + + + + Copy amount + + + + + Copy transaction ID + + + + + Lock unspent + + + + + Unlock unspent + + + + + Copy quantity + + + + + Copy fee + + + + + Copy after fee + + + + + Copy bytes + + + + + Copy priority + + + + + Copy dust + + + + + Copy change + + + + + highest + + + + + higher + + + + + high + + + + + medium-high + + + + + medium + + + + + low-medium + + + + + low + + + + + lower + + + + + lowest + + + + + (%1 locked) + + + + + none + + + + + yes + + + + + no + + + + + This label turns red if the transaction size is greater than 1000 bytes. + + + + + + This means a fee of at least %1 per kB is required. + + + + + Can vary +/- 1 byte per input. + + + + + Transactions with higher priority are more likely to get included into a block. + + + + + This label turns red if the priority is smaller than "medium". + + + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + + + + + Can vary +/- %1 satoshi(s) per input. + + + + + + (no label) + + + + + change from %1 (%2) + + + + + (change) + + EditAddressDialog @@ -617,6 +1006,46 @@ &Address &Address + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + The entered address "%1" is already in the address book. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + FreespaceChecker @@ -753,7 +1182,7 @@ - + Error Error @@ -796,6 +1225,11 @@ Select payment request file + + + Select payment request file to open + + OptionsDialog @@ -1192,6 +1626,132 @@ + + PaymentServer + + + + + + + + Payment request error + + + + + Cannot start bitcoin: click-to-pay handler + + + + + + + URI handling + + + + + Payment request fetch URL is invalid: %1 + + + + + Invalid payment address %1 + + + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + + + + + Payment request file handling + + + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + + + + + + + + + + Payment request rejected + + + + + Payment request network doesn't match client network. + + + + + Payment request expired. + + + + + Payment request is not initialized. + + + + + Unverified payment requests to custom payment scripts are unsupported. + + + + + + Invalid payment request. + + + + + Requested payment amount of %1 is too small (considered dust). + + + + + Refund from %1 + + + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + + + + + Error communicating with %1: %2 + + + + + Payment request cannot be parsed! + + + + + Bad response from server %1 + + + + + Network request error + + + + + Payment acknowledged + + + PeerTableModel @@ -1259,6 +1819,29 @@ + + QRImageWidget + + + &Save Image... + + + + + &Copy Image + + + + + Save QR Code + + + + + PNG Image (*.png) + + + RPCConsole @@ -1749,6 +2332,21 @@ Remove + + + Copy label + + + + + Copy message + + + + + Copy amount + + ReceiveRequestDialog @@ -1772,11 +2370,95 @@ &Save Image... + + + Request payment to %1 + + + + + Payment information + + + + + URI + + + + + Address + + + + + Amount + Amount + + + + Label + + + + + Message + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Error encoding URI into QR Code. + + + + + RecentRequestsTableModel + + + Date + Date + + + + Label + + + + + Message + + + + + (no label) + + + + + (no message) + + + + + (no amount requested) + + + + + Requested + + SendCoinsDialog + Send Coins Send Coins @@ -1962,6 +2644,152 @@ S&end S&end + + + Copy quantity + + + + + Copy amount + + + + + Copy fee + + + + + Copy after fee + + + + + Copy bytes + + + + + Copy priority + + + + + Copy dust + + + + + Copy change + + + + + + + + %1 to %2 + + + + + Are you sure you want to send? + + + + + added as transaction fee + + + + + Total Amount %1 + + + + + or + + + + + Confirm send coins + + + + + The recipient address is not valid. Please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found: addresses should only be used once each. + + + + + Transaction creation failed! + + + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + + + + A fee higher than %1 is considered an absurdly high fee. + + + + + Payment request expired. + + + + + Pay only the required fee of %1 + + + + + Estimated to begin confirmation within %n block(s). + + + + + + + + Warning: Invalid Bitcoin address + + + + + Warning: Unknown change address + + + + + (no label) + + SendCoinsEntry @@ -2066,6 +2894,20 @@ Memo: + + + Enter a label for this address to add it to your address book + + + + + SendConfirmationDialog + + + + Yes + + ShutdownWindow @@ -2190,6 +3032,77 @@ Reset all verify message fields Reset all verify message fields + + + Click "Sign Message" to generate signature + + + + + + The entered address is invalid. + + + + + + + + Please check the address and try again. + + + + + + The entered address does not refer to a key. + + + + + Wallet unlock was cancelled. + + + + + Private key for the entered address is not available. + + + + + Message signing failed. + + + + + Message signed. + + + + + The signature could not be decoded. + + + + + + Please check the signature and try again. + + + + + The signature did not match the message digest. + + + + + Message verification failed. + + + + + Message verified. + + SplashScreen @@ -2207,6 +3120,242 @@ + + TransactionDesc + + + Open for %n more block(s) + + + + + + + + Open until %1 + + + + + conflicted with a transaction with %1 confirmations + + + + + %1/offline + + + + + 0/unconfirmed, %1 + + + + + in memory pool + + + + + not in memory pool + + + + + abandoned + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + Status + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %n node(s) + + + + + + + + Date + Date + + + + Source + + + + + Generated + + + + + + + From + + + + + unknown + + + + + + + To + + + + + own address + + + + + + watch-only + + + + + label + + + + + + + + + Credit + + + + + matures in %n more block(s) + + + + + + + + not accepted + + + + + + + Debit + + + + + Total debit + + + + + Total credit + + + + + Transaction fee + + + + + Net amount + + + + + + Message + + + + + Comment + + + + + Transaction ID + + + + + Output index + + + + + Merchant + + + + + 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. + + + + + Debug information + + + + + Transaction + + + + + Inputs + + + + + Amount + Amount + + + + + true + + + + + + false + + + TransactionDescDialog @@ -2214,6 +3363,351 @@ This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction + + + Details for %1 + + + + + TransactionTableModel + + + Date + Date + + + + Type + + + + + Label + + + + + Open for %n more block(s) + + + + + + + + Open until %1 + + + + + Offline + + + + + Unconfirmed + + + + + Abandoned + + + + + Confirming (%1 of %2 recommended confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Conflicted + + + + + Immature (%1 confirmations, will be available after %2) + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + watch-only + + + + + (n/a) + + + + + (no label) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Whether or not a watch-only address is involved in this transaction. + + + + + User-defined intent/purpose of the transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Abandon transaction + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Copy transaction ID + + + + + Copy raw transaction + + + + + Copy full transaction details + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction History + + + + + Comma separated file (*.csv) + + + + + Confirmed + Confirmed + + + + Watch-only + + + + + Date + Date + + + + Type + + + + + Label + + + + + Address + + + + + ID + + + + + Exporting Failed + + + + + There was an error trying to save the transaction history to %1. + + + + + Exporting Successful + + + + + The transaction history was successfully saved to %1. + + + + + Range: + + + + + to + + UnitDisplayStatusBarControl @@ -2223,6 +3717,65 @@ + + WalletFrame + + + No wallet has been loaded. + + + + + WalletModel + + + Send Coins + Send Coins + + + + WalletView + + + &Export + &Export + + + + Export the data in the current tab to a file + Export the data in the current tab to a file + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to %1. + + + + + Backup Successful + + + + + The wallet data was successfully saved to %1. + + + bitcoin-core @@ -2296,12 +3849,12 @@ Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) @@ -2371,12 +3924,7 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - - - - + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) @@ -2702,6 +4250,11 @@ + Starting network threads... + + + + The source code is available from %s. @@ -2766,7 +4319,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -2806,7 +4359,12 @@ - + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) @@ -2961,7 +4519,7 @@ Signing transaction failed - + The transaction amount is too small to pay the fee @@ -3041,7 +4599,7 @@ - + Password for JSON-RPC connections Password for JSON-RPC connections @@ -3251,7 +4809,7 @@ - + Threshold for disconnecting misbehaving peers (default: %u) @@ -3261,7 +4819,7 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 596fd1db2..16a85ee34 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -1830,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Error loading %s: You can't enable HD on a already existing non-HD wallet @@ -2054,10 +2058,6 @@ Location of the auth cookie (default: data dir) Location of the auth cookie (default: data dir) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Not enough file descriptors available. Not enough file descriptors available. @@ -2098,6 +2098,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Set database cache size in megabytes (%d to %d, default: %d) + + Set maximum BIP141 block weight (default: %d) + Set maximum BIP141 block weight (default: %d) + Set maximum block size in bytes (default: %d) Set maximum block size in bytes (default: %d) diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 5e1187301..7b9425851 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1829,6 +1829,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Bytes equivalentes por sigop en transacciones para retrasmisión y minado (predeterminado: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Error cargando %s: No puede habilitar HD en un monedero existente que no es HD @@ -2053,10 +2057,6 @@ Location of the auth cookie (default: data dir) Ubicación de la cookie de autenticación (default: data dir) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Mínimo de bytes por sigop en transacciones que retransmitimos y minamos (predeterminado: %u) - Not enough file descriptors available. No hay suficientes descriptores de archivo disponibles. diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 98543ded4..a58743270 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -242,6 +242,10 @@ Show the list of used receiving addresses and labels نمایش لیست آدرس های دریافت و لیبل ها + + Open a bitcoin: URI or payment request + بازکردن یک بیت کوین: آدرس یا درخواست پرداخت + &Command-line options گزینه‌های خط‌فرمان @@ -488,6 +492,14 @@ command-line options گزینه‌های خط فرمان + + UI Options: + گزینه‌های رابط کاربری: + + + Show splash screen on startup (default: %u) + نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیش‌فرض: %u) + Intro @@ -522,7 +534,11 @@ Open URI بازکردن آدرس - + + Select payment request file + انتخاب فایل درخواست پرداخت + + OptionsDialog @@ -533,6 +549,10 @@ &Main &عمومی + + MB + مگابایت + Accept connections from outside پذیرش اتصالات از بیرون @@ -672,6 +692,10 @@ Your current spendable balance تراز علی‌الحساب شما + + Pending: + در انتظار: + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance مجموع تراکنش‌هایی که هنوز تأیید نشده‌اند؛ و هنوز روی تراز علی‌الحساب اعمال نشده‌اند @@ -718,6 +742,10 @@ Amount مبلغ + + Enter a Bitcoin address (e.g. %1) + یک آدرس بیت‌کوین وارد کنید (مثلاً %1) + %1 d %1 روز @@ -793,6 +821,10 @@ Current number of blocks تعداد فعلی بلوک‌ها + + Memory Pool + استخر حافظه + Memory usage مصرف حافظه @@ -813,6 +845,14 @@ Services سرویس ها + + Connection Time + مدت اتصال + + + Last Send + ارسال شده آخرین بار + Last Receive آخرین دریافتی @@ -908,6 +948,14 @@ &Message: پیام: + + Use this form to request payments. All fields are <b>optional</b>. + برای درخواست پرداخت از این فرم استفاده کنید.تمام قسمت ها <b>اختیاری<b> هستند. + + + Clear all fields of the form. + تمام قسمت های فرم را خالی کن. + Clear پاک‌کردن @@ -916,6 +964,10 @@ Show نمایش + + Remove the selected entries from the list + حذف ورودی های انتخاب‌شده از لیست + Remove حذف کردن @@ -942,6 +994,14 @@ Send Coins ارسال سکه + + Inputs... + ورودی‌ها... + + + automatically selected + به طور خودکار انتخاب شدند + Insufficient funds! بود جه نا کافی @@ -978,10 +1038,22 @@ Transaction Fee: هزینهٔ تراکنش: + + Choose... + انتخاب... + + + per kilobyte + در هر کیلوبایت + Hide پنهان کردن + + total at least + در مجموع حداقل + Recommended: توصیه شده: @@ -1010,6 +1082,10 @@ Add &Recipient &دریافت‌کنندهٔ جدید + + Clear all fields of the form. + تمام قسمت های فرم را خالی کن. + Clear &All پاکسازی &همه @@ -1370,6 +1446,10 @@ Loading addresses... بار گیری آدرس ها + + (default: %s) + (پیش‌فرض %s) + Invalid -proxy address: '%s' آدرس پراکسی اشتباه %s diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 4a2cc17f3..4be3085a4 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -114,6 +114,10 @@ &About %1 &Tietoja %1 + + Show information about %1 + Näytä tietoa aiheesta %1 + About &Qt Tietoja &Qt @@ -126,6 +130,10 @@ &Options... &Asetukset... + + Modify configuration options for %1 + Muuta kohteen %1 kokoonpanoasetuksia + &Encrypt Wallet... &Salaa lompakko... @@ -254,6 +262,14 @@ %n active connection(s) to Bitcoin network %n aktiivinen yhteys Bitcoin-verkkoon%n aktiivista yhteyttä Bitcoin-verkkoon + + Indexing blocks on disk... + Ladataan lohkoindeksiä... + + + Processing blocks on disk... + Käsitellään lohkoja levyllä... + No block source available... Lohkojen lähdettä ei saatavilla... @@ -310,6 +326,14 @@ Up to date Rahansiirtohistoria on ajan tasalla + + Show the %1 help message to get a list with possible Bitcoin command-line options + Näytä %1 ohjeet saadaksesi listan mahdollisista Bitcoinin komentorivivalinnoista + + + %1 client + %1-asiakas + Catching up... Saavutetaan verkkoa... @@ -496,6 +520,10 @@ (%1-bit) (%1-bit) + + About %1 + Tietoja %1 + Command-line options Komentorivi parametrit @@ -532,13 +560,29 @@ Show splash screen on startup (default: %u) Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u) - + + Reset all settings changed in the GUI + Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset + + Intro Welcome Tervetuloa + + Welcome to %1. + Tervetuloa %1 pariin. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Tämä on ensimmäinen kerta, kun %1 on käynnistetty, joten voit valita data-hakemiston paikan. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 lataa ja tallentaa kopion Bitcoinin lohkoketjusta. Vähintään %2Gt dataa tullaan tallentamaan tähän hakemistoon, ja tarve kasvaa ajan myötä. Lompakko tullaan myös tallentamaan tähän hakemistoon. + Use the default data directory Käytä oletuskansiota @@ -593,6 +637,14 @@ &Main &Yleiset + + Automatically start %1 after logging in to the system. + Käynnistä %1 automaattisesti järjestelmään kirjautumisen jälkeen. + + + &Start %1 on system login + &Käynnistä %1 järjestelmään kirjautuessa + Size of &database cache &Tietokannan välimuistin koko @@ -749,6 +801,10 @@ User Interface &language: &Käyttöliittymän kieli + + The user interface language can be set here. This setting will take effect after restarting %1. + Tässä voit määritellä käyttöliittymän kielen. Muutokset astuvat voimaan seuraavan kerran, kun %1 käynnistetään. + &Unit to show amounts in: Yksikkö jona bitcoin-määrät näytetään @@ -953,6 +1009,10 @@ Using BerkeleyDB version Käyttää BerkeleyDB-versiota + + Datadir + Data-hakemisto + Startup time Käynnistysaika @@ -1037,6 +1097,10 @@ User Agent Käyttöliittymä + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Avaa %1 -debug-loki tämänhetkisestä data-hakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille. + Decrease font size Pienennä fontin kokoa @@ -1481,6 +1545,10 @@ Remove this entry Poista tämä alkio + + 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. + Kulu vähennetään lähetettävästä määrästä. Saaja vastaanottaa vähemmän bitcoineja kuin merkitset Määrä-kenttään. Jos saajia on monia, kulu jaetaan tasan. + S&ubtract fee from amount V&ähennä maksukulu määrästä @@ -1714,6 +1782,14 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle. + + Cannot obtain a lock on data directory %s. %s is probably already running. + Ei voida lukita data-hakemistoa %s. %s on luultavasti jo käynnissä. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Jaettu MIT-ohjelmistolisenssin alla, katso mukana tullut tiedosto COPYING tai <http://www.opensource.org/licenses/mit-license.php>. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa) @@ -1722,10 +1798,18 @@ Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Tarkistathan että tietokoneesi päivämäärä ja kellonaika ovat oikeassa! Jos kellosi on väärässä, %s ei toimi oikein. + + Please contribute if you find %s useful. Visit %s for further information about the software. + Ole hyvä ja avusta, jos %s on mielestäsi hyödyllinen. Vieraile %s saadaksesi lisää tietoa ohjelmistosta. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d) + + 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 + Lohkotietokanta sisältää lohkon, joka vaikuttaa olevan tulevaisuudesta. Tämä saattaa johtua tietokoneesi virheellisesti asetetuista aika-asetuksista. Rakenna lohkotietokanta uudelleen vain jos olet varma, että tietokoneesi päivämäärä ja aika ovat oikein. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Tämä on esi-julkaistu testiversio - Käytä omalla riskillä - Ei saa käytää louhimiseen tai kauppasovelluksiin. @@ -1746,6 +1830,14 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Salli vertaisten yhdistää annetusta verkkomaskista tai IP-osoitteesta. Voidaan määrittää useampia kertoja. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex-chainstate vaihtaaksesi -txindex + + + %s corrupt, salvage failed + %s korruptoitunut, korjaaminen epäonnistui + -maxmempool must be at least %d MB -maxmempool on oltava vähintään %d MB @@ -1754,10 +1846,18 @@ <category> can be: <category> voi olla: + + Attempt to recover private keys from a corrupt wallet on startup + Yritä palauttaa yksityiset avaimet korruptoituneesta lompakosta käynnistyksen yhteydessä + Block creation options: Lohkon luonnin asetukset: + + Cannot resolve -%s address: '%s' + -%s -osoitteen '%s' selvittäminen epäonnistui + Connect only to the specified node(s) Yhidstä ainoastaan määrättyihin noodeihin @@ -1766,6 +1866,10 @@ Connection options: Yhteyden valinnat: + + Copyright (C) %i-%i + Tekijänoikeus (C) %i-%i + Corrupted block database detected Vioittunut lohkotietokanta havaittu @@ -1794,6 +1898,18 @@ Error initializing wallet database environment %s! Virhe alustaessa lompakon tietokantaympäristöä %s! + + Error loading %s + Virhe ladattaessa %s + + + Error loading %s: Wallet corrupted + Virhe ladattaessa %s: Lompakko vioittunut + + + Error loading %s: Wallet requires newer version of %s + Virhe ladattaessa %s: Tarvitset uudemman %s -version + Error loading block database Virhe avattaessa lohkoketjua @@ -1822,6 +1938,22 @@ Invalid -onion address: '%s' Virheellinen -onion osoite: '%s' + + Invalid amount for -%s=<amount>: '%s' + Virheellinen määrä -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Virheellinen määrä -fallbackfee=<amount>: '%s' + + + Loading banlist... + Ladataan kieltolistaa... + + + Location of the auth cookie (default: data dir) + Todennusevästeen sijainti (oletus: datahakemisto) + Not enough file descriptors available. Ei tarpeeksi tiedostomerkintöjä vapaana. @@ -1830,6 +1962,14 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Yhdistä vain solmukohtiin <net>-verkossa (ipv4, ipv6 tai onion) + + Print this help message and exit + Näytä tämä ohjeviesti ja poistu + + + Print version and exit + Näytä versio ja poistu. + Prune mode is incompatible with -txindex. Karsittu tila ei ole yhteensopiva -txindex:n kanssa. @@ -1838,6 +1978,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d + + Set maximum BIP141 block weight (default: %d) + Aseta suurin BIP141-lohkopaino (oletus: %d) + Set maximum block size in bytes (default: %d) Aseta lohkon maksimikoko tavuissa (oletus: %d) @@ -1846,6 +1990,22 @@ Specify wallet file (within data directory) Aseta lompakkotiedosto (data-hakemiston sisällä) + + The source code is available from %s. + Lähdekoodi löytyy %s. + + + Unsupported argument -benchmark ignored, use -debug=bench. + Argumenttia -benchmark ei tueta, käytä -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argumenttia -debugnet ei tueta, käytä -debug=net. + + + Unsupported argument -tor found, use -onion. + Argumenttia -tor ei tueta, käytä -onion. + Use UPnP to map the listening port (default: %u) Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u) @@ -1862,6 +2022,10 @@ Wallet %s resides outside data directory %s Lompakko %s sijaitsee data-hakemiston ulkopuolella %s + + Wallet needed to be rewritten: restart %s to complete + Lompakko tarvitsee uudelleenkirjoittaa: käynnistä %s uudelleen + Wallet options: Lompakon valinnat: @@ -1874,6 +2038,10 @@ Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) Paljasta omat IP-osoitteet (oletus: 1 kun kuunnellaan ja -externalip tai -proxy ei ole käytössä) + + Error: Listening for incoming connections failed (listen returned error %s) + Virhe: Saapuvien yhteyksien kuuntelu epäonnistui (kuuntelu palautti virheen %s) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Aja komento kun olennainen hälytys vastaanotetaan tai nähdään todella pitkä haara (%s komennossa korvataan viestillä) @@ -1882,6 +2050,14 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Aseta maksimikoko korkea prioriteetti/pieni palkkio rahansiirtoihin tavuissa (oletus: %d) + + The transaction amount is too small to send after the fee has been deducted + Siirtomäärä on liian pieni lähetettäväksi kulun vähentämisen jälkeen. + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + Tämä tuote sisältää ohjelmistoa, jonka on kehittänyt OpenSSL Project käytettäväksi OpenSSL Toolkit -ohjelmistossa <https://www.openssl.org/>, ja Eric Youngin kirjoittamaa salausohjelmistoa sekä Thomas Bernardin kirjoittamaa UPnP-ohjelmistoa. + (default: %u) (oletus: %u) @@ -1890,6 +2066,10 @@ Accept public REST requests (default: %u) Hyväksy julkisia REST-pyyntöjä (oletus: %u) + + Automatically create Tor hidden service (default: %d) + Luo Tor-salattu palvelu automaattisesti (oletus: %d) + Connect through SOCKS5 proxy Yhdistä SOCKS5 proxin kautta @@ -1898,14 +2078,30 @@ Error reading from database, shutting down. Virheitä tietokantaa luettaessa, ohjelma pysäytetään. + + Imports blocks from external blk000??.dat file on startup + Tuo lohkot ulkoisesta blk000??.dat -tiedostosta käynnistettäessä + Information Tietoa + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Kelvoton määrä argumentille -paytxfee=<amount>: '%s' (pitää olla vähintään %s) + + + Invalid netmask specified in -whitelist: '%s' + Kelvoton verkkopeite määritelty argumentissa -whitelist: '%s' + Keep at most <n> unconnectable transactions in memory (default: %u) Pidä enimmillään <n> yhdistämiskelvotonta rahansiirtoa muistissa (oletus: %u) + + Need to specify a port with -whitebind: '%s' + Pitää määritellä portti argumentilla -whitebind: '%s' + Node relay options: Välityssolmukohdan asetukset: @@ -2022,6 +2218,10 @@ How thorough the block verification of -checkblocks is (0-4, default: %u) Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) + + Output debugging information (default: %u, supplying <category> is optional) + Tulosta debuggaustieto (oletus: %u, annettu <category> valinnainen) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index ebfc773fb..ef27c6fc2 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -80,7 +80,7 @@ Synchronizing with network... - Synchronisation avec le réseau en cours… + Synchronisation avec le réseau… &Overview @@ -156,7 +156,7 @@ Open &URI... - Ouvrir un &URI... + Ouvrir une &URI... Reindexing blocks on disk... @@ -204,7 +204,7 @@ &Show / Hide - &Afficher / Cacher + &Afficher / Masquer Show or hide the main Window @@ -220,7 +220,7 @@ Verify messages to ensure they were signed with specified Bitcoin addresses - Vérifier les messages pour vous assurer qu'ils ont été signés avec les adresses Bitcoin spécifiées + Vérifier les messages pour s'assurer qu'ils ont été signés avec les adresses Bitcoin spécifiées &File @@ -228,7 +228,7 @@ &Settings - &Réglages + &Paramètres &Help @@ -240,7 +240,7 @@ Request payments (generates QR codes and bitcoin: URIs) - Demander des paiements (génère des codes QR et des URIs bitcoin:) + Demander des paiements (génère des codes QR et des URI bitcoin:) Show the list of used sending addresses and labels @@ -300,7 +300,7 @@ %1 behind - %1 en retard + en retard d'%1 Last received block was generated %1 ago. @@ -308,7 +308,7 @@ Transactions after this will not yet be visible. - Les transactions après ceci ne sont pas encore visibles. + Les transactions suivantes ne seront pas déjà visibles. Error @@ -336,7 +336,7 @@ Catching up... - Rattrapage en cours… + Rattrapage… Date: %1 @@ -425,7 +425,7 @@ (un)select all - Tout (dé)sélectionner + Tout (des)sélectionner Tree mode @@ -472,7 +472,7 @@ &Label - &Étiquette + É&tiquette The label associated with this address list entry @@ -480,7 +480,7 @@ The address associated with this address list entry. This can only be modified for sending addresses. - L'adresse associée à cette entrée de la liste d'adresses. Ceci ne peut être modifié que pour les adresses d'envoi. + L'adresse associée à cette entrée de la liste d'adresses. Cela ne peut être modifié que pour les adresses d'envoi. &Address @@ -499,7 +499,7 @@ Directory already exists. Add %1 if you intend to create a new directory here. - Le répertoire existe déjà. Ajoutez %1 si vous voulez créer un nouveau répertoire ici. + Le répertoire existe déjà. Ajouter %1 si vous comptez créer un nouveau répertoire ici. Path already exists, and is not a directory. @@ -605,18 +605,18 @@ (of %n GB needed) - (sur %n Go nécessaire)(sur %n Go nécessaires) + (sur %n Go requis)(sur %n Go requis) OpenURIDialog Open URI - Ouvrir un URI + Ouvrir une URI Open payment request from URI or file - Ouvrir une demande de paiement à partir d'un URI ou d'un fichier + Ouvrir une demande de paiement à partir d'une URI ou d'un fichier URI: @@ -635,7 +635,7 @@ &Main - Réglages &principaux + &Principaux Automatically start %1 after logging in to the system. @@ -655,7 +655,7 @@ Number of script &verification threads - Nombre d'exétrons de &vérification de script + Nombre de fils de &vérification de script Accept connections from outside @@ -667,7 +667,7 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) - Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1) + Adresse IP du mandataire (p. ex. IPv4 : 127.0.0.1 / IPv6 : ::1) 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. @@ -675,7 +675,7 @@ 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 |. - URL de tiers (par ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. + URL de tiers (p. ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. Third party transaction URLs @@ -691,7 +691,7 @@ &Reset Options - &Réinitialisation des options + &Réinitialiser les options &Network @@ -711,11 +711,11 @@ Enable coin &control features - Activer les fonctions de &contrôle des pièces + Activer les fonctions de &contrôle des pièces 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. - Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d'une transaction ne peut pas être utilisée tant que cette transaction n'a pas reçu au moins une confirmation. Ceci affecte aussi comment votre solde est calculé. + Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d'une transaction ne peut pas être utilisée tant que cette transaction n'a pas reçu au moins une confirmation. Celai affecte aussi le calcul de votre solde. &Spend unconfirmed change @@ -723,7 +723,7 @@ Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - Ouvrir le port du client Bitcoin automatiquement sur le routeur. Ceci ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée. + Ouvrir automatiquement le port du client Bitcoin sur le routeur. Cela ne fonctionne que si votre routeur prend en charge l'UPnP et si la fonction est activée. Map port using &UPnP @@ -739,7 +739,7 @@ Proxy &IP: - &IP du serveur mandataire : + &IP du mandataire : &Port: @@ -747,7 +747,7 @@ Port of the proxy (e.g. 9050) - Port du serveur mandataire (par ex. 9050) + Port du mandataire (p. ex. 9050) Used for reaching peers via: @@ -791,11 +791,11 @@ Show only a tray icon after minimizing the window. - Afficher uniquement une icône système après minimisation. + N'afficher qu'une icône dans la zone de notification après minimisation. &Minimize to the tray instead of the taskbar - &Minimiser dans la barre système au lieu de la barre des tâches + &Minimiser dans la zone de notification au lieu de la barre des tâches M&inimize on close @@ -819,7 +819,7 @@ Choose the default subdivision unit to show in the interface and when sending coins. - Choisissez la sous-unité par défaut pour l'affichage dans l'interface et lors de l'envoi de pièces. + Choisir la sous-unité par défaut d'affichage dans l'interface et lors d'envoi de pièces. Whether to show coin control features or not. @@ -847,7 +847,7 @@ Client restart required to activate changes. - Le redémarrage du client est nécessaire pour activer les changements. + Le redémarrage du client est exigé pour activer les changements. Client will be shut down. Do you want to proceed? @@ -882,7 +882,7 @@ Your current spendable balance - Votre solde actuel pouvant être dépensé + Votre solde actuel disponible Pending: @@ -890,7 +890,7 @@ Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total des transactions qui doivent encore être confirmées et qu'il n'est pas encore possible de dépenser + Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte dans le solde disponible Immature: @@ -1143,7 +1143,7 @@ The duration of a currently outstanding ping. - La durée d'un ping actuellement en cours. + La durée d'un ping en cours. Ping Wait @@ -1171,7 +1171,7 @@ &Clear - &Nettoyer + &Effacer Totals @@ -1187,11 +1187,11 @@ Debug log file - Journal de débogage + Fichier journal de débogage Clear console - Nettoyer la console + Effacer la console &Disconnect Node @@ -1227,7 +1227,7 @@ Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - Utiliser les touches de curseur pour naviguer dans l'historique et <b>Ctrl-L</b> pour effacer l'écran. + Utiliser les touches de déplacement pour naviguer dans l'historique et <b>Ctrl-L</b> pour effacer l'écran. Type <b>help</b> for an overview of available commands. @@ -1298,7 +1298,7 @@ Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. - Réutilise une adresse de réception précédemment utilisée. Réutiliser une adresse pose des problèmes de sécurité et de vie privée. N'utilisez pas cette option sauf si vous générez à nouveau une demande de paiement déjà faite. + Réutiliser une adresse de réception utilisée précédemment. Réutiliser une adresse comporte des problèmes de sécurité et de confidentialité. À ne pas utiliser, sauf pour générer une demande de paiement faite au préalable. R&euse an existing receiving address (not recommended) @@ -1306,19 +1306,19 @@ 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. - Un message optionnel à joindre à la demande de paiement qui sera affiché à l'ouverture de celle-ci. Note : le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. + Un message facultatif à joindre à la demande de paiement et qui sera affiché à l'ouverture de celle-ci. Note : le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. An optional label to associate with the new receiving address. - Un étiquette optionnelle à associer à la nouvelle adresse de réception + Un étiquette facultative à associer à la nouvelle adresse de réception. Use this form to request payments. All fields are <b>optional</b>. - Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>optionnels</b>. + Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>facultatifs</b>. An optional amount to request. Leave this empty or zero to not request a specific amount. - Un montant optionnel à demander. Laisser ceci vide ou à zéro pour ne pas demander de montant spécifique. + Un montant facultatif à demander. Ne rien saisir ou un zéro pour ne pas demander de montant spécifique. Clear all fields of the form. @@ -1334,11 +1334,11 @@ &Request payment - &Demande de paiement + &Demander un paiement Show the selected request (does the same as double clicking an entry) - Afficher la demande choisie (identique à un double-clic sur une entrée) + Afficher la demande choisie (comme double-cliquer sur une entrée) Show @@ -1346,11 +1346,11 @@ Remove the selected entries from the list - Enlever les entrées sélectionnées de la liste + Retirer les entrées sélectionnées de la liste Remove - Enlever + Retirer @@ -1369,7 +1369,7 @@ &Save Image... - &Sauvegarder l'image... + &Enregistrer l'image... @@ -1424,7 +1424,7 @@ If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Si ceci est actif mais l'adresse de monnaie rendue est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. + Si cette option est activée, et l'adresse de monnaie rendue est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. Custom change address @@ -1460,7 +1460,7 @@ Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. - Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que ceci pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter. + Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que cela pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter. (read the tooltip) @@ -1476,7 +1476,7 @@ (Smart fee not initialized yet. This usually takes a few blocks...) - (Les frais intelligents ne sont pas encore initialisés. Ceci prend habituellement quelques blocs...) + (Les frais intelligents ne sont pas encore initialisés. Cela prend habituellement quelques blocs...) Confirmation time: @@ -1508,7 +1508,7 @@ Clear &All - &Tout nettoyer + &Tout effacer Balance: @@ -1555,7 +1555,7 @@ Paste address from clipboard - Coller l'adresse depuis le presse-papiers + Coller l'adresse du presse-papiers Alt+P @@ -1563,7 +1563,7 @@ Remove this entry - Enlever cette entrée + Retirer cette entrée 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. @@ -1591,7 +1591,7 @@ 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. - Un message qui était joint à l'URI Bitcoin et qui sera stocké avec la transaction pour référence. Note : ce message ne sera pas envoyé par le réseau Bitcoin. + Un message qui était joint à l'URI bitcoin: et qui sera stocké avec la transaction pour référence. Note : ce message ne sera pas envoyé par le réseau Bitcoin. Pay To: @@ -1617,7 +1617,7 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Signatures - Signer / Vérifier un message + Signatures - Signer / vérifier un message &Sign Message @@ -1633,7 +1633,7 @@ Choose previously used address - Choisir une adresse précédemment utilisée + Choisir une adresse déjà utilisée Alt+A @@ -1641,7 +1641,7 @@ Paste address from clipboard - Coller une adresse depuis le presse-papiers + Coller une adresse du presse-papiers Alt+P @@ -1661,7 +1661,7 @@ Sign the message to prove you own this Bitcoin address - Signer le message pour prouver que vous détenez cette adresse Bitcoin + Signer le message afin de prouver que vous détenez cette adresse Bitcoin Sign &Message @@ -1673,7 +1673,7 @@ Clear &All - &Tout nettoyer + &Tout effacer &Verify Message @@ -1681,7 +1681,7 @@ 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! - Saisissez ci-dessous l'adresse de destinataire, le message (assurez-vous de copier exactement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faites attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d'être trompé par une attaque d'homme du milieu. Notez que ceci ne fait que prouver que le signataire reçoit l'adresse et ne peut pas prouver la provenance d'une transaction. + Saisir ci-dessous l'adresse du destinataire, le message (s'assurer de copier fidèlement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faire attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d'être trompé par une attaque d'homme du milieu. Prendre en compte que cela ne fait que prouver que le signataire reçoit l'adresse et ne peut pas prouver la provenance d'une transaction ! The Bitcoin address the message was signed with @@ -1689,7 +1689,7 @@ Verify the message to ensure it was signed with the specified Bitcoin address - Vérifier le message pour vous assurer qu'il a bien été signé par l'adresse Bitcoin spécifiée + Vérifier le message pour s'assurer qu'il a été signé avec l'adresse Bitcoin spécifiée Verify &Message @@ -1748,7 +1748,7 @@ Accept command line and JSON-RPC commands - Accepter les commandes de JSON-RPC et de la ligne de commande + Accepter les commandes JSON-RPC et en ligne de commande If <category> is not supplied or if <category> = 1, output all debugging information. @@ -1812,7 +1812,7 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 - Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6 + Se lier à l'adresse donnée et toujours l'écouter. Utiliser la notation [host]:port pour l'IPv6 Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup @@ -1822,6 +1822,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Octets équivalents par sigop dans les transactions pour relayer et miner (par défaut : %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Erreur de chargement de %s : vous ne pouvez pas activer HD sur un porte-monnaie non HD existant @@ -1844,7 +1848,7 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) - Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) + Définir le nombre de fils de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) 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 @@ -1852,7 +1856,7 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes + Ceci est une préversion de test - l'utiliser à vos risques - ne pas l'utiliser pour miner ou pour des applications marchandes Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain @@ -1860,7 +1864,7 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) - Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) + Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 en écoute et sans -proxy) Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. @@ -1900,7 +1904,7 @@ Block creation options: - Options de création de bloc : + Options de création de blocs : Cannot resolve -%s address: '%s' @@ -1924,7 +1928,7 @@ Corrupted block database detected - Base corrompue de données des blocs détectée + Une base de données de blocs corrompue a été détectée Debugging/Testing options: @@ -1936,7 +1940,7 @@ Do you want to rebuild the block database now? - Voulez-vous reconstruire la base de données des blocs maintenant ? + Voulez-vous reconstruire la base de données de blocs maintenant ? Enable publish hash block in <address> @@ -1956,23 +1960,23 @@ Error initializing block database - Erreur lors de l'initialisation de la base de données des blocs + Erreur d'initialisation de la base de données de blocs Error initializing wallet database environment %s! - Erreur lors de l'initialisation de l'environnement de la base de données du porte-monnaie %s ! + Erreur d'initialisation de l'environnement de la base de données du porte-monnaie %s ! Error loading %s - Erreur lors du chargement de %s + Erreur de chargement de %s Error loading %s: Wallet corrupted - Erreur lors du chargement de %s : porte-monnaie corrompu + Erreur de chargement de %s : porte-monnaie corrompu Error loading %s: Wallet requires newer version of %s - Erreur lors du chargement de %s : le porte-monnaie exige une version plus récente de %s + Erreur de chargement de %s : le porte-monnaie exige une version plus récente de %s Error loading %s: You can't disable HD on a already existing HD wallet @@ -1980,11 +1984,11 @@ Error loading block database - Erreur du chargement de la base de données des blocs + Erreur de chargement de la base de données de blocs Error opening block database - Erreur lors de l'ouverture de la base de données des blocs + Erreur d'ouverture de la base de données de blocs Error: Disk space is low! @@ -1992,7 +1996,7 @@ Failed to listen on any port. Use -listen=0 if you want this. - Échec de l'écoute sur un port quelconque. Utilisez -listen=0 si vous voulez ceci. + Échec d'écoute sur un port quelconque. Utiliser -listen=0 si vous le voulez. Importing... @@ -2000,7 +2004,7 @@ Incorrect or no genesis block found. Wrong datadir for network? - Bloc de genèse incorrect ou introuvable. Mauvais répertoire de données pour le réseau ? + Bloc de genèse incorrect ou introuvable. Mauvais datadir pour le réseau ? Invalid -onion address: '%s' @@ -2026,10 +2030,6 @@ Location of the auth cookie (default: data dir) Emplacement du fichier témoin auth (par défaut : data dir) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Octets minimaux par sigop dans les transactions que nous relayons et minons (par défaut : %u) - Not enough file descriptors available. Pas assez de descripteurs de fichiers proposés. @@ -2068,7 +2068,7 @@ Set database cache size in megabytes (%d to %d, default: %d) - Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) + Définir la taille du cache de la base de données en mégaoctets (%d à %d, default: %d) Set maximum BIP141 block weight (default: %d) @@ -2108,11 +2108,11 @@ Verifying blocks... - Vérification des blocs en cours... + Vérification des blocs... Verifying wallet... - Vérification du porte-monnaie en cours... + Vérification du porte-monnaie... Wallet %s resides outside data directory %s @@ -2152,7 +2152,7 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) - Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) + Exécuter une commande lorsqu'une alerte pertinente est reçue, ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) @@ -2176,7 +2176,7 @@ Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) - Aléer les authentifiants pour chaque connexion mandataire. Ceci active l'isolement de flux de Tor (par défaut : %u) + Aléer les authentifiants pour chaque connexion mandataire. Cela active l'isolement de flux de Tor (par défaut : %u) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) @@ -2200,7 +2200,7 @@ You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Ceci retéléchargera complètement la chaîne de blocs. + Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Cela retéléchargera complètement la chaîne de blocs. (default: %u) @@ -2264,7 +2264,7 @@ Send trace/debug info to console instead of debug.log file - Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log + Envoyer les infos de débogage/trace à la console au lieu du fichier debug.log Send transactions as zero-fee transactions if possible (default: %u) @@ -2276,11 +2276,11 @@ Shrink debug.log file on client startup (default: 1 when no -debug) - Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent) + Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 sans -debug) Signing transaction failed - La signature de la transaction a échoué + Échec de signature de la transaction The transaction amount is too small to pay the fee @@ -2300,7 +2300,7 @@ Transaction amount too small - Montant de la transaction trop bas + Le montant de la transaction est trop bas Transaction amounts must be positive @@ -2312,7 +2312,7 @@ Transaction too large - Transaction trop volumineuse + La transaction est trop grosse Unable to bind to %s on this computer (bind returned error %s) @@ -2364,7 +2364,7 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) - (1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission) + (1 = conserver les métadonnées de transmission, p. ex. les informations du propriétaire du compte et de demande de paiement, 2 = abandonner les métadonnées de transmission) -maxtxfee is set very high! Fees this large could be paid on a single transaction. @@ -2396,7 +2396,7 @@ Output debugging information (default: %u, supplying <category> is optional) - Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel) + Extraire les informations de débogage (par défaut : %u, fournir <category> est facultatif) Support filtering of blocks and transaction with bloom filters (default: %u) @@ -2496,7 +2496,7 @@ Set the number of threads to service RPC calls (default: %d) - Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d) + Définir le nombre de fils pour les appels RPC (par défaut : %d) Specify configuration file (default: %s) @@ -2520,7 +2520,7 @@ Unknown network specified in -onlynet: '%s' - Réseau inconnu spécifié sur -onlynet : « %s » + Réseau inconnu spécifié dans -onlynet : « %s » Insufficient funds diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 0ed0fc442..2d99b90c6 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Fare clic con il tasto destro del mouse per modificare l'indirizzo o l'etichetta + Fare clic con il tasto destro del mouse per modificare l'indirizzo o l'etichettadefault Create a new address @@ -520,6 +520,10 @@ (%1-bit) (%1-bit) + + About %1 + Informazioni %1 + Command-line options Opzioni della riga di comando @@ -575,6 +579,10 @@ As this is the first time the program is launched, you can choose where %1 will store its data. Dato che questa è la prima volta che il programma viene lanciato, puoi scegliere dove %1 salverà i suoi dati. + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 scaricherà e salverà una copia della Blockchain di Bitcoin. Saranno salvati almeno %2GB di dati in questo percorso e continueranno ad aumentare col tempo. Anche il portafoglio verrà salvato in questo percorso. + Use the default data directory Usa la cartella dati predefinita @@ -633,6 +641,10 @@ Automatically start %1 after logging in to the system. Avvia automaticamente %1 una volta effettuato l'accesso al sistema. + + &Start %1 on system login + &Start %1 all'accesso al sistema + Size of &database cache Dimensione della cache del &database. @@ -770,6 +782,10 @@ Per specificare più URL separarli con una barra verticale "|". &Window &Finestra + + Hide tray icon + Nascondi l'icona della barra applicazioni + Show only a tray icon after minimizing the window. Mostra solo nella tray bar quando si riduce ad icona. @@ -790,6 +806,10 @@ Per specificare più URL separarli con una barra verticale "|". User Interface &language: &Lingua Interfaccia Utente: + + The user interface language can be set here. This setting will take effect after restarting %1. + La lingua dell'interfaccia utente può essere impostata qui. L'impostazione avrà effetto dopo il riavvio %1. + &Unit to show amounts in: &Unità di misura con cui visualizzare gli importi: @@ -994,6 +1014,10 @@ Per specificare più URL separarli con una barra verticale "|". Using BerkeleyDB version Versione BerkeleyDB in uso + + Datadir + Datadir + Startup time Ora di avvio @@ -1078,6 +1102,18 @@ Per specificare più URL separarli con una barra verticale "|". User Agent User Agent + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Apri il file log del debug di %1 dalla cartella dati attuale. Può richiedere alcuni secondi per file di log di grandi dimensioni. + + + Decrease font size + Riduci dimensioni font. + + + Increase font size + Aumenta dimensioni font + Services Servizi @@ -1182,6 +1218,10 @@ Per specificare più URL separarli con una barra verticale "|". &Unban Node &Elimina Ban Nodo + + Welcome to the %1 RPC console. + Benvenuto nella console RPC di %1. + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Usa le frecce direzionali per scorrere la cronologia, e <b>Ctrl-L</b> per cancellarla. @@ -1561,6 +1601,10 @@ Per specificare più URL separarli con una barra verticale "|". ShutdownWindow + + %1 is shutting down... + Arresto di %1 in corso... + Do not shut down the computer until this window disappears. Non spegnere il computer fino a quando questa finestra non si sarà chiusa. @@ -1751,6 +1795,18 @@ Per specificare più URL separarli con una barra verticale "|". Bitcoin Core Bitcoin Core + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee è impostato su un valore molto elevato! Questa è la commissione che potresti pagare quando la stima della commissione non è disponibile. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Un importo (in %s/kB) che sarà utilizzato quando la stima delle commissioni non ha abbastanza dati (default: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accetta le transazioni trasmesse ricevute da peers in whitelist anche se non si stanno trasmettendo transazioni (default: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6 @@ -1763,10 +1819,38 @@ Per specificare più URL separarli con una barra verticale "|". Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Errore caricamento %s: Non puoi abilitare HD in un portafoglio non-HD già esistente + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Errore lettura %s! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID) + + Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) + Forza la trasmissione della transazione dai peer presenti nella whitelist anche se violano le regole di trasmissione locali (default: %d) + + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Regolazione della massima differenza media di tempo dei peer consentita. L'impostazione dell'orario locale può essere impostata in avanti o indietro di questa quantità. (default %u secondi) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Totale massimo di commissioni (in %s) da usare in una transazione singola o di gruppo del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Per favore controllate che la data del computer e l'ora siano corrette! Se il vostro orologio è sbagliato %s non funzionerà correttamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Per favore contribuite se ritenete %s utile. Visitate %s per maggiori informazioni riguardo il software. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, <0 = lascia questo numero di core liberi, predefinito: %d) @@ -1779,6 +1863,10 @@ Per specificare più URL separarli con una barra verticale "|". This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Impossibile riportare il database ad un livello pre-fork. Dovrai riscaricare tutta la blockchain + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) @@ -1795,6 +1883,14 @@ Per specificare più URL separarli con una barra verticale "|". Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte. + + You need to rebuild the database using -reindex-chainstate to change -txindex + È necessario ricostruire il database usando -reindex per cambiare -txindex + + + %s corrupt, salvage failed + %s corrotto, recupero fallito + -maxmempool must be at least %d MB -maxmempool deve essere almeno %d MB @@ -1803,10 +1899,26 @@ Per specificare più URL separarli con una barra verticale "|". <category> can be: Valori possibili per <category>: + + Append comment to the user agent string + Aggiungi commento alla stringa dell'applicazione utente + + + Attempt to recover private keys from a corrupt wallet on startup + Prova a recuperare le chiavi private da un portafoglio corrotto all'avvio + Block creation options: Opzioni creazione blocco: + + Cannot resolve -%s address: '%s' + Impossobile risolvere l'indirizzo -%s: '%s' + + + Change index out of range + Cambio indice fuori paramentro + Connect only to the specified node(s) Connessione ai soli nodi specificati @@ -1815,6 +1927,10 @@ Per specificare più URL separarli con una barra verticale "|". Connection options: Opzioni di connessione: + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected Rilevato database blocchi corrotto @@ -1847,6 +1963,10 @@ Per specificare più URL separarli con una barra verticale "|". Enable publish raw transaction in <address> Abilita pubblicazione transazione raw in <address> + + Enable transaction replacement in the memory pool (default: %u) + Abilita la sostituzione della transazione nel pool della memoria (default: %u) + Error initializing block database Errore durante l'inizializzazione del database dei blocchi @@ -1855,6 +1975,22 @@ Per specificare più URL separarli con una barra verticale "|". Error initializing wallet database environment %s! Errore durante l'inizializzazione dell'ambiente del database del portamonete %s! + + Error loading %s + Errore caricamento %s + + + Error loading %s: Wallet corrupted + Errore caricamento %s: Portafoglio corrotto + + + Error loading %s: Wallet requires newer version of %s + Errore caricamento %s: il Portafoglio richiede una versione aggiornata di %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Errore caricamento %s: Non puoi disabilitare HD in un portafoglio HD già esistente + Error loading block database Errore durante il caricamento del database blocchi @@ -1879,14 +2015,34 @@ Per specificare più URL separarli con una barra verticale "|". Incorrect or no genesis block found. Wrong datadir for network? Blocco genesi non corretto o non trovato. È possibile che la cartella dati appartenga ad un'altra rete. + + Initialization sanity check failed. %s is shutting down. + Test di integrità iniziale fallito. %s si arresterà. + Invalid -onion address: '%s' Indirizzo -onion non valido: '%s' + + Invalid amount for -%s=<amount>: '%s' + Importo non valido per -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Importo non valido per -fallbackfee=<amount>: '%s' + Keep the transaction memory pool below <n> megabytes (default: %u) Mantieni la memory pool delle transazioni al di sotto di <n> megabytes (default: %u) + + Loading banlist... + Caricamento bloccati... + + + Location of the auth cookie (default: data dir) + Posizione del cookie di aiutorizzazione (default: data dir) + Not enough file descriptors available. Non ci sono abbastanza descrittori di file disponibili. @@ -1895,6 +2051,14 @@ Per specificare più URL separarli con una barra verticale "|". Only connect to nodes in network <net> (ipv4, ipv6 or onion) Connessione ai soli nodi appartenenti alla rete <net> (ipv4, ipv6 o Tor) + + Print this help message and exit + Mostra questo messaggio di aiuto ed esci + + + Print version and exit + Mostra la versione ed esci + Prune cannot be configured with a negative value. La modalità prune non può essere configurata con un valore negativo. @@ -1903,10 +2067,26 @@ Per specificare più URL separarli con una barra verticale "|". Prune mode is incompatible with -txindex. La modalità prune è incompatibile con l'opzione -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Ricostruisci lo stato della catena e l'indice dei blocchi partendo dai file blk*.dat presenti sul disco + + + Rebuild chain state from the currently indexed blocks + Ricrea l'indice della catena dei blocchi partendo da quelli già indicizzati + + + Rewinding blocks... + Verifica blocchi... + Set database cache size in megabytes (%d to %d, default: %d) Imposta la dimensione della cache del database in megabyte (%d a %d, predefinito: %d) + + Set maximum BIP141 block weight (default: %d) + Imposta la dimensione massima del blocco BIP141 (default: %d) + Set maximum block size in bytes (default: %d) Imposta la dimensione massima del blocco in byte (predefinito: %d) @@ -1915,6 +2095,14 @@ Per specificare più URL separarli con una barra verticale "|". Specify wallet file (within data directory) Specifica il file del portamonete (all'interno della cartella dati) + + The source code is available from %s. + Il codice sorgente è disponibile in %s + + + Unable to bind to %s on this computer. %s is probably already running. + Impossibile collegarsi a %s su questo computer. Probabilmente %s è già in esecuzione. + Unsupported argument -benchmark ignored, use -debug=bench. Ignorata opzione -benchmark non supportata, utilizzare -debug=bench. @@ -1947,6 +2135,14 @@ Per specificare più URL separarli con una barra verticale "|". Wallet %s resides outside data directory %s Il portamonete %s si trova al di fuori dalla cartella dati %s + + Wallet debugging/testing options: + Opzioni di Debug/Test del portafoglio: + + + Wallet needed to be rewritten: restart %s to complete + Il portamonete necessita di essere riscritto: riavviare %s per completare + Wallet options: Opzioni portamonete: @@ -2015,6 +2211,10 @@ Per specificare più URL separarli con una barra verticale "|". This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Questo prodotto include software sviluppato dal progetto OpenSSL per l'uso del Toolkit OpenSSL <https://www.openssl.org/>, software crittografico scritto da Eric Young e software UPnP scritto da Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usa la generazione gerarchica deterministica (HD) della chiave dopo BIP32. Valido solamente durante la creazione del portafoglio o al primo avvio + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway I peer inclusi in whitelist non possono subire ban per DoS e le loro transazioni saranno sempre trasmesse, anche nel caso in cui si trovino già nel mempool. Ciò è utile ad es. per i gateway @@ -2151,6 +2351,10 @@ Per specificare più URL separarli con una barra verticale "|". Warning Attenzione + + Warning: unknown new rules activated (versionbit %i) + Attenzione: nuove regole non conosciute attivate (versionbit %i) + Whether to operate in a blocks only mode (default: %u) Imposta se operare in modalità solo blocchi (default: %u) @@ -2231,6 +2435,10 @@ Per specificare più URL separarli con una barra verticale "|". Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati. + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argomento non supportato -whitelistalwaysrelay è stato ignorato, utilizzare -whitelistrelay e/o -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s) @@ -2239,6 +2447,14 @@ Per specificare più URL separarli con una barra verticale "|". Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Username e hash password per connessioni JSON-RPC. Il campo <userpw> utilizza il formato: <USERNAME>:<SALT>$<HASH>. Uno script python standard è incluso in share/rpcuser. Questa opzione può essere specificata più volte + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Attenzione: si stanno minando versioni sconocsiute di blocchi! E' possibile che siano attive regole sconosciute + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Attenzione: file del Portafoglio corrotto, dati recuperati! %s originale salvato come %s in %s; se il saldo o le transazioni non sono corrette effettua un ripristino da un backup. + (default: %s) (predefinito: %s) diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts index f89f4bdc4..d17b267ba 100644 --- a/src/qt/locale/bitcoin_it_IT.ts +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -103,6 +103,10 @@ RPCConsole + + Ban Node for + Nodo bannato per + ReceiveCoinsDialog diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 52f18c118..63fb9d681 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1830,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは<http://www.opensource.org/licenses/mit-license.php>を参照してください。 + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + 中継や採掘を行う際のトランザクション内の、sigopあたりバイト数の相当量 (初期値: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet %s の読み込みエラー: 非HDウォレットが既に存在するため、HDウォレットを有効化できません @@ -2055,10 +2059,6 @@ Location of the auth cookie (default: data dir) 認証クッキーの場所 (デフォルト: ) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 中継や採掘を行ってもよい、sigopあたりの最小バイト数 (デフォルト: %u) - Not enough file descriptors available. 使用可能なファイルディスクリプタが不足しています。 diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 012632c0e..8aad8df46 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -110,6 +110,14 @@ Quit application 어플리케이션 종료 + + &About %1 + %1 정보(&A) + + + Show information about %1 + %1 정보를 표시합니다 + About &Qt &Qt 정보 @@ -122,6 +130,10 @@ &Options... 옵션(&O) + + Modify configuration options for %1 + %1 설정 옵션 수정 + &Encrypt Wallet... 지갑 암호화(&E)... @@ -250,6 +262,14 @@ %n active connection(s) to Bitcoin network 비트코인 네트워크에 %n개의 연결이 활성화되어 있습니다. + + Indexing blocks on disk... + 디스크에서 블록 색인중... + + + Processing blocks on disk... + 디스크에서 블록 처리중... + No block source available... 사용 가능한 블록이 없습니다... @@ -306,6 +326,14 @@ Up to date 현재까지 + + Show the %1 help message to get a list with possible Bitcoin command-line options + 사용할 수 있는 비트코인 명령줄 옵션 목록을 가져오기 위해 %1 도움말 메시지를 표시합니다. + + + %1 client + %1 클라이언트 + Catching up... 블록 따라잡기... @@ -492,6 +520,10 @@ (%1-bit) (%1-비트) + + About %1 + %1 정보(&A) + Command-line options 명령줄 옵션 @@ -528,13 +560,29 @@ Show splash screen on startup (default: %u) 실행시 시작화면 보기 (기본값: %u) - + + Reset all settings changed in the GUI + GUI를 통해 수정된 모든 설정을 초기화 + + Intro Welcome 환영합니다 + + Welcome to %1. + %1에 오신것을 환영합니다. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + 프로그램이 처음으로 실행되고 있습니다. %1가 어디에 데이터를 저장할지 선택할 수 있습니다. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1가 블럭체인의 복사본을 다운로드 저장합니다. 적어도 %2GB의 데이터가 이 폴더에 저장되며 시간이 경과할수록 점차 증가합니다. 그리고 지갑 또한 이 폴더에 저장됩니다. + Use the default data directory 기본 데이터 폴더를 사용하기 @@ -589,6 +637,14 @@ &Main 메인(&M) + + Automatically start %1 after logging in to the system. + 시스템 로그인후에 %1을 자동으로 시작합니다. + + + &Start %1 on system login + 시스템 로그인시 %1 시작(&S) + Size of &database cache 데이터베이스 캐시 크기(&D) @@ -691,7 +747,7 @@ Port of the proxy (e.g. 9050) - 프록시의 포트번호입니다(예: 9050) + 프록시의 포트번호입니다 (예: 9050) Used for reaching peers via: @@ -725,6 +781,14 @@ &Window 창(&W) + + &Hide the icon from the system tray. + 시스템 트레이 로 부터 아이콘 숨기기(&H) + + + Hide tray icon + 트레이 아이콘 숨기기 + Show only a tray icon after minimizing the window. 창을 최소화 하면 트레이에 아이콘만 표시합니다. @@ -745,6 +809,10 @@ User Interface &language: 사용자 인터페이스 언어(&L): + + The user interface language can be set here. This setting will take effect after restarting %1. + 사용자 인터페이스 언어를 여기서 설정할 수 있습니다. 이 설정은 %1을 다시 시작할때 적용됩니다. + &Unit to show amounts in: 거래액을 표시할 단위(&U): @@ -949,6 +1017,10 @@ Using BerkeleyDB version 사용 중인 BerkeleyDB 버전 + + Datadir + 데이터 폴더 + Startup time 시작 시간 @@ -1033,6 +1105,18 @@ User Agent 유저 에이전트 + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + %1 디버그 로그파일을 현재 데이터 폴더에서 엽니다. 용량이 큰 로그 파일들은 몇 초가 걸릴 수 있습니다. + + + Decrease font size + 글자 크기 축소 + + + Increase font size + 글자 크기 확대 + Services 서비스 @@ -1137,6 +1221,10 @@ &Unban Node 노드 추방 취소(&U) + + Welcome to the %1 RPC console. + %1 RPC 콘솔에 오신걸 환영합니다 + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 <b>Ctrl-L</b>키를 사용하십시오. @@ -1443,11 +1531,11 @@ Pay &To: - 송금할 대상(&T) : + 송금할 대상(&T): &Label: - 라벨(&L) + 라벨(&L): Choose previously used address @@ -1507,7 +1595,7 @@ Pay To: - 송금할 대상 : + 송금할 대상: Memo: @@ -1516,6 +1604,10 @@ ShutdownWindow + + %1 is shutting down... + %1이 종료 중입니다... + Do not shut down the computer until this window disappears. 창이 사라지기 전까지 컴퓨터를 끄지마시오. @@ -1706,6 +1798,10 @@ Bitcoin Core 비트코인 코어 + + The %s developers + %s 코어 개발자 + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee은 너무 높습니다! 이것은 수수료 예측을 이용할 수 없을 때 지불되는 트랜잭션 수수료입니다. @@ -1722,6 +1818,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 선택된 주소로 고정하며 항상 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. + + Cannot obtain a lock on data directory %s. %s is probably already running. + %s 데이터 디렉토리에 락을 걸 수 없었습니다. %s가 이미 실행 중인 것으로 보입니다. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup 시작시 모든 지갑 트랜잭션을 삭제하고 -rescan을 통하여 블록체인만 복구합니다. @@ -1730,6 +1830,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MIT 소프트웨어 라이센스에 따라 배포됩니다. 동봉된 파일 혹은 <http://www.opensource.org/licenses/mit-license.php>를 참조하세요. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + %s 불러오기 오류: 비-HD 지갑이 존재하는 상태에서 HD 지갑을 활성화 할 수 없습니다 + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + %s 불러오기 오류: 주소 키는 모두 정확하게 로드되었으나 거래 데이터와 주소록 필드에서 누락이나 오류가 존재할 수 있습니다. + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다) @@ -1738,6 +1846,18 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) 피어들이 로컬 중계 정책을 위반하더라도 화이트 리스트에 포함된 피어인경우 강제로 중계하기 (기본값: %d) + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + 하나의 지갑 트랜잭션에서의 총 수수료(%s)의 최대치; 너무 낮게 설정하면 큰 트랜잭션이 중지 됩니다 (기본값: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + 컴퓨터의 날짜와 시간이 올바른지 확인하십시오! 시간이 잘못되면 %s은 제대로 동작하지 않습니다. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + %s가 유용하다고 생각한다면 프로젝트에 공헌해주세요. 이 소프트웨어에 대한 보다 자세한 정보는 %s를 방문해주십시오. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 스크립트 인증 스레드의 갯수 설정 (%u-%d, 0 = 자동, <0 = 지정된 코어 개수만큼 사용 안함, 기본값: %d) @@ -1750,6 +1870,10 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다. + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + 데이터베이스를 포크 전 상태로 돌리지 못했습니다. 블록체인을 다시 다운로드 해주십시오. + Use UPnP to map the listening port (default: 1 when listening and no -proxy) 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: 열려있거나 -proxy 옵션을 사용하지 않을 시 1) @@ -1766,6 +1890,14 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 설정된 넷마스크 혹은 IP 주소로 화이트리스트에 포함된 피어에 접속합니다. 이 설정은 복수로 지정 할 수 있습니다. + + You need to rebuild the database using -reindex-chainstate to change -txindex + -txindex를 바꾸기 위해서는 -reindex-chainstate를 사용해서 데이터베이스를 재구성해야 합니다. + + + %s corrupt, salvage failed + %s 손상되었고 복구가 실패하였습니다 + -maxmempool must be at least %d MB -maxmempool은 최소한 %d MB가 필요합니다 @@ -1778,10 +1910,18 @@ Append comment to the user agent string 사용자 에이전트 문자열에 코멘트 첨부 + + Attempt to recover private keys from a corrupt wallet on startup + 시작시 망가진 wallet.dat에서 개인키 복원을 시도합니다 + Block creation options: 블록 생성 옵션: + + Cannot resolve -%s address: '%s' + %s 주소를 확인할 수 없습니다: '%s' + Connect only to the specified node(s) 지정된 노드에만 연결하기 @@ -1790,6 +1930,10 @@ Connection options: 연결 설정 : + + Copyright (C) %i-%i + Copyright (C) %i-%i + Corrupted block database detected 손상된 블록 데이터베이스가 감지되었습니다 @@ -1834,6 +1978,22 @@ Error initializing wallet database environment %s! 지갑 데이터베이스 환경 초기화하는데 오류 %s + + Error loading %s + %s 불러오기 오류 + + + Error loading %s: Wallet corrupted + %s 불러오기 오류: 지갑 오류 + + + Error loading %s: Wallet requires newer version of %s + %s 불러오기 에러: 지갑은 새 버전의 %s이 필요합니다 + + + Error loading %s: You can't disable HD on a already existing HD wallet + %s 불러오기 오류: 이미 HD 지갑이 존재하는 상태에서 HD 지갑을 비활성화 할 수 없습니다 + Error loading block database 블록 데이터베이스를 불러오는데 오류 @@ -1858,10 +2018,18 @@ Incorrect or no genesis block found. Wrong datadir for network? 올바르지 않거나 생성된 블록을 찾을 수 없습니다. 잘못된 네트워크 자료 디렉토리? + + Initialization sanity check failed. %s is shutting down. + 무결성 확인 초기화가 실패했습니다. %s가 종료됩니다. + Invalid -onion address: '%s' 잘못된 -onion 주소입니다: '%s' + + Invalid amount for -%s=<amount>: '%s' + 유효하지 않은 금액 -%s=<amount>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' 유효하지 않은 금액 -fallbackfee=<amount>: '%s' @@ -1871,12 +2039,12 @@ 트랜잭션 메모리 풀의 용량을 <n>메가바이트 아래로 유지하기 (기본값: %u) - Location of the auth cookie (default: data dir) - 인증 쿠키의 위치 (기본값: data dir) + Loading banlist... + 추방리스트를 불러오는 중... - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 중계 및 채굴을 할 때 트랜잭션에서의 sigop 당 데이터의 최소 크기 (기본값: %u) + Location of the auth cookie (default: data dir) + 인증 쿠키의 위치 (기본값: data dir) Not enough file descriptors available. @@ -1886,6 +2054,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) 오직 <net> 네트워크로 로만 접속 (IPv4, IPv6 혹은 onion) + + Print this help message and exit + 도움말 메시지 출력 후 종료 + Print version and exit 버전 출력후 종료 @@ -1898,6 +2070,18 @@ Prune mode is incompatible with -txindex. 블록 축소 모드는 -txindex와 호환되지 않습니다. + + Rebuild chain state and block index from the blk*.dat files on disk + 현재의 blk*.dat 파일들로부터 블록체인 색인을 재구성합니다. + + + Rebuild chain state from the currently indexed blocks + 현재 색인 된 블록들로부터 블록체인을 재구성합니다. + + + Rewinding blocks... + 블록 되감는중... + Set database cache size in megabytes (%d to %d, default: %d) 데이터베이스 케시 크기를 메가바이트로 설정(%d 부터 %d, 기본값: %d) @@ -1910,6 +2094,14 @@ Specify wallet file (within data directory) 데이터 폴더 안에 지갑 파일을 선택하세요. + + The source code is available from %s. + 소스코드는 %s 에서 확인하실 수 있습니다. + + + Unable to bind to %s on this computer. %s is probably already running. + 이 컴퓨터의 %s에 바인딩 할 수 없습니다. 아마도 %s이 실행중인 것 같습니다. + Unsupported argument -benchmark ignored, use -debug=bench. 지원하지 않는 인수 -benchmark 은 무시됩니다, -debug=bench 형태로 사용하세요. @@ -1946,6 +2138,10 @@ Wallet debugging/testing options: 지갑 디버깅/테스트 옵션: + + Wallet needed to be rewritten: restart %s to complete + 지갑을 새로 써야 합니다: 완성하기 위하여 %s을 다시 시작하십시오. + Wallet options: 지갑 옵션: @@ -2246,6 +2442,10 @@ Warning: Unknown block versions being mined! It's possible unknown rules are in effect 경고: 알려지지 않은 버전의 블록이 채굴되었습니다. 알려지지 않은 규칙이 적용되었을 가능성이 있습니다. + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + 경고 : 지갑파일이 손상되어 데이터가 복구되었습니다. 원래의 %s 파일은 %s 후에 %s 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. + Always query for peer addresses via DNS lookup (default: %u) DNS lookup을 통해 항상 피어주소에 대한 쿼리 보내기 (기본값: %u) diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 4d270a6ef..7ec8c36d9 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -114,6 +114,10 @@ &About %1 &Om %1 + + Show information about %1 + Vis informasjon om %1 + About &Qt Om &Qt @@ -126,6 +130,10 @@ &Options... &Innstillinger... + + Modify configuration options for %1 + Endre innstilinger for %1 + &Encrypt Wallet... &Krypter Lommebok... @@ -741,6 +749,10 @@ &Window &Vindu + + Hide tray icon + Skjul søppel ikon + Show only a tray icon after minimizing the window. Vis kun ikon i systemkurv etter minimering av vinduet. @@ -1049,6 +1061,14 @@ User Agent Brukeragent + + Decrease font size + Forminsk font størrelsen + + + Increase font size + Forstørr font størrelse + Services Tjenester @@ -1826,6 +1846,10 @@ Error initializing wallet database environment %s! Feil under oppstart av lommeboken sitt databasemiljø %s! + + Error loading %s + Feil ved lasting av %s + Error loading block database Feil ved lasting av blokkdatabase @@ -1866,6 +1890,14 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Bare koble til noder i nettverket <net> (IPv4, IPv6 eller onion) + + Print this help message and exit + Skriv ut denne hjelpemeldingen og avslutt + + + Print version and exit + Skriv ut denne versjonen og avslutt + Prune cannot be configured with a negative value. Beskjæringsmodus kan ikke konfigureres med en negativ verdi. @@ -1886,6 +1918,10 @@ Specify wallet file (within data directory) Angi lommebokfil (inne i datamappe) + + The source code is available from %s. + Kildekoden er tilgjengelig fra %s. + Unsupported argument -benchmark ignored, use -debug=bench. Ustøttet argument -benchmark ble ignorert, bruk -debug=bench. diff --git a/src/qt/locale/bitcoin_ne.ts b/src/qt/locale/bitcoin_ne.ts new file mode 100644 index 000000000..6ffde979f --- /dev/null +++ b/src/qt/locale/bitcoin_ne.ts @@ -0,0 +1,548 @@ + + + AddressBookPage + + Right-click to edit address or label + ठेगाना वा लेबल सम्पादन गर्न दायाँ-क्लिक गर्नुहोस् + + + Create a new address + नयाँ ठेगाना सिर्जना गर्नुहोस् + + + &New + &amp;नयाँ + + + Copy the currently selected address to the system clipboard + भर्खरै चयन गरेको ठेगाना प्रणाली क्लिपबोर्डमा कपी गर्नुहोस् + + + &Copy + &amp;कपी गर्नुहोस् + + + C&lose + बन्द गर्नुहोस् + + + Delete the currently selected address from the list + भर्खरै चयन गरेको ठेगाना सूचीबाट मेटाउनुहोस् + + + Export the data in the current tab to a file + वर्तमान ट्याबको डाटालाई फाइलमा निर्यात गर्नुहोस् + + + &Export + &amp;निर्यात गर्नुहोस् + + + &Delete + &amp;मेटाउनुहोस् + + + + AskPassphraseDialog + + Passphrase Dialog + पासफ्रेज संवाद + + + Enter passphrase + पासफ्रेज प्रवेश गर्नुहोस् + + + New passphrase + नयाँ पासफ्रेज + + + Repeat new passphrase + नयाँ पासफ्रेज दोहोर्याउनुहोस् + + + + BanTableModel + + IP/Netmask + IP/नेटमास्क + + + Banned Until + प्रतिबन्धित समय + + + + BitcoinGUI + + Sign &message... + सन्देशमा &amp;हस्ताक्षर गर्नुहोस्... + + + Synchronizing with network... + नेटवर्कमा समिकरण हुँदै... + + + &Overview + शारांश + + + Node + नोड + + + Show general overview of wallet + वालेटको साधारण शारांश देखाउनुहोस् + + + &Transactions + &amp;कारोबार + + + Browse transaction history + कारोबारको इतिहास हेर्नुहोस् + + + E&xit + बाहिर निस्कनुहोस् + + + Quit application + एप्लिकेसन बन्द गर्नुहोस् + + + &About %1 + &amp;बारेमा %1 + + + Show information about %1 + %1 को बारेमा सूचना देखाउनुहोस् + + + About &Qt + &amp;Qt + + + Show information about Qt + Qt को बारेमा सूचना देखाउनुहोस् + + + &Options... + &amp;विकल्प... + + + Modify configuration options for %1 + %1 का लागि कन्फिगुरेसनको विकल्प परिमार्जन गर्नुहोस + + + &Encrypt Wallet... + &amp;वालेटलाई इन्क्रिप्ट गर्नुहोस्... + + + &Backup Wallet... + &amp;वालेटलाई ब्याकअप गर्नुहोस्... + + + &Change Passphrase... + &amp;पासफ्रेज परिवर्तन गर्नुहोस्... + + + &Sending addresses... + &amp;पठाउने ठेगानाहरू... + + + &Receiving addresses... + &amp;प्राप्त गर्ने ठेगानाहरू... + + + Open &URI... + URI &amp;खोल्नुहोस्... + + + Reindexing blocks on disk... + डिस्कमा ब्लकलाई पुनः सूचीकरण गरिँदै... + + + Send coins to a Bitcoin address + बिटकोइन ठेगानामा सिक्का पठाउनुहोस् + + + Backup wallet to another location + वालेटलाई अर्को ठेगानामा ब्याकअप गर्नुहोस् + + + Change the passphrase used for wallet encryption + वालेट इन्क्रिप्सनमा प्रयोग हुने इन्क्रिप्सन पासफ्रेज परिवर्तन गर्नुहोस् + + + &Debug window + &amp;डिबग विन्डो + + + Open debugging and diagnostic console + डिबगिङ र डायाग्नोस्टिक कन्सोल खोल्नुहोस् + + + + CoinControlDialog + + Amount + रकम + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + 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. + देखाइएको सूचना पूरानो हुन सक्छ । कनेक्सन स्थापित भएपछि, तपाईंको वालेट बिटकोइन नेटवर्कमा स्वचालित रूपमा समिकरण हुन्छ , तर यो प्रक्रिया अहिले सम्म पूरा भएको छैन । + + + Watch-only: + हेर्ने-मात्र: + + + Available: + उपलब्ध: + + + Your current spendable balance + तपाईंको खर्च गर्न मिल्ने ब्यालेन्स + + + Pending: + विचाराधिन: + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + अझै पुष्टि हुन बाँकी र खर्च गर्न मिल्ने ब्यालेन्समा गणना गर्न नमिल्ने जम्मा कारोबार + + + Immature: + अपरिपक्व: + + + Mined balance that has not yet matured + अझै परिपक्व नभएको खनन गरिएको ब्यालेन्स + + + Balances + ब्यालेन्स + + + Mined balance in watch-only addresses that has not yet matured + अहिलेसम्म परिपक्व नभएको खनन गरिएको, हेर्ने-मात्र ठेगानामा रहेको ब्यालेन्स + + + Current total balance in watch-only addresses + हेर्ने-मात्र ठेगानामा रहेको हालको जम्मा ब्यालेन्स + + + + PeerTableModel + + User Agent + प्रयोगकर्ता एजेन्ट + + + Node/Service + नोड/सेव + + + Ping Time + पिङ समय + + + + QObject + + Amount + रकम + + + + RPCConsole + + User Agent + प्रयोगकर्ता एजेन्ट + + + Ping Time + पिङ समय + + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + SendCoinsDialog + + + SendCoinsEntry + + 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. + पठाइँदै गरेको रकमबाट शुल्क कटौती गरिनेछ । प्राप्तकर्ताले तपाईंले रकम क्षेत्रमा प्रवेष गरेको भन्दा थोरै बिटकोइन प्राप्त गर्ने छन् । धेरै प्राप्तकर्ता चयन गरिएको छ भने समान रूपमा शुल्क विभाजित गरिनेछ । + + + 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. + बिटकोइनमा संलग्न गरिएको सन्देश: तपाईंको मध्यस्थको लागि कारोबारको साथमा भण्डारण गरिने URI । नोट: यो सन्देश बिटकोइन नेटवर्क मार्फत पठाइने छैन । + + + + ShutdownWindow + + + SignVerifyMessageDialog + + 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. + आफ्नो ठेगानामा पठाइएको बिटकोइन प्राप्त गर्न सकिन्छ भनेर प्रमाणित गर्न तपाईंले ती ठेगानाले सन्देश/सम्झौताहरूमा हस्ताक्षर गर्न सक्नुहुन्छ । फिसिङ आक्रमणले तपाईंलाई छक्याएर अरूका लागि तपाईंको परिचयमा हस्ताक्षर गराउने प्रयास गर्न सक्ने भएकाले अस्पष्ट वा जथाभावीमा हस्ताक्षर गर्दा ध्यान दिनुहोस् । आफू सहमत भएको पूर्ण विस्तृत-कथनमा मात्र हस्ताक्षर गर्नुहोस् । + + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDescDialog + + + UnitDisplayStatusBarControl + + + bitcoin-core + + 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 + ब्लक डाटाबेसमा भविष्यबाट आए जस्तो देखिने एउटा ब्लक हुन्छ । तपाईंको कम्प्युटरको मिति र समय गलत तरिकाले सेट गरिएकाले यस्तो हुन सक्छ । तपाईं आफ्नो कम्प्युटरको मिति र समय सही छ भनेर पक्का हुनुहुन्छ भने मात्र ब्लक डाटाबेस पुनर्निर्माण गर्नुहोस् । + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + यो जारी गर्नु पूर्वको परीक्षण संस्करण हो - आफ्नै जोखिममा प्रयोग गर्नुहोस् - खनन वा व्यापारीक प्रयोगको लागि प्रयोग नगर्नुहोस + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + प्रि-फर्क अवस्थामा डाटाबेस रिवाइन्ड गर्न सकिएन । तपाईंले फेरि ब्लकचेन डाउनलोड गर्नु पर्ने हुन्छ + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + UPnP प्रयोग गरेर सुन्ने पोर्टलाई म्याप गर्नुहोस् (सुन्दा र -प्रोक्सी नहुँदा डिफल्ट: 1) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + चेतावनी: नेटवर्क पूरै तरिकाले सहमत छैन जस्तो देखिन्छ! केही खननकर्ताहरूले समस्या भोगिरहेका छन् जस्तो देखिन्छ । + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + चेतावनी: हामी हाम्रा सहकर्मीहरूसँग पूर्णतया सहमत छैनौं जस्तो देखिन्छ! तपाईंले अपग्रेड गर्नु पर्ने हुनसक्छ वा अरू नोडहरूले अपग्रेड गर्नु पर्ने हुनसक्छ । + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + दिइएको नेटमास्क वा ठेगानाबाट कनेक्ट भइरहेका श्वेतसूचीका सहकर्मी । + + + You need to rebuild the database using -reindex-chainstate to change -txindex + तपाईंले -चेनस्टेट-पुनः सूचकांकबाट -txindex परिवर्तन प्रयोग गरेर डाटाबेस पुनर्निर्माण गर्नु आवश्यक छ + + + %s corrupt, salvage failed + %s मा क्षति, बचाव विफल भयो + + + -maxmempool must be at least %d MB + -maxmempool कम्तिमा %d MB को हुनुपर्छ । + + + <category> can be: + &lt;वर्ग&gt; निम्न आकारको हुनसक्छ: + + + Append comment to the user agent string + प्रयोगकर्ता एजेन्ट स्ट्रिङमा टिप्पणी जोड्नुहोस् + + + Attempt to recover private keys from a corrupt wallet on startup + स्टार्टअपमा क्षति पूगेको वालेटबाट निजी की प्राप्त गर्न प्रयास गर्नुहोस् + + + Block creation options: + ब्लक सिर्जनाको बिकल्प: + + + Cannot resolve -%s address: '%s' + -%s ठेगाना: &apos;%s&apos; निश्चय गर्न सकिँदैन + + + Change index out of range + सूचकांक परिवर्तन सीमा भन्दा बाहर + + + Connect only to the specified node(s) + उल्लेख गरिएको नोड (हरू) मात्र कनेक्ट गर्नुहोस + + + Connection options: + कनेक्सनको विकल्प: + + + Copyright (C) %i-%i + सर्वाधिकार (C) %i-%i + + + Corrupted block database detected + क्षति पुगेको ब्लक डाटाबेस फेला पर + + + Debugging/Testing options: + डिबगिङ/परीक्षणका विकल्पहरू: + + + Do not load the wallet and disable wallet RPC calls + वालेट लोड नगर्नुहोस् र वालेट RPC कलहरू अक्षम गर्नुहोस् + + + Do you want to rebuild the block database now? + तपाईं अहिले ब्लक डेटाबेस पुनर्निर्माण गर्न चाहनुहुन्छ ? + + + Unable to bind to %s on this computer. %s is probably already running. + यो कम्प्युटरको %s मा बाँध्न सकिएन । %s सम्भवित रूपमा पहिलैबाट चलिरहेको छ । + + + Unsupported argument -benchmark ignored, use -debug=bench. + असमर्थित तर्क -बेन्चमार्कलाई बेवास्ता गरियो, -डिबग=बेन्च प्रयोग गर्नुहोस् । + + + Unsupported argument -debugnet ignored, use -debug=net. + असमर्थित तर्क -डिबगनेटलाई बेवास्ता गरियो, -डिबग=नेट प्रयोग गर्नुहोस् । + + + Unsupported argument -tor found, use -onion. + असमर्थित तर्क -टोर फेला पर्यो, -ओनियन प्रयोग गर्नुहोस् । + + + Use UPnP to map the listening port (default: %u) + UPnP प्रयोग गरेर सुन्ने पोर्ट म्याप गर्नुहोस् (डिफल्ट: %u) + + + Verifying blocks... + ब्लक प्रमाणित गरिँदै... + + + Verifying wallet... + वालेट प्रमाणित गरिँदै... + + + Wallet %s resides outside data directory %s + वालेट %s डाटा निर्देशिका %s बाहिरमा बस्छ + + + Wallet debugging/testing options: + वालेट डिबगिङ/परीक्षणका विकल्पहरू: + + + Wallet needed to be rewritten: restart %s to complete + वालेट फेरि लेख्नु आवश्यक छ: पूरा गर्न %s लाई पुन: सुरु गर्नुहोस् + + + Wallet options: + वालेटका विकल्पहरू: + + + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + निर्दिष्ट गरिएको स्रोतबाट आएको JSON-RPC कनेक्सनलाई अनुमति दिनुहोस् । एकल IP (e.g. 1.2.3.4), नेटवर्क/नेटमास्क (उदाहरण 1.2.3.4/255.255.255.0) वा नेटवर्क/CIDR (उदाहरण 1.2.3.4/24) &lt;ip&gt; का लागि मान्य छन् । यो विकल्पलाई धेरै पटक निर्दिष्ट गर्न सकिन्छ + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + दिइएको ठेगानामा बाँध्नुहोस् र यसमा कनेक्ट गर्ने सहकर्मीलाई श्वेतसूचीमा राख्नुहोस् । IPv6 लागि [होस्ट]:पोर्ट संकेतन प्रयोग गर्नुहोस् + + + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + JSON-RPC कनेक्सन सुन्नको लागि दिइएको ठेगानामा बाँध्नुहोस् । IPv6 लागि [होस्ट]:पोर्ट संकेतन प्रयोग गर्नुहोस् । यो विकल्पलाई धेरै पटक निर्दिष्ट गर्न सकिन्छ (डिफल्ट: सबै इन्टरफेसमा बाँध्नुहोस्) + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + umask 077 को सट्टामा प्रणालीको डिफल्ट अनुमतिको साथमा नयाँ फाइलहरू सिर्जना गर्नुहोस् । (असक्षम गरिएको वालेट कार्यक्षमतामा मात्र प्रभावकारी हुने) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + आफ्नै IP ठेगाना पत्ता लगाउनुहोस् (सुन्दा र -बाहिरीआइपी वा -प्रोक्सी नहुँदा डिफल्ट: 1 ) + + + Error: Listening for incoming connections failed (listen returned error %s) + त्रुटि: आगमन कनेक्सनमा सुन्ने कार्य असफल भयो (सुन्ने कार्यले त्रुटि %s फर्कायो) + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + सान्दर्भिक चेतावनी प्राप्त गर्दा आदेश कार्यान्वयन गर्नुहोस् नभए धेरै लामो फोर्क देखा पर्न सक्छ । (cmd को %s लाई सन्देशले प्रतिस्थापन गर्छ) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + रिले, खनन वा कारोबारको सिर्जनाको लागि यो भन्दा कम शुल्क (%s/kB मा) लाई शून्य शुल्कको रूपमा लिइन्छ । (डिफल्ट: %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + paytxfee सेट गरिएको छैन भने, औसतमा n ब्लक भित्र कारोबार पुष्टिकरण सुरु होस् भन्नका लागि पर्याप्त शुल्क समावेश गर्नुहोस् (डिफल्ट: %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + maxtxfee=&lt;रकम&gt;: का लागि अमान्य रकम &apos;%s&apos; (कारोबारलाई अड्कन नदिन अनिवार्य रूपमा कम्तिमा %s को न्यूनतम रिले शुल्क हुनु पर्छ) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + हामीले रिले र खनन गर्ने डाटा वाहक कारोबारको डाटाको अधिकतम आकार (डिफल्ट: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + यदि ठेगाना कम भएमा, DNS लुकअप मार्फत सहकर्मी ठेगानाको जाँच गर्नुहोस (डिफल्ट: 1 सिवाय -कनेक्ट) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + हरेक प्रोक्सी कनेक्सनका लागि क्रेडिन्सियल अनियमित बनाउनुहोस् । यसले टोर स्ट्रिमको अलगावलाई सक्षम पार्छ (डिफल्ट: %u) + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + बाइटमा उच्च-प्राथमिकता/कम शुल्कको कारोबारको अधिकतम आकार सेट गर्नुहोस् (डिफल्ट: %d) + + + The transaction amount is too small to send after the fee has been deducted + कारोबार रकम शुल्क कटौती गरेपछि पठाउँदा धेरै नै सानो हुन्छ + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + यो उत्पादन ले OpenSSL टुलकिट <https://www.openssl.org/> को प्रयोगको लागि OpenSSL परियोजनाले विकास गरेको सफ्टवेयर, एरिक यंग द्वारा लिखित क्रिप्टोग्राफिक सफ्टवेयर र थमस बर्नार्डद्वारा लिखित UPnP सफ्टवेयरलाई समावेश गर्छ । + + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + BIP32 पछि पदानुक्रमित निर्धारक की सिर्जना (HD) प्रयोग गर्नुहोस् ।. केवल वालेट सिर्जना/पहिलो सुरुवातको समयमा प्रभाव पार्छ + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + श्वेतसूचीका सहकर्मी पहिलैबाट मेमपूल, उपयोगीमा भए पनि उनीहरूलाई DoS banned गर्न सकिँदैन र उनीहरूको कारोबार सधैं रिले हुन्छ, उदाहरण, गेटवेको लाग + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + तपाईंले काटछाँट नगरेको मोडमा जान पुनः सूचकांक प्रयोग गरेर डाटाबेस पुनर्निर्माण गर्नु पर्ने हुन्छ । यसले सम्पूर्ण ब्लकचेनलाई फेरि डाउनलोड गर्नेछ + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 6fe1acfbb..80de2103c 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1826,6 +1826,14 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Equivalent byter per sigop in transactions voor doorsturen en mijnen (standaard: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Fout bij het laden van %s: Je kan HD niet activeren voor een reeds bestaande niet-HD portemonnee + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Waarschuwing: Fout bij het lezen van %s! Alle sleutels zijn in goede orde uitgelezen, maar transactiedata of adresboeklemma's zouden kunnen ontbreken of fouten bevatten. @@ -1850,6 +1858,10 @@ Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Waarschuwing: Controleer dat de datum en tijd van uw computer correct zijn ingesteld! Bij een onjuist ingestelde klok zal %s niet goed werken. + + Please contribute if you find %s useful. Visit %s for further information about the software. + Gelieve bij te dragen als je %s nuttig vindt. Bezoek %s voor meer informatie over de software. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) @@ -1860,7 +1872,11 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden + Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor mijnen of handelsdoeleinden + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Niet mogelijk om de databank terug te draaien naar een staat voor de vork. Je zal je blokketen opnieuw moeten downloaden Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -1978,6 +1994,10 @@ Error loading %s: Wallet requires newer version of %s Fout bij laden %s: Portemonnee vereist een nieuwere versie van %s + + Error loading %s: You can't disable HD on a already existing HD wallet + Fout bij het laden van %s: Je kan HD niet deactiveren voor een reeds bestaande HD portemonnee + Error loading block database Fout bij het laden van blokkendatabase @@ -2030,10 +2050,6 @@ Location of the auth cookie (default: data dir) Locatie van de auth cookie (standaard: data dir) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum aantal bytes dat er per sigop in een transactie gerelayed en gemined worden (standaard: %u) - Not enough file descriptors available. Niet genoeg file descriptors beschikbaar. @@ -2066,10 +2082,18 @@ Rebuild chain state from the currently indexed blocks Herbouw ketenstaat vanuit de huidige geindexeerde blokken + + Rewinding blocks... + Blokken aan het terugdraaien... + Set database cache size in megabytes (%d to %d, default: %d) Zet database cache grootte in megabytes (%d tot %d, standaard: %d) + + Set maximum BIP141 block weight (default: %d) + Zet het BIP141 maximum gewicht van een blok (standaard: %d) + Set maximum block size in bytes (default: %d) Stel maximum blokgrootte in in bytes (standaard: %d) @@ -2078,6 +2102,10 @@ Specify wallet file (within data directory) Specificeer het portemonnee bestand (vanuit de gegevensmap) + + The source code is available from %s. + De broncode is beschikbaar van %s. + Unable to bind to %s on this computer. %s is probably already running. Niet in staat om %s te verbinden op deze computer. %s draait waarschijnlijk al. @@ -2190,13 +2218,17 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Dit product bevat software dat ontwikkeld is door het OpenSSL Project voor gebruik in de OpenSSL Toolkit <https://www.openssl.org/> en cryptografische software geschreven door Eric Young en UPnP software geschreven door Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Gebruik hiërarchische deterministische sleutelgeneratie (HD) na BIP32. Dit heeft enkel effect bij het aanmaken van portemonnees of het eerste gebruik + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgegeven, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokkketen opnieuw downloaden. + U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokketen opnieuw downloaden. (default: %u) diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 929f38a5b..b902e69f5 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1871,6 +1871,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <category> can be: <category> mogą być: + + Append comment to the user agent string + Dodaj komentarz do pola user agent + Attempt to recover private keys from a corrupt wallet on startup Próbuj odzyskać klucze prywatne z uszkodzonego portfela podczas uruchamiania. diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index bc7ee034d..12da991ad 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -332,7 +332,7 @@ %1 client - cliente %1 + %1 Catching up... @@ -643,7 +643,7 @@ &Start %1 on system login - $Iniciar %1 ao fazer login no sistema + &Iniciar %1 ao fazer login no sistema Size of &database cache @@ -1752,11 +1752,11 @@ Prune configured below the minimum of %d MiB. Please use a higher number. - Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto. + Prune configurado abaixo do mínimo de %d MiB. Por favor use um número mais alto. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) - Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente) + Prune: A ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar (fazer o download de toda a blockchain novamente) Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) @@ -1764,7 +1764,7 @@ Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. - Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. + Rescans não são possíveis no modo prune. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. Error: A fatal internal error occurred, see debug.log for details @@ -1792,7 +1792,7 @@ Bitcoin Core - Bitcoin + Bitcoin Core -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. @@ -1886,6 +1886,10 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Você precisa reconstruir o banco de dados utilizando -reindex-chainstate para mudar -txindex + %s corrupt, salvage failed %s corrompido, recuperação falhou @@ -1910,6 +1914,10 @@ Block creation options: Opções de criação de blocos: + + Cannot resolve -%s address: '%s' + Impossível resolver -%s endereço: '%s' + Connect only to the specified node(s) Conectar apenas a cliente(s) específico(s) @@ -2006,6 +2014,10 @@ Incorrect or no genesis block found. Wrong datadir for network? Bloco gênese incorreto ou não encontrado. Datadir errado para a rede? + + Initialization sanity check failed. %s is shutting down. + O teste de integridade de inicialização falhou. O %s está sendo desligado. + Invalid -onion address: '%s' Endereço -onion inválido: '%s' @@ -2024,16 +2036,12 @@ Loading banlist... - Carregando banlist... + Carregando lista de banidos... Location of the auth cookie (default: data dir) Localização do cookie de autenticação (padrão: diretório de dados) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Número mínimo de bytes por sigop em transações que transmitimos e mineramos (default: %u) - Not enough file descriptors available. Decriptadores de arquivos disponíveis insuficientes. @@ -2042,17 +2050,21 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Somente conectar a clientes na rede <net> (ipv4, ipv6 ou onion) + + Print this help message and exit + Mostra essa mensagem de ajuda e sai + Print version and exit Mostra a versão e sai Prune cannot be configured with a negative value. - O modo Prune não pode ser configurado com um valor negativo. + O modo prune não pode ser configurado com um valor negativo. Prune mode is incompatible with -txindex. - O modo Prune é incompatível com -txindex. + O modo prune é incompatível com -txindex. Rewinding blocks... @@ -2062,6 +2074,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d) + + Set maximum BIP141 block weight (default: %d) + Define a altura máxima BIP141 do bloco (padrão: %d) + Set maximum block size in bytes (default: %d) Define o tamanho máximo de cada bloco em bytes (padrão: %d) @@ -2418,6 +2434,10 @@ Warning: Unknown block versions being mined! It's possible unknown rules are in effect Aviso: Versões de bloco desconhecidas sendo mineradas! É possível que regras estranhas estejam ativas + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Atenção: Arquivo da carteira corrompido, dados recuperados! Original %s salvo como %s em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup. + (default: %s) (padrão: %s) @@ -2536,7 +2556,7 @@ Done loading - Carregamento terminado + Carregamento terminado! Error diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 097c6de49..834067897 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -1951,10 +1951,6 @@ Location of the auth cookie (default: data dir) Localização de cookie de autorização (predefinição: diretoria de dados) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Mínimo de bytes por sigop nas transações que nós transmitimos e mine (predefinição: %u) - Not enough file descriptors available. Os descritores de ficheiros disponíveis são insuficientes. diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index cf85cf44c..9f6ba2709 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -63,6 +63,10 @@ BanTableModel + + IP/Netmask + IP/Netmask + Banned Until Blocat până @@ -70,56 +74,620 @@ BitcoinGUI + + Sign &message... + Semnează &mesajul... + Synchronizing with network... Se sincronizează cu rețeaua + + Node + Nod + + + Show general overview of wallet + Arată o prezentare generală a portofelului. + + + &Transactions + &Tranzacții + + + Browse transaction history + Navighează în istoricul tranzacțiilor + + + Quit application + Părăsește aplicația + + + About &Qt + Despre &Qt + + + Show information about Qt + Arată informații despre Qt + &Options... &Opțiuni... - + + &Encrypt Wallet... + &Criptează portofelul... + + + &Backup Wallet... + &Backup portofel + + + &Change Passphrase... + &Schimbă parola... + + + &Sending addresses... + &Trimite adresele... + + + &Receiving addresses... + &Primește adresele... + + + Open &URI... + Deschide &URI... + + + Send coins to a Bitcoin address + Trimite monedele către o adresă Bitcoin + + + Backup wallet to another location + Fă o copie de rezervă a portofelului într-o altă locație + + + Change the passphrase used for wallet encryption + Schimbă parola folosită pentru criptarea portofelului + + + &Debug window + &Fereastra pentru depanare + + + Open debugging and diagnostic console + Pornește consola pentru depanare si diagnoză + + + &Verify message... + &Verifică mesajul... + + + Bitcoin + Bitcoin + + + Wallet + Portofel + + + &Send + &Trimite + + + &Receive + &Primește + + + &Show / Hide + &Arată/Ascunde + + + Show or hide the main Window + Arată sau ascunde fereastra principală + + + Encrypt the private keys that belong to your wallet + Criptează cheile private care aparțin portofelului tău. + + + Sign messages with your Bitcoin addresses to prove you own them + Semnează mesajele cu adresa ta de Bitcoin pentru a face dovada că îți aparțin. + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verifică mesajele cu scopul de a asigura faptul că au fost semnate cu adresa de Bitcoin specificată. + + + &File + &Fișier + + + &Settings + &Setări + + + &Help + &Ajutor + + + Request payments (generates QR codes and bitcoin: URIs) + Cerere plată (generează coduri QR și bitcoin: URIs) + + + Open a bitcoin: URI or payment request + Deschide un bitcoin: URI sau cerere de plată + + + %1 and %2 + %1 și %2 + + + %1 behind + %1 în urmă + + + Last received block was generated %1 ago. + Ultimul bloc primit a fost generat acum %1 + + + Error + Eroare + + + Warning + Atenționare + + + Information + Informație + + + Up to date + Actual + + + Date: %1 + + Data: %1 + + + Amount: %1 + + Cantitate: %1 + + + Type: %1 + + Tip: %1 + + + + Label: %1 + + Etichetă: %1 + + + + Address: %1 + + Adresa: %1 + + + + Sent transaction + Trimite tranzacția + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Portofelul este <b>criptat</b> și în prezent <b>deblocat</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Portofelul este <b>criptat</b> și în prezent <b>blocat</b> + + CoinControlDialog - + + Coin Selection + Selecția monedelor + + + Quantity: + Cantitatea: + + + Bytes: + Biți: + + + Amount: + Cantitate: + + + Priority: + Prioritate: + + + Fee: + Taxa: + + + After Fee: + După taxă: + + + Change: + Schimbă: + + + Tree mode + Mod arbore + + + List mode + Mod listă + + + Amount + Cantitate + + + Received with address + Primit cu adresa + + + Date + Data + + + Confirmations + Confirmări + + + Confirmed + Confirmat + + + Priority + Prioritate + + EditAddressDialog - + + Edit Address + Modifică adresa + + + &Address + &Adresa + + FreespaceChecker + + name + Nume + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directoriul există deja. Adaugă %1 dacă ai intenționat să creezi aici un directoriu nou. + HelpMessageDialog + + version + versiune + + + (%1-bit) + (%1-bit) + + + Start minimized + Pornește minimalizat + Intro + + Welcome + Bine ai venit! + + + Use the default data directory + Folosește directoriul pentru date din modul implicit. + + + Error + Eroare + + + %n GB of free space available + %n GB de spațiu liber disponibil%n GB de spațiu liber disponibil%n GB de spațiu liber disponibil + OpenURIDialog + + Open URI + Deschide URI + + + URI: + URI: + OptionsDialog + + Options + Opțiuni + + + MB + MB + + + Accept connections from outside + Acceptă conexiuni externe + + + Allow incoming connections + Acceptă conexiunea care sosește + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Adresa IP a proxy-ului (ex. IPv4: 127.0.0.1 / IPv6: ::1) + + + &Reset Options + &Resetează opțiunile + + + &Network + &Rețea + + + Expert + Expert + + + Proxy &IP: + Proxy &IP: + + + &Port: + &Port: + + + Port of the proxy (e.g. 9050) + Portul pentru proxy (ex.: 9050) + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + &OK + &OK + + + &Cancel + &Anulează + + + default + inițial + + + none + fără + + + Confirm options reset + Confirmă resetarea opțiunilor + + + Client restart required to activate changes. + Repornirea clientului este necesară pentru ca schimbările să fie activate + + + Client will be shut down. Do you want to proceed? + Clientul va fi oprit. Dorești sa continui? + + + This change would require a client restart. + Această schimbare necesită repornirea clientului. + OverviewPage + + Available: + Disponibil: + + + Total: + Total: + + + Recent transactions + Tranzacții recente + PeerTableModel QObject + + Amount + Cantitate + RPCConsole - + + Client version + Versiunea clientului + + + &Information + &Informații + + + Debug window + Fereastra pentru depanare + + + General + General + + + Network + Rețea + + + Name + Nume + + + Number of connections + Numărul de conexiuni + + + Received + Primit + + + Sent + Trimis + + + Direction + Direcția + + + Version + Versiune + + + Connection Time + Durata conexiunii + + + &Open + &Deschide + + + &Console + &Consolă + + + 1 &hour + 1 &ore + + + 1 &day + 1 &zi + + + 1 &week + 1 &săptămână + + + 1 &year + 1 &an + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + Yes + Da + + + No + Nu + + + Unknown + Necunoscut + + ReceiveCoinsDialog - + + Show + Arată + + + Remove + Elimină + + ReceiveRequestDialog - + + &Save Image... + &Salvează imaginea... + + SendCoinsDialog + + Quantity: + Cantitatea: + + + Bytes: + Biți: + + + Amount: + Cantitate: + + + Priority: + Prioritate: + + + Fee: + Taxa: + + + After Fee: + După taxă: + + + Change: + Schimbă: + SendCoinsEntry @@ -144,5 +712,21 @@ bitcoin-core - + + Bitcoin Core + Bitcoin Core + + + Information + Informație + + + Warning + Atenționare + + + Error + Eroare + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 271b11122..25fe77bee 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -326,6 +326,10 @@ Up to date Синхронизировано + + Show the %1 help message to get a list with possible Bitcoin command-line options + Показать помощь по %1, чтобы получить список доступных параметров командной строки + %1 client %1 клиент @@ -1822,6 +1826,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Эквивалентных байт на sigop в транзакциях для ретрансляции или добычи (по умолчанию: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Ошибка загрузки %s: Вы не можете включить HD в уже существующем не-HD кошельке @@ -1838,10 +1846,22 @@ Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) Всегда разрешать транзакции, полученные от участников из белого списка (по умолчанию: %d) + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Максимально допустимое среднее отклонение времени участников. Локальное представление времени может меняться вперед или назад на это количество. (по умолчанию: %u секунд) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Максимальная сумма комиссий (%s) для одной транзакции в бумажнике или сырой транзакции; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s) + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Пожалуйста убедитесь в корректности установки времени и даты на вашем компьютере! Если время установлено неверно, %s не будет работать правильно. + + Please contribute if you find %s useful. Visit %s for further information about the software. + Пожалуйста, внести свой вклад, если вы найдете %s полезными. Посетите %s для получения дополнительной информации о программном обеспечении. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d) @@ -2026,10 +2046,6 @@ Location of the auth cookie (default: data dir) Расположение куки входы(по умолчанию: data dir) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Минимально байт на sigop в транзакциях, которые мы ретранслируем и добываем (по умолчанию: %u) - Not enough file descriptors available. Недостаточно файловых дескрипторов. @@ -2054,6 +2070,10 @@ Prune mode is incompatible with -txindex. Режим удаления блоков несовместим с -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Перестроить состояние цепи блоков и индекс блоков из blk*.dat файлов с диска + Rebuild chain state from the currently indexed blocks Перестроить индекс цепи из текущих индексированных блоков diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 66419728e..52a0020c5 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -23,7 +23,7 @@ C&lose - Закрыть + &Закрыть Delete the currently selected address from the list @@ -54,6 +54,10 @@ BitcoinGUI + + Bitcoin + Bitcoin Core + &Command-line options Опции командной строки @@ -184,6 +188,10 @@ Bitcoin Core Bitcoin Core + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + bitcoin-core + Information Информация @@ -192,6 +200,10 @@ Warning Предупреждение + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Error Ошибка diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 527f95d14..60eeba702 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -579,6 +579,10 @@ As this is the first time the program is launched, you can choose where %1 will store its data. Keďže toto je prvé spustenie programu, môžete si vybrať, kam %1 bude ukladať vaše údaje. + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 stiahne a uloží kópiu Bitcoin block chain. Minimálne %2GB dát bude uložených v tejto zložke, a bude sa zväčšovať postupom času. Peňaženka bude taktiež uložená v tejto zložke. + Use the default data directory Použiť predvolený dátový adresár @@ -1013,6 +1017,10 @@ Using BerkeleyDB version Používa BerkeleyDB verziu + + Datadir + Zložka s dátami + Startup time Čas spustenia @@ -1134,6 +1142,10 @@ Ping Time Čas odozvy + + The duration of a currently outstanding ping. + Trvanie aktuálneho pingu + Ping Wait Čakanie na ping @@ -1210,6 +1222,10 @@ &Unban Node &odblokovať uzol + + Welcome to the %1 RPC console. + Vitajte v %1 RPC konzole + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Použi šípky hore a dolu pre navigáciu históriou a <b>Ctrl-L</b> pre vyčistenie obrazovky. @@ -1763,6 +1779,10 @@ Bitcoin Core Jadro Bitcoin + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee je nastavená veľmi vysoko. Ide o poplatok za transakciu, ktorý môže platiť, keď odhady poplatku nie sú k dispozícii. + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6 @@ -1779,6 +1799,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo <http://www.opensource.org/licenses/mit-license.php>. + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Chyba počas načítavania %s: Nemôžete povoliť HD na už existujúcej non-HD peaženke + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID) @@ -1817,6 +1841,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát. + + %s corrupt, salvage failed + %s je poškodený, záchrana zlyhala + -maxmempool must be at least %d MB -maxmempool musí byť najmenej %d MB @@ -1941,6 +1969,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Loading banlist... Načítavam banlist... + + Location of the auth cookie (default: data dir) + Poloha overovacieho cookie súboru (predvolená: zložka s dátami) + Not enough file descriptors available. Nedostatok kľúčových slov súboru. @@ -2217,6 +2249,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Zapping all transactions from wallet... Zmazať všetky transakcie z peňaženky... + + ZeroMQ notification options: + Možnosti pripojenia ZeroMQ: + Password for JSON-RPC connections Heslo pre JSON-rPC spojenia @@ -2253,10 +2289,38 @@ The network does not appear to fully agree! Some miners appear to be experiencin Output debugging information (default: %u, supplying <category> is optional) Výstupné ladiace informácie (predvolené: %u, dodanie <category> je voliteľné) + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Celková dĺžka verzie sieťového reťazca (%i) prekračuje maximálnu dĺžku (%i). Znížte počet a veľkosť komentárov. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Sa snaží držať odchádzajúce prevádzku v rámci daného cieľa (v MB za 24h), 0 = žiadny limit (predvolený: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Nepodporovaný argument -socks nájdený. Nastavenie SOCKS verzie už nie je viac moźné, iba SOCKS5 proxies sú podporované. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Nepodporovaný argument -whitelistalwaysrelay ignorovaný, použite -whitelistrelay a/alebo -whitelistforcerelay. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Užívateľské hash meno a heslo pre JSON-RPC pripojenia. Pole <userpw> je vo formáte <USERNAME>:<SALT>$<HASH>. Kanonický python skript je zahrnutý v share/rpcuser. Toto nastavenie môže byť špecifikované viac krát + + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Varovanie: Neznáma verzia blokov sa doluje! Je možné, že neznáme pravidlá majú efekt + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Varovanie: Peňaženka poškodená, dáta boli zachránené! Originálna %s ako %s v %s; ak váš zostatok alebo transakcie sú nesprávne, mali by ste obnoviť zálohu. + (default: %s) (predvolené: %s) diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 16ef20ea3..94e219636 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -63,7 +63,15 @@ BanTableModel - + + IP/Netmask + IP/Netmaska + + + Banned Until + Prepoved do + + BitcoinGUI @@ -242,6 +250,14 @@ %n active connection(s) to Bitcoin network %n aktivna povezava v omrežje Bitcoin%n aktivni povezavi v omrežje Bitcoin%n aktivne povezave v omrežje Bitcoin%n aktivnih povezav v omrežje Bitcoin + + Indexing blocks on disk... + Indeksirani bloki na disku ... + + + Processing blocks on disk... + Obdelava blokov na disku ... + No block source available... Ni virov za prenos blokov ... @@ -298,6 +314,10 @@ Up to date Posodobljeno + + %1 client + %1 odjemalec + Catching up... Dohitevam omrežje ... @@ -484,6 +504,10 @@ (%1-bit) (%1-bit) + + About %1 + O %1 + Command-line options Možnosti ukazne vrstice @@ -496,6 +520,18 @@ command-line options možnosti ukazne vrstice + + UI Options: + UI možnosti: + + + Set language, for example "de_DE" (default: system locale) + Nastavi jezik, na primer "sl_SI" (privzeto: sistemsko) + + + Start minimized + Začni minimizirano + Intro @@ -503,6 +539,10 @@ Welcome Dobrodošli + + Welcome to %1. + Dobrodošli v %1 + Use the default data directory Uporabi privzeto podatkovno mapo diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts index 86243bc14..229618e34 100644 --- a/src/qt/locale/bitcoin_sr@latin.ts +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -74,13 +74,147 @@ BitcoinGUI + + Synchronizing with network... + Usklađivanje sa mrežom... + + + &Overview + &Pregled + + + Quit application + Isključi aplikaciju + + + &Options... + &Opcije... + + + &Change Passphrase... + &Izmeni pristupnu frazu... + + + &Sending addresses... + &Slanje adresa... + + + &Receiving addresses... + &Primanje adresa... + + + Open &URI... + Otvori &URI... + + + Send coins to a Bitcoin address + Pošalji novčiće na Bitcoin adresu + + + &Verify message... + &Proveri poruku... + + + Bitcoin + Bitcoin + + + Wallet + Novčanik + + + &Send + &Pošalji + + + &Receive + &Primi + + + &Show / Hide + &Prikazati / Sakriti + + + Show or hide the main Window + Prikaži ili sakrij glavni prozor + + + &Settings + &Podešavanja + + + &Help + &Pomoć + Error Greska + + Warning + Upozorenje + + + Information + Informacije + + + %1 client + %1 klijent + + + Date: %1 + + Datum: %1 + + + + Amount: %1 + + Iznos: %1 + + + + Type: %1 + + Tip: %1 + + + + Label: %1 + + Oznaka: %1 + + + + Address: %1 + + Adresa: %1 + + CoinControlDialog + + Quantity: + Količina: + + + Amount: + Iznos: + + + Priority: + Prioritet: + + + Fee: + Naknada: + + + After Fee: + Nakon Naknade: + Amount Kolicina @@ -89,10 +223,26 @@ Date Datum - + + Priority + Prioritet + + EditAddressDialog - + + Edit Address + Izmeni Adresu + + + &Label + &Oznaka + + + &Address + &Adresa + + FreespaceChecker @@ -136,6 +286,26 @@ SendCoinsDialog + + Quantity: + Količina: + + + Amount: + Iznos: + + + Priority: + Prioritet: + + + Fee: + Naknada: + + + After Fee: + Nakon Naknade: + SendCoinsEntry @@ -164,6 +334,14 @@ Bitcoin Core Bitcoin Core + + Information + Informacije + + + Warning + Upozorenje + Insufficient funds Nedovoljno sredstava diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 84ae9145e..bcee9768f 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1826,6 +1826,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Samma antal byte per sigop i transaktioner som vi reläar och bryter (förvalt: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Fel vid laddning av %s: Du kan inte aktivera HD på en existerande icke-HD plånbok @@ -2050,10 +2054,6 @@ Location of the auth cookie (default: data dir) Plats för authcookie (förvalt: datamapp) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum antal byte per sigop i transaktioner som vi reläar och bryter (förvalt: %u) - Not enough file descriptors available. Inte tillräckligt med filbeskrivningar tillgängliga. @@ -2094,6 +2094,10 @@ Set database cache size in megabytes (%d to %d, default: %d) Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d) + + Set maximum BIP141 block weight (default: %d) + Sätt maximal BIP141 blockvikt (förvalt: %d) + Set maximum block size in bytes (default: %d) Sätt maximal blockstorlek i byte (förvalt: %d) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 21a91a86f..8e9ec36b0 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1830,6 +1830,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Oluşturma ve aktarşa muamelelerinde sigop başına eşdeğer bayt (varsayılan: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet %s yüklenmesinde hata: zaten var olan ve HD olmayan bir cüzdanda HD etkinleştirilemez. @@ -2054,10 +2058,6 @@ Location of the auth cookie (default: data dir) auth çerezinin konumu (varsayılan: veri klasörü) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Aktardığımız ve oluşturduğumuz muamelelerdeki sigop başına asgari bayt (varsayılan: %u) - Not enough file descriptors available. Kafi derecede dosya tanımlayıcıları mevcut değil. diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index e7a706ee5..b8296649b 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -114,6 +114,10 @@ &About %1 &关于 %1 + + Show information about %1 + 显示 %1 相关信息 + About &Qt 关于Qt(&Q) @@ -126,6 +130,10 @@ &Options... 选项(&O)... + + Modify configuration options for %1 + 修改%1配置选项 + &Encrypt Wallet... 加密钱包(&E)... @@ -254,6 +262,14 @@ %n active connection(s) to Bitcoin network %n 个到比特币网络的活动连接 + + Indexing blocks on disk... + 正在为数据块建立索引... + + + Processing blocks on disk... + 正在处理数据块... + No block source available... 沒有可用的区块来源... @@ -310,6 +326,10 @@ Up to date 已是最新 + + %1 client + %1 客戶 + Catching up... 更新中... @@ -496,6 +516,10 @@ (%1-bit) (%1 位) + + About %1 + 關於 %1 + Command-line options 命令行选项 @@ -532,13 +556,26 @@ Show splash screen on startup (default: %u) 显示启动画面(默认:%u) - + + Reset all settings changed in the GUI + 重置图形界面所有的变更设置 + + Intro Welcome 欢迎 + + Welcome to %1. + +歡迎來到 %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + 由于这是第一次启动此程序,您可以选择%1的数据所存储的位置 + Use the default data directory 使用默认的数据目录 @@ -1879,10 +1916,6 @@ Location of the auth cookie (default: data dir) 认证Cookie的位置 (默认: data目录) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 我们关联和挖掘的每sigop的最低交易字节(默认: %u) - Not enough file descriptors available. 没有足够的文件描述符可用。 diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 21ca417ac..efea3da9e 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -1831,6 +1831,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. 這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + 轉發和開採時,交易資料中每個 sigop 的等同位元組數(預設值: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet 載入 %s 發生錯誤:不能對已存在的非 HD 錢包啟用 HD 功能。 @@ -2055,10 +2059,6 @@ Location of the auth cookie (default: data dir) 認證 cookie 資料的位置(預設值: 同資料目錄) - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 轉發和開採時,對交易資料的 sigop 平均位元組數下限(預設值: %u) - Not enough file descriptors available. 檔案描述元不足。 From 0027672c8075d063f376c8c84e1cce77d572d353 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 23 Sep 2016 13:06:45 +0800 Subject: [PATCH 1072/1223] Make non-minimal OP_IF/NOTIF argument non-standard for P2WSH Github-Pull: #8526 Rebased-From: c72c5b1e3bd42e84465677e94aa83316ff3d9a14 --- src/policy/policy.h | 1 + src/script/interpreter.cpp | 6 +++ src/script/interpreter.h | 4 ++ src/script/script_error.cpp | 2 + src/script/script_error.h | 3 +- src/test/data/script_tests.json | 85 ++++++++++++++++++++++++++++++++- src/test/script_tests.cpp | 1 + src/test/transaction_tests.cpp | 1 + 8 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index 6bf5ca0ee..458ec4a0c 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -42,6 +42,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_NULLDUMMY | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | + SCRIPT_VERIFY_MINIMALIF | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S | diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 47ea261e3..fd356fed0 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -428,6 +428,12 @@ bool EvalScript(vector >& stack, const CScript& script, un if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); + if (sigversion == SIGVERSION_WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) { + if (vch.size() > 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + if (vch.size() == 1 && vch[0] != 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + } fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e5d7865cd..2ce4b23e5 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -94,6 +94,10 @@ enum // Making v1-v16 witness program non-standard // SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), + + // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector + // + SCRIPT_VERIFY_MINIMALIF = (1U << 13), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index cef807edc..9969c232f 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -63,6 +63,8 @@ const char* ScriptErrorString(const ScriptError serror) return "Non-canonical signature: S value is unnecessarily high"; case SCRIPT_ERR_SIG_NULLDUMMY: return "Dummy CHECKMULTISIG argument must be zero"; + case SCRIPT_ERR_MINIMALIF: + return "OP_IF/NOTIF argument must be minimal"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: return "NOPx reserved for soft-fork upgrades"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: diff --git a/src/script/script_error.h b/src/script/script_error.h index 09dc6945a..6d34d3792 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -39,7 +39,7 @@ typedef enum ScriptError_t SCRIPT_ERR_NEGATIVE_LOCKTIME, SCRIPT_ERR_UNSATISFIED_LOCKTIME, - /* BIP62 */ + /* Malleability */ SCRIPT_ERR_SIG_HASHTYPE, SCRIPT_ERR_SIG_DER, SCRIPT_ERR_MINIMALDATA, @@ -48,6 +48,7 @@ typedef enum ScriptError_t SCRIPT_ERR_SIG_NULLDUMMY, SCRIPT_ERR_PUBKEYTYPE, SCRIPT_ERR_CLEANSTACK, + SCRIPT_ERR_MINIMALIF, /* softfork safeness */ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index fcd545738..d456a8bef 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -2125,5 +2125,88 @@ ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], ["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], -["The End"] + +["MINIMALIF tests"], +["MINIMALIF is not applied to non-segwit scripts"], +["1", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["2", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["1", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["Normal P2SH IF 1 ENDIF"], +["1 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["2 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["Normal P2SH NOTIF 1 ENDIF"], +["1 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + + + +["P2SH-P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2SH-P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + + ["The End"] ] diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 5a9aaf9bc..36c591d61 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -89,6 +89,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"}, {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"}, {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"}, + {SCRIPT_ERR_MINIMALIF, "MINIMALIF"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"}, {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"}, diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index b5af400bc..165dfd9a3 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -50,6 +50,7 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) + (string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) From 3e80ab7f2a338d1bb3d9321c13a18f1324130617 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Thu, 22 Sep 2016 15:06:54 +0800 Subject: [PATCH 1073/1223] Add policy: null signature for failed CHECK(MULTI)SIG Github-Pull: #8634 Rebased-From: e41bd449ab2b8d01260795383af2c40b659d8587 --- src/policy/policy.h | 1 + src/script/interpreter.cpp | 14 +++++++++++++- src/script/interpreter.h | 4 ++++ src/script/script_error.cpp | 2 ++ src/script/script_error.h | 1 + src/test/data/script_tests.json | 33 ++++++++++++++++++++++++++++++++- src/test/script_tests.cpp | 1 + src/test/transaction_tests.cpp | 1 + 8 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index 458ec4a0c..9d6ff1233 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -43,6 +43,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_MINIMALIF | + SCRIPT_VERIFY_NULLFAIL | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S | diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index fd356fed0..41756ea71 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -885,6 +885,9 @@ bool EvalScript(vector >& stack, const CScript& script, un } bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); @@ -914,6 +917,9 @@ bool EvalScript(vector >& stack, const CScript& script, un if (nOpCount > MAX_OPS_PER_SCRIPT) return set_error(serror, SCRIPT_ERR_OP_COUNT); int ikey = ++i; + // ikey2 is the position of last non-signature item in the stack. Top stack item = 1. + // With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails. + int ikey2 = nKeysCount + 2; i += nKeysCount; if ((int)stack.size() < i) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -970,8 +976,14 @@ bool EvalScript(vector >& stack, const CScript& script, un } // Clean up stack of actual arguments - while (i-- > 1) + while (i-- > 1) { + // If the operation failed, we require that all signatures must be empty vector + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && stacktop(-1).size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + if (ikey2 > 0) + ikey2--; popstack(stack); + } // A bug causes CHECKMULTISIG to consume one extra argument // whose contents were not checked in any way. diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 2ce4b23e5..0adc9482f 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -98,6 +98,10 @@ enum // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector // SCRIPT_VERIFY_MINIMALIF = (1U << 13), + + // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed + // + SCRIPT_VERIFY_NULLFAIL = (1U << 14), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index 9969c232f..e27b715c2 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -65,6 +65,8 @@ const char* ScriptErrorString(const ScriptError serror) return "Dummy CHECKMULTISIG argument must be zero"; case SCRIPT_ERR_MINIMALIF: return "OP_IF/NOTIF argument must be minimal"; + case SCRIPT_ERR_SIG_NULLFAIL: + return "Signature must be zero for failed CHECK(MULTI)SIG operation"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: return "NOPx reserved for soft-fork upgrades"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: diff --git a/src/script/script_error.h b/src/script/script_error.h index 6d34d3792..bccfdb99e 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -49,6 +49,7 @@ typedef enum ScriptError_t SCRIPT_ERR_PUBKEYTYPE, SCRIPT_ERR_CLEANSTACK, SCRIPT_ERR_MINIMALIF, + SCRIPT_ERR_SIG_NULLFAIL, /* softfork safeness */ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index d456a8bef..06103ea5b 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1491,6 +1491,27 @@ "OK", "BIP66 example 4, with DERSIG" ], +[ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "OK", + "BIP66 example 4, with DERSIG, non-null DER-compliant signature" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "OK", + "BIP66 example 4, with DERSIG and NULLFAIL" +], +[ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "NULLFAIL", + "BIP66 example 4, with DERSIG and NULLFAIL, non-null DER-compliant signature" +], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -2208,5 +2229,15 @@ [["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], [["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], - ["The End"] +["NULLFAIL should cover all signatures and signatures only"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL,NULLDUMMY", "SIG_NULLDUMMY", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], + +["The End"] ] diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 36c591d61..836ef734d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -90,6 +90,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"}, {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"}, {SCRIPT_ERR_MINIMALIF, "MINIMALIF"}, + {SCRIPT_ERR_SIG_NULLFAIL, "NULLFAIL"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"}, {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"}, diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 165dfd9a3..6163d2f63 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -51,6 +51,7 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) (string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) + (string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL) (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) From 7ae624296000e714034d86891ffcd4a565f278fa Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 12 Sep 2016 21:32:53 -0400 Subject: [PATCH 1074/1223] net: fix a few cases where messages were sent rather than dropped upon disconnection 75ead758 turned these into crashes in the event of a handshake failure, most notably when a peer does not offer the expected services. There are likely other cases that these assertions will find as well. Github-Pull: #8862 Rebased-From: 905bc68d05595f41cca36b3df83accd10c00cc48 --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c9869d04f..c8e290ae5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6342,7 +6342,7 @@ bool SendMessages(CNode* pto) // Ping automatically sent as a latency probe & keepalive. pingSend = true; } - if (pingSend) { + if (pingSend && !pto->fDisconnect) { uint64_t nonce = 0; while (nonce == 0) { GetRandBytes((unsigned char*)&nonce, sizeof(nonce)); @@ -6423,7 +6423,7 @@ bool SendMessages(CNode* pto) if (pindexBestHeader == NULL) pindexBestHeader = chainActive.Tip(); bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. - if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) { + if (!state.fSyncStarted && !pto->fClient && !pto->fDisconnect && !fImporting && !fReindex) { // Only actively request headers from a single peer, unless we're close to today. if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { state.fSyncStarted = true; From 7a34a4614c3ac89ef31cb4854620e381d5df72ad Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 30 Sep 2016 23:08:29 +0800 Subject: [PATCH 1075/1223] Add NULLDUMMY verify flag in bitcoinconsensus.h Github-Pull: #8848 Rebased-From: 2fa0063c26c80c719a1c0d30e548e338689ac917 --- doc/shared-libraries.md | 5 +++++ src/script/bitcoinconsensus.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/shared-libraries.md b/doc/shared-libraries.md index ec6f16c8a..dc363582c 100644 --- a/doc/shared-libraries.md +++ b/doc/shared-libraries.md @@ -30,12 +30,17 @@ The interface is defined in the C header `bitcoinconsensus.h` located in `src/s - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE` - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH` - Evaluate P2SH ([BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)) subscripts - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG` - Enforce strict DER ([BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki)) compliance +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY` - Enforce NULLDUMMY ([BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY` - Enable CHECKLOCKTIMEVERIFY ([BIP65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY` - Enable CHECKSEQUENCEVERIFY ([BIP112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS` - Enable WITNESS ([BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)) ##### Errors - `bitcoinconsensus_ERR_OK` - No errors with input parameters *(see the return value of `bitcoinconsensus_verify_script` for the verification status)* - `bitcoinconsensus_ERR_TX_INDEX` - An invalid index for `txTo` - `bitcoinconsensus_ERR_TX_SIZE_MISMATCH` - `txToLen` did not match with the size of `txTo` - `bitcoinconsensus_ERR_DESERIALIZE` - An error deserializing `txTo` +- `bitcoinconsensus_ERR_AMOUNT_REQUIRED` - Input amount is required if WITNESS is used ### Example Implementations - [NBitcoin](https://github.com/NicolasDorier/NBitcoin/blob/master/NBitcoin/Script.cs#L814) (.NET Bindings) diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index f73a8e30b..1d2d5c23e 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -50,6 +50,7 @@ enum bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enforce NULLDUMMY (BIP147) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141) From e47299a8f2ebc98644bb8d15a3222faac51875fd Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 16 Sep 2016 20:48:23 -0400 Subject: [PATCH 1076/1223] [qa] Update p2p-compactblocks.py for compactblocks v2 Github-Pull: #8393 Rebased-From: 27acfc1d2ee53cc52b54befd2d4bfa24a77a2eef --- qa/rpc-tests/p2p-compactblocks.py | 583 ++++++++++++++++++++---------- 1 file changed, 389 insertions(+), 194 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index cd6804376..cdcfb36e7 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -12,14 +12,16 @@ from test_framework.script import CScript, OP_TRUE ''' CompactBlocksTest -- test compact blocks (BIP 152) -''' +Version 1 compact blocks are pre-segwit (txids) +Version 2 compact blocks are post-segwit (wtxids) +''' # TestNode: A peer we use to send messages to bitcoind, and store responses. class TestNode(SingleNodeConnCB): def __init__(self): SingleNodeConnCB.__init__(self) - self.last_sendcmpct = None + self.last_sendcmpct = [] self.last_headers = None self.last_inv = None self.last_cmpctblock = None @@ -34,7 +36,7 @@ class TestNode(SingleNodeConnCB): self.set_announced_blockhashes = set() def on_sendcmpct(self, conn, message): - self.last_sendcmpct = message + self.last_sendcmpct.append(message) def on_block(self, conn, message): self.last_block = message @@ -108,29 +110,31 @@ class CompactBlocksTest(BitcoinTestFramework): def __init__(self): super().__init__() self.setup_clean_chain = True - self.num_nodes = 1 + # Node0 = pre-segwit, node1 = segwit-aware + self.num_nodes = 2 self.utxos = [] def setup_network(self): self.nodes = [] - # Turn off segwit in this test, as compact blocks don't currently work - # with segwit. (After BIP 152 is updated to support segwit, we can - # test behavior with and without segwit enabled by adding a second node - # to the test.) - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0"]]) + # Start up node0 to be a version 1, pre-segwit node. + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0"], + ["-debug", "-logtimemicros", "-txindex"]]) + connect_nodes(self.nodes[0], 1) - def build_block_on_tip(self): - height = self.nodes[0].getblockcount() - tip = self.nodes[0].getbestblockhash() - mtp = self.nodes[0].getblockheader(tip)['mediantime'] + def build_block_on_tip(self, node): + height = node.getblockcount() + tip = node.getbestblockhash() + mtp = node.getblockheader(tip)['mediantime'] block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1) block.solve() return block # Create 10 more anyone-can-spend utxo's for testing. def make_utxos(self): - block = self.build_block_on_tip() + # Doesn't matter which node we use, just use node0. + block = self.build_block_on_tip(self.nodes[0]) self.test_node.send_and_ping(msg_block(block)) assert(int(self.nodes[0].getbestblockhash(), 16) == block.sha256) self.nodes[0].generate(100) @@ -143,7 +147,7 @@ class CompactBlocksTest(BitcoinTestFramework): tx.vout.append(CTxOut(out_value, CScript([OP_TRUE]))) tx.rehash() - block2 = self.build_block_on_tip() + block2 = self.build_block_on_tip(self.nodes[0]) block2.vtx.append(tx) block2.hashMerkleRoot = block2.calc_merkle_root() block2.solve() @@ -152,26 +156,30 @@ class CompactBlocksTest(BitcoinTestFramework): self.utxos.extend([[tx.sha256, i, out_value] for i in range(10)]) return - # Test "sendcmpct": - # - No compact block announcements or getdata(MSG_CMPCT_BLOCK) unless - # sendcmpct is sent. - # - If sendcmpct is sent with version > 1, the message is ignored. + # Test "sendcmpct" (between peers preferring the same version): + # - No compact block announcements unless sendcmpct is sent. + # - If sendcmpct is sent with version > preferred_version, the message is ignored. # - If sendcmpct is sent with boolean 0, then block announcements are not # made with compact blocks. # - If sendcmpct is then sent with boolean 1, then new block announcements # are made with compact blocks. - def test_sendcmpct(self): - print("Testing SENDCMPCT p2p message... ") - - # Make sure we get a version 0 SENDCMPCT message from our peer + # If old_node is passed in, request compact blocks with version=preferred-1 + # and verify that it receives block announcements via compact block. + def test_sendcmpct(self, node, test_node, preferred_version, old_node=None): + # Make sure we get a SENDCMPCT message from our peer def received_sendcmpct(): - return (self.test_node.last_sendcmpct is not None) + return (len(test_node.last_sendcmpct) > 0) got_message = wait_until(received_sendcmpct, timeout=30) assert(received_sendcmpct()) assert(got_message) - assert_equal(self.test_node.last_sendcmpct.version, 1) + with mininode_lock: + # Check that the first version received is the preferred one + assert_equal(test_node.last_sendcmpct[0].version, preferred_version) + # And that we receive versions down to 1. + assert_equal(test_node.last_sendcmpct[-1].version, 1) + test_node.last_sendcmpct = [] - tip = int(self.nodes[0].getbestblockhash(), 16) + tip = int(node.getbestblockhash(), 16) def check_announcement_of_new_block(node, peer, predicate): peer.clear_block_announcement() @@ -183,56 +191,75 @@ class CompactBlocksTest(BitcoinTestFramework): assert(predicate(peer)) # We shouldn't get any block announcements via cmpctblock yet. - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) # Try one more time, this time after requesting headers. - self.test_node.request_headers_and_sync(locator=[tip]) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None and p.last_inv is not None) + test_node.request_headers_and_sync(locator=[tip]) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None and p.last_inv is not None) # Test a few ways of using sendcmpct that should NOT # result in compact block announcements. # Before each test, sync the headers chain. - self.test_node.request_headers_and_sync(locator=[tip]) + test_node.request_headers_and_sync(locator=[tip]) # Now try a SENDCMPCT message with too-high version sendcmpct = msg_sendcmpct() - sendcmpct.version = 2 - self.test_node.send_and_ping(sendcmpct) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) + sendcmpct.version = preferred_version+1 + sendcmpct.announce = True + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) # Headers sync before next test. - self.test_node.request_headers_and_sync(locator=[tip]) + test_node.request_headers_and_sync(locator=[tip]) # Now try a SENDCMPCT message with valid version, but announce=False - self.test_node.send_and_ping(msg_sendcmpct()) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None) + sendcmpct.version = preferred_version + sendcmpct.announce = False + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) # Headers sync before next test. - self.test_node.request_headers_and_sync(locator=[tip]) + test_node.request_headers_and_sync(locator=[tip]) # Finally, try a SENDCMPCT message with announce=True - sendcmpct.version = 1 + sendcmpct.version = preferred_version sendcmpct.announce = True - self.test_node.send_and_ping(sendcmpct) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) # Try one more time (no headers sync should be needed!) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) # Try one more time, after turning on sendheaders - self.test_node.send_and_ping(msg_sendheaders()) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is not None) + test_node.send_and_ping(msg_sendheaders()) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) + + # Try one more time, after sending a version-1, announce=false message. + sendcmpct.version = preferred_version-1 + sendcmpct.announce = False + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) # Now turn off announcements + sendcmpct.version = preferred_version sendcmpct.announce = False - self.test_node.send_and_ping(sendcmpct) - check_announcement_of_new_block(self.nodes[0], self.test_node, lambda p: p.last_cmpctblock is None and p.last_headers is not None) + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None and p.last_headers is not None) + + if old_node is not None: + # Verify that a peer using an older protocol version can receive + # announcements from this node. + sendcmpct.version = preferred_version-1 + sendcmpct.announce = True + old_node.send_and_ping(sendcmpct) + # Header sync + old_node.request_headers_and_sync(locator=[tip]) + check_announcement_of_new_block(node, old_node, lambda p: p.last_cmpctblock is not None) # This test actually causes bitcoind to (reasonably!) disconnect us, so do this last. def test_invalid_cmpctblock_message(self): - print("Testing invalid index in cmpctblock message...") self.nodes[0].generate(101) - block = self.build_block_on_tip() + block = self.build_block_on_tip(self.nodes[0]) cmpct_block = P2PHeaderAndShortIDs() cmpct_block.header = CBlockHeader(block) @@ -245,47 +272,63 @@ class CompactBlocksTest(BitcoinTestFramework): # Compare the generated shortids to what we expect based on BIP 152, given # bitcoind's choice of nonce. - def test_compactblock_construction(self): - print("Testing compactblock headers and shortIDs are correct...") - + def test_compactblock_construction(self, node, test_node, version, use_witness_address): # Generate a bunch of transactions. - self.nodes[0].generate(101) + node.generate(101) num_transactions = 25 - address = self.nodes[0].getnewaddress() + address = node.getnewaddress() + if use_witness_address: + # Want at least one segwit spend, so move all funds to + # a witness address. + address = node.addwitnessaddress(address) + value_to_send = node.getbalance() + node.sendtoaddress(address, satoshi_round(value_to_send-Decimal(0.1))) + node.generate(1) + + segwit_tx_generated = False for i in range(num_transactions): - self.nodes[0].sendtoaddress(address, 0.1) + txid = node.sendtoaddress(address, 0.1) + hex_tx = node.gettransaction(txid)["hex"] + tx = FromHex(CTransaction(), hex_tx) + if not tx.wit.is_null(): + segwit_tx_generated = True + + if use_witness_address: + assert(segwit_tx_generated) # check that our test is not broken # Wait until we've seen the block announcement for the resulting tip tip = int(self.nodes[0].getbestblockhash(), 16) assert(self.test_node.wait_for_block_announcement(tip)) # Now mine a block, and look at the resulting compact block. - self.test_node.clear_block_announcement() - block_hash = int(self.nodes[0].generate(1)[0], 16) + test_node.clear_block_announcement() + block_hash = int(node.generate(1)[0], 16) # Store the raw block in our internal format. - block = FromHex(CBlock(), self.nodes[0].getblock("%02x" % block_hash, False)) + block = FromHex(CBlock(), node.getblock("%02x" % block_hash, False)) [tx.calc_sha256() for tx in block.vtx] block.rehash() # Don't care which type of announcement came back for this test; just # request the compact block if we didn't get one yet. - wait_until(self.test_node.received_block_announcement, timeout=30) + wait_until(test_node.received_block_announcement, timeout=30) + assert(test_node.received_block_announcement()) with mininode_lock: - if self.test_node.last_cmpctblock is None: - self.test_node.clear_block_announcement() + if test_node.last_cmpctblock is None: + test_node.clear_block_announcement() inv = CInv(4, block_hash) # 4 == "CompactBlock" - self.test_node.send_message(msg_getdata([inv])) + test_node.send_message(msg_getdata([inv])) - wait_until(self.test_node.received_block_announcement, timeout=30) + wait_until(test_node.received_block_announcement, timeout=30) + assert(test_node.received_block_announcement()) # Now we should have the compactblock header_and_shortids = None with mininode_lock: - assert(self.test_node.last_cmpctblock is not None) + assert(test_node.last_cmpctblock is not None) # Convert the on-the-wire representation to absolute indexes - header_and_shortids = HeaderAndShortIDs(self.test_node.last_cmpctblock.header_and_shortids) + header_and_shortids = HeaderAndShortIDs(test_node.last_cmpctblock.header_and_shortids) # Check that we got the right block! header_and_shortids.header.calc_sha256() @@ -298,8 +341,17 @@ class CompactBlocksTest(BitcoinTestFramework): # Check that all prefilled_txn entries match what's in the block. for entry in header_and_shortids.prefilled_txn: entry.tx.calc_sha256() + # This checks the non-witness parts of the tx agree assert_equal(entry.tx.sha256, block.vtx[entry.index].sha256) + # And this checks the witness + wtxid = entry.tx.calc_sha256(True) + if version == 2: + assert_equal(wtxid, block.vtx[entry.index].calc_sha256(True)) + else: + # Shouldn't have received a witness + assert(entry.tx.wit.is_null()) + # Check that the cmpctblock message announced all the transactions. assert_equal(len(header_and_shortids.prefilled_txn) + len(header_and_shortids.shortids), len(block.vtx)) @@ -314,7 +366,10 @@ class CompactBlocksTest(BitcoinTestFramework): # Already checked prefilled transactions above header_and_shortids.prefilled_txn.pop(0) else: - shortid = calculate_shortid(k0, k1, block.vtx[index].sha256) + tx_hash = block.vtx[index].sha256 + if version == 2: + tx_hash = block.vtx[index].calc_sha256(True) + shortid = calculate_shortid(k0, k1, tx_hash) assert_equal(shortid, header_and_shortids.shortids[0]) header_and_shortids.shortids.pop(0) index += 1 @@ -322,49 +377,50 @@ class CompactBlocksTest(BitcoinTestFramework): # Test that bitcoind requests compact blocks when we announce new blocks # via header or inv, and that responding to getblocktxn causes the block # to be successfully reconstructed. - def test_compactblock_requests(self): - print("Testing compactblock requests... ") - + # Post-segwit: upgraded nodes would only make this request of cb-version-2, + # NODE_WITNESS peers. Unupgraded nodes would still make this request of + # any cb-version-1-supporting peer. + def test_compactblock_requests(self, node, test_node): # Try announcing a block with an inv or header, expect a compactblock # request for announce in ["inv", "header"]: - block = self.build_block_on_tip() + block = self.build_block_on_tip(node) with mininode_lock: - self.test_node.last_getdata = None + test_node.last_getdata = None if announce == "inv": - self.test_node.send_message(msg_inv([CInv(2, block.sha256)])) + test_node.send_message(msg_inv([CInv(2, block.sha256)])) else: - self.test_node.send_header_for_blocks([block]) - success = wait_until(lambda: self.test_node.last_getdata is not None, timeout=30) + test_node.send_header_for_blocks([block]) + success = wait_until(lambda: test_node.last_getdata is not None, timeout=30) assert(success) - assert_equal(len(self.test_node.last_getdata.inv), 1) - assert_equal(self.test_node.last_getdata.inv[0].type, 4) - assert_equal(self.test_node.last_getdata.inv[0].hash, block.sha256) + assert_equal(len(test_node.last_getdata.inv), 1) + assert_equal(test_node.last_getdata.inv[0].type, 4) + assert_equal(test_node.last_getdata.inv[0].hash, block.sha256) # Send back a compactblock message that omits the coinbase comp_block = HeaderAndShortIDs() comp_block.header = CBlockHeader(block) comp_block.nonce = 0 comp_block.shortids = [1] # this is useless, and wrong - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) # Expect a getblocktxn message. with mininode_lock: - assert(self.test_node.last_getblocktxn is not None) - absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert(test_node.last_getblocktxn is not None) + absolute_indexes = test_node.last_getblocktxn.block_txn_request.to_absolute() assert_equal(absolute_indexes, [0]) # should be a coinbase request # Send the coinbase, and verify that the tip advances. msg = msg_blocktxn() msg.block_transactions.blockhash = block.sha256 msg.block_transactions.transactions = [block.vtx[0]] - self.test_node.send_and_ping(msg) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + test_node.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) # Create a chain of transactions from given utxo, and add to a new block. - def build_block_with_transactions(self, utxo, num_transactions): - block = self.build_block_on_tip() + def build_block_with_transactions(self, node, utxo, num_transactions): + block = self.build_block_on_tip(node) for i in range(num_transactions): tx = CTransaction() @@ -381,118 +437,113 @@ class CompactBlocksTest(BitcoinTestFramework): # Test that we only receive getblocktxn requests for transactions that the # node needs, and that responding to them causes the block to be # reconstructed. - def test_getblocktxn_requests(self): - print("Testing getblocktxn requests...") + def test_getblocktxn_requests(self, node, test_node, version): + with_witness = (version==2) + + def test_getblocktxn_response(compact_block, peer, expected_result): + msg = msg_cmpctblock(compact_block.to_p2p()) + peer.send_and_ping(msg) + with mininode_lock: + assert(peer.last_getblocktxn is not None) + absolute_indexes = peer.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, expected_result) + + def test_tip_after_message(node, peer, msg, tip): + peer.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), tip) # First try announcing compactblocks that won't reconstruct, and verify # that we receive getblocktxn messages back. utxo = self.utxos.pop(0) - block = self.build_block_with_transactions(utxo, 5) + block = self.build_block_with_transactions(node, utxo, 5) self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) - comp_block = HeaderAndShortIDs() - comp_block.initialize_from_block(block) + comp_block.initialize_from_block(block, use_witness=with_witness) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) - with mininode_lock: - assert(self.test_node.last_getblocktxn is not None) - absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() - assert_equal(absolute_indexes, [1, 2, 3, 4, 5]) - msg = msg_blocktxn() - msg.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) - self.test_node.send_and_ping(msg) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + test_getblocktxn_response(comp_block, test_node, [1, 2, 3, 4, 5]) + + msg_bt = msg_blocktxn() + if with_witness: + msg_bt = msg_witness_blocktxn() # serialize with witnesses + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) utxo = self.utxos.pop(0) - block = self.build_block_with_transactions(utxo, 5) + block = self.build_block_with_transactions(node, utxo, 5) self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) # Now try interspersing the prefilled transactions - comp_block.initialize_from_block(block, prefill_list=[0, 1, 5]) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) - with mininode_lock: - assert(self.test_node.last_getblocktxn is not None) - absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() - assert_equal(absolute_indexes, [2, 3, 4]) - msg.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) - self.test_node.send_and_ping(msg) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + comp_block.initialize_from_block(block, prefill_list=[0, 1, 5], use_witness=with_witness) + test_getblocktxn_response(comp_block, test_node, [2, 3, 4]) + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) # Now try giving one transaction ahead of time. utxo = self.utxos.pop(0) - block = self.build_block_with_transactions(utxo, 5) + block = self.build_block_with_transactions(node, utxo, 5) self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) - self.test_node.send_and_ping(msg_tx(block.vtx[1])) - assert(block.vtx[1].hash in self.nodes[0].getrawmempool()) + test_node.send_and_ping(msg_tx(block.vtx[1])) + assert(block.vtx[1].hash in node.getrawmempool()) # Prefill 4 out of the 6 transactions, and verify that only the one # that was not in the mempool is requested. - comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4]) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) - with mininode_lock: - assert(self.test_node.last_getblocktxn is not None) - absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() - assert_equal(absolute_indexes, [5]) + comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4], use_witness=with_witness) + test_getblocktxn_response(comp_block, test_node, [5]) - msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]]) - self.test_node.send_and_ping(msg) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + msg_bt.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) # Now provide all transactions to the node before the block is # announced and verify reconstruction happens immediately. utxo = self.utxos.pop(0) - block = self.build_block_with_transactions(utxo, 10) + block = self.build_block_with_transactions(node, utxo, 10) self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) for tx in block.vtx[1:]: - self.test_node.send_message(msg_tx(tx)) - self.test_node.sync_with_ping() + test_node.send_message(msg_tx(tx)) + test_node.sync_with_ping() # Make sure all transactions were accepted. - mempool = self.nodes[0].getrawmempool() + mempool = node.getrawmempool() for tx in block.vtx[1:]: assert(tx.hash in mempool) # Clear out last request. with mininode_lock: - self.test_node.last_getblocktxn = None + test_node.last_getblocktxn = None # Send compact block - comp_block.initialize_from_block(block, prefill_list=[0]) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + comp_block.initialize_from_block(block, prefill_list=[0], use_witness=with_witness) + test_tip_after_message(node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.sha256) with mininode_lock: # Shouldn't have gotten a request for any transaction - assert(self.test_node.last_getblocktxn is None) - # Tip should have updated - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + assert(test_node.last_getblocktxn is None) # Incorrectly responding to a getblocktxn shouldn't cause the block to be # permanently failed. - def test_incorrect_blocktxn_response(self): - print("Testing handling of incorrect blocktxn responses...") - + def test_incorrect_blocktxn_response(self, node, test_node, version): if (len(self.utxos) == 0): self.make_utxos() utxo = self.utxos.pop(0) - block = self.build_block_with_transactions(utxo, 10) + block = self.build_block_with_transactions(node, utxo, 10) self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) # Relay the first 5 transactions from the block in advance for tx in block.vtx[1:6]: - self.test_node.send_message(msg_tx(tx)) - self.test_node.sync_with_ping() + test_node.send_message(msg_tx(tx)) + test_node.sync_with_ping() # Make sure all transactions were accepted. - mempool = self.nodes[0].getrawmempool() + mempool = node.getrawmempool() for tx in block.vtx[1:6]: assert(tx.hash in mempool) # Send compact block comp_block = HeaderAndShortIDs() - comp_block.initialize_from_block(block, prefill_list=[0]) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + comp_block.initialize_from_block(block, prefill_list=[0], use_witness=(version == 2)) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) absolute_indexes = [] with mininode_lock: - assert(self.test_node.last_getblocktxn is not None) - absolute_indexes = self.test_node.last_getblocktxn.block_txn_request.to_absolute() + assert(test_node.last_getblocktxn is not None) + absolute_indexes = test_node.last_getblocktxn.block_txn_request.to_absolute() assert_equal(absolute_indexes, [6, 7, 8, 9, 10]) # Now give an incorrect response. @@ -504,100 +555,107 @@ class CompactBlocksTest(BitcoinTestFramework): # verifying that the block isn't marked bad permanently. This is good # enough for now. msg = msg_blocktxn() + if version==2: + msg = msg_witness_blocktxn() msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]] + block.vtx[7:]) - self.test_node.send_and_ping(msg) + test_node.send_and_ping(msg) # Tip should not have updated - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) + assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) # We should receive a getdata request - success = wait_until(lambda: self.test_node.last_getdata is not None, timeout=10) + success = wait_until(lambda: test_node.last_getdata is not None, timeout=10) assert(success) - assert_equal(len(self.test_node.last_getdata.inv), 1) - assert_equal(self.test_node.last_getdata.inv[0].type, 2) - assert_equal(self.test_node.last_getdata.inv[0].hash, block.sha256) + assert_equal(len(test_node.last_getdata.inv), 1) + assert(test_node.last_getdata.inv[0].type == 2 or test_node.last_getdata.inv[0].type == 2|MSG_WITNESS_FLAG) + assert_equal(test_node.last_getdata.inv[0].hash, block.sha256) # Deliver the block - self.test_node.send_and_ping(msg_block(block)) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) - - def test_getblocktxn_handler(self): - print("Testing getblocktxn handler...") + if version==2: + test_node.send_and_ping(msg_witness_block(block)) + else: + test_node.send_and_ping(msg_block(block)) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + def test_getblocktxn_handler(self, node, test_node, version): # bitcoind won't respond for blocks whose height is more than 15 blocks # deep. MAX_GETBLOCKTXN_DEPTH = 15 - chain_height = self.nodes[0].getblockcount() + chain_height = node.getblockcount() current_height = chain_height while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): - block_hash = self.nodes[0].getblockhash(current_height) - block = FromHex(CBlock(), self.nodes[0].getblock(block_hash, False)) + block_hash = node.getblockhash(current_height) + block = FromHex(CBlock(), node.getblock(block_hash, False)) msg = msg_getblocktxn() msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), []) num_to_request = random.randint(1, len(block.vtx)) msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request))) - self.test_node.send_message(msg) - success = wait_until(lambda: self.test_node.last_blocktxn is not None, timeout=10) + test_node.send_message(msg) + success = wait_until(lambda: test_node.last_blocktxn is not None, timeout=10) assert(success) [tx.calc_sha256() for tx in block.vtx] with mininode_lock: - assert_equal(self.test_node.last_blocktxn.block_transactions.blockhash, int(block_hash, 16)) + assert_equal(test_node.last_blocktxn.block_transactions.blockhash, int(block_hash, 16)) all_indices = msg.block_txn_request.to_absolute() for index in all_indices: - tx = self.test_node.last_blocktxn.block_transactions.transactions.pop(0) + tx = test_node.last_blocktxn.block_transactions.transactions.pop(0) tx.calc_sha256() assert_equal(tx.sha256, block.vtx[index].sha256) - self.test_node.last_blocktxn = None + if version == 1: + # Witnesses should have been stripped + assert(tx.wit.is_null()) + else: + # Check that the witness matches + assert_equal(tx.calc_sha256(True), block.vtx[index].calc_sha256(True)) + test_node.last_blocktxn = None current_height -= 1 # Next request should be ignored, as we're past the allowed depth. - block_hash = self.nodes[0].getblockhash(current_height) + block_hash = node.getblockhash(current_height) msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0]) - self.test_node.send_and_ping(msg) + test_node.send_and_ping(msg) with mininode_lock: - assert_equal(self.test_node.last_blocktxn, None) - - def test_compactblocks_not_at_tip(self): - print("Testing compactblock requests/announcements not at chain tip...") + assert_equal(test_node.last_blocktxn, None) + def test_compactblocks_not_at_tip(self, node, test_node): # Test that requesting old compactblocks doesn't work. MAX_CMPCTBLOCK_DEPTH = 11 new_blocks = [] for i in range(MAX_CMPCTBLOCK_DEPTH): - self.test_node.clear_block_announcement() - new_blocks.append(self.nodes[0].generate(1)[0]) - wait_until(self.test_node.received_block_announcement, timeout=30) + test_node.clear_block_announcement() + new_blocks.append(node.generate(1)[0]) + wait_until(test_node.received_block_announcement, timeout=30) - self.test_node.clear_block_announcement() - self.test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) - success = wait_until(lambda: self.test_node.last_cmpctblock is not None, timeout=30) + test_node.clear_block_announcement() + test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: test_node.last_cmpctblock is not None, timeout=30) assert(success) - self.test_node.clear_block_announcement() - self.nodes[0].generate(1) - wait_until(self.test_node.received_block_announcement, timeout=30) - self.test_node.clear_block_announcement() - self.test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) - success = wait_until(lambda: self.test_node.last_block is not None, timeout=30) + test_node.clear_block_announcement() + node.generate(1) + wait_until(test_node.received_block_announcement, timeout=30) + test_node.clear_block_announcement() + test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: test_node.last_block is not None, timeout=30) assert(success) with mininode_lock: - self.test_node.last_block.block.calc_sha256() - assert_equal(self.test_node.last_block.block.sha256, int(new_blocks[0], 16)) + test_node.last_block.block.calc_sha256() + assert_equal(test_node.last_block.block.sha256, int(new_blocks[0], 16)) # Generate an old compactblock, and verify that it's not accepted. - cur_height = self.nodes[0].getblockcount() - hashPrevBlock = int(self.nodes[0].getblockhash(cur_height-5), 16) - block = self.build_block_on_tip() + cur_height = node.getblockcount() + hashPrevBlock = int(node.getblockhash(cur_height-5), 16) + block = self.build_block_on_tip(node) block.hashPrevBlock = hashPrevBlock block.solve() comp_block = HeaderAndShortIDs() comp_block.initialize_from_block(block) - self.test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) - tips = self.nodes[0].getchaintips() + tips = node.getchaintips() found = False for x in tips: if x["hash"] == block.hash: @@ -611,18 +669,61 @@ class CompactBlocksTest(BitcoinTestFramework): msg = msg_getblocktxn() msg.block_txn_request = BlockTransactionsRequest(block.sha256, [0]) with mininode_lock: - self.test_node.last_blocktxn = None - self.test_node.send_and_ping(msg) + test_node.last_blocktxn = None + test_node.send_and_ping(msg) with mininode_lock: - assert(self.test_node.last_blocktxn is None) + assert(test_node.last_blocktxn is None) + + def activate_segwit(self, node): + node.generate(144*3) + assert_equal(get_bip9_status(node, "segwit")["status"], 'active') + + def test_end_to_end_block_relay(self, node, listeners): + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(node, utxo, 10) + + [l.clear_block_announcement() for l in listeners] + + # ToHex() won't serialize with witness, but this block has no witnesses + # anyway. TODO: repeat this test with witness tx's to a segwit node. + node.submitblock(ToHex(block)) + + for l in listeners: + wait_until(lambda: l.received_block_announcement(), timeout=30) + with mininode_lock: + for l in listeners: + assert(l.last_cmpctblock is not None) + l.last_cmpctblock.header_and_shortids.header.calc_sha256() + assert_equal(l.last_cmpctblock.header_and_shortids.header.sha256, block.sha256) + + # Helper for enabling cb announcements + # Send the sendcmpct request and sync headers + def request_cb_announcements(self, peer, node, version): + tip = node.getbestblockhash() + peer.get_headers(locator=[int(tip, 16)], hashstop=0) + + msg = msg_sendcmpct() + msg.version = version + msg.announce = True + peer.send_and_ping(msg) + def run_test(self): # Setup the p2p connections and start up the network thread. self.test_node = TestNode() + self.segwit_node = TestNode() + self.old_node = TestNode() # version 1 peer <--> segwit node connections = [] connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.test_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], + self.segwit_node, services=NODE_NETWORK|NODE_WITNESS)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], + self.old_node, services=NODE_NETWORK)) self.test_node.add_connection(connections[0]) + self.segwit_node.add_connection(connections[1]) + self.old_node.add_connection(connections[2]) NetworkThread().start() # Start up network handling in another thread @@ -632,13 +733,107 @@ class CompactBlocksTest(BitcoinTestFramework): # We will need UTXOs to construct transactions in later tests. self.make_utxos() - self.test_sendcmpct() - self.test_compactblock_construction() - self.test_compactblock_requests() - self.test_getblocktxn_requests() - self.test_getblocktxn_handler() - self.test_compactblocks_not_at_tip() - self.test_incorrect_blocktxn_response() + print("Running tests, pre-segwit activation:") + + print("\tTesting SENDCMPCT p2p message... ") + self.test_sendcmpct(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_sendcmpct(self.nodes[1], self.segwit_node, 2, old_node=self.old_node) + sync_blocks(self.nodes) + + print("\tTesting compactblock construction...") + self.test_compactblock_construction(self.nodes[0], self.test_node, 1, False) + sync_blocks(self.nodes) + self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, False) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests... ") + self.test_compactblock_requests(self.nodes[0], self.test_node) + sync_blocks(self.nodes) + self.test_compactblock_requests(self.nodes[1], self.segwit_node) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn requests...") + self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn handler...") + self.test_getblocktxn_handler(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2) + self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests/announcements not at chain tip...") + self.test_compactblocks_not_at_tip(self.nodes[0], self.test_node) + sync_blocks(self.nodes) + self.test_compactblocks_not_at_tip(self.nodes[1], self.segwit_node) + self.test_compactblocks_not_at_tip(self.nodes[1], self.old_node) + sync_blocks(self.nodes) + + print("\tTesting handling of incorrect blocktxn responses...") + self.test_incorrect_blocktxn_response(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_incorrect_blocktxn_response(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + # End-to-end block relay tests + print("\tTesting end-to-end block relay...") + self.request_cb_announcements(self.test_node, self.nodes[0], 1) + self.request_cb_announcements(self.old_node, self.nodes[1], 1) + self.request_cb_announcements(self.segwit_node, self.nodes[1], 2) + self.test_end_to_end_block_relay(self.nodes[0], [self.segwit_node, self.test_node, self.old_node]) + self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + + # Advance to segwit activation + print ("\nAdvancing to segwit activation\n") + self.activate_segwit(self.nodes[1]) + print ("Running tests, post-segwit activation...") + + print("\tTesting compactblock construction...") + self.test_compactblock_construction(self.nodes[1], self.old_node, 1, True) + self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, True) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests (unupgraded node)... ") + self.test_compactblock_requests(self.nodes[0], self.test_node) + + print("\tTesting getblocktxn requests (unupgraded node)...") + self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1) + + # Need to manually sync node0 and node1, because post-segwit activation, + # node1 will not download blocks from node0. + print("\tSyncing nodes...") + assert(self.nodes[0].getbestblockhash() != self.nodes[1].getbestblockhash()) + while (self.nodes[0].getblockcount() > self.nodes[1].getblockcount()): + block_hash = self.nodes[0].getblockhash(self.nodes[1].getblockcount()+1) + self.nodes[1].submitblock(self.nodes[0].getblock(block_hash, False)) + assert_equal(self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash()) + + print("\tTesting compactblock requests (segwit node)... ") + self.test_compactblock_requests(self.nodes[1], self.segwit_node) + + print("\tTesting getblocktxn requests (segwit node)...") + self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn handler (segwit node should return witnesses)...") + self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2) + self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1) + + # Test that if we submitblock to node1, we'll get a compact block + # announcement to all peers. + # (Post-segwit activation, blocks won't propagate from node0 to node1 + # automatically, so don't bother testing a block announced to node0.) + print("\tTesting end-to-end block relay...") + self.request_cb_announcements(self.test_node, self.nodes[0], 1) + self.request_cb_announcements(self.old_node, self.nodes[1], 1) + self.request_cb_announcements(self.segwit_node, self.nodes[1], 2) + self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + + print("\tTesting invalid index in cmpctblock message...") self.test_invalid_cmpctblock_message() From 61e282b62d7d4f0bca435c6e1b836d3b2c3a0874 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 14 Sep 2016 21:00:29 -0400 Subject: [PATCH 1077/1223] [qa] Add support for compactblocks v2 to mininode Github-Pull: #8393 Rebased-From: 422fac649f75c907cad6ab7e2768b9032b9eae42 --- qa/rpc-tests/test_framework/mininode.py | 35 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 88a3b7e0f..b7e473748 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -755,6 +755,9 @@ class PrefilledTransaction(object): r += self.tx.serialize_without_witness() return r + def serialize_with_witness(self): + return self.serialize(with_witness=True) + def __repr__(self): return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) @@ -779,6 +782,7 @@ class P2PHeaderAndShortIDs(object): self.prefilled_txn = deser_vector(f, PrefilledTransaction) self.prefilled_txn_length = len(self.prefilled_txn) + # When using version 2 compact blocks, we must serialize with_witness. def serialize(self, with_witness=False): r = b"" r += self.header.serialize() @@ -787,12 +791,20 @@ class P2PHeaderAndShortIDs(object): for x in self.shortids: # We only want the first 6 bytes r += struct.pack(" Date: Sat, 17 Sep 2016 22:11:00 -0400 Subject: [PATCH 1078/1223] [qa] Fix bug in mininode witness deserialization Also improve tx printing Github-Pull: #8393 Rebased-From: f5b9b8f437c040205896ad0d7a6656efa08b5601 --- qa/rpc-tests/test_framework/mininode.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index b7e473748..4d238c08d 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -452,7 +452,7 @@ class CTransaction(object): else: self.vout = deser_vector(f, CTxOut) if flags != 0: - self.wit.vtxinwit = [CTxInWitness()]*len(self.vin) + self.wit.vtxinwit = [CTxInWitness() for i in range(len(self.vin))] self.wit.deserialize(f) self.nLockTime = struct.unpack(" Date: Sat, 25 Jun 2016 19:17:45 +0200 Subject: [PATCH 1079/1223] Use cmpctblock type 2 for segwit-enabled transfer Contains version negotiation logic by Matt Corallo and bugfixes by Suhas Daftuar. Github-Pull: #8393 Rebased-From: 6aa28abf53ef4694692474b4a3b0a8fa7559b50b --- src/blockencodings.cpp | 4 +- src/blockencodings.h | 2 +- src/main.cpp | 78 ++++++++++++++++++++++--------- src/test/blockencodings_tests.cpp | 6 +-- src/txmempool.cpp | 2 +- src/txmempool.h | 2 +- 6 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index df237f8f2..93d3fa372 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -17,7 +17,7 @@ #define MIN_TRANSACTION_BASE_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)) -CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : +CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) : nonce(GetRand(std::numeric_limits::max())), shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) { FillShortTxIDSelector(); @@ -25,7 +25,7 @@ CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : prefilledtxn[0] = {0, block.vtx[0]}; for (size_t i = 1; i < block.vtx.size(); i++) { const CTransaction& tx = block.vtx[i]; - shorttxids[i - 1] = GetShortID(tx.GetHash()); + shorttxids[i - 1] = GetShortID(fUseWTXID ? tx.GetWitnessHash() : tx.GetHash()); } } diff --git a/src/blockencodings.h b/src/blockencodings.h index b980e9e28..2f87c6d31 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -146,7 +146,7 @@ public: // Dummy for deserialization CBlockHeaderAndShortTxIDs() {} - CBlockHeaderAndShortTxIDs(const CBlock& block); + CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID); uint64_t GetShortID(const uint256& txhash) const; diff --git a/src/main.cpp b/src/main.cpp index c8e290ae5..ea7c7fd95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -292,10 +292,21 @@ struct CNodeState { bool fPreferHeaders; //! Whether this peer wants invs or cmpctblocks (when possible) for block announcements. bool fPreferHeaderAndIDs; - //! Whether this peer will send us cmpctblocks if we request them + /** + * Whether this peer will send us cmpctblocks if we request them. + * This is not used to gate request logic, as we really only care about fSupportsDesiredCmpctVersion, + * but is used as a flag to "lock in" the version of compact blocks (fWantsCmpctWitness) we send. + */ bool fProvidesHeaderAndIDs; //! Whether this peer can give us witnesses bool fHaveWitness; + //! Whether this peer wants witnesses in cmpctblocks/blocktxns + bool fWantsCmpctWitness; + /** + * If we've announced NODE_WITNESS to this peer: whether the peer sends witnesses in cmpctblocks/blocktxns, + * otherwise: whether this peer sends non-witnesses in cmpctblocks/blocktxns. + */ + bool fSupportsDesiredCmpctVersion; CNodeState() { fCurrentlyConnected = false; @@ -316,6 +327,8 @@ struct CNodeState { fPreferHeaderAndIDs = false; fProvidesHeaderAndIDs = false; fHaveWitness = false; + fWantsCmpctWitness = false; + fSupportsDesiredCmpctVersion = false; } }; @@ -475,8 +488,8 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom) { - if (nLocalServices & NODE_WITNESS) { - // Don't ever request compact blocks when segwit is enabled. + if (!nodestate->fSupportsDesiredCmpctVersion) { + // Never ask from peers who can't provide witnesses. return; } if (nodestate->fProvidesHeaderAndIDs) { @@ -484,7 +497,7 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf if (nodeid == pfrom->GetId()) return; bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = (pfrom->GetLocalServices() & NODE_WITNESS) ? 2 : 1; if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { // As per BIP152, we only get 3 of our peers to announce // blocks using compact encodings. @@ -4832,11 +4845,12 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // they wont have a useful mempool to match against a compact block, // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. + bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness; if (mi->second->nHeight >= chainActive.Height() - 10) { - CBlockHeaderAndShortTxIDs cmpctblock(block); - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); + CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness); + pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); } else - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); + pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); } // Trigger the peer node to send a getblocks request for the next batch of inventory @@ -5102,13 +5116,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage(NetMsgType::SENDHEADERS); } if (pfrom->nVersion >= SHORT_IDS_BLOCKS_VERSION) { - // Tell our peer we are willing to provide version-1 cmpctblocks + // Tell our peer we are willing to provide version 1 or 2 cmpctblocks // However, we do not request new block announcements using // cmpctblock messages. // We send this to non-NODE NETWORK peers as well, because // they may wish to request compact blocks from us bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = 2; + if (pfrom->GetLocalServices() & NODE_WITNESS) + pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + nCMPCTBLOCKVersion = 1; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); } } @@ -5188,12 +5205,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::SENDCMPCT) { bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = 0; vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion; - if (nCMPCTBLOCKVersion == 1) { + if (nCMPCTBLOCKVersion == 1 || ((pfrom->GetLocalServices() & NODE_WITNESS) && nCMPCTBLOCKVersion == 2)) { LOCK(cs_main); - State(pfrom->GetId())->fProvidesHeaderAndIDs = true; - State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; + // fProvidesHeaderAndIDs is used to "lock in" version of compact blocks we send (fWantsCmpctWitness) + if (!State(pfrom->GetId())->fProvidesHeaderAndIDs) { + State(pfrom->GetId())->fProvidesHeaderAndIDs = true; + State(pfrom->GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2; + } + if (State(pfrom->GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) // ignore later version announces + State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; + if (!State(pfrom->GetId())->fSupportsDesiredCmpctVersion) { + if (pfrom->GetLocalServices() & NODE_WITNESS) + State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2); + else + State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1); + } } } @@ -5251,7 +5279,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER && (!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { inv.type |= nFetchFlags; - if (nodestate->fProvidesHeaderAndIDs && !(nLocalServices & NODE_WITNESS)) + if (nodestate->fSupportsDesiredCmpctVersion) vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); else vToFetch.push_back(inv); @@ -5379,7 +5407,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } resp.txn[i] = block.vtx[req.indexes[i]]; } - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp); + pfrom->PushMessageWithFlag(State(pfrom->GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp); } @@ -5643,7 +5671,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // We requested this block for some reason, but our mempool will probably be useless // so we just grab the block via normal getdata std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); } return true; @@ -5655,6 +5683,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CNodeState *nodestate = State(pfrom->GetId()); + if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) { + // Don't bother trying to process compact blocks from v1 peers + // after segwit activates. + return true; + } + // We want to be a bit conservative just to be extra careful about DoS // possibilities in compact block processing... if (pindex->nHeight <= chainActive.Height() + 2) { @@ -5681,7 +5715,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (status == READ_STATUS_FAILED) { // Duplicate txindexes, the block is now in-flight, so just request it std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); return true; } @@ -5708,7 +5742,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // We requested this block, but its far into the future, so our // mempool will probably be useless - request the block normally std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); return true; } else { @@ -5750,7 +5784,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (status == READ_STATUS_FAILED) { // Might have collided, fall back to getdata now :( std::vector invs; - invs.push_back(CInv(MSG_BLOCK, resp.blockhash)); + invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()), resp.blockhash)); pfrom->PushMessage(NetMsgType::GETDATA, invs); } else { CValidationState state; @@ -5899,7 +5933,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { - if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(nLocalServices & NODE_WITNESS)) { + if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); @@ -6527,8 +6561,8 @@ bool SendMessages(CNode* pto) //TODO: Shouldn't need to reload block from disk, but requires refactor CBlock block; assert(ReadBlockFromDisk(block, pBestIndex, consensusParams)); - CBlockHeaderAndShortTxIDs cmpctblock(block); - pto->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); + CBlockHeaderAndShortTxIDs cmpctblock(block, state.fWantsCmpctWitness); + pto->PushMessageWithFlag(state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); state.pindexBestHeaderSent = pBestIndex; } else if (state.fPreferHeaders) { if (vHeaders.size() > 1) { diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 3884bf3fe..153a41ba7 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) // Do a simple ShortTxIDs RT { - CBlockHeaderAndShortTxIDs shortIDs(block); + CBlockHeaderAndShortTxIDs shortIDs(block, true); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << shortIDs; @@ -116,7 +116,7 @@ public: stream >> *this; } TestHeaderAndShortIDs(const CBlock& block) : - TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block)) {} + TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block, true)) {} uint64_t GetShortID(const uint256& txhash) const { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) // Test simple header round-trip with only coinbase { - CBlockHeaderAndShortTxIDs shortIDs(block); + CBlockHeaderAndShortTxIDs shortIDs(block, false); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << shortIDs; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 8b974d731..59afb2cf5 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -444,7 +444,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, totalTxSize += entry.GetTxSize(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); - vTxHashes.emplace_back(hash, newit); + vTxHashes.emplace_back(tx.GetWitnessHash(), newit); newit->vTxHashesIdx = vTxHashes.size() - 1; return true; diff --git a/src/txmempool.h b/src/txmempool.h index 2c2127f32..afb328b5a 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -462,7 +462,7 @@ public: indexed_transaction_set mapTx; typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; - std::vector > vTxHashes; //!< All tx hashes/entries in mapTx, in random order + std::vector > vTxHashes; //!< All tx witness hashes/entries in mapTx, in random order struct CompareIteratorByHash { bool operator()(const txiter &a, const txiter &b) const { From 890ac2563872f9b71b9863ad531c639e526df5d7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 3 Oct 2016 13:33:07 -0400 Subject: [PATCH 1080/1223] Fix overly-prescriptive p2p-segwit test for new fetch logic Github-Pull: #8393 Rebased-From: be7555f0c03057bb5537cc42ca9d4937389f0670 --- qa/rpc-tests/p2p-segwit.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index ada5fba7f..69bab3876 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -909,14 +909,6 @@ class SegWitTest(BitcoinTestFramework): # But eliminating the witness should fix it self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) - # Verify that inv's to test_node come with getdata's for non-witness tx's - # Just tweak the transaction, announce it, and verify we get a getdata - # for a normal tx - tx.vout[0].scriptPubKey = CScript([OP_TRUE, OP_TRUE]) - tx.rehash() - self.test_node.announce_tx_and_wait_for_getdata(tx) - assert(self.test_node.last_getdata.inv[0].type == 1) - # Cleanup: mine the first transaction and update utxo self.nodes[0].generate(1) assert_equal(len(self.nodes[0].getrawmempool()), 0) @@ -1022,7 +1014,7 @@ class SegWitTest(BitcoinTestFramework): def test_block_relay(self, segwit_activated): print("\tTesting block relay") - blocktype = 2|MSG_WITNESS_FLAG if segwit_activated else 2 + blocktype = 2|MSG_WITNESS_FLAG # test_node has set NODE_WITNESS, so all getdata requests should be for # witness blocks. From 4bb9ce8a958f5a55d6a72330728b7fc3b5c820c0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 3 Oct 2016 13:00:14 -0400 Subject: [PATCH 1081/1223] Use cmpctblock type 2 for segwit-enabled transfer Contains version negotiation logic by Matt Corallo and bugfixes by Suhas Daftuar. Github-Pull: #8393 Rebased-From: 6aa28abf53ef4694692474b4a3b0a8fa7559b50b --- src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ea7c7fd95..7fd13f4ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -497,7 +497,7 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf if (nodeid == pfrom->GetId()) return; bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = (pfrom->GetLocalServices() & NODE_WITNESS) ? 2 : 1; + uint64_t nCMPCTBLOCKVersion = (nLocalServices & NODE_WITNESS) ? 2 : 1; if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { // As per BIP152, we only get 3 of our peers to announce // blocks using compact encodings. @@ -4912,7 +4912,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params& chainparams) { uint32_t nFetchFlags = 0; - if (IsWitnessEnabled(pprev, chainparams) && State(pfrom->GetId())->fHaveWitness) { + if ((nLocalServices & NODE_WITNESS) && State(pfrom->GetId())->fHaveWitness) { nFetchFlags |= MSG_WITNESS_FLAG; } return nFetchFlags; @@ -5123,7 +5123,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // they may wish to request compact blocks from us bool fAnnounceUsingCMPCTBLOCK = false; uint64_t nCMPCTBLOCKVersion = 2; - if (pfrom->GetLocalServices() & NODE_WITNESS) + if (nLocalServices & NODE_WITNESS) pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); nCMPCTBLOCKVersion = 1; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); @@ -5207,7 +5207,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fAnnounceUsingCMPCTBLOCK = false; uint64_t nCMPCTBLOCKVersion = 0; vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion; - if (nCMPCTBLOCKVersion == 1 || ((pfrom->GetLocalServices() & NODE_WITNESS) && nCMPCTBLOCKVersion == 2)) { + if (nCMPCTBLOCKVersion == 1 || ((nLocalServices & NODE_WITNESS) && nCMPCTBLOCKVersion == 2)) { LOCK(cs_main); // fProvidesHeaderAndIDs is used to "lock in" version of compact blocks we send (fWantsCmpctWitness) if (!State(pfrom->GetId())->fProvidesHeaderAndIDs) { @@ -5217,7 +5217,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (State(pfrom->GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) // ignore later version announces State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; if (!State(pfrom->GetId())->fSupportsDesiredCmpctVersion) { - if (pfrom->GetLocalServices() & NODE_WITNESS) + if (nLocalServices & NODE_WITNESS) State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2); else State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1); From cc6f55191a75dafa669fc6ee93ed86d860eb0d4a Mon Sep 17 00:00:00 2001 From: Dagur Valberg Johannsson Date: Sun, 9 Oct 2016 15:47:55 -0400 Subject: [PATCH 1082/1223] [qa] Fix compact block shortids for a test case Github-Pull: #8904 Rebased-From: 4cdece40419bcc97345357f9268e03b0aff400b5 --- qa/rpc-tests/p2p-compactblocks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index cdcfb36e7..e7f5a1c9c 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -402,7 +402,9 @@ class CompactBlocksTest(BitcoinTestFramework): comp_block = HeaderAndShortIDs() comp_block.header = CBlockHeader(block) comp_block.nonce = 0 - comp_block.shortids = [1] # this is useless, and wrong + [k0, k1] = comp_block.get_siphash_keys() + comp_block.shortids = [ + calculate_shortid(k0, k1, block.vtx[0].sha256) ] test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) # Expect a getblocktxn message. From bcf3806f4cb9dad1424c78f458b5398a927161e8 Mon Sep 17 00:00:00 2001 From: jonnynewbs Date: Wed, 21 Sep 2016 10:52:53 -0400 Subject: [PATCH 1083/1223] Update bitcoin-tx to output witness data. Github-Pull: #8817 Rebased-From: 4408558843c6c2b7abeb4160f641dfdbf5be5eb4 --- src/core_write.cpp | 11 ++++++++++- src/test/data/blanktx.json | 1 + src/test/data/tt-delin1-out.json | 1 + src/test/data/tt-delout1-out.json | 1 + src/test/data/tt-locktime317000-out.json | 1 + src/test/data/txcreate1.json | 1 + src/test/data/txcreate2.json | 1 + src/test/data/txcreatedata1.json | 1 + src/test/data/txcreatedata2.json | 1 + src/test/data/txcreatedata_seq0.json | 1 + src/test/data/txcreatedata_seq1.json | 1 + src/test/data/txcreatesign.json | 1 + 12 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core_write.cpp b/src/core_write.cpp index 6f9e2266a..ea01ddc10 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -151,11 +151,13 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) { entry.pushKV("txid", tx.GetHash().GetHex()); + entry.pushKV("hash", tx.GetWitnessHash().GetHex()); entry.pushKV("version", tx.nVersion); entry.pushKV("locktime", (int64_t)tx.nLockTime); UniValue vin(UniValue::VARR); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const CTxIn& txin = tx.vin[i]; UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); @@ -166,6 +168,13 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); in.pushKV("scriptSig", o); + if (!tx.wit.IsNull() && i < tx.wit.vtxinwit.size() && !tx.wit.vtxinwit[i].IsNull()) { + UniValue txinwitness(UniValue::VARR); + for (const auto& item : tx.wit.vtxinwit[i].scriptWitness.stack) { + txinwitness.push_back(HexStr(item.begin(), item.end())); + } + in.pushKV("txinwitness", txinwitness); + } } in.pushKV("sequence", (int64_t)txin.nSequence); vin.push_back(in); diff --git a/src/test/data/blanktx.json b/src/test/data/blanktx.json index f6d6ab588..51c25a5a9 100644 --- a/src/test/data/blanktx.json +++ b/src/test/data/blanktx.json @@ -1,5 +1,6 @@ { "txid": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43", + "hash": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/tt-delin1-out.json b/src/test/data/tt-delin1-out.json index 2c7a68636..712a2c27f 100644 --- a/src/test/data/tt-delin1-out.json +++ b/src/test/data/tt-delin1-out.json @@ -1,5 +1,6 @@ { "txid": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", + "hash": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/tt-delout1-out.json b/src/test/data/tt-delout1-out.json index 9cf8cbb16..afc4e9576 100644 --- a/src/test/data/tt-delout1-out.json +++ b/src/test/data/tt-delout1-out.json @@ -1,5 +1,6 @@ { "txid": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", + "hash": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/tt-locktime317000-out.json b/src/test/data/tt-locktime317000-out.json index 65b6a4451..2b9075f8a 100644 --- a/src/test/data/tt-locktime317000-out.json +++ b/src/test/data/tt-locktime317000-out.json @@ -1,5 +1,6 @@ { "txid": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", + "hash": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", "version": 1, "locktime": 317000, "vin": [ diff --git a/src/test/data/txcreate1.json b/src/test/data/txcreate1.json index 3890dbaf6..567e8026a 100644 --- a/src/test/data/txcreate1.json +++ b/src/test/data/txcreate1.json @@ -1,5 +1,6 @@ { "txid": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", + "hash": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json index c56293eaf..a70c1d302 100644 --- a/src/test/data/txcreate2.json +++ b/src/test/data/txcreate2.json @@ -1,5 +1,6 @@ { "txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", + "hash": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreatedata1.json b/src/test/data/txcreatedata1.json index 2fed22810..760518d30 100644 --- a/src/test/data/txcreatedata1.json +++ b/src/test/data/txcreatedata1.json @@ -1,5 +1,6 @@ { "txid": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e", + "hash": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreatedata2.json b/src/test/data/txcreatedata2.json index 3d4d367f3..56dfe4a1b 100644 --- a/src/test/data/txcreatedata2.json +++ b/src/test/data/txcreatedata2.json @@ -1,5 +1,6 @@ { "txid": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", + "hash": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreatedata_seq0.json b/src/test/data/txcreatedata_seq0.json index f25aa43c2..9bc0ed459 100644 --- a/src/test/data/txcreatedata_seq0.json +++ b/src/test/data/txcreatedata_seq0.json @@ -1,5 +1,6 @@ { "txid": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", + "hash": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreatedata_seq1.json b/src/test/data/txcreatedata_seq1.json index 33585d6df..d32325541 100644 --- a/src/test/data/txcreatedata_seq1.json +++ b/src/test/data/txcreatedata_seq1.json @@ -1,5 +1,6 @@ { "txid": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b", + "hash": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b", "version": 1, "locktime": 0, "vin": [ diff --git a/src/test/data/txcreatesign.json b/src/test/data/txcreatesign.json index 057fe9b01..ff39e71b4 100644 --- a/src/test/data/txcreatesign.json +++ b/src/test/data/txcreatesign.json @@ -1,5 +1,6 @@ { "txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af", + "hash": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af", "version": 1, "locktime": 0, "vin": [ From df5069bb0e56476fe3c0670922d9cdb678c40c29 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 14 Oct 2016 12:54:15 -0400 Subject: [PATCH 1084/1223] [qa] Send segwit-encoded blocktxn messages in p2p-compactblocks Github-Pull: #8916 Rebased-From: 032e883b937a6b70d5c367fc2ee57d7eea8cb473 --- qa/rpc-tests/p2p-compactblocks.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index e7f5a1c9c..1beab609b 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -6,7 +6,7 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.blocktools import create_block, create_coinbase +from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment from test_framework.siphash import siphash256 from test_framework.script import CScript, OP_TRUE @@ -123,11 +123,13 @@ class CompactBlocksTest(BitcoinTestFramework): ["-debug", "-logtimemicros", "-txindex"]]) connect_nodes(self.nodes[0], 1) - def build_block_on_tip(self, node): + def build_block_on_tip(self, node, segwit=False): height = node.getblockcount() tip = node.getbestblockhash() mtp = node.getblockheader(tip)['mediantime'] block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1) + if segwit: + add_witness_commitment(block) block.solve() return block @@ -380,11 +382,11 @@ class CompactBlocksTest(BitcoinTestFramework): # Post-segwit: upgraded nodes would only make this request of cb-version-2, # NODE_WITNESS peers. Unupgraded nodes would still make this request of # any cb-version-1-supporting peer. - def test_compactblock_requests(self, node, test_node): + def test_compactblock_requests(self, node, test_node, version, segwit): # Try announcing a block with an inv or header, expect a compactblock # request for announce in ["inv", "header"]: - block = self.build_block_on_tip(node) + block = self.build_block_on_tip(node, segwit=segwit) with mininode_lock: test_node.last_getdata = None @@ -403,8 +405,11 @@ class CompactBlocksTest(BitcoinTestFramework): comp_block.header = CBlockHeader(block) comp_block.nonce = 0 [k0, k1] = comp_block.get_siphash_keys() + coinbase_hash = block.vtx[0].sha256 + if version == 2: + coinbase_hash = block.vtx[0].calc_sha256(True) comp_block.shortids = [ - calculate_shortid(k0, k1, block.vtx[0].sha256) ] + calculate_shortid(k0, k1, coinbase_hash) ] test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) # Expect a getblocktxn message. @@ -414,7 +419,10 @@ class CompactBlocksTest(BitcoinTestFramework): assert_equal(absolute_indexes, [0]) # should be a coinbase request # Send the coinbase, and verify that the tip advances. - msg = msg_blocktxn() + if version == 2: + msg = msg_witness_blocktxn() + else: + msg = msg_blocktxn() msg.block_transactions.blockhash = block.sha256 msg.block_transactions.transactions = [block.vtx[0]] test_node.send_and_ping(msg) @@ -750,9 +758,9 @@ class CompactBlocksTest(BitcoinTestFramework): sync_blocks(self.nodes) print("\tTesting compactblock requests... ") - self.test_compactblock_requests(self.nodes[0], self.test_node) + self.test_compactblock_requests(self.nodes[0], self.test_node, 1, False) sync_blocks(self.nodes) - self.test_compactblock_requests(self.nodes[1], self.segwit_node) + self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, False) sync_blocks(self.nodes) print("\tTesting getblocktxn requests...") @@ -800,7 +808,7 @@ class CompactBlocksTest(BitcoinTestFramework): sync_blocks(self.nodes) print("\tTesting compactblock requests (unupgraded node)... ") - self.test_compactblock_requests(self.nodes[0], self.test_node) + self.test_compactblock_requests(self.nodes[0], self.test_node, 1, True) print("\tTesting getblocktxn requests (unupgraded node)...") self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1) @@ -815,7 +823,7 @@ class CompactBlocksTest(BitcoinTestFramework): assert_equal(self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash()) print("\tTesting compactblock requests (segwit node)... ") - self.test_compactblock_requests(self.nodes[1], self.segwit_node) + self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, True) print("\tTesting getblocktxn requests (segwit node)...") self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2) From 9bb2a02f0dd8851a6dc413fd86ce0b51878b5007 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 15 Oct 2016 17:51:05 -0400 Subject: [PATCH 1085/1223] [qa] Build v4 blocks in p2p-compactblocktests This fixes an issue in backporting to 0.13 as 0.13 enforces SF activation by block version lockin instead of through a hard-coded block height. Github-Pull: #8916 Rebased-From: a4ad37d4ef4bcd81bc9d867b277efdebc86bc2e8 --- qa/rpc-tests/p2p-compactblocks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 1beab609b..131654c33 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -128,6 +128,7 @@ class CompactBlocksTest(BitcoinTestFramework): tip = node.getbestblockhash() mtp = node.getblockheader(tip)['mediantime'] block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1) + block.nVersion = 4 if segwit: add_witness_commitment(block) block.solve() From 540413d9958fd253d4bf99858db431164db275e1 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sun, 16 Oct 2016 23:53:16 +0800 Subject: [PATCH 1086/1223] Add standard limits for P2WSH with tests Github-Pull: #8499 Rebased-From: 3ade2f64cfe43ab53e4869ffc35d5fd23201e1c1 --- qa/rpc-tests/p2p-segwit.py | 111 +++++++++++++++++++++++++++++++++++++ src/main.cpp | 6 +- src/policy/policy.cpp | 54 +++++++++++++++++- src/policy/policy.h | 12 ++++ 4 files changed, 181 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 69bab3876..90f43b417 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -1703,6 +1703,116 @@ class SegWitTest(BitcoinTestFramework): assert(block_version & (1 << VB_WITNESS_BIT) != 0) self.nodes[0].setmocktime(0) # undo mocktime + def test_non_standard_witness(self): + print("\tTesting detection of non-standard P2WSH witness") + pad = chr(1).encode('latin-1') + + # Create scripts for tests + scripts = [] + scripts.append(CScript([OP_DROP] * 100)) + scripts.append(CScript([OP_DROP] * 99)) + scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 60)) + scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 61)) + + p2wsh_scripts = [] + + assert(len(self.utxo)) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + + # For each script, generate a pair of P2WSH and P2SH-P2WSH output. + outputvalue = (self.utxo[0].nValue - 1000) // (len(scripts) * 2) + for i in scripts: + p2wsh = CScript([OP_0, sha256(i)]) + p2sh = hash160(p2wsh) + p2wsh_scripts.append(p2wsh) + tx.vout.append(CTxOut(outputvalue, p2wsh)) + tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL]))) + tx.rehash() + txid = tx.sha256 + self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # Creating transactions for tests + p2wsh_txs = [] + p2sh_txs = [] + for i in range(len(scripts)): + p2wsh_tx = CTransaction() + p2wsh_tx.vin.append(CTxIn(COutPoint(txid,i*2))) + p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) + p2wsh_tx.wit.vtxinwit.append(CTxInWitness()) + p2wsh_tx.rehash() + p2wsh_txs.append(p2wsh_tx) + p2sh_tx = CTransaction() + p2sh_tx.vin.append(CTxIn(COutPoint(txid,i*2+1), CScript([p2wsh_scripts[i]]))) + p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) + p2sh_tx.wit.vtxinwit.append(CTxInWitness()) + p2sh_tx.rehash() + p2sh_txs.append(p2sh_tx) + + # Testing native P2WSH + # Witness stack size, excluding witnessScript, over 100 is non-standard + p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] + self.std_node.test_transaction_acceptance(p2wsh_txs[0], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[0], True, True) + + # Stack element size over 80 bytes is non-standard + p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] + # It can't be used to blind a node to the transaction + self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) + self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, False, b'bad-witness-nonstandard') + self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) + self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[1], True, True) + # Standard nodes should accept if element size is not over 80 bytes + p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] + self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) + self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, True) + + # witnessScript size at 3600 bytes is standard + p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] + self.test_node.test_transaction_acceptance(p2wsh_txs[2], True, True) + self.std_node.test_transaction_acceptance(p2wsh_txs[2], True, True) + + # witnessScript size at 3601 bytes is non-standard + p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] + self.std_node.test_transaction_acceptance(p2wsh_txs[3], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[3], True, True) + + # Repeating the same tests with P2SH-P2WSH + p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] + self.std_node.test_transaction_acceptance(p2sh_txs[0], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[0], True, True) + p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] + self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) + self.std_node.test_transaction_acceptance(p2sh_txs[1], True, False, b'bad-witness-nonstandard') + self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) + self.std_node.test_transaction_acceptance(p2sh_txs[1], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[1], True, True) + p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] + self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) + self.std_node.test_transaction_acceptance(p2sh_txs[1], True, True) + p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] + self.test_node.test_transaction_acceptance(p2sh_txs[2], True, True) + self.std_node.test_transaction_acceptance(p2sh_txs[2], True, True) + p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] + self.std_node.test_transaction_acceptance(p2sh_txs[3], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[3], True, True) + + self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node + # Valid but non-standard transactions in a block should be accepted by standard node + sync_blocks(self.nodes) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + assert_equal(len(self.nodes[1].getrawmempool()), 0) + + self.utxo.pop(0) + + def run_test(self): # Setup the p2p connections and start up the network thread. self.test_node = TestNode() # sets NODE_WITNESS|NODE_NETWORK @@ -1775,6 +1885,7 @@ class SegWitTest(BitcoinTestFramework): self.test_segwit_versions() self.test_premature_coinbase_witness_spend() self.test_signature_version_1() + self.test_non_standard_witness() sync_blocks(self.nodes) if self.test_upgrade: self.test_upgrade_after_activation(self.nodes[2], 2) diff --git a/src/main.cpp b/src/main.cpp index 7fd13f4ec..61d0aaf0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1282,6 +1282,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); + // Check for non-standard witness in P2WSH + if (!tx.wit.IsNull() && fRequireStandard && !IsWitnessStandard(tx, view)) + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-witness-nonstandard", true); + int64_t nSigOpsCost = GetTransactionSigOpCost(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); CAmount nValueOut = tx.GetValueOut(); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 48080abc7..ae42b2bd7 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -154,6 +154,58 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } +bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +{ + if (tx.IsCoinBase()) + return true; // Coinbases are skipped + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + // We don't care if witness for this input is empty, since it must not be bloated. + // If the script is invalid without witness, it would be caught sooner or later during validation. + if (tx.wit.vtxinwit[i].IsNull()) + continue; + + const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]); + + // get the scriptPubKey corresponding to this input: + CScript prevScript = prev.scriptPubKey; + + if (prevScript.IsPayToScriptHash()) { + std::vector > stack; + // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig + // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway. + // If the check fails at this stage, we know that this txid must be a bad one. + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) + return false; + if (stack.empty()) + return false; + prevScript = CScript(stack.back().begin(), stack.back().end()); + } + + int witnessversion = 0; + std::vector witnessprogram; + + // Non-witness program must not be associated with any witness + if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram)) + return false; + + // Check P2WSH standard limits + if (witnessversion == 0 && witnessprogram.size() == 32) { + if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) + return false; + size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1; + if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS) + return false; + for (unsigned int j = 0; j < sizeWitnessStack; j++) { + if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE) + return false; + } + } + } + return true; +} + unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) diff --git a/src/policy/policy.h b/src/policy/policy.h index 9d6ff1233..fb528d748 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -30,6 +30,12 @@ static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5; static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; /** Default for -bytespersigop */ static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; +/** The maximum number of witness stack items in a standard P2WSH script */ +static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100; +/** The maximum size of each witness stack item in a standard P2WSH script */ +static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80; +/** The maximum size of a standard witnessScript */ +static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600; /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid @@ -69,6 +75,12 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes * @return True if all inputs (scriptSigs) use only standard transaction forms */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); + /** + * Check if the transaction is over standard P2WSH resources limit: + * 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements + * These limits are adequate for multi-signature up to n-of-100 using OP_CHECKSIG, OP_ADD, and OP_EQUAL, + */ +bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); extern unsigned int nBytesPerSigOp; From 821f3e67510b9ea0b5c7b79d162daf5f0f075462 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sun, 2 Oct 2016 01:19:33 +0800 Subject: [PATCH 1087/1223] Require compressed keys in segwit as policy and disable signing with uncompressed keys for segwit scripts Github-Pull: #8499 Rebased-From: 4c0c25a604cec39675187507df423cff5d707ab5 --- src/policy/policy.h | 5 +++-- src/script/interpreter.cpp | 28 ++++++++++++++++++++------ src/script/interpreter.h | 6 +++++- src/script/script_error.cpp | 2 ++ src/script/script_error.h | 1 + src/script/sign.cpp | 6 +++++- src/test/script_tests.cpp | 1 + src/test/transaction_tests.cpp | 36 ++++++++++------------------------ 8 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index fb528d748..814e6c0b6 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -54,7 +54,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_WITNESS | - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM | + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 41756ea71..836cf9ee3 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -79,8 +79,20 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { return false; } } else { - // Non-canonical public key: neither compressed nor uncompressed - return false; + // Non-canonical public key: neither compressed nor uncompressed + return false; + } + return true; +} + +bool static IsCompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) { + // Non-canonical public key: invalid prefix for compressed key + return false; } return true; } @@ -199,10 +211,14 @@ bool CheckSignatureEncoding(const vector &vchSig, unsigned int fl return true; } -bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { - if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { +bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, const SigVersion &sigversion, ScriptError* serror) { + if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } + // Only compressed keys are accepted in segwit + if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SIGVERSION_WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) { + return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE); + } return true; } @@ -879,7 +895,7 @@ bool EvalScript(vector >& stack, const CScript& script, un scriptCode.FindAndDelete(CScript(vchSig)); } - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { //serror is set return false; } @@ -953,7 +969,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Note how this makes the exact order of pubkey/signature evaluation // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. // See the script_(in)valid tests for details. - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { // serror is set return false; } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 0adc9482f..79894c530 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -102,6 +102,10 @@ enum // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed // SCRIPT_VERIFY_NULLFAIL = (1U << 14), + + // Public keys in segregated witness scripts must be compressed + // + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1U << 15), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index e27b715c2..2c5359fe8 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -85,6 +85,8 @@ const char* ScriptErrorString(const ScriptError serror) return "Witness requires only-redeemscript scriptSig"; case SCRIPT_ERR_WITNESS_UNEXPECTED: return "Witness provided for non-witness script"; + case SCRIPT_ERR_WITNESS_PUBKEYTYPE: + return "Using non-compressed keys in segwit"; case SCRIPT_ERR_UNKNOWN_ERROR: case SCRIPT_ERR_ERROR_COUNT: default: break; diff --git a/src/script/script_error.h b/src/script/script_error.h index bccfdb99e..430836991 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -62,6 +62,7 @@ typedef enum ScriptError_t SCRIPT_ERR_WITNESS_MALLEATED, SCRIPT_ERR_WITNESS_MALLEATED_P2SH, SCRIPT_ERR_WITNESS_UNEXPECTED, + SCRIPT_ERR_WITNESS_PUBKEYTYPE, SCRIPT_ERR_ERROR_COUNT } ScriptError; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 87f38d9c7..f552ad5bb 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,6 +26,10 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, if (!keystore->GetKey(address, key)) return false; + // Signing with uncompressed keys is disabled in witness scripts + if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed()) + return false; + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); if (!key.Sign(hash, vchSig)) return false; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 836ef734d..68a9991e7 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -99,6 +99,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_WITNESS_MALLEATED, "WITNESS_MALLEATED"}, {SCRIPT_ERR_WITNESS_MALLEATED_P2SH, "WITNESS_MALLEATED_P2SH"}, {SCRIPT_ERR_WITNESS_UNEXPECTED, "WITNESS_UNEXPECTED"}, + {SCRIPT_ERR_WITNESS_PUBKEYTYPE, "WITNESS_PUBKEYTYPE"}, }; const char *FormatScriptError(ScriptError_t err) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 6163d2f63..34d9547f3 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -55,7 +55,8 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) - (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); + (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) + (string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); unsigned int ParseScriptFlags(string strFlags) { @@ -429,7 +430,7 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { mtx.nVersion = 1; CKey key; - key.MakeNewKey(false); + key.MakeNewKey(true); // Need to use compressed keys in segwit or the signing will fail CBasicKeyStore keystore; keystore.AddKeyPubKey(key, key.GetPubKey()); CKeyID hash = key.GetPubKey().GetID(); @@ -625,30 +626,13 @@ BOOST_AUTO_TEST_CASE(test_witness) CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); - // Witness pay-to-uncompressed-pubkey (v1). - CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1); - CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2); - CheckWithFlag(output1, input1, 0, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); - CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + // Signing disabled for witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1, false); + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2, false); - // P2SH witness pay-to-uncompressed-pubkey (v1). - CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1); - CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2); - ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1L)); - CheckWithFlag(output1, input1, 0, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); - CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + // Signing disabled for P2SH witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1, false); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2, false); // Normal 2-of-2 multisig CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false); From b4b85279a906605bd2d98498f5b65f4991ebffa4 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Wed, 24 Aug 2016 14:44:17 +0800 Subject: [PATCH 1088/1223] Make test framework produce lowS signatures Github-Pull: #8499 Rebased-From: 9f0397aff7afa2afa9328daea0a2053122e79d44 --- qa/rpc-tests/test_framework/key.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/key.py b/qa/rpc-tests/test_framework/key.py index ba3038fe0..c63a15c1e 100644 --- a/qa/rpc-tests/test_framework/key.py +++ b/qa/rpc-tests/test_framework/key.py @@ -75,6 +75,9 @@ ssl.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, # this specifies the curve used with ECDSA. NID_secp256k1 = 714 # from openssl/obj_mac.h +SECP256K1_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2 + # Thx to Sam Devlin for the ctypes magic 64-bit fix. def _check_result(val, func, args): if val == 0: @@ -147,7 +150,7 @@ class CECKey(object): r = self.get_raw_ecdh_key(other_pubkey) return kdf(r) - def sign(self, hash): + def sign(self, hash, low_s = True): # FIXME: need unit tests for below cases if not isinstance(hash, bytes): raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) @@ -159,7 +162,25 @@ class CECKey(object): mb_sig = ctypes.create_string_buffer(sig_size0.value) result = ssl.ECDSA_sign(0, hash, len(hash), mb_sig, ctypes.byref(sig_size0), self.k) assert 1 == result - return mb_sig.raw[:sig_size0.value] + assert mb_sig.raw[0] == 0x30 + assert mb_sig.raw[1] == sig_size0.value - 2 + total_size = mb_sig.raw[1] + assert mb_sig.raw[2] == 2 + r_size = mb_sig.raw[3] + assert mb_sig.raw[4 + r_size] == 2 + s_size = mb_sig.raw[5 + r_size] + s_value = int.from_bytes(mb_sig.raw[6+r_size:6+r_size+s_size], byteorder='big') + if (not low_s) or s_value <= SECP256K1_ORDER_HALF: + return mb_sig.raw[:sig_size0.value] + else: + low_s_value = SECP256K1_ORDER - s_value + low_s_bytes = (low_s_value).to_bytes(33, byteorder='big') + while len(low_s_bytes) > 1 and low_s_bytes[0] == 0 and low_s_bytes[1] < 0x80: + low_s_bytes = low_s_bytes[1:] + new_s_size = len(low_s_bytes) + new_total_size_byte = (total_size + new_s_size - s_size).to_bytes(1,byteorder='big') + new_s_size_byte = (new_s_size).to_bytes(1,byteorder='big') + return b'\x30' + new_total_size_byte + mb_sig.raw[2:5+r_size] + new_s_size_byte + low_s_bytes def verify(self, hash, sig): """Verify a DER signature""" From 908fced29600514d5fff544e429fa40ebbc58733 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 6 Oct 2016 13:15:33 -0400 Subject: [PATCH 1089/1223] [qa] Add tests for uncompressed pubkeys in segwit Github-Pull: #8499 Rebased-From: b811124202152424109b8e95ebe7ac25ff2e83c0 --- qa/rpc-tests/p2p-segwit.py | 125 ++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 8 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 90f43b417..864579dc4 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -166,6 +166,17 @@ class UTXO(object): self.n = n self.nValue = nValue +# Helper for getting the script associated with a P2PKH +def GetP2PKHScript(pubkeyhash): + return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) + +# Add signature for a P2PK witness program. +def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): + tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) + signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') + txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] + txTo.rehash() + class SegWitTest(BitcoinTestFramework): def setup_chain(self): @@ -1320,13 +1331,6 @@ class SegWitTest(BitcoinTestFramework): sync_blocks(self.nodes) self.utxo.pop(0) - # Add signature for a P2PK witness program. - def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): - tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) - signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') - txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] - txTo.rehash() - # Test each hashtype prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue) for sigflag in [ 0, SIGHASH_ANYONECANPAY ]: @@ -1440,7 +1444,7 @@ class SegWitTest(BitcoinTestFramework): tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) - script = CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) + script = GetP2PKHScript(pubkeyhash) sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL @@ -1703,6 +1707,110 @@ class SegWitTest(BitcoinTestFramework): assert(block_version & (1 << VB_WITNESS_BIT) != 0) self.nodes[0].setmocktime(0) # undo mocktime + # Uncompressed pubkeys are no longer supported in default relay policy, + # but (for now) are still valid in blocks. + def test_uncompressed_pubkey(self): + print("\tTesting uncompressed pubkeys") + # Segwit transactions using uncompressed pubkeys are not accepted + # under default policy, but should still pass consensus. + key = CECKey() + key.set_secretbytes(b"9") + key.set_compressed(False) + pubkey = CPubKey(key.get_pubkey()) + assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey + + assert(len(self.utxo) > 0) + utxo = self.utxo.pop(0) + + # Test 1: P2WPKH + # First create a P2WPKH output that uses an uncompressed pubkey + pubkeyhash = hash160(pubkey) + scriptPKH = CScript([OP_0, pubkeyhash]) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b"")) + tx.vout.append(CTxOut(utxo.nValue-1000, scriptPKH)) + tx.rehash() + + # Confirm it in a block. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + # Now try to spend it. Send it to a P2WSH output, which we'll + # use in the next test. + witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) + witness_hash = sha256(witness_program) + scriptWSH = CScript([OP_0, witness_hash]) + + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptWSH)) + script = GetP2PKHScript(pubkeyhash) + sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) + signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + tx2.wit.vtxinwit.append(CTxInWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [ signature, pubkey ] + tx2.rehash() + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + # But passes consensus. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx2]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 2: P2WSH + # Try to spend the P2WSH output created in last test. + # Send it to a P2SH(P2WSH) output, which we'll use in the next test. + p2sh_witness_hash = hash160(scriptWSH) + scriptP2SH = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) + scriptSig = CScript([scriptWSH]) + + tx3 = CTransaction() + tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) + tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptP2SH)) + tx3.wit.vtxinwit.append(CTxInWitness()) + sign_P2PK_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + # But passes consensus. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx3]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 3: P2SH(P2WSH) + # Try to spend the P2SH output created in the last test. + # Send it to a P2PKH output, which we'll use in the next test. + scriptPubKey = GetP2PKHScript(pubkeyhash) + tx4 = CTransaction() + tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), scriptSig)) + tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, scriptPubKey)) + tx4.wit.vtxinwit.append(CTxInWitness()) + sign_P2PK_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx4]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 4: Uncompressed pubkeys should still be valid in non-segwit + # transactions. + tx5 = CTransaction() + tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b"")) + tx5.vout.append(CTxOut(tx4.vout[0].nValue-1000, CScript([OP_TRUE]))) + (sig_hash, err) = SignatureHash(scriptPubKey, tx5, 0, SIGHASH_ALL) + signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + tx5.vin[0].scriptSig = CScript([signature, pubkey]) + tx5.rehash() + # Should pass policy and consensus. + self.test_node.test_transaction_acceptance(tx5, True, True) + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx5]) + self.test_node.test_witness_block(block, accepted=True) + self.utxo.append(UTXO(tx5.sha256, 0, tx5.vout[0].nValue)) + def test_non_standard_witness(self): print("\tTesting detection of non-standard P2WSH witness") pad = chr(1).encode('latin-1') @@ -1884,6 +1992,7 @@ class SegWitTest(BitcoinTestFramework): self.test_standardness_v0(segwit_activated=True) self.test_segwit_versions() self.test_premature_coinbase_witness_spend() + self.test_uncompressed_pubkey() self.test_signature_version_1() self.test_non_standard_witness() sync_blocks(self.nodes) From 4ec21e8a64f53f0fb4cef5ff26b6b3551dba70e6 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 17 Oct 2016 00:32:36 +0800 Subject: [PATCH 1090/1223] Fix ismine and addwitnessaddress: no uncompressed keys in segwit Github-Pull: #8499 Rebased-From: 248f3a76a825a332e5495c5947ad283a9e5e938f --- src/script/ismine.cpp | 64 ++++++++++++++++++++++++++++++++++------ src/script/ismine.h | 11 +++++-- src/wallet/rpcwallet.cpp | 17 +++++++---- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 0bf180341..7467d23b2 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -29,13 +29,25 @@ unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) return nResult; } -isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion) { - CScript script = GetScriptForDestination(dest); - return IsMine(keystore, script); + bool isInvalid = false; + return IsMine(keystore, scriptPubKey, isInvalid, sigversion); } -isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion sigversion) +{ + bool isInvalid = false; + return IsMine(keystore, dest, isInvalid, sigversion); +} + +isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest, bool& isInvalid, SigVersion sigversion) +{ + CScript script = GetScriptForDestination(dest); + return IsMine(keystore, script, isInvalid, sigversion); +} + +isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion) { vector vSolutions; txnouttype whichType; @@ -53,12 +65,35 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); + if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) { + isInvalid = true; + return ISMINE_NO; + } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; - case TX_PUBKEYHASH: case TX_WITNESS_V0_KEYHASH: + { + if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { + // We do not support bare witness outputs unless the P2SH version of it would be + // acceptable as well. This protects against matching before segwit activates. + // This also applies to the P2WSH case. + break; + } + isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) + return ret; + break; + } + case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); + if (sigversion != SIGVERSION_BASE) { + CPubKey pubkey; + if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) { + isInvalid = true; + return ISMINE_NO; + } + } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; @@ -67,21 +102,24 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { - isminetype ret = IsMine(keystore, subscript); - if (ret == ISMINE_SPENDABLE) + isminetype ret = IsMine(keystore, subscript, isInvalid); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_WITNESS_V0_SCRIPTHASH: { + if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { + break; + } uint160 hash; CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin()); CScriptID scriptID = CScriptID(hash); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { - isminetype ret = IsMine(keystore, subscript); - if (ret == ISMINE_SPENDABLE) + isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; @@ -95,6 +133,14 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + if (sigversion != SIGVERSION_BASE) { + for (size_t i = 0; i < keys.size(); i++) { + if (keys[i].size() != 33) { + isInvalid = true; + return ISMINE_NO; + } + } + } if (HaveKeys(keys, keystore) == keys.size()) return ISMINE_SPENDABLE; break; diff --git a/src/script/ismine.h b/src/script/ismine.h index 4b7db8802..ec7a620e3 100644 --- a/src/script/ismine.h +++ b/src/script/ismine.h @@ -28,7 +28,14 @@ enum isminetype /** used for bitflags of isminetype */ typedef uint8_t isminefilter; -isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); +/* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion + * and return a ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as + * different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed + * keys in SIGVERSION_WITNESS_V0 script, but could also be used in similar cases in the future + */ +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, bool& isInvalid, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion = SIGVERSION_BASE); #endif // BITCOIN_SCRIPT_ISMINE_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 901e6a5d1..2ad379e46 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1020,9 +1020,12 @@ public: bool operator()(const CKeyID &keyID) { CPubKey pubkey; - if (pwalletMain && pwalletMain->GetPubKey(keyID, pubkey)) { - CScript basescript; - basescript << ToByteVector(pubkey) << OP_CHECKSIG; + if (pwalletMain) { + CScript basescript = GetScriptForDestination(keyID); + isminetype typ; + typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(basescript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1040,6 +1043,10 @@ public: result = scriptID; return true; } + isminetype typ; + typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(subscript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1085,7 +1092,7 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) CTxDestination dest = address.Get(); bool ret = boost::apply_visitor(w, dest); if (!ret) { - throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet"); + throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); } pwalletMain->SetAddressBook(w.result, "", "receive"); From fef7b468415e77e1876225988a177eed70418eb1 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 15 Oct 2016 02:29:39 +0800 Subject: [PATCH 1091/1223] test segwit uncompressed key fixes Github-Pull: #8499 Rebased-From: 9260085377e89e666d0cb95b462261d7e3a9c82f --- qa/rpc-tests/segwit.py | 362 +++++++++++++++++++++++- qa/rpc-tests/test_framework/address.py | 74 +++++ src/test/data/script_tests.json | 368 ++++++++++++++++++++++++- src/test/script_tests.cpp | 93 +++++++ 4 files changed, 893 insertions(+), 4 deletions(-) create mode 100644 qa/rpc-tests/test_framework/address.py diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 097e119f3..493ad2e67 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -9,9 +9,10 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import sha256, ripemd160 -import os -import shutil +from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut +from test_framework.address import script_to_p2sh, key_to_p2pkh +from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG +from io import BytesIO NODE_0 = 0 NODE_1 = 1 @@ -243,5 +244,360 @@ class SegWitTest(BitcoinTestFramework): # This is an acceptable outcome pass + print("Verify behaviour of importaddress, addwitnessaddress and listunspent") + + # Some public keys to be used later + pubkeys = [ + "0363D44AABD0F1699138239DF2F042C3282C0671CC7A76826A55C8203D90E39242", # cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb + "02D3E626B3E616FC8662B489C123349FECBFC611E778E5BE739B257EAE4721E5BF", # cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97 + "04A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538A62F5BD8EC85C2477F39650BD391EA6250207065B2A81DA8B009FC891E898F0E", # 91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV + "02A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538", # cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd + "036722F784214129FEB9E8129D626324F3F6716555B603FFE8300BBCB882151228", # cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66 + "0266A8396EE936BF6D99D17920DB21C6C7B1AB14C639D5CD72B300297E416FD2EC", # cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K + "0450A38BD7F0AC212FEBA77354A9B036A32E0F7C81FC4E0C5ADCA7C549C4505D2522458C2D9AE3CEFD684E039194B72C8A10F9CB9D4764AB26FCC2718D421D3B84", # 92h2XPssjBpsJN5CqSP7v9a7cf2kgDunBC6PDFwJHMACM1rrVBJ + ] + + # Import a compressed key and an uncompressed key, generate some multisig addresses + self.nodes[0].importprivkey("92e6XLo5jVAVwrQKPNTs93oQco8f8sDNBcpv73Dsrs397fQtFQn") + uncompressed_spendable_address = ["mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu"] + self.nodes[0].importprivkey("cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR") + compressed_spendable_address = ["mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe"] + assert ((self.nodes[0].validateaddress(uncompressed_spendable_address[0])['iscompressed'] == False)) + assert ((self.nodes[0].validateaddress(compressed_spendable_address[0])['iscompressed'] == True)) + + self.nodes[0].importpubkey(pubkeys[0]) + compressed_solvable_address = [key_to_p2pkh(pubkeys[0])] + self.nodes[0].importpubkey(pubkeys[1]) + compressed_solvable_address.append(key_to_p2pkh(pubkeys[1])) + self.nodes[0].importpubkey(pubkeys[2]) + uncompressed_solvable_address = [key_to_p2pkh(pubkeys[2])] + + spendable_anytime = [] # These outputs should be seen anytime after importprivkey and addmultisigaddress + spendable_after_importaddress = [] # These outputs should be seen after importaddress + solvable_after_importaddress = [] # These outputs should be seen after importaddress but not spendable + unsolvable_after_importaddress = [] # These outputs should be unsolvable after importaddress + solvable_anytime = [] # These outputs should be solvable after importpubkey + unseen_anytime = [] # These outputs should never be seen + + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], uncompressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], compressed_solvable_address[1]])) + unknown_address = ["mtKKyoHabkk6e4ppT7NaM7THqPUt7AzPrT", "2NDP3jLWAFT8NDAiUa9qiE6oBt2awmMq7Dx"] + + # Test multisig_without_privkey + # We have 2 public keys without private keys, use addmultisigaddress to add to wallet. + # Money sent to P2SH of multisig of this should only be seen after importaddress with the BASE58 P2SH address. + + multisig_without_privkey_address = self.nodes[0].addmultisigaddress(2, [pubkeys[3], pubkeys[4]]) + script = CScript([OP_2, hex_str_to_bytes(pubkeys[3]), hex_str_to_bytes(pubkeys[4]), OP_2, OP_CHECKMULTISIG]) + solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL])) + + for i in compressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # bare and p2sh multisig with compressed keys should always be spendable + spendable_anytime.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after direct importaddress + spendable_after_importaddress.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with compressed keys should always be spendable + spendable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are spendable after direct importaddress + spendable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in uncompressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # bare and p2sh multisig with uncompressed keys should always be spendable + spendable_anytime.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with uncompressed keys should always be spendable + spendable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK and P2SH_P2PKH are spendable after direct importaddress + spendable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) + # witness with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in compressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + # Multisig without private is not seen after addmultisigaddress, but seen after importaddress + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + solvable_after_importaddress.extend([bare, p2sh, p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with compressed keys should always be seen + solvable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are seen after direct importaddress + solvable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress + solvable_after_importaddress.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with uncompressed keys should always be seen + solvable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH with uncompressed keys are seen after direct importaddress + solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) + # witness with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + op1 = CScript([OP_1]) + op0 = CScript([OP_0]) + # 2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe is the P2SH(P2PKH) version of mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V + unsolvable_address = ["mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V", "2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe", script_to_p2sh(op1), script_to_p2sh(op0)] + unsolvable_address_key = hex_str_to_bytes("02341AEC7587A51CDE5279E0630A531AEA2615A9F80B17E8D9376327BAEAA59E3D") + unsolvablep2pkh = CScript([OP_DUP, OP_HASH160, hash160(unsolvable_address_key), OP_EQUALVERIFY, OP_CHECKSIG]) + unsolvablep2wshp2pkh = CScript([OP_0, sha256(unsolvablep2pkh)]) + p2shop0 = CScript([OP_HASH160, hash160(op0), OP_EQUAL]) + p2wshop1 = CScript([OP_0, sha256(op1)]) + unsolvable_after_importaddress.append(unsolvablep2pkh) + unsolvable_after_importaddress.append(unsolvablep2wshp2pkh) + unsolvable_after_importaddress.append(op1) # OP_1 will be imported as script + unsolvable_after_importaddress.append(p2wshop1) + unseen_anytime.append(op0) # OP_0 will be imported as P2SH address with no script provided + unsolvable_after_importaddress.append(p2shop0) + + spendable_txid = [] + solvable_txid = [] + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime, 1)) + self.mine_and_test_listunspent(spendable_after_importaddress + solvable_after_importaddress + unseen_anytime + unsolvable_after_importaddress, 0) + + importlist = [] + for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + bare = hex_str_to_bytes(v['hex']) + importlist.append(bytes_to_hex_str(bare)) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(bare)]))) + else: + pubkey = hex_str_to_bytes(v['pubkey']) + p2pk = CScript([pubkey, OP_CHECKSIG]) + p2pkh = CScript([OP_DUP, OP_HASH160, hash160(pubkey), OP_EQUALVERIFY, OP_CHECKSIG]) + importlist.append(bytes_to_hex_str(p2pk)) + importlist.append(bytes_to_hex_str(p2pkh)) + importlist.append(bytes_to_hex_str(CScript([OP_0, hash160(pubkey)]))) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(p2pk)]))) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(p2pkh)]))) + + importlist.append(bytes_to_hex_str(unsolvablep2pkh)) + importlist.append(bytes_to_hex_str(unsolvablep2wshp2pkh)) + importlist.append(bytes_to_hex_str(op1)) + importlist.append(bytes_to_hex_str(p2wshop1)) + + for i in importlist: + try: + self.nodes[0].importaddress(i,"",False,True) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "The wallet already contains the private key for this address or script") + + self.nodes[0].importaddress(script_to_p2sh(op0)) # import OP_0 as address only + self.nodes[0].importaddress(multisig_without_privkey_address) # Test multisig_without_privkey + + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime + spendable_after_importaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime + solvable_after_importaddress, 1)) + self.mine_and_test_listunspent(unsolvable_after_importaddress, 1) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # addwitnessaddress should refuse to return a witness address if an uncompressed key is used or the address is + # not in the wallet + # note that no witness address should be returned by unsolvable addresses + # the multisig_without_privkey_address will fail because its keys were not added with importpubkey + for i in uncompressed_spendable_address + uncompressed_solvable_address + unknown_address + unsolvable_address + [multisig_without_privkey_address]: + try: + self.nodes[0].addwitnessaddress(i) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed") + else: + assert(False) + + for i in compressed_spendable_address + compressed_solvable_address: + witaddress = self.nodes[0].addwitnessaddress(i) + # addwitnessaddress should return the same address if it is a known P2SH-witness address + assert_equal(witaddress, self.nodes[0].addwitnessaddress(witaddress)) + + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime + spendable_after_importaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime + solvable_after_importaddress, 1)) + self.mine_and_test_listunspent(unsolvable_after_importaddress, 1) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # Repeat some tests. This time we don't add witness scripts with importaddress + # Import a compressed key and an uncompressed key, generate some multisig addresses + self.nodes[0].importprivkey("927pw6RW8ZekycnXqBQ2JS5nPyo1yRfGNN8oq74HeddWSpafDJH") + uncompressed_spendable_address = ["mguN2vNSCEUh6rJaXoAVwY3YZwZvEmf5xi"] + self.nodes[0].importprivkey("cMcrXaaUC48ZKpcyydfFo8PxHAjpsYLhdsp6nmtB3E2ER9UUHWnw") + compressed_spendable_address = ["n1UNmpmbVUJ9ytXYXiurmGPQ3TRrXqPWKL"] + + self.nodes[0].importpubkey(pubkeys[5]) + compressed_solvable_address = [key_to_p2pkh(pubkeys[5])] + self.nodes[0].importpubkey(pubkeys[6]) + uncompressed_solvable_address = [key_to_p2pkh(pubkeys[6])] + + spendable_after_addwitnessaddress = [] # These outputs should be seen after importaddress + solvable_after_addwitnessaddress=[] # These outputs should be seen after importaddress but not spendable + unseen_anytime = [] # These outputs should never be seen + + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], uncompressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) + + premature_witaddress = [] + + for i in compressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after addwitnessaddress + spendable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh]) + premature_witaddress.append(script_to_p2sh(p2wsh)) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2WPKH, P2SH_P2WPKH are spendable after addwitnessaddress + spendable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) + premature_witaddress.append(script_to_p2sh(p2wpkh)) + + for i in uncompressed_spendable_address + uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2WPKH, P2SH_P2WPKH with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh]) + + for i in compressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + # P2WSH multisig without private key are seen after addwitnessaddress + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + solvable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh]) + premature_witaddress.append(script_to_p2sh(p2wsh)) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after addwitnessaddress + solvable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) + premature_witaddress.append(script_to_p2sh(p2wpkh)) + + self.mine_and_test_listunspent(spendable_after_addwitnessaddress + solvable_after_addwitnessaddress + unseen_anytime, 0) + + # addwitnessaddress should refuse to return a witness address if an uncompressed key is used + # note that a multisig address returned by addmultisigaddress is not solvable until it is added with importaddress + # premature_witaddress are not accepted until the script is added with addwitnessaddress first + for i in uncompressed_spendable_address + uncompressed_solvable_address + premature_witaddress + [compressed_solvable_address[1]]: + try: + self.nodes[0].addwitnessaddress(i) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed") + else: + assert(False) + + # after importaddress it should pass addwitnessaddress + v = self.nodes[0].validateaddress(compressed_solvable_address[1]) + self.nodes[0].importaddress(v['hex'],"",False,True) + for i in compressed_spendable_address + compressed_solvable_address + premature_witaddress: + witaddress = self.nodes[0].addwitnessaddress(i) + assert_equal(witaddress, self.nodes[0].addwitnessaddress(witaddress)) + + spendable_txid.append(self.mine_and_test_listunspent(spendable_after_addwitnessaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_after_addwitnessaddress, 1)) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # Check that spendable outputs are really spendable + self.create_and_mine_tx_from_txids(spendable_txid) + + # import all the private keys so solvable addresses become spendable + self.nodes[0].importprivkey("cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb") + self.nodes[0].importprivkey("cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97") + self.nodes[0].importprivkey("91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV") + self.nodes[0].importprivkey("cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd") + self.nodes[0].importprivkey("cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66") + self.nodes[0].importprivkey("cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K") + self.create_and_mine_tx_from_txids(solvable_txid) + + def mine_and_test_listunspent(self, script_list, ismine): + utxo = find_unspent(self.nodes[0], 50) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(int('0x'+utxo['txid'],0), utxo['vout']))) + for i in script_list: + tx.vout.append(CTxOut(10000000, i)) + tx.rehash() + signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] + txid = self.nodes[0].sendrawtransaction(signresults, True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + watchcount = 0 + spendcount = 0 + for i in self.nodes[0].listunspent(): + if (i['txid'] == txid): + watchcount += 1 + if (i['spendable'] == True): + spendcount += 1 + if (ismine == 2): + assert_equal(spendcount, len(script_list)) + elif (ismine == 1): + assert_equal(watchcount, len(script_list)) + assert_equal(spendcount, 0) + else: + assert_equal(watchcount, 0) + return txid + + def p2sh_address_to_script(self,v): + bare = CScript(hex_str_to_bytes(v['hex'])) + p2sh = CScript(hex_str_to_bytes(v['scriptPubKey'])) + p2wsh = CScript([OP_0, sha256(bare)]) + p2sh_p2wsh = CScript([OP_HASH160, hash160(p2wsh), OP_EQUAL]) + return([bare, p2sh, p2wsh, p2sh_p2wsh]) + + def p2pkh_address_to_script(self,v): + pubkey = hex_str_to_bytes(v['pubkey']) + p2wpkh = CScript([OP_0, hash160(pubkey)]) + p2sh_p2wpkh = CScript([OP_HASH160, hash160(p2wpkh), OP_EQUAL]) + p2pk = CScript([pubkey, OP_CHECKSIG]) + p2pkh = CScript(hex_str_to_bytes(v['scriptPubKey'])) + p2sh_p2pk = CScript([OP_HASH160, hash160(p2pk), OP_EQUAL]) + p2sh_p2pkh = CScript([OP_HASH160, hash160(p2pkh), OP_EQUAL]) + p2wsh_p2pk = CScript([OP_0, sha256(p2pk)]) + p2wsh_p2pkh = CScript([OP_0, sha256(p2pkh)]) + p2sh_p2wsh_p2pk = CScript([OP_HASH160, hash160(p2wsh_p2pk), OP_EQUAL]) + p2sh_p2wsh_p2pkh = CScript([OP_HASH160, hash160(p2wsh_p2pkh), OP_EQUAL]) + return [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] + + def create_and_mine_tx_from_txids(self, txids, success = True): + tx = CTransaction() + for i in txids: + txtmp = CTransaction() + txraw = self.nodes[0].getrawtransaction(i) + f = BytesIO(hex_str_to_bytes(txraw)) + txtmp.deserialize(f) + for j in range(len(txtmp.vout)): + tx.vin.append(CTxIn(COutPoint(int('0x'+i,0), j))) + tx.vout.append(CTxOut(0, CScript())) + tx.rehash() + signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] + self.nodes[0].sendrawtransaction(signresults, True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + if __name__ == '__main__': SegWitTest().main() diff --git a/qa/rpc-tests/test_framework/address.py b/qa/rpc-tests/test_framework/address.py new file mode 100644 index 000000000..50b999be6 --- /dev/null +++ b/qa/rpc-tests/test_framework/address.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# address.py +# +# This file encodes and decodes BASE58 P2PKH and P2SH addresses +# + +from .script import hash256, hash160, sha256, CScript, OP_0 +from .util import bytes_to_hex_str, hex_str_to_bytes + +chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + +def byte_to_base58(b, version): + result = '' + str = bytes_to_hex_str(b) + str = bytes_to_hex_str(chr(version).encode('latin-1')) + str + checksum = bytes_to_hex_str(hash256(hex_str_to_bytes(str))) + str += checksum[:8] + value = int('0x'+str,0) + while value > 0: + result = chars[value % 58] + result + value //= 58 + while (str[:2] == '00'): + result = chars[0] + result + str = str[2:] + return result + +# TODO: def base58_decode + +def keyhash_to_p2pkh(hash, main = False): + assert (len(hash) == 20) + version = 0 if main else 111 + return byte_to_base58(hash, version) + +def scripthash_to_p2sh(hash, main = False): + assert (len(hash) == 20) + version = 5 if main else 196 + return byte_to_base58(hash, version) + +def key_to_p2pkh(key, main = False): + key = check_key(key) + return keyhash_to_p2pkh(hash160(key), main) + +def script_to_p2sh(script, main = False): + script = check_script(script) + return scripthash_to_p2sh(hash160(script), main) + +def key_to_p2sh_p2wpkh(key, main = False): + key = check_key(key) + p2shscript = CScript([OP_0, hash160(key)]) + return script_to_p2sh(p2shscript, main) + +def script_to_p2sh_p2wsh(script, main = False): + script = check_script(script) + p2shscript = CScript([OP_0, sha256(script)]) + return script_to_p2sh(p2shscript, main) + +def check_key(key): + if (type(key) is str): + key = hex_str_to_bytes(key) # Assuming this is hex string + if (type(key) is bytes and (len(key) == 33 or len(key) == 65)): + return key + assert(False) + +def check_script(script): + if (type(script) is str): + script = hex_str_to_bytes(script) # Assuming this is hex string + if (type(script) is bytes or type(script) is CScript): + return script + assert(False) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 06103ea5b..5c054ed3e 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1855,6 +1855,8 @@ "OK", "P2SH with CLEANSTACK" ], + +["Testing with uncompressed keys in witness v0 without WITNESS_PUBKEYTYPE"], [ [ "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", @@ -2139,7 +2141,371 @@ "P2PK with witness" ], -["CHECKSEQUENCEVERIFY tests"], +["Testing with compressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402204256146fcf8e73b0fd817ffa2a4e408ff0418ff987dd08a4f485b62546f6c43c02203f3c8c3e2febc051e1222867f5f9d0eaf039d6792911c10940aa3cc74123378e01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "", + "0 0x20 0x1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WSH with compressed key" +], +[ + [ + "304402204edf27486f11432466b744df533e1acac727e0c83e5f912eb289a3df5bf8035f022075809fdd876ede40ad21667eba8b7e96394938f9c9c50f11b6a1280cce2cea8601", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "", + "0 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WPKH with compressed key" +], +[ + [ + "304402203a549090cc46bce1e5e95c4922ea2c12747988e0207b04c42f81cdbe87bb1539022050f57a245b875fd5119c419aaf050bcdf41384f0765f04b809e5bced1fe7093d01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "0x22 0x00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "HASH160 0x14 0xe4300531190587e3880d4c3004f5355d88ff928d EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WSH) with compressed key" +], +[ + [ + "304402201bc0d53046827f4a35a3166e33e3b3366c4085540dc383b95d21ed2ab11e368a0220333e78c6231214f5f8e59621e15d7eeab0d4e4d0796437e00bfbd2680c5f9c1701", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "0x16 0x0014751e76e8199196d454941c45d1b3a323f1433bd6", + "HASH160 0x14 0xbcfeb728b584253d5f3f70bcb780e9ef218a68f4 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WPKH) with compressed key" +], + +["Testing with uncompressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WSH" +], +[ + [ + "304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WPKH" +], +[ + [ + "3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WSH)" +], +[ + [ + "304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WPKH)" +], + +["Testing P2WSH multisig with compressed keys"], +[ + [ + "", + "304402207eb8a59b5c65fc3f6aeef77066556ed5c541948a53a3ba7f7c375b8eed76ee7502201e036a7a9a98ff919ff94dc905d67a1ec006f79ef7cff0708485c8bb79dce38e01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022033706aed33b8155d5486df3b9bca8cdd3bd4bdb5436dce46d72cdaba51d22b4002203626e94fe53a178af46624f17315c6931f20a30b103f5e044e1eda0c3fe185c601", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "304402204048b7371ab1c544362efb89af0c80154747d665aa4fcfb2edfd2d161e57b42e02207e043748e96637080ffc3acbd4dcc6fee1e58d30f6d1269535f32188e5ddae7301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022073902ef0b8a554c36c44cc03c1b64df96ce2914ebcf946f5bb36078fd5245cdf02205b148f1ba127065fb8c83a5a9576f2dcd111739788ed4bb3ee08b2bd3860c91c01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], + +["Testing P2WSH multisig with compressed and uncompressed keys (first key being the key closer to the top of stack)"], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], + +["CHECKSEQUENCEVERIFY tests"], ["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 68a9991e7..532921a72 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -826,6 +826,99 @@ BOOST_AUTO_TEST_CASE(script_build) "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH ).PushSig(keys.key0).Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_UNEXPECTED)); + // Compressed keys should pass SCRIPT_VERIFY_WITNESS_PUBKEYTYPE + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "Basic P2WSH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), + "Basic P2WPKH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "Basic P2SH(P2WSH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), + "Basic P2SH(P2WPKH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem()); + + // Testing uncompressed key in witness with SCRIPT_VERIFY_WITNESS_PUBKEYTYPE + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + + // P2WSH 1-of-2 multisig with compressed keys + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); + + // P2WSH 1-of-2 multisig with first key uncompressed + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + // P2WSH 1-of-2 multisig with second key uncompressed + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + std::set tests_set; { From 9777fe12722ddab7b1b17df11077d448c7a25006 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Mon, 17 Oct 2016 03:18:36 +0800 Subject: [PATCH 1092/1223] remove redundant tests in p2p-segwit.py Github-Pull: #8499 Rebased-From: 67d6ee1e3679504f46473fe0818970565ff3b137 --- qa/rpc-tests/p2p-segwit.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 864579dc4..7218ae83d 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -1869,16 +1869,11 @@ class SegWitTest(BitcoinTestFramework): # Stack element size over 80 bytes is non-standard p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - # It can't be used to blind a node to the transaction - self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) - self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, False, b'bad-witness-nonstandard') - self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, False, b'bad-witness-nonstandard') # Non-standard nodes should accept self.test_node.test_transaction_acceptance(p2wsh_txs[1], True, True) # Standard nodes should accept if element size is not over 80 bytes p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] - self.std_node.announce_tx_and_wait_for_getdata(p2wsh_txs[1]) self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, True) # witnessScript size at 3600 bytes is standard @@ -1897,13 +1892,9 @@ class SegWitTest(BitcoinTestFramework): self.std_node.test_transaction_acceptance(p2sh_txs[0], True, False, b'bad-witness-nonstandard') self.test_node.test_transaction_acceptance(p2sh_txs[0], True, True) p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) - self.std_node.test_transaction_acceptance(p2sh_txs[1], True, False, b'bad-witness-nonstandard') - self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) self.std_node.test_transaction_acceptance(p2sh_txs[1], True, False, b'bad-witness-nonstandard') self.test_node.test_transaction_acceptance(p2sh_txs[1], True, True) p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] - self.std_node.announce_tx_and_wait_for_getdata(p2sh_txs[1]) self.std_node.test_transaction_acceptance(p2sh_txs[1], True, True) p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] self.test_node.test_transaction_acceptance(p2sh_txs[2], True, True) From cb8887e87df315dbc6c560149b3a97b704a676aa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 17 Oct 2016 14:15:01 +0000 Subject: [PATCH 1093/1223] qt: periodic translation update --- src/qt/locale/bitcoin_af.ts | 39 +- src/qt/locale/bitcoin_af_ZA.ts | 41 +- src/qt/locale/bitcoin_ar.ts | 51 +- src/qt/locale/bitcoin_be_BY.ts | 45 +- src/qt/locale/bitcoin_bg.ts | 51 +- src/qt/locale/bitcoin_bg_BG.ts | 37 +- src/qt/locale/bitcoin_ca.ts | 55 +- src/qt/locale/bitcoin_ca@valencia.ts | 55 +- src/qt/locale/bitcoin_ca_ES.ts | 55 +- src/qt/locale/bitcoin_cs.ts | 59 +- src/qt/locale/bitcoin_cs_CZ.ts | 41 +- src/qt/locale/bitcoin_cy.ts | 39 +- src/qt/locale/bitcoin_da.ts | 1235 +++++++++++++++++++++++++- src/qt/locale/bitcoin_de.ts | 395 +++++++- src/qt/locale/bitcoin_el.ts | 39 +- src/qt/locale/bitcoin_el_GR.ts | 55 +- src/qt/locale/bitcoin_en_GB.ts | 59 +- src/qt/locale/bitcoin_eo.ts | 55 +- src/qt/locale/bitcoin_es.ts | 59 +- src/qt/locale/bitcoin_es_AR.ts | 37 +- src/qt/locale/bitcoin_es_CL.ts | 47 +- src/qt/locale/bitcoin_es_CO.ts | 37 +- src/qt/locale/bitcoin_es_DO.ts | 55 +- src/qt/locale/bitcoin_es_ES.ts | 39 +- src/qt/locale/bitcoin_es_MX.ts | 43 +- src/qt/locale/bitcoin_es_UY.ts | 41 +- src/qt/locale/bitcoin_es_VE.ts | 43 +- src/qt/locale/bitcoin_et.ts | 47 +- src/qt/locale/bitcoin_eu_ES.ts | 41 +- src/qt/locale/bitcoin_fa.ts | 55 +- src/qt/locale/bitcoin_fa_IR.ts | 45 +- src/qt/locale/bitcoin_fi.ts | 55 +- src/qt/locale/bitcoin_fr.ts | 195 +++- src/qt/locale/bitcoin_fr_CA.ts | 39 +- src/qt/locale/bitcoin_fr_FR.ts | 51 +- src/qt/locale/bitcoin_gl.ts | 53 +- src/qt/locale/bitcoin_he.ts | 155 +++- src/qt/locale/bitcoin_hi_IN.ts | 41 +- src/qt/locale/bitcoin_hr.ts | 77 +- src/qt/locale/bitcoin_hu.ts | 53 +- src/qt/locale/bitcoin_id_ID.ts | 55 +- src/qt/locale/bitcoin_it.ts | 63 +- src/qt/locale/bitcoin_it_IT.ts | 37 +- src/qt/locale/bitcoin_ja.ts | 1205 ++++++++++++++++++++++++- src/qt/locale/bitcoin_ka.ts | 55 +- src/qt/locale/bitcoin_kk_KZ.ts | 41 +- src/qt/locale/bitcoin_ko_KR.ts | 59 +- src/qt/locale/bitcoin_ku_IQ.ts | 39 +- src/qt/locale/bitcoin_ky.ts | 39 +- src/qt/locale/bitcoin_la.ts | 45 +- src/qt/locale/bitcoin_lt.ts | 45 +- src/qt/locale/bitcoin_lv_LV.ts | 55 +- src/qt/locale/bitcoin_mk_MK.ts | 43 +- src/qt/locale/bitcoin_mn.ts | 45 +- src/qt/locale/bitcoin_ms_MY.ts | 37 +- src/qt/locale/bitcoin_nb.ts | 55 +- src/qt/locale/bitcoin_ne.ts | 37 +- src/qt/locale/bitcoin_nl.ts | 1201 ++++++++++++++++++++++++- src/qt/locale/bitcoin_pam.ts | 45 +- src/qt/locale/bitcoin_pl.ts | 59 +- src/qt/locale/bitcoin_pt_BR.ts | 69 +- src/qt/locale/bitcoin_pt_PT.ts | 59 +- src/qt/locale/bitcoin_ro.ts | 45 +- src/qt/locale/bitcoin_ro_RO.ts | 55 +- src/qt/locale/bitcoin_ru.ts | 1201 ++++++++++++++++++++++++- src/qt/locale/bitcoin_ru_RU.ts | 37 +- src/qt/locale/bitcoin_sk.ts | 55 +- src/qt/locale/bitcoin_sl_SI.ts | 55 +- src/qt/locale/bitcoin_sq.ts | 41 +- src/qt/locale/bitcoin_sr.ts | 43 +- src/qt/locale/bitcoin_sr@latin.ts | 89 +- src/qt/locale/bitcoin_sv.ts | 91 +- src/qt/locale/bitcoin_ta.ts | 43 +- src/qt/locale/bitcoin_th_TH.ts | 43 +- src/qt/locale/bitcoin_tr.ts | 59 +- src/qt/locale/bitcoin_tr_TR.ts | 37 +- src/qt/locale/bitcoin_uk.ts | 55 +- src/qt/locale/bitcoin_ur_PK.ts | 39 +- src/qt/locale/bitcoin_uz@Cyrl.ts | 51 +- src/qt/locale/bitcoin_vi.ts | 37 +- src/qt/locale/bitcoin_vi_VN.ts | 41 +- src/qt/locale/bitcoin_zh.ts | 33 + src/qt/locale/bitcoin_zh_CN.ts | 59 +- src/qt/locale/bitcoin_zh_HK.ts | 37 +- src/qt/locale/bitcoin_zh_TW.ts | 1207 ++++++++++++++++++++++++- 85 files changed, 9918 insertions(+), 637 deletions(-) diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 8305b7060..0b8a738ea 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -41,7 +41,10 @@ &Delete &Vee uit - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Herhaal nuwe wagwoord - + BanTableModel @@ -357,7 +360,7 @@ Priority Prioriteit - + EditAddressDialog @@ -499,6 +502,9 @@ Onlangse transaksies + + PaymentServer + PeerTableModel @@ -537,6 +543,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -606,6 +615,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -656,6 +668,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -668,12 +683,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index e553fc775..1d4d726c7 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -13,7 +13,10 @@ &Delete &Verwyder - + + + AddressTableModel + AskPassphraseDialog @@ -32,7 +35,7 @@ Repeat new passphrase Herhaal nuwe wagfrase - + BanTableModel @@ -140,7 +143,7 @@ &Address &Adres - + FreespaceChecker @@ -179,6 +182,9 @@ Vorm + + PaymentServer + PeerTableModel @@ -189,6 +195,9 @@ Bedrag + + QRImageWidget + RPCConsole @@ -210,6 +219,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -240,7 +252,7 @@ S&end S&tuur - + SendCoinsEntry @@ -252,6 +264,9 @@ Boodskap: + + SendConfirmationDialog + ShutdownWindow @@ -276,12 +291,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 2e1603bb8..407788989 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -41,7 +41,10 @@ &Delete &أمسح - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase ادخل كلمة المرور الجديدة مرة أخرى - + BanTableModel @@ -411,7 +414,7 @@ Priority أفضلية - + EditAddressDialog @@ -434,7 +437,7 @@ &Address &العنوان - + FreespaceChecker @@ -538,7 +541,7 @@ Select payment request file حدد ملف طلب الدفع - + OptionsDialog @@ -661,6 +664,9 @@ رصيدك الكلي الحالي + + PaymentServer + PeerTableModel @@ -683,6 +689,9 @@ غير معروف + + QRImageWidget + RPCConsole @@ -868,7 +877,7 @@ Remove ازل - + ReceiveRequestDialog @@ -887,7 +896,10 @@ &Save Image... &حفظ الصورة - + + + RecentRequestsTableModel + SendCoinsDialog @@ -978,7 +990,7 @@ S&end &ارسال - + SendCoinsEntry @@ -1030,6 +1042,9 @@ ادفع &الى : + + SendConfirmationDialog + ShutdownWindow @@ -1098,16 +1113,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction يبين هذا الجزء وصفا مفصلا لهده المعاملة - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index 5894148fe..dfbf3873a 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -41,7 +41,10 @@ &Delete Выдаліць - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Паўтарыце новую кодавую фразу - + BanTableModel @@ -415,7 +418,7 @@ Priority Прыярытэт - + EditAddressDialog @@ -430,7 +433,7 @@ &Address Адрас - + FreespaceChecker @@ -513,6 +516,9 @@ Форма + + PaymentServer + PeerTableModel @@ -523,6 +529,9 @@ Колькасць + + QRImageWidget + RPCConsole @@ -552,6 +561,9 @@ Капіяваць адрас + + RecentRequestsTableModel + SendCoinsDialog @@ -641,7 +653,10 @@ Memo: Памятка: - + + + SendConfirmationDialog + ShutdownWindow @@ -674,16 +689,34 @@ Кб/с + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Гэтая панэль паказвае дэтальнае апісанне транзакцыі - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index acb60cf41..b1d772ea1 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -41,7 +41,10 @@ &Delete &Изтриване - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Въведете новата парола повторно - + BanTableModel @@ -463,7 +466,7 @@ Priority Приоритет - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Адрес - + FreespaceChecker @@ -829,6 +832,9 @@ Скорошни транзакции + + PaymentServer + PeerTableModel @@ -879,6 +885,9 @@ %1 милисекунда + + QRImageWidget + RPCConsole @@ -1112,7 +1121,7 @@ Remove Премахване - + ReceiveRequestDialog @@ -1131,7 +1140,10 @@ &Save Image... &Запиши изображение... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1254,7 +1266,7 @@ S&end И&зпрати - + SendCoinsEntry @@ -1305,7 +1317,10 @@ Memo: Бележка: - + + + SendConfirmationDialog + ShutdownWindow @@ -1390,16 +1405,34 @@ Килобайта в секунда + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Описание на транзакцията - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_bg_BG.ts b/src/qt/locale/bitcoin_bg_BG.ts index 4bddb5ff4..977fbf57e 100644 --- a/src/qt/locale/bitcoin_bg_BG.ts +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -41,7 +41,10 @@ &Delete Изтрий - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Повтори парола - + BanTableModel @@ -187,12 +190,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -202,12 +211,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -220,12 +235,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index f066760ff..355cd4418 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetiu la nova contrasenya - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritat - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adreça - + FreespaceChecker @@ -578,7 +581,7 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + OptionsDialog @@ -869,6 +872,9 @@ Balanç total actual en adreces de només lectura + + PaymentServer + PeerTableModel @@ -923,6 +929,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1264,7 +1273,7 @@ Remove Esborra - + ReceiveRequestDialog @@ -1283,7 +1292,10 @@ &Save Image... De&sa la imatge... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1434,7 +1446,7 @@ S&end E&nvia - + SendCoinsEntry @@ -1513,7 +1525,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1607,7 +1622,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1622,13 +1637,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1636,6 +1660,15 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index bf779aad6..213e57ce1 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetiu la nova contrasenya - + BanTableModel @@ -427,7 +430,7 @@ Priority Prioritat - + EditAddressDialog @@ -450,7 +453,7 @@ &Address &Adreça - + FreespaceChecker @@ -546,7 +549,7 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + OptionsDialog @@ -813,6 +816,9 @@ Balanç total actual en adreces de només lectura + + PaymentServer + PeerTableModel @@ -867,6 +873,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1136,7 +1145,7 @@ Remove Esborra - + ReceiveRequestDialog @@ -1155,7 +1164,10 @@ &Save Image... &Guarda la imatge... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1306,7 +1318,7 @@ S&end E&nvia - + SendCoinsEntry @@ -1385,7 +1397,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1479,7 +1494,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1494,13 +1509,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Este panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1508,6 +1532,15 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 9835c8547..976881531 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetiu la nova contrasenya - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritat - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adreça - + FreespaceChecker @@ -578,7 +581,7 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + OptionsDialog @@ -869,6 +872,9 @@ Balanç total actual en adreces de només lectura + + PaymentServer + PeerTableModel @@ -923,6 +929,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1264,7 +1273,7 @@ Remove Esborra - + ReceiveRequestDialog @@ -1283,7 +1292,10 @@ &Save Image... De&sa la imatge... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1434,7 +1446,7 @@ S&end E&nvia - + SendCoinsEntry @@ -1513,7 +1525,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1607,7 +1622,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1622,13 +1637,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1636,6 +1660,15 @@ Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 0b28956ff..449e67dd3 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -41,7 +41,10 @@ &Delete S&maž - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Totéž heslo ještě jednou - + BanTableModel @@ -427,7 +430,7 @@ Priority Priorita - + EditAddressDialog @@ -450,7 +453,7 @@ &Address &Adresa - + FreespaceChecker @@ -570,7 +573,7 @@ Select payment request file Vyber soubor platebního požadavku - + OptionsDialog @@ -861,6 +864,9 @@ Aktuální stav účtu sledovaných adres + + PaymentServer + PeerTableModel @@ -915,6 +921,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1220,7 +1229,7 @@ Remove Smazat - + ReceiveRequestDialog @@ -1239,7 +1248,10 @@ &Save Image... &Ulož obrázek... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1390,7 +1402,7 @@ S&end Pošl&i - + SendCoinsEntry @@ -1469,7 +1481,10 @@ Memo: Poznámka: - + + + SendConfirmationDialog + ShutdownWindow @@ -1563,7 +1578,7 @@ Reset all verify message fields Vymaž všechna pole formuláře pro ověření zrávy - + SplashScreen @@ -1578,13 +1593,22 @@ kB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Toto okno zobrazuje detailní popis transakce - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1592,6 +1616,15 @@ Jednotka pro částky. Klikni pro výběr nějaké jiné. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1690,10 +1723,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Vynutit přeposílání transakcí od vždy vítaných protějšků (tj. těch na bílé listině), i když porušují místní zásady pro přeposílání (výchozí: %d) - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d) diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts index 70aa981f5..e7e38d65a 100644 --- a/src/qt/locale/bitcoin_cs_CZ.ts +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -29,7 +29,10 @@ &Delete &Odstranit - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Zopakujte nové heslo - + BanTableModel @@ -160,7 +163,7 @@ &Address &Adresa - + FreespaceChecker @@ -199,6 +202,9 @@ OverviewPage + + PaymentServer + PeerTableModel @@ -209,6 +215,9 @@ Množství + + QRImageWidget + RPCConsole @@ -230,6 +239,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -252,6 +264,9 @@ Zpráva: + + SendConfirmationDialog + ShutdownWindow @@ -268,16 +283,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Toto podokno zobrazuje detailní popis transakce - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index 38bc45775..9fcd5eeb8 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -29,7 +29,10 @@ &Delete &Dileu - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Ailadroddwch gyfrinymadrodd newydd - + BanTableModel @@ -252,7 +255,7 @@ &Address &Cyfeiriad - + FreespaceChecker @@ -331,12 +334,18 @@ Ffurflen + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -366,6 +375,9 @@ &Cyfeiriad Copi + + RecentRequestsTableModel + SendCoinsDialog @@ -416,6 +428,9 @@ Neges: + + SendConfirmationDialog + ShutdownWindow @@ -444,12 +459,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 8675f8aa6..eee6cf20a 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -41,6 +41,77 @@ &Delete &Slet + + Choose the address to send coins to + Vælg adresse at sende bitcoins til + + + Choose the address to receive coins with + Vælg adresse at modtage bitcoins med + + + C&hoose + &Vælg + + + Sending addresses + Afsendelsesadresser + + + Receiving addresses + Modtagelsesadresser + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Disse er dine Bitcoin-adresser til afsendelse af betalinger. Tjek altid beløb og modtagelsesadresse, inden du sender bitcoins. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dette er dine Bitcoin-adresser til modtagelse af betalinger. Det anbefales at bruge en ny modtagelsesadresse for hver transaktion. + + + &Copy Address + &Kopiér adresse + + + Copy &Label + Kopiér &mærkat + + + &Edit + &Redigér + + + Export Address List + Eksportér adresseliste + + + Comma separated file (*.csv) + Kommasepareret fil (*.csv) + + + Exporting Failed + Eksport mislykkedes + + + There was an error trying to save the address list to %1. Please try again. + Der opstod en fejl under gemning af adresselisten til %1. Prøv venligst igen. + + + + AddressTableModel + + Label + Mærkat + + + Address + Adresse + + + (no label) + (ingen mærkat) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Gentag ny adgangskode + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Indtast det nye kodeord til tegnebogen.<br/>Brug venligst et kodeord på <b>ti eller flere tilfældige tegn</b> eller <b>otte eller flere ord</b>. + + + Encrypt wallet + Kryptér tegnebog + + + This operation needs your wallet passphrase to unlock the wallet. + Denne funktion har brug for din tegnebogs adgangskode for at låse tegnebogen op. + + + Unlock wallet + Lås tegnebog op + + + This operation needs your wallet passphrase to decrypt the wallet. + Denne funktion har brug for din tegnebogs adgangskode for at dekryptere tegnebogen. + + + Decrypt wallet + Dekryptér tegnebog + + + Change passphrase + Skift adgangskode + + + Enter the old passphrase and new passphrase to the wallet. + Indtast den gamle adgangskode og en ny adgangskode til tegnebogen. + + + Confirm wallet encryption + Bekræft tegnebogskryptering + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advarsel: Hvis du krypterer din tegnebog og mister din adgangskode, vil du <b>MISTE ALLE DINE BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Er du sikker på, at du ønsker at kryptere din tegnebog? + + + Wallet encrypted + Tegnebog krypteret + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 vil nu lukke for at færdiggøre krypteringsprocessen. Husk at kryptering af din tegnebog kan ikke beskytte dine bitcoin fuldt ud mod at blive stjålet af eventuel malware, der måtte have inficeret din computer. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + VIGTIGT: Enhver tidligere sikkerhedskopi, som du har lavet af tegnebogsfilen, bør blive erstattet af den nyligt genererede, krypterede tegnebogsfil. Af sikkerhedsmæssige årsager vil tidligere sikkerhedskopier af den ikke-krypterede tegnebogsfil blive ubrugelige i det øjeblik, du starter med at anvende den nye, krypterede tegnebog. + + + Wallet encryption failed + Tegnebogskryptering mislykkedes + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Tegnebogskryptering mislykkedes på grund af en intern fejl. Din tegnebog blev ikke krypteret. + + + The supplied passphrases do not match. + De angivne adgangskoder stemmer ikke overens. + + + Wallet unlock failed + Tegnebogsoplåsning mislykkedes + + + The passphrase entered for the wallet decryption was incorrect. + Den angivne adgangskode for tegnebogsdekrypteringen er forkert. + + + Wallet decryption failed + Tegnebogsdekryptering mislykkedes + + + Wallet passphrase was successfully changed. + Tegnebogens adgangskode blev ændret. + + + Warning: The Caps Lock key is on! + Advarsel: Caps Lock-tasten er aktiveret! + BanTableModel @@ -76,7 +235,7 @@ BitcoinGUI Sign &message... - Underskriv &besked… + Signér &besked… Synchronizing with network... @@ -216,11 +375,11 @@ Sign messages with your Bitcoin addresses to prove you own them - Underskriv beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig + Signér beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig Verify messages to ensure they were signed with specified Bitcoin addresses - Verificér beskeder for at sikre, at de er underskrevet med de angivne Bitcoin-adresser + Verificér beskeder for at sikre, at de er signeret med de angivne Bitcoin-adresser &File @@ -463,6 +622,150 @@ Priority Prioritet + + Copy address + Kopiér adresse + + + Copy label + Kopiér mærkat + + + Copy amount + Kopiér beløb + + + Copy transaction ID + Kopiér transaktions-ID + + + Lock unspent + Fastlås ubrugte + + + Unlock unspent + Lås ubrugte op + + + Copy quantity + Kopiér mængde + + + Copy fee + Kopiér gebyr + + + Copy after fee + Kopiér eftergebyr + + + Copy bytes + Kopiér byte + + + Copy priority + Kopiér prioritet + + + Copy dust + Kopiér støv + + + Copy change + Kopiér byttepenge + + + highest + højest + + + higher + højere + + + high + højt + + + medium-high + mellemhøjt + + + medium + medium + + + low-medium + mellemlavt + + + low + lavt + + + lower + lavere + + + lowest + lavest + + + (%1 locked) + (%1 fastlåst) + + + none + ingen + + + yes + ja + + + no + nej + + + This label turns red if the transaction size is greater than 1000 bytes. + Denne mærkat bliver rød, hvis transaktionsstørrelsen er større end 1000 byte. + + + This means a fee of at least %1 per kB is required. + Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt. + + + Can vary +/- 1 byte per input. + Kan variere ±1 byte pr. input. + + + Transactions with higher priority are more likely to get included into a block. + Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok. + + + This label turns red if the priority is smaller than "medium". + Denne mærkat bliver rød, hvis prioriteten er mindre end "medium". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Denne mærkat bliver rød, hvis en eller flere modtagere modtager et beløb, der er mindre end den aktuelle støvgrænse. + + + Can vary +/- %1 satoshi(s) per input. + Kan variere med ±%1 satoshi per input. + + + (no label) + (ingen mærkat) + + + change from %1 (%2) + byttepenge fra %1 (%2) + + + (change) + (byttepange) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Adresse + + New receiving address + Ny modtagelsesadresse + + + New sending address + Ny afsendelsesadresse + + + Edit receiving address + Redigér modtagelsesadresse + + + Edit sending address + Redigér afsendelsesadresse + + + The entered address "%1" is not a valid Bitcoin address. + Den indtastede adresse "%1" er ikke en gyldig Bitcoin-adresse. + + + The entered address "%1" is already in the address book. + Den indtastede adresse "%1" er allerede i adressebogen. + + + Could not unlock wallet. + Kunne ikke låse tegnebog op. + + + New key generation failed. + Ny nøglegenerering mislykkedes. + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file Vælg fil for betalingsanmodning + + Select payment request file to open + Vælg fil for betalingsanmodning til åbning + OptionsDialog @@ -937,6 +1276,97 @@ Nuværende totalsaldo på kigge-adresser + + PaymentServer + + Payment request error + Fejl i betalingsanmodning + + + Cannot start bitcoin: click-to-pay handler + Kan ikke starte bitcoin: click-to-pay-håndtering + + + URI handling + URI-håndtering + + + Payment request fetch URL is invalid: %1 + Hentnings-URL for betalingsanmodning er ugyldig: %1 + + + Invalid payment address %1 + Ugyldig betalingsadresse %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kan ikke tolkes! Dette kan skyldes en ugyldig Bitcoin-adresse eller forkert udformede URL-parametre. + + + Payment request file handling + Filhåndtering for betalingsanmodninger + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Fil for betalingsanmodning kan ikke læses! Dette kan skyldes en ugyldig fil for betalingsanmodning. + + + Payment request rejected + Betalingsanmodning afvist + + + Payment request network doesn't match client network. + Netværk for betalingsanmodning stemmer ikke overens med klientens netværk. + + + Payment request expired. + Betalingsanmodning er udløbet. + + + Payment request is not initialized. + Betalingsanmodning er ikke klargjort. + + + Unverified payment requests to custom payment scripts are unsupported. + Ikke-verificerede betalingsanmodninger for tilpassede betalings-scripts understøttes ikke. + + + Invalid payment request. + Ugyldig betalingsanmodning. + + + Requested payment amount of %1 is too small (considered dust). + Anmodet betalingsbeløb på %1 er for lille (regnes som støv). + + + Refund from %1 + Tilbagebetaling fra %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Betalingsanmodning %1 er for stor (%2 byte; %3 byte tilladt). + + + Error communicating with %1: %2 + Fejl under kommunikation med %1: %2 + + + Payment request cannot be parsed! + Betalingsanmodning kan ikke tolkes! + + + Bad response from server %1 + Fejlagtigt svar fra server %1 + + + Network request error + Fejl i netværksforespørgsel + + + Payment acknowledged + Betaling anerkendt + + PeerTableModel @@ -991,6 +1421,25 @@ %1 ms + + QRImageWidget + + &Save Image... + Gem billede… + + + &Copy Image + &Kopiér foto + + + Save QR Code + Gem QR-kode + + + PNG Image (*.png) + PNG-billede (*.png) + + RPCConsole @@ -1352,6 +1801,18 @@ Remove Fjern + + Copy label + Kopiér mærkat + + + Copy message + Kopiér besked + + + Copy amount + Kopiér beløb + ReceiveRequestDialog @@ -1371,6 +1832,73 @@ &Save Image... &Gem billede… + + Request payment to %1 + Anmod om betaling til %1 + + + Payment information + Betalingsinformation + + + URI + URI + + + Address + Adresse + + + Amount + Beløb + + + Label + Mærkat + + + Message + Besked + + + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI var for lang; prøv at forkorte teksten til mærkaten/beskeden. + + + Error encoding URI into QR Code. + Fejl ved kodning fra URI til QR-kode. + + + + RecentRequestsTableModel + + Date + Dato + + + Label + Mærkat + + + Message + Besked + + + (no label) + (ingen mærkat) + + + (no message) + (ingen besked) + + + (no amount requested) + (intet anmodet beløb) + + + Requested + Anmodet + SendCoinsDialog @@ -1522,6 +2050,118 @@ S&end &Afsend + + Copy quantity + Kopiér mængde + + + Copy amount + Kopiér beløb + + + Copy fee + Kopiér gebyr + + + Copy after fee + Kopiér eftergebyr + + + Copy bytes + Kopiér byte + + + Copy priority + Kopiér prioritet + + + Copy dust + Kopiér støv + + + Copy change + Kopiér byttepenge + + + %1 to %2 + %1 til %2 + + + Are you sure you want to send? + Er du sikker på, at du vil sende? + + + added as transaction fee + tilføjet som transaktionsgebyr + + + Total Amount %1 + Beløb i alt %1 + + + or + eller + + + Confirm send coins + Bekræft afsendelse af bitcoins + + + The recipient address is not valid. Please recheck. + Modtageradressen er ikke gyldig. Tjek venligst igen. + + + The amount to pay must be larger than 0. + Beløbet til betaling skal være større end 0. + + + The amount exceeds your balance. + Beløbet overstiger din saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + Totalen overstiger din saldo, når transaktionsgebyret på %1 er inkluderet. + + + Duplicate address found: addresses should only be used once each. + Adressegenganger fundet. Adresser bør kun bruges én gang hver. + + + Transaction creation failed! + Oprettelse af transaktion mislykkedes! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her. + + + A fee higher than %1 is considered an absurdly high fee. + Et gebyr højere end %1 opfattes som et absurd højt gebyr. + + + Payment request expired. + Betalingsanmodning er udløbet. + + + Pay only the required fee of %1 + Betal kun det påkrævede gebyr på %1 + + + Estimated to begin confirmation within %n block(s). + Bekræftelse estimeret til at begynde inden for %n blok.Bekræftelse estimeret til at begynde inden for %n blokke. + + + Warning: Invalid Bitcoin address + Advarsel: Ugyldig Bitcoin-adresse + + + Warning: Unknown change address + Advarsel: Ukendt byttepengeadresse + + + (no label) + (ingen mærkat) + SendCoinsEntry @@ -1601,6 +2241,17 @@ Memo: Memo: + + Enter a label for this address to add it to your address book + Indtast en mærkat for denne adresse for at føje den til din adressebog + + + + SendConfirmationDialog + + Yes + Ja + ShutdownWindow @@ -1617,11 +2268,11 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Signature - Underskriv/verificér en besked + Signaturer – Underskriv/verificér en besked &Sign Message - &Underskriv besked + &Singér besked 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. @@ -1649,27 +2300,27 @@ Enter the message you want to sign here - Indtast her beskeden, du ønsker at underskrive + Indtast her beskeden, du ønsker at signere Signature - Underskrift + Signatur Copy the current signature to the system clipboard - Kopiér den nuværende underskrift til systemets udklipsholder + Kopiér den nuværende signatur til systemets udklipsholder Sign the message to prove you own this Bitcoin address - Underskriv denne besked for at bevise, at Bitcoin-adressen tilhører dig + Signér denne besked for at bevise, at Bitcoin-adressen tilhører dig Sign &Message - Underskriv &besked + Signér &besked Reset all sign message fields - Nulstil alle "underskriv besked"-felter + Nulstil alle "signér besked"-felter Clear &All @@ -1689,7 +2340,7 @@ Verify the message to ensure it was signed with the specified Bitcoin address - Verificér beskeden for at sikre, at den er underskrevet med den angivne Bitcoin-adresse + Verificér beskeden for at sikre, at den er signeret med den angivne Bitcoin-adresse Verify &Message @@ -1699,6 +2350,58 @@ Reset all verify message fields Nulstil alle "verificér besked"-felter + + Click "Sign Message" to generate signature + Klik "Signér besked" for at generere underskriften + + + The entered address is invalid. + Den indtastede adresse er ugyldig. + + + Please check the address and try again. + Tjek venligst adressen og forsøg igen. + + + The entered address does not refer to a key. + Den indtastede adresse henviser ikke til en nøgle. + + + Wallet unlock was cancelled. + Tegnebogsoplåsning annulleret. + + + Private key for the entered address is not available. + Den private nøgle for den indtastede adresse er ikke tilgængelig. + + + Message signing failed. + Signering af besked mislykkedes. + + + Message signed. + Besked signeret. + + + The signature could not be decoded. + Signaturen kunne ikke afkodes. + + + Please check the signature and try again. + Tjek venligst signaturen og forsøg igen. + + + The signature did not match the message digest. + Signaturen passer ikke overens med beskedens indhold. + + + Message verification failed. + Verificering af besked mislykkedes. + + + Message verified. + Besked verificeret. + SplashScreen @@ -1714,12 +2417,457 @@ KB/s + + TransactionDesc + + Open for %n more block(s) + Åbn yderligere %n blokÅbn yderligere %n blokke + + + Open until %1 + Åben indtil %1 + + + conflicted with a transaction with %1 confirmations + i konflikt med en transaktion, der har %1 bekræftelser + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/ubekræftet, %1 + + + in memory pool + i hukommelsespulje + + + not in memory pool + ikke i hukommelsespulje + + + abandoned + opgivet + + + %1/unconfirmed + %1/ubekræftet + + + %1 confirmations + %1 bekræftelser + + + Status + Status + + + , has not been successfully broadcast yet + , er ikke blevet transmitteret endnu + + + , broadcast through %n node(s) + , transmitteret igennem %n knude, transmitteret igennem %n knuder + + + Date + Dato + + + Source + Kilde + + + Generated + Genereret + + + From + Fra + + + unknown + ukendt + + + To + Til + + + own address + egen adresse + + + watch-only + kigge + + + label + mærkat + + + Credit + Kredit + + + matures in %n more block(s) + modner efter yderligere %n blokmodner efter yderligere %n blokke + + + not accepted + ikke accepteret + + + Debit + Debet + + + Total debit + Total debet + + + Total credit + Total kredit + + + Transaction fee + Transaktionsgebyr + + + Net amount + Nettobeløb + + + Message + Besked + + + Comment + Kommentar + + + Transaction ID + Transaktions-ID + + + Output index + Outputindeks + + + Merchant + Forretningsdrivende + + + 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. + Minede bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den transmitteret til netværket for at blive føjet til blokkæden. Hvis det ikke lykkes at få den i kæden, vil dens tilstand ændres til "ikke accepteret", og den vil ikke kunne bruges. Dette kan ske nu og da, hvis en anden knude udvinder en blok inden for nogle få sekunder fra din. + + + Debug information + Fejlsøgningsinformation + + + Transaction + Transaktion + + + Inputs + Input + + + Amount + Beløb + + + true + sand + + + false + falsk + + TransactionDescDialog This pane shows a detailed description of the transaction Denne rude viser en detaljeret beskrivelse af transaktionen + + Details for %1 + Detaljer for %1 + + + + TransactionTableModel + + Date + Dato + + + Type + Type + + + Label + Mærkat + + + Open for %n more block(s) + Åben i yderligere %n blokÅben i yderligere %n blokke + + + Open until %1 + Åben indtil %1 + + + Offline + Offline + + + Unconfirmed + Ubekræftet + + + Abandoned + Opgivet + + + Confirming (%1 of %2 recommended confirmations) + Bekræfter (%1 af %2 anbefalede bekræftelser) + + + Confirmed (%1 confirmations) + Bekræftet (%1 bekræftelser) + + + Conflicted + Konflikt + + + Immature (%1 confirmations, will be available after %2) + Umoden (%1 bekræftelser; vil være tilgængelig efter %2) + + + This block was not received by any other nodes and will probably not be accepted! + Denne blok blev ikke modtaget af nogen andre knuder og vil formentlig ikke blive accepteret! + + + Generated but not accepted + Genereret, men ikke accepteret + + + Received with + Modtaget med + + + Received from + Modtaget fra + + + Sent to + Sendt til + + + Payment to yourself + Betaling til dig selv + + + Mined + Minet + + + watch-only + kigge + + + (n/a) + (n/a) + + + (no label) + (ingen mærkat) + + + Transaction status. Hover over this field to show number of confirmations. + Transaktionsstatus. Hold musen over dette felt for at vise antallet af bekræftelser. + + + Date and time that the transaction was received. + Dato og klokkeslæt for modtagelse af transaktionen. + + + Type of transaction. + Transaktionstype. + + + Whether or not a watch-only address is involved in this transaction. + Afgør hvorvidt en kigge-adresse er involveret i denne transaktion. + + + User-defined intent/purpose of the transaction. + Brugerdefineret hensigt/formål med transaktionen. + + + Amount removed from or added to balance. + Beløb trukket fra eller tilføjet balance. + + + + TransactionView + + All + Alle + + + Today + I dag + + + This week + Denne uge + + + This month + Denne måned + + + Last month + Sidste måned + + + This year + I år + + + Range... + Interval… + + + Received with + Modtaget med + + + Sent to + Sendt til + + + To yourself + Til dig selv + + + Mined + Minet + + + Other + Andet + + + Enter address or label to search + Indtast adresse eller mærkat for at søge + + + Min amount + Minimumsbeløb + + + Abandon transaction + Opgiv transaktion + + + Copy address + Kopiér adresse + + + Copy label + Kopiér mærkat + + + Copy amount + Kopiér beløb + + + Copy transaction ID + Kopiér transaktions-ID + + + Copy raw transaction + Kopiér rå transaktion + + + Copy full transaction details + Kopiér komplette transaktionsdetaljer + + + Edit label + Redigér mærkat + + + Show transaction details + Vis transaktionsdetaljer + + + Export Transaction History + Eksportér transaktionshistorik + + + Comma separated file (*.csv) + Kommasepareret fil (*.csv) + + + Confirmed + Bekræftet + + + Watch-only + Kigge + + + Date + Dato + + + Type + Type + + + Label + Mærkat + + + Address + Adresse + + + ID + ID + + + Exporting Failed + Eksport mislykkedes + + + There was an error trying to save the transaction history to %1. + En fejl opstod under gemning af transaktionshistorik til %1. + + + Exporting Successful + Eksport problemfri + + + The transaction history was successfully saved to %1. + Transaktionshistorikken blev gemt til %1. + + + Range: + Interval: + + + to + til + UnitDisplayStatusBarControl @@ -1728,6 +2876,55 @@ Enhed, som beløb vises i. Klik for at vælge en anden enhed. + + WalletFrame + + No wallet has been loaded. + Ingen tegnebog er indlæst. + + + + WalletModel + + Send Coins + Send bitcoins + + + + WalletView + + &Export + &Eksportér + + + Export the data in the current tab to a file + Eksportér den aktuelle visning til en fil + + + Backup Wallet + Sikkerhedskopiér tegnebog + + + Wallet Data (*.dat) + Tegnebogsdata (*.dat) + + + Backup Failed + Sikkerhedskopiering mislykkedes + + + There was an error trying to save the wallet data to %1. + Der skete en fejl under gemning af tegnebogsdata til %1. + + + Backup Successful + Sikkerhedskopiering problemfri + + + The wallet data was successfully saved to %1. + Tegnebogsdata blev gemt til %1. + + bitcoin-core @@ -1846,10 +3043,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Justering af maksimalt tilladt gennemsnitlig afvigelse fra peer-tid. Den lokale opfattelse af tid kan blive påvirket frem eller tilbage af peers med denne mængde tid. (standard: %u sekunder) @@ -2110,6 +3303,10 @@ Specify wallet file (within data directory) Angiv tegnebogsfil (inden for datamappe) + + Starting network threads... + Starter netværkstråde… + The source code is available from %s. Kildekoden er tilgængelig fra %s. @@ -2194,6 +3391,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr for videresendelse, mining og oprettelse af transaktioner (standard: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u) @@ -2316,7 +3517,7 @@ Signing transaction failed - Underskrift af transaktion mislykkedes + Signering af transaktion mislykkedes The transaction amount is too small to pay the fee diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 498baf97e..0e99b8df0 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -41,6 +41,77 @@ &Delete &Löschen + + Choose the address to send coins to + Wählen Sie die Adresse aus, an die Sie Bitcoins überweisen möchten + + + Choose the address to receive coins with + Wählen Sie die Adresse aus, über die Sie Bitcoins empfangen wollen + + + C&hoose + &Auswählen + + + Sending addresses + Zahlungsadressen + + + Receiving addresses + Empfangsadressen + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Dies sind ihre Bitcoin-Adressen zum Tätigen von Überweisungen. Bitte prüfen Sie den Betrag und die Empfangsadresse, bevor Sie Bitcoins überweisen. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dies sind Ihre Bitcoin-Adressen zum Empfangen von Zahlungen. Es wird empfohlen, für jede Transaktion eine neue Empfangsadresse zu verwenden. + + + &Copy Address + Adresse &kopieren + + + Copy &Label + &Bezeichnung kopieren + + + &Edit + &Editieren + + + Export Address List + Addressliste exportieren + + + Comma separated file (*.csv) + Kommagetrennte-Datei (*.csv) + + + Exporting Failed + Exportieren fehlgeschlagen + + + There was an error trying to save the address list to %1. Please try again. + Beim Speichern der Adressliste nach %1 ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut. + + + + AddressTableModel + + Label + Bezeichnung + + + Address + Adresse + + + (no label) + (keine Bezeichnung) + AskPassphraseDialog @@ -60,7 +131,59 @@ Repeat new passphrase Neue Passphrase bestätigen - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Geben Sie die neue Passphrase für die Wallet ein.<br>Bitte benutzen Sie eine Passphrase bestehend aus <b>zehn oder mehr zufälligen Zeichen</b> oder <b>acht oder mehr Wörtern</b>. + + + Encrypt wallet + Wallet verschlüsseln + + + This operation needs your wallet passphrase to unlock the wallet. + Dieser Vorgang benötigt ihre Passphrase, um die Wallet zu entsperren. + + + Unlock wallet + Wallet entsperren + + + This operation needs your wallet passphrase to decrypt the wallet. + Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entschlüsseln. + + + Decrypt wallet + Wallet entschlüsseln + + + Change passphrase + Passphrase ändern + + + Enter the old passphrase and new passphrase to the wallet. + Geben Sie die alte und neue Wallet-Passphrase ein. + + + Confirm wallet encryption + Wallet-Verschlüsselung bestätigen + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Warnung: Wenn Sie Ihre Wallet verschlüsseln und Ihre Passphrase verlieren, werden Sie <b>alle Ihre Bitcoins verlieren</b>! + + + Are you sure you wish to encrypt your wallet? + Sind Sie sich sicher, dass Sie Ihre Wallet verschlüsseln möchten? + + + Wallet encrypted + Wallet verschlüsselt + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Bitte beachten Sie, dass die Wallet-Verschlüsselung nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadprogramme schützt, die Ihren Computer befällt. + + BanTableModel @@ -463,6 +586,102 @@ Priority Priorität + + Copy address + Adresse kopieren + + + Copy label + Bezeichnung kopieren + + + Copy amount + Betrag kopieren + + + Copy transaction ID + Transaktionskennung kopieren + + + Copy fee + Gebühr kopieren + + + Copy after fee + Abzüglich Gebühr kopieren + + + Copy bytes + Byte kopieren + + + Copy priority + Priorität kopieren + + + Copy change + Wechselgeld kopieren + + + highest + am höchsten + + + higher + höher + + + high + hoch + + + medium-high + mittel-hoch + + + medium + mittel + + + low-medium + niedrig-mittel + + + low + niedrig + + + lower + niedriger + + + lowest + am niedrigsten + + + (%1 locked) + (%1 gesperrt) + + + none + keine + + + yes + ja + + + no + nein + + + (no label) + (keine Bezeichnung) + + + (change) + (Wechselgeld) + EditAddressDialog @@ -486,7 +705,7 @@ &Address &Adresse - + FreespaceChecker @@ -626,7 +845,7 @@ Select payment request file Zahlungsanforderungsdatei auswählen - + OptionsDialog @@ -937,6 +1156,9 @@ Aktueller Gesamtbetrag in beobachteten Adressen aus obigen Kategorien + + PaymentServer + PeerTableModel @@ -991,6 +1213,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,6 +1577,14 @@ Remove Entfernen + + Copy label + Bezeichnung kopieren + + + Copy amount + Betrag kopieren + ReceiveRequestDialog @@ -1371,7 +1604,26 @@ &Save Image... Grafik &speichern... - + + Address + Adresse + + + Label + Bezeichnung + + + + RecentRequestsTableModel + + Label + Bezeichnung + + + (no label) + (keine Bezeichnung) + + SendCoinsDialog @@ -1522,6 +1774,34 @@ S&end &Überweisen + + Copy amount + Betrag kopieren + + + Copy fee + Gebühr kopieren + + + Copy after fee + Abzüglich Gebühr kopieren + + + Copy bytes + Byte kopieren + + + Copy priority + Priorität kopieren + + + Copy change + Wechselgeld kopieren + + + (no label) + (keine Bezeichnung) + SendCoinsEntry @@ -1601,7 +1881,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1982,7 @@ Reset all verify message fields Alle "Nachricht verifizieren"-Felder zurücksetzen - + SplashScreen @@ -1714,13 +1997,62 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Dieser Bereich zeigt eine detaillierte Beschreibung der Transaktion an - + + + TransactionTableModel + + Label + Bezeichnung + + + (no label) + (keine Bezeichnung) + + + + TransactionView + + Copy address + Adresse kopieren + + + Copy label + Bezeichnung kopieren + + + Copy amount + Betrag kopieren + + + Copy transaction ID + Transaktionskennung kopieren + + + Comma separated file (*.csv) + Kommagetrennte-Datei (*.csv) + + + Label + Bezeichnung + + + Address + Adresse + + + Exporting Failed + Exportieren fehlgeschlagen + + UnitDisplayStatusBarControl @@ -1728,6 +2060,47 @@ Die Einheit in der Beträge angezeigt werden. Klicken, um eine andere Einheit auszuwählen. + + WalletFrame + + + WalletModel + + + WalletView + + &Export + E&xportieren + + + Export the data in the current tab to a file + Daten der aktuellen Ansicht in eine Datei exportieren + + + Backup Wallet + Wallet sichern + + + Wallet Data (*.dat) + Wallet-Daten (*.dat) + + + Backup Failed + Sicherung fehlgeschlagen + + + There was an error trying to save the wallet data to %1. + Beim Speichern der Wallet-Daten nach %1 ist ein Fehler aufgetreten. + + + Backup Successful + Sicherung erfolgreich + + + The wallet data was successfully saved to %1. + Speichern der Wallet-Daten nach %1 war erfolgreich. + + bitcoin-core @@ -1834,10 +2207,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) @@ -2170,6 +2539,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Niedrigere Gebühren (in %s/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u) diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts index de76a110c..8134baeac 100644 --- a/src/qt/locale/bitcoin_el.ts +++ b/src/qt/locale/bitcoin_el.ts @@ -6,6 +6,9 @@ Δημιουργία νέου λογαριασμού + + AddressTableModel + AskPassphraseDialog @@ -20,7 +23,7 @@ Repeat new passphrase Επαναλάβετε νέο συνθηματικό - + BanTableModel @@ -56,7 +59,7 @@ &Address Διεύθυνση - + FreespaceChecker @@ -91,12 +94,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -110,10 +119,13 @@ Remove Αφαίρεση - + ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -132,6 +144,9 @@ Μήνυμα: + + SendConfirmationDialog + ShutdownWindow @@ -144,12 +159,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 2814e4f6e..43b04f1a8 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -41,7 +41,10 @@ &Delete &Διαγραφή - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Επανέλαβε τον νέο κωδικό πρόσβασης - + BanTableModel @@ -407,7 +410,7 @@ Priority Προτεραιότητα - + EditAddressDialog @@ -430,7 +433,7 @@ &Address &Διεύθυνση - + FreespaceChecker @@ -526,7 +529,7 @@ Select payment request file Επιλέξτε πληρωμή αρχείου αίτησης - + OptionsDialog @@ -786,6 +789,9 @@ Το τρέχον συνολικό υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο + + PaymentServer + PeerTableModel @@ -832,6 +838,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1053,7 +1062,7 @@ Remove Αφαίρεση - + ReceiveRequestDialog @@ -1072,7 +1081,10 @@ &Save Image... &Αποθήκευση εικόνας... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1203,7 +1215,7 @@ S&end Αποστολη - + SendCoinsEntry @@ -1262,7 +1274,10 @@ Memo: Σημείωση: - + + + SendConfirmationDialog + ShutdownWindow @@ -1348,7 +1363,7 @@ Reset all verify message fields Επαναφορά όλων επαλήθευμενων πεδίων μήνυματος - + SplashScreen @@ -1363,13 +1378,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1377,6 +1401,15 @@ Μονάδα μέτρησης προβολής ποσών. Κάντε κλικ για επιλογή άλλης μονάδας. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 16a85ee34..f308f6d4d 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -41,7 +41,10 @@ &Delete &Delete - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repeat new passphrase - + BanTableModel @@ -463,7 +466,7 @@ Priority Priority - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Address - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Select payment request file - + OptionsDialog @@ -937,6 +940,9 @@ Current total balance in watch-only addresses + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1361,7 @@ Remove Remove - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... &Save Image... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end S&end - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1714,7 @@ Reset all verify message fields Reset all verify message fields - + SplashScreen @@ -1714,13 +1729,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1728,6 +1752,15 @@ Unit to show amounts in. Click to select another unit. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1846,10 +1879,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 4471aeb72..e29527063 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -41,7 +41,10 @@ &Delete &Forigi - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ripetu la novan pasfrazon - + BanTableModel @@ -415,7 +418,7 @@ Priority Prioritato - + EditAddressDialog @@ -438,7 +441,7 @@ &Address &Adreso - + FreespaceChecker @@ -526,7 +529,7 @@ Select payment request file Elektu la dosieron de la pagpeto - + OptionsDialog @@ -709,6 +712,9 @@ Lastaj transakcioj + + PaymentServer + PeerTableModel @@ -739,6 +745,9 @@ neaplikebla + + QRImageWidget + RPCConsole @@ -920,7 +929,7 @@ Remove Forigi - + ReceiveRequestDialog @@ -939,7 +948,10 @@ &Save Image... &Konservi Bildon... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1022,7 +1034,7 @@ S&end Ŝendi - + SendCoinsEntry @@ -1077,7 +1089,10 @@ Memo: Memorando: - + + + SendConfirmationDialog + ShutdownWindow @@ -1155,7 +1170,7 @@ Reset all verify message fields Reagordigi ĉiujn prikontrolajn kampojn - + SplashScreen @@ -1170,16 +1185,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Tiu ĉi panelo montras detalan priskribon de la transakcio - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 7b9425851..aa0ebd292 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -41,7 +41,10 @@ &Delete &Eliminar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repita la nueva contraseña - + BanTableModel @@ -463,7 +466,7 @@ Priority Prioridad - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Dirección - + FreespaceChecker @@ -622,7 +625,7 @@ Select payment request file Seleccionar archivo de sulicitud de pago - + OptionsDialog @@ -933,6 +936,9 @@ Saldo total en las direcciones watch-only + + PaymentServer + PeerTableModel @@ -987,6 +993,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1348,7 +1357,7 @@ Remove Eliminar - + ReceiveRequestDialog @@ -1367,7 +1376,10 @@ &Save Image... Guardar Imagen... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1518,7 +1530,7 @@ S&end &Enviar - + SendCoinsEntry @@ -1597,7 +1609,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1695,7 +1710,7 @@ Reset all verify message fields Vaciar todos los campos de la verificación de mensaje - + SplashScreen @@ -1710,13 +1725,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1724,6 +1748,15 @@ Unidad en la que se muestran las cantidades. Haga clic para seleccionar otra unidad. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1845,10 +1878,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Ajuste máximo permitido del tiempo offset medio de pares. La perspectiva local de tiempo se verá influenciada por los pares anteriores y posteriores a esta cantidad. (Por defecto: %u segundos) diff --git a/src/qt/locale/bitcoin_es_AR.ts b/src/qt/locale/bitcoin_es_AR.ts index 40ebaf885..c1581b798 100644 --- a/src/qt/locale/bitcoin_es_AR.ts +++ b/src/qt/locale/bitcoin_es_AR.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetí la nueva Frase de Contraseña - + BanTableModel @@ -91,12 +94,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -106,12 +115,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -124,12 +139,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index 188641d6e..c864753f2 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repite nueva contraseña - + BanTableModel @@ -282,7 +285,7 @@ Priority prioridad - + EditAddressDialog @@ -297,7 +300,7 @@ &Address &Dirección - + FreespaceChecker @@ -441,6 +444,9 @@ Total: + + PaymentServer + PeerTableModel @@ -455,6 +461,9 @@ N/A + + QRImageWidget + RPCConsole @@ -548,7 +557,10 @@ &Save Image... Guardar imagen... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -608,7 +620,7 @@ S&end &Envía - + SendCoinsEntry @@ -644,6 +656,9 @@ Pagar a: + + SendConfirmationDialog + ShutdownWindow @@ -708,16 +723,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts index 7d10e0320..6cf512fdc 100644 --- a/src/qt/locale/bitcoin_es_CO.ts +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -37,7 +37,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repetir nueva contraseña - + BanTableModel @@ -215,12 +218,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -230,12 +239,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -248,12 +263,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index ba963d2b8..9cb1e93ad 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -37,7 +37,10 @@ &Delete &Eliminar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repita la nueva contraseña - + BanTableModel @@ -349,7 +352,7 @@ Priority Prioridad - + EditAddressDialog @@ -372,7 +375,7 @@ &Address &Dirección - + FreespaceChecker @@ -452,7 +455,7 @@ Select payment request file Seleccione archivo de sulicitud de pago - + OptionsDialog @@ -615,6 +618,9 @@ Su balance actual total + + PaymentServer + PeerTableModel @@ -637,6 +643,9 @@ N/D + + QRImageWidget + RPCConsole @@ -798,7 +807,7 @@ Remove Eliminar - + ReceiveRequestDialog @@ -817,7 +826,10 @@ &Save Image... Guardar Imagen... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -908,7 +920,7 @@ S&end &Enviar - + SendCoinsEntry @@ -963,7 +975,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1037,7 +1052,7 @@ Reset all verify message fields Limpiar todos los campos de la verificación de mensaje - + SplashScreen @@ -1052,16 +1067,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index c66a477cc..40b6bb7df 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -41,7 +41,10 @@ &Delete &Eliminar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repite la nueva contraseña - + BanTableModel @@ -164,7 +167,7 @@ &Address Dirección - + FreespaceChecker @@ -183,12 +186,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -202,12 +211,18 @@ &Copiar Direccón + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -220,12 +235,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 0a6ea1e1d..bfda085d9 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repita la nueva contraseña - + BanTableModel @@ -293,7 +296,7 @@ Priority Prioridad - + EditAddressDialog @@ -308,7 +311,7 @@ &Address &Dirección - + FreespaceChecker @@ -375,6 +378,9 @@ Formulario + + PaymentServer + PeerTableModel @@ -385,6 +391,9 @@ Monto + + QRImageWidget + RPCConsole @@ -426,6 +435,9 @@ &Copiar dirección + + RecentRequestsTableModel + SendCoinsDialog @@ -520,6 +532,9 @@ Pago para: + + SendConfirmationDialog + ShutdownWindow @@ -552,16 +567,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Este panel muestras una descripción detallada de la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index c565a63cd..5e37c3f17 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -33,7 +33,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -48,7 +51,7 @@ Repeat new passphrase Repetir nueva contraseña - + BanTableModel @@ -224,7 +227,7 @@ Priority Prioridad - + EditAddressDialog @@ -239,7 +242,7 @@ &Address &Direccion - + FreespaceChecker @@ -274,12 +277,18 @@ Formulario + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -301,6 +310,9 @@ Copiar Dirección + + RecentRequestsTableModel + SendCoinsDialog @@ -371,6 +383,9 @@ Pagar A: + + SendConfirmationDialog + ShutdownWindow @@ -399,12 +414,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts index 432adc57e..322b311ed 100644 --- a/src/qt/locale/bitcoin_es_VE.ts +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetir nueva frase de contraseña - + BanTableModel @@ -301,7 +304,7 @@ Priority Prioridad - + EditAddressDialog @@ -324,7 +327,7 @@ &Address &Dirección - + FreespaceChecker @@ -408,7 +411,7 @@ Select payment request file Seleccionar archivo de solicitud de pago - + OptionsDialog @@ -447,6 +450,9 @@ Pendiente: + + PaymentServer + PeerTableModel @@ -457,6 +463,9 @@ Monto + + QRImageWidget + RPCConsole @@ -494,6 +503,9 @@ &Copiar Dirección + + RecentRequestsTableModel + SendCoinsDialog @@ -536,6 +548,9 @@ &Etiqueta: + + SendConfirmationDialog + ShutdownWindow @@ -548,12 +563,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index d17904d97..5d2423eef 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -41,7 +41,10 @@ &Delete &Kustuta - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Korda salafraasi - + BanTableModel @@ -350,7 +353,7 @@ &Address &Aadress - + FreespaceChecker @@ -529,6 +532,9 @@ Hiljutised tehingud + + PaymentServer + PeerTableModel @@ -543,6 +549,9 @@ N/A + + QRImageWidget + RPCConsole @@ -676,7 +685,7 @@ Remove Eemalda - + ReceiveRequestDialog @@ -684,6 +693,9 @@ &Kopeeri Aadress + + RecentRequestsTableModel + SendCoinsDialog @@ -754,7 +766,7 @@ S&end S&aada - + SendCoinsEntry @@ -790,6 +802,9 @@ Maksa : + + SendConfirmationDialog + ShutdownWindow @@ -859,7 +874,7 @@ Reset all verify message fields Tühjenda kõik sõnumi kinnitamise väljad - + SplashScreen @@ -874,16 +889,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Paan kuvab tehingu detailid - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index cbe246f44..51ee5b0b8 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -41,7 +41,10 @@ &Delete &Ezabatu - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Errepikatu pasahitz berria - + BanTableModel @@ -184,7 +187,7 @@ &Address &Helbidea - + FreespaceChecker @@ -211,6 +214,9 @@ Inprimakia + + PaymentServer + PeerTableModel @@ -221,6 +227,9 @@ Kopurua + + QRImageWidget + RPCConsole @@ -246,6 +255,9 @@ &Kopiatu helbidea + + RecentRequestsTableModel + SendCoinsDialog @@ -304,6 +316,9 @@ Ordaindu honi: + + SendConfirmationDialog + ShutdownWindow @@ -332,16 +347,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Panel honek transakzioaren deskribapen xehea erakusten du - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index a58743270..a02c2dd9a 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -41,7 +41,10 @@ &Delete &حذف - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase تکرار گذرواژهٔ جدید - + BanTableModel @@ -431,7 +434,7 @@ Priority اولویت - + EditAddressDialog @@ -446,7 +449,7 @@ &Address &نشانی - + FreespaceChecker @@ -538,7 +541,7 @@ Select payment request file انتخاب فایل درخواست پرداخت - + OptionsDialog @@ -729,6 +732,9 @@ تراکنش های اخیر + + PaymentServer + PeerTableModel @@ -775,6 +781,9 @@ %1 میلیونم ثانیه + + QRImageWidget + RPCConsole @@ -972,7 +981,7 @@ Remove حذف کردن - + ReceiveRequestDialog @@ -987,7 +996,10 @@ &Save Image... &ذخیره عکس... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1102,7 +1114,7 @@ S&end &ارسال - + SendCoinsEntry @@ -1157,7 +1169,10 @@ Memo: یادداشت: - + + + SendConfirmationDialog + ShutdownWindow @@ -1243,7 +1258,7 @@ Reset all verify message fields بازنشانی تمام فیلدهای پیام - + SplashScreen @@ -1258,16 +1273,34 @@ کیلوبایت + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction این پانل شامل توصیف کاملی از جزئیات تراکنش است - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index afeab08c7..64faca8fe 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -37,7 +37,10 @@ &Delete حذف - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase رمز/پَس فرِیز را دوباره وارد کنید - + BanTableModel @@ -224,7 +227,7 @@ &Address حساب& - + FreespaceChecker @@ -287,6 +290,9 @@ اطلاعات نمایش داده شده ممکن است روزآمد نباشد. wallet شما به صورت خودکار بعد از برقراری اتصال با شبکه bitcoin به روز می شود اما این فرایند هنوز تکمیل نشده است. + + PaymentServer + PeerTableModel @@ -297,6 +303,9 @@ میزان + + QRImageWidget + RPCConsole @@ -342,6 +351,9 @@ کپی آدرس + + RecentRequestsTableModel + SendCoinsDialog @@ -372,7 +384,7 @@ S&end و ارسال - + SendCoinsEntry @@ -411,7 +423,10 @@ Memo: یادداشت: - + + + SendConfirmationDialog + ShutdownWindow @@ -452,16 +467,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction این بخش جزئیات تراکنش را نشان می دهد - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 4be3085a4..9f7974eee 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -41,7 +41,10 @@ &Delete &Poista - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Toista uusi tunnuslause - + BanTableModel @@ -463,7 +466,7 @@ Priority Prioriteetti - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Osoite - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Valitse maksupyynnön tiedosto - + OptionsDialog @@ -929,6 +932,9 @@ Nykyinen tase seurantaosoitetteissa + + PaymentServer + PeerTableModel @@ -983,6 +989,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1340,7 +1349,7 @@ Remove Poista - + ReceiveRequestDialog @@ -1359,7 +1368,10 @@ &Save Image... &Tallenna kuva - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1502,7 +1514,7 @@ S&end &Lähetä - + SendCoinsEntry @@ -1581,7 +1593,10 @@ Memo: Muistio: - + + + SendConfirmationDialog + ShutdownWindow @@ -1671,7 +1686,7 @@ Reset all verify message fields Tyhjennä kaikki varmista-viesti-kentät - + SplashScreen @@ -1686,13 +1701,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Tämä ruutu näyttää yksityiskohtaisen tiedon rahansiirrosta - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1700,6 +1724,15 @@ Yksikkö jossa määrät näytetään. Klikkaa valitaksesi toisen yksikön. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index ef27c6fc2..4d33a58bf 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -41,6 +41,77 @@ &Delete &Supprimer + + Choose the address to send coins to + Choisir l'adresse à laquelle envoyer des pièces + + + Choose the address to receive coins with + Choisir l'adresse avec laquelle recevoir des pîèces + + + C&hoose + C&hoisir + + + Sending addresses + Adresses d'envoi + + + Receiving addresses + Adresses de réception + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Voici vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l'adresse du destinataire avant d'envoyer des pièces. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Voici vos adresses Bitcoin pour recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction. + + + &Copy Address + &Copier l'adresse + + + Copy &Label + Copier l'é&tiquette + + + &Edit + &Modifier + + + Export Address List + Exporter la liste d'adresses + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + Exporting Failed + L'exportation a échoué + + + There was an error trying to save the address list to %1. Please try again. + Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez ressayer plus tard. + + + + AddressTableModel + + Label + Étiquette + + + Address + Adresse + + + (no label) + (aucune étiquette) + AskPassphraseDialog @@ -60,7 +131,35 @@ Repeat new passphrase Répéter la phrase de passe - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Saisissez une nouvelle phrase de passe pour le portefeuille.<br/>Veuillez utiliser une phrase composée de <b>dix caractères aléatoires ou plus</b>, ou bien de <b>huit mots ou plus</b>. + + + Encrypt wallet + Chiffrer le porte-monnaie + + + This operation needs your wallet passphrase to unlock the wallet. + Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. + + + Unlock wallet + Déverrouiller le porte-monnaie + + + This operation needs your wallet passphrase to decrypt the wallet. + Cette opération nécessite votre phrase de passe pour déchiffrer le porte-monnaie. + + + Decrypt wallet + Déchiffrer le porte-monnaie + + + Change passphrase + Changer la phrase de passe + + BanTableModel @@ -463,7 +562,11 @@ Priority Priorité - + + (no label) + (aucune étiquette) + + EditAddressDialog @@ -486,7 +589,7 @@ &Address &Adresse - + FreespaceChecker @@ -626,7 +729,7 @@ Select payment request file Choisir le fichier de demande de paiement - + OptionsDialog @@ -937,6 +1040,9 @@ Solde total actuel dans des adresses juste-regarder + + PaymentServer + PeerTableModel @@ -991,6 +1097,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1461,7 @@ Remove Retirer - + ReceiveRequestDialog @@ -1371,7 +1480,26 @@ &Save Image... &Enregistrer l'image... - + + Address + Adresse + + + Label + Étiquette + + + + RecentRequestsTableModel + + Label + Étiquette + + + (no label) + (aucune étiquette) + + SendCoinsDialog @@ -1522,6 +1650,10 @@ S&end E&nvoyer + + (no label) + (aucune étiquette) + SendCoinsEntry @@ -1601,7 +1733,10 @@ Memo: Mémo : - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1834,7 @@ Reset all verify message fields Réinitialiser tous les champs de vérification de message - + SplashScreen @@ -1714,13 +1849,46 @@ Ko/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - + + + TransactionTableModel + + Label + Étiquette + + + (no label) + (aucune étiquette) + + + + TransactionView + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + Label + Étiquette + + + Address + Adresse + + + Exporting Failed + L'exportation a échoué + + UnitDisplayStatusBarControl @@ -1728,6 +1896,15 @@ Unité d'affichage des montants. Cliquer pour choisir une autre unité. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index fca1e6288..e576f8d74 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -13,7 +13,10 @@ &Delete &Supprimer - + + + AddressTableModel + AskPassphraseDialog @@ -28,7 +31,7 @@ Repeat new passphrase Répéter Mot de Passe - + BanTableModel @@ -52,7 +55,7 @@ &Address Addresse - + FreespaceChecker @@ -75,12 +78,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -90,12 +99,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -108,12 +123,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index a6f6ac4fd..3fa055de2 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -41,7 +41,10 @@ &Delete &Supprimer - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Répétez la phrase de passe - + BanTableModel @@ -443,7 +446,7 @@ Priority Priorité - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adresse - + FreespaceChecker @@ -566,7 +569,7 @@ Select payment request file Sélectionner un fichier de demande de paiement - + OptionsDialog @@ -753,6 +756,9 @@ Transactions récentes + + PaymentServer + PeerTableModel @@ -807,6 +813,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1064,7 +1073,7 @@ Remove Retirer - + ReceiveRequestDialog @@ -1083,7 +1092,10 @@ &Save Image... &Sauvegarder image - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1241,7 +1253,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1310,16 +1325,34 @@ KO/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 9aa7b5509..3308c2401 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -37,7 +37,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repite novo contrasinal - + BanTableModel @@ -333,7 +336,7 @@ Priority Prioridade - + EditAddressDialog @@ -356,7 +359,7 @@ &Address &Dirección - + FreespaceChecker @@ -436,7 +439,7 @@ Select payment request file Seleccionar ficheiro de solicitude de pago - + OptionsDialog @@ -571,6 +574,9 @@ O teu balance actual total + + PaymentServer + PeerTableModel @@ -593,6 +599,9 @@ N/A + + QRImageWidget + RPCConsole @@ -749,7 +758,10 @@ &Save Image... &Gardar Imaxe... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -816,7 +828,7 @@ S&end &Enviar - + SendCoinsEntry @@ -871,7 +883,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -945,7 +960,7 @@ Reset all verify message fields Restaurar todos os campos de verificación de mensaxe - + SplashScreen @@ -960,16 +975,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Este panel amosa unha descripción detallada da transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 4a293c1c3..394cc3173 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -41,6 +41,69 @@ &Delete מ&חיקה + + Choose the address to send coins to + בחר את הכתובת אליה תרצה לשלוח את המטבעות + + + Choose the address to receive coins with + בחר את הכתובת בה תקבל את המטבעות + + + C&hoose + בחר + + + Sending addresses + כתובת לשליחה + + + Receiving addresses + מקבל כתובות + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + אלה הם כתובות הביטקוין שלך לשליחת תשלומים. חשוב לבדוק את הכמות של הכתובות המקבלות לפני שליחת מטבעות + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + אלה הן כתובות הביטקוין שלך לקבלת תשלומים. מומלץ להשתמש בכתובת חדשה לכל העברה. + + + &Copy Address + &העתק כתובת + + + Copy &Label + העתק &תוית + + + &Edit + &ערוך + + + Exporting Failed + יצוא נכשל + + + There was an error trying to save the address list to %1. Please try again. + אירעה שגיאה בעת הניסיון לשמור את רשימת הכתובת אל %1. נא לנסות שוב. + + + + AddressTableModel + + Label + תוית + + + Address + כתובת + + + (no label) + (ללא תוית) + AskPassphraseDialog @@ -60,7 +123,7 @@ Repeat new passphrase נא לחזור על מילת הצופן החדשה - + BanTableModel @@ -389,7 +452,11 @@ Priority עדיפות - + + (no label) + (ללא תוית) + + EditAddressDialog @@ -412,7 +479,7 @@ &Address &כתובת - + FreespaceChecker @@ -516,7 +583,7 @@ Select payment request file בחירת קובץ בקשת תשלום - + OptionsDialog @@ -775,6 +842,9 @@ המאזן הכולל הנוכחי בכתובות לצפייה בלבד + + PaymentServer + PeerTableModel @@ -825,6 +895,9 @@ %1 מילישניות + + QRImageWidget + RPCConsole @@ -1150,7 +1223,7 @@ Remove הסרה - + ReceiveRequestDialog @@ -1169,7 +1242,26 @@ &Save Image... &שמירת תמונה… - + + Address + כתובת + + + Label + תוית + + + + RecentRequestsTableModel + + Label + תוית + + + (no label) + (ללא תוית) + + SendCoinsDialog @@ -1300,6 +1392,10 @@ S&end &שליחה + + (no label) + (ללא תוית) + SendCoinsEntry @@ -1367,7 +1463,10 @@ Memo: תזכורת: - + + + SendConfirmationDialog + ShutdownWindow @@ -1453,7 +1552,7 @@ Reset all verify message fields איפוס כל שדות אימות ההודעה - + SplashScreen @@ -1468,13 +1567,42 @@ ק״ב/ש׳ + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction חלונית זו מציגה תיאור מפורט של ההעברה - + + + TransactionTableModel + + Label + תוית + + + (no label) + (ללא תוית) + + + + TransactionView + + Label + תוית + + + Address + כתובת + + + Exporting Failed + יצוא נכשל + + UnitDisplayStatusBarControl @@ -1482,6 +1610,15 @@ יחידת המידה להצגת הסכומים. יש ללחוץ כדי לבחור ביחידת מידה אחרת. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 86c53b4ce..1cb5cf17a 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -13,7 +13,10 @@ &Delete &मिटाए !! - + + + AddressTableModel + AskPassphraseDialog @@ -28,7 +31,7 @@ Repeat new passphrase दोबारा नया पहचान शब्द/अक्षर डालिए ! - + BanTableModel @@ -169,7 +172,7 @@ &Address &पता - + FreespaceChecker @@ -220,6 +223,9 @@ फार्म + + PaymentServer + PeerTableModel @@ -235,6 +241,9 @@ + + QRImageWidget + RPCConsole @@ -265,6 +274,9 @@ &पता कॉपी करे + + RecentRequestsTableModel + SendCoinsDialog @@ -319,6 +331,9 @@ प्राप्तकर्ता: + + SendConfirmationDialog + ShutdownWindow @@ -351,16 +366,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction ये खिड़की आपको लेन-देन का विस्तृत विवरण देगी ! - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index f5accfb0b..f770cf146 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -41,7 +41,34 @@ &Delete Iz&briši - + + Choose the address to send coins to + Odaberi adresu na koju šalješ novac + + + Choose the address to receive coins with + Odaberi adresu na koju primaš novac + + + C&hoose + &Odaberi + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca. + + + &Copy Address + &Kopiraj adresu + + + Exporting Failed + Izvoz neuspješan + + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +87,7 @@ Repeat new passphrase Ponovite novu lozinku - + BanTableModel @@ -411,7 +438,7 @@ Priority Prioriteta - + EditAddressDialog @@ -434,7 +461,7 @@ &Address &Adresa - + FreespaceChecker @@ -502,7 +529,7 @@ Select payment request file Izaberi datoteku zahtjeva za plaćanje - + OptionsDialog @@ -641,6 +668,9 @@ Ukupno: + + PaymentServer + PeerTableModel @@ -655,6 +685,9 @@ N/A + + QRImageWidget + RPCConsole @@ -791,7 +824,10 @@ &Save Image... &Spremi sliku... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -862,7 +898,7 @@ S&end &Pošalji - + SendCoinsEntry @@ -898,6 +934,9 @@ Primatelj plaćanja: + + SendConfirmationDialog + ShutdownWindow @@ -954,16 +993,38 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ovaj prozor prikazuje detaljni opis transakcije - + + + TransactionTableModel + + + TransactionView + + Exporting Failed + Izvoz neuspješan + + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 895e919c9..e5e0d1059 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -41,7 +41,10 @@ &Delete &Törlés - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Új jelszó újra - + BanTableModel @@ -439,7 +442,7 @@ Priority Prioritás - + EditAddressDialog @@ -462,7 +465,7 @@ &Address &Cím - + FreespaceChecker @@ -550,7 +553,7 @@ Select payment request file Fizetési kérelmi fájl kiválasztása - + OptionsDialog @@ -761,6 +764,9 @@ A legutóbbi tranzakciók + + PaymentServer + PeerTableModel @@ -811,6 +817,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1072,7 +1081,7 @@ Remove Eltávolítás - + ReceiveRequestDialog @@ -1091,7 +1100,10 @@ &Save Image... &Kép mentése - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1202,7 +1214,7 @@ S&end &Küldés - + SendCoinsEntry @@ -1249,7 +1261,10 @@ Memo: Jegyzet: - + + + SendConfirmationDialog + ShutdownWindow @@ -1330,16 +1345,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ez a mező a tranzakció részleteit mutatja - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index feb6f690c..f47ed16ba 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -41,7 +41,10 @@ &Delete &Hapus - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ulangi kata kunci baru - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritas - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Alamat - + FreespaceChecker @@ -578,7 +581,7 @@ Select payment request file Pilih data permintaan pembayaran - + OptionsDialog @@ -821,6 +824,9 @@ Jumlah saldo Anda sekarang + + PaymentServer + PeerTableModel @@ -851,6 +857,9 @@ T/S + + QRImageWidget + RPCConsole @@ -1070,7 +1079,7 @@ Remove Menghapus - + ReceiveRequestDialog @@ -1089,7 +1098,10 @@ &Save Image... &Simpan Gambaran... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1200,7 +1212,7 @@ S&end K&irim - + SendCoinsEntry @@ -1255,7 +1267,10 @@ Memo: Catatan Peringatan: - + + + SendConfirmationDialog + ShutdownWindow @@ -1329,7 +1344,7 @@ Reset all verify message fields Hapus semua bidang verifikasi pesan - + SplashScreen @@ -1344,16 +1359,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Jendela ini menampilkan deskripsi rinci dari transaksi tersebut - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 2d99b90c6..26615ecd2 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ripeti la nuova passphrase - + BanTableModel @@ -463,7 +466,7 @@ Priority Priorità - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Indirizzo - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Seleziona il file di richiesta di pagamento - + OptionsDialog @@ -934,6 +937,9 @@ Per specificare più URL separarli con una barra verticale "|". Saldo corrente totale negli indirizzi di sola lettura + + PaymentServer + PeerTableModel @@ -988,6 +994,9 @@ Per specificare più URL separarli con una barra verticale "|". %1 ms + + QRImageWidget + RPCConsole @@ -1349,7 +1358,7 @@ Per specificare più URL separarli con una barra verticale "|". Remove Rimuovi - + ReceiveRequestDialog @@ -1368,7 +1377,10 @@ Per specificare più URL separarli con una barra verticale "|". &Save Image... &Salva Immagine... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1519,7 +1531,7 @@ Per specificare più URL separarli con una barra verticale "|". S&end &Invia - + SendCoinsEntry @@ -1598,7 +1610,10 @@ Per specificare più URL separarli con una barra verticale "|". Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1696,7 +1711,7 @@ Per specificare più URL separarli con una barra verticale "|". Reset all verify message fields Reimposta tutti i campi della verifica messaggio - + SplashScreen @@ -1711,13 +1726,22 @@ Per specificare più URL separarli con una barra verticale "|". KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Questo pannello mostra una descrizione dettagliata della transazione - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1725,6 +1749,15 @@ Per specificare più URL separarli con una barra verticale "|". Unità con cui visualizzare gli importi. Clicca per selezionare un'altra unità. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1819,6 +1852,10 @@ Per specificare più URL separarli con una barra verticale "|". Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Byte equivalenti per ottimizzazione segnale dedicati a ritrasmissione ed estrazione (default: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Errore caricamento %s: Non puoi abilitare HD in un portafoglio non-HD già esistente @@ -1831,10 +1868,6 @@ Per specificare più URL separarli con una barra verticale "|". Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Forza la trasmissione della transazione dai peer presenti nella whitelist anche se violano le regole di trasmissione locali (default: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Regolazione della massima differenza media di tempo dei peer consentita. L'impostazione dell'orario locale può essere impostata in avanti o indietro di questa quantità. (default %u secondi) diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts index d17b267ba..10216a71f 100644 --- a/src/qt/locale/bitcoin_it_IT.ts +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -41,7 +41,10 @@ &Delete Cancella - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Ripeti nuova passphrase - + BanTableModel @@ -95,12 +98,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -114,12 +123,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -132,12 +147,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 63fb9d681..3ca1f3e4f 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -41,6 +41,77 @@ &Delete 削除(&D) + + Choose the address to send coins to + 先のアドレスを選択 + + + Choose the address to receive coins with + 支払いを受け取るアドレスを指定する + + + C&hoose + 選択 (&C) + + + Sending addresses + 送金用 + + + Receiving addresses + 受け取りアドレス + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + これらは支払いを受け取るためのビットコインアドレスです。トランザクションごとに新しい受け取り用アドレスを作成することが推奨されます。 + + + &Copy Address + アドレスをコピー (&C) + + + Copy &Label + ラベルをコピー (&L) + + + &Edit + 編集 (&E) + + + Export Address List + アドレス帳をエクスポート + + + Comma separated file (*.csv) + テキスト CSV (*.csv) + + + Exporting Failed + エクスポートに失敗しました + + + There was an error trying to save the address list to %1. Please try again. + トランザクション履歴を %1 へ保存する際にエラーが発生しました。再試行してください。 + + + + AddressTableModel + + Label + ラベル + + + Address + アドレス + + + (no label) + (ラベル無し) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase 新しいパスフレーズをもう一度 + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + ウォレットの新しいパスフレーズを入力してください。<br/><b>10文字以上のランダムな文字</b>で構成されたものか、<b>8単語以上の単語</b>で構成されたパスフレーズを使用してください。 + + + Encrypt wallet + ウォレットを暗号化する + + + This operation needs your wallet passphrase to unlock the wallet. + この操作はウォレットをアンロックするためにパスフレーズが必要です。 + + + Unlock wallet + ウォレットをアンロックする + + + This operation needs your wallet passphrase to decrypt the wallet. + この操作はウォレットの暗号化解除のためにパスフレーズが必要です。 + + + Decrypt wallet + ウォレットの暗号化を解除する + + + Change passphrase + パスフレーズの変更 + + + Enter the old passphrase and new passphrase to the wallet. + ウォレットの古いパスフレーズおよび新しいパスフレーズを入力してください。 + + + Confirm wallet encryption + ウォレットの暗号化を確認する + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: もしもあなたのウォレットを暗号化してパスフレーズを失ってしまったなら、<b>あなたの Bitcoin はすべて失われます</b>! + + + Are you sure you wish to encrypt your wallet? + 本当にウォレットを暗号化しますか? + + + Wallet encrypted + ウォレットは暗号化されました + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + 暗号化処理を完了させるため %1 をいますぐ終了します。ウォレットの暗号化では、コンピュータに感染したマルウェアなどによるビットコインの盗難から完全に守ることはできないことにご注意ください。 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 重要: 過去のウォレット ファイルのバックアップは、暗号化された新しいウォレット ファイルに取り替える必要があります。セキュリティ上の理由により、暗号化された新しいウォレットを使い始めると、暗号化されていないウォレット ファイルのバックアップはすぐに使えなくなります。 + + + Wallet encryption failed + ウォレットの暗号化に失敗しました + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 内部エラーによりウォレットの暗号化が失敗しました。ウォレットは暗号化されませんでした。 + + + The supplied passphrases do not match. + パスフレーズが同じではありません。 + + + Wallet unlock failed + ウォレットのアンロックに失敗しました + + + The passphrase entered for the wallet decryption was incorrect. + ウォレットの暗号化解除のパスフレーズが正しくありません。 + + + Wallet decryption failed + ウォレットの暗号化解除に失敗しました + + + Wallet passphrase was successfully changed. + ウォレットのパスフレーズの変更が成功しました。 + + + Warning: The Caps Lock key is on! + 警告: Caps Lock キーがオンになっています! + BanTableModel @@ -463,6 +622,150 @@ Priority 優先度 + + Copy address + アドレスをコピーする + + + Copy label + ラベルをコピーする + + + Copy amount + 総額のコピー + + + Copy transaction ID + 取引 ID をコピー + + + Lock unspent + 未使用トランザクションをロックする + + + Unlock unspent + 未使用トランザクションをアンロックする + + + Copy quantity + 数量をコピーする + + + Copy fee + 手数料をコピーする + + + Copy after fee + 手数料差引後の値をコピーする + + + Copy bytes + バイト数をコピーする + + + Copy priority + 優先度をコピーする + + + Copy dust + ダストをコピーする + + + Copy change + 釣り銭をコピー + + + highest + 最高 + + + higher + 非常に高 + + + high + + + + medium-high + 中〜高 + + + medium + + + + low-medium + 低〜中 + + + low + + + + lower + 非常に低 + + + lowest + 最低 + + + (%1 locked) + (%1 がロック済み) + + + none + なし + + + yes + はい + + + no + いいえ + + + This label turns red if the transaction size is greater than 1000 bytes. + トランザクションのサイズが1000バイトを超える場合にはこのラベルは赤色になります。 + + + This means a fee of at least %1 per kB is required. + これは少なくとも1kBあたり %1 の手数料が必要であることを意味します。 + + + Can vary +/- 1 byte per input. + ひとつの入力につき1バイト程度ずれることがあります。 + + + Transactions with higher priority are more likely to get included into a block. + より高い優先度を持つトランザクションの方がブロックに取り込まれやすくなります。 + + + This label turns red if the priority is smaller than "medium". + 優先度が「中」未満の場合、このラベルは赤色になります。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 少なくともひとつの受取額が現在のダスト閾値を下回る場合にはこのラベルは赤くなります。 + + + Can vary +/- %1 satoshi(s) per input. + ひとつの入力につき %1 satoshi 前後ずれることがあります。 + + + (no label) + (ラベル無し) + + + change from %1 (%2) + %1 (%2) からのおつり + + + (change) + (おつり) + EditAddressDialog @@ -486,6 +789,38 @@ &Address アドレス帳 (&A) + + New receiving address + 新しい受信アドレス + + + New sending address + 新しい送信アドレス + + + Edit receiving address + 入金アドレスを編集 + + + Edit sending address + 送信アドレスを編集 + + + The entered address "%1" is not a valid Bitcoin address. + 入力されたアドレス "%1" は無効な Bitcoin アドレスです。 + + + The entered address "%1" is already in the address book. + 入力されたアドレス "%1" は既にアドレス帳にあります。 + + + Could not unlock wallet. + ウォレットをアンロックできませんでした。 + + + New key generation failed. + 新しいキーの生成に失敗しました。 + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file 支払いリクエストファイルを選択してください + + Select payment request file to open + 開きたい支払いリクエストファイルを選択してください + OptionsDialog @@ -937,6 +1276,97 @@ 監視限定アドレス内の現在の全残高 + + PaymentServer + + Payment request error + 支払いのリクエストのエラーです + + + Cannot start bitcoin: click-to-pay handler + Bitcoin を起動できません: click-to-pay handler + + + URI handling + URI の操作 + + + Payment request fetch URL is invalid: %1 + 支払い要求の取得先URLが無効です: %1 + + + Invalid payment address %1 + 支払いのアドレス「%1」は無効です + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI を解析できません! これは無効な Bitcoin アドレスあるいや不正な形式の URI パラメーターによって引き起こされる場合があります。 + + + Payment request file handling + 支払いリクエストファイルを処理しています + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 支払いリクエストファイルを読み込めませんでした!無効な支払いリクエストファイルにより引き起こされた可能性があります。 + + + Payment request rejected + 支払い要求は拒否されました + + + Payment request network doesn't match client network. + 支払いリクエストのネットワークは現在のクライアントのネットワークに一致しません。 + + + Payment request expired. + 支払いリクエストの期限が切れました。 + + + Payment request is not initialized. + 支払いリクエストは開始されていません。 + + + Unverified payment requests to custom payment scripts are unsupported. + カスタム支払いスクリプトに対する、検証されていない支払いリクエストはサポートされていません。 + + + Invalid payment request. + 無効な支払いリクエスト。 + + + Requested payment amount of %1 is too small (considered dust). + 要求された支払額 %1 は少なすぎます (ダストとみなされてしまいます)。 + + + Refund from %1 + %1 からの返金 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + 支払リクエスト %1 は大きすぎます(%2バイトですが、%3バイトまでが許されています)。 + + + Error communicating with %1: %2 + %1: %2とコミュニケーション・エラーです + + + Payment request cannot be parsed! + 支払リクエストを読み込めませんでした! + + + Bad response from server %1 + サーバーの返事は無効 %1 + + + Network request error + ネットワーク・リクエストのエラーです + + + Payment acknowledged + 支払いは確認しました + + PeerTableModel @@ -991,6 +1421,25 @@ %1ミリ秒 + + QRImageWidget + + &Save Image... + 画像を保存(&S) + + + &Copy Image + 画像をコピー(&C) + + + Save QR Code + QR コードの保存 + + + PNG Image (*.png) + PNG画像ファイル(*.png) + + RPCConsole @@ -1352,6 +1801,18 @@ Remove 削除 + + Copy label + ラベルをコピーする + + + Copy message + メッセージをコピーする + + + Copy amount + 総額のコピー + ReceiveRequestDialog @@ -1371,6 +1832,73 @@ &Save Image... 画像を保存(&S) + + Request payment to %1 + %1 への支払いリクエストを行う + + + Payment information + 支払い情報 + + + URI + URI + + + Address + アドレス + + + Amount + 総額 + + + Label + ラベル + + + Message + メッセージ + + + Resulting URI too long, try to reduce the text for label / message. + URI が長くなり過ぎます。ラベルやメッセージのテキストを短くしてください。 + + + Error encoding URI into QR Code. + QR コード用の URI エンコードでエラー。 + + + + RecentRequestsTableModel + + Date + 日付 + + + Label + ラベル + + + Message + メッセージ + + + (no label) + (ラベル無し) + + + (no message) + (メッセージなし) + + + (no amount requested) + (金額指定なし) + + + Requested + 要求 + SendCoinsDialog @@ -1522,6 +2050,114 @@ S&end 送金 (&E) + + Copy quantity + 数量をコピーする + + + Copy amount + 総額のコピー + + + Copy fee + 手数料をコピーする + + + Copy after fee + 手数料差引後の値をコピーする + + + Copy bytes + バイト数をコピーする + + + Copy priority + 優先度をコピーする + + + Copy dust + ダストをコピーする + + + Copy change + 釣り銭をコピー + + + %1 to %2 + %1 から %2 + + + Are you sure you want to send? + 送ってよろしいですか? + + + added as transaction fee + 取引手数料として追加された + + + Total Amount %1 + 合計: %1 + + + or + または + + + Confirm send coins + コインを送る確認 + + + The recipient address is not valid. Please recheck. + 受取アドレスが不正です。再チェックしてください。 + + + The amount to pay must be larger than 0. + 支払額は0より大きくないといけません。 + + + The amount exceeds your balance. + 額が残高を超えています。 + + + The total exceeds your balance when the %1 transaction fee is included. + %1 の取引手数料を含めると額が残高を超えています。 + + + Duplicate address found: addresses should only be used once each. + 重複したアドレスが見つかりました: アドレスはそれぞれ一度のみ使用することができます。 + + + Transaction creation failed! + トラザクションの作成に失敗しました! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + トランザクションは拒否されました。wallet.dat のコピーを使い、そしてコピーしたウォレットからコインを使用したことがマークされなかったときなど、ウォレットのいくつかのコインがすでに使用されている場合に、このエラーは起こるかもしれません。 + + + A fee higher than %1 is considered an absurdly high fee. + %1 よりも高い手数料の場合、手数料が高すぎると判断されます。 + + + Payment request expired. + 支払いリクエストの期限が切れました。 + + + Pay only the required fee of %1 + 要求手数料 %1 のみを支払う + + + Warning: Invalid Bitcoin address + 警告:無効なBitcoinアドレスです + + + Warning: Unknown change address + 警告:未知のおつりアドレスです + + + (no label) + (ラベル無し) + SendCoinsEntry @@ -1601,6 +2237,17 @@ Memo: メモ: + + Enter a label for this address to add it to your address book + アドレス帳に追加するには、このアドレスのラベルを入力します + + + + SendConfirmationDialog + + Yes + はい + ShutdownWindow @@ -1699,6 +2346,58 @@ Reset all verify message fields 入力項目の内容をすべて消去します + + Click "Sign Message" to generate signature + 署名を作成するには"メッセージの署名"をクリック + + + The entered address is invalid. + 不正なアドレスが入力されました。 + + + Please check the address and try again. + アドレスを確かめてからもう一度試してください。 + + + The entered address does not refer to a key. + 入力されたアドレスに関連するキーがありません。 + + + Wallet unlock was cancelled. + ウォレットのアンロックはキャンセルされました。 + + + Private key for the entered address is not available. + 入力されたアドレスのプライベート キーが無効です。 + + + Message signing failed. + メッセージの署名に失敗しました。 + + + Message signed. + メッセージに署名しました。 + + + The signature could not be decoded. + 署名がデコードできません。 + + + Please check the signature and try again. + 署名を確認してからもう一度試してください。 + + + The signature did not match the message digest. + 署名はメッセージ ダイジェストと一致しませんでした。 + + + Message verification failed. + メッセージの検証に失敗しました。 + + + Message verified. + メッセージは検証されました。 + SplashScreen @@ -1714,12 +2413,457 @@ KB/s + + TransactionDesc + + Open for %n more block(s) + %n 以上のブロックを開く + + + Open until %1 + ユニット %1 を開く + + + conflicted with a transaction with %1 confirmations + %1 検証のトランザクションと衝突 + + + %1/offline + %1/オフライン + + + 0/unconfirmed, %1 + 0/未検証, %1 + + + in memory pool + メモリプール内 + + + not in memory pool + メモリプール外 + + + abandoned + 中止 + + + %1/unconfirmed + %1/未検証 + + + %1 confirmations + %1 確認 + + + Status + ステータス + + + , has not been successfully broadcast yet + まだブロードキャストが成功していません + + + , broadcast through %n node(s) + %n ノードにブロードキャスト + + + Date + 日付 + + + Source + ソース + + + Generated + 生成された + + + From + 送信 + + + unknown + 未確認 + + + To + 受信 + + + own address + 自分のアドレス + + + watch-only + 監視限定 + + + label + ラベル + + + Credit + クレジット + + + matures in %n more block(s) + %n 以上のブロックが満期 + + + not accepted + 承認されなかった + + + Debit + 引き落とし額 + + + Total debit + 総出金額 + + + Total credit + 総入金額 + + + Transaction fee + 取引手数料 + + + Net amount + 正味金額 + + + Message + メッセージ + + + Comment + コメント + + + Transaction ID + 取引 ID + + + Output index + 出力インデックス + + + Merchant + 商人 + + + 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. + 生成されたコインは使う前に%1のブロックを完成させる必要があります。あなたが生成した時、このブロックはブロック チェーンに追加されるネットワークにブロードキャストされました。チェーンに追加されるのが失敗した場合、状態が"不承認"に変更されて使えなくなるでしょう。これは、別のノードがあなたの数秒前にブロックを生成する場合に時々起こるかもしれません。 + + + Debug information + デバッグ情報 + + + Transaction + 取引 + + + Inputs + 入力 + + + Amount + 総額 + + + true + 正しい + + + false + 正しくない + + TransactionDescDialog This pane shows a detailed description of the transaction ここでは取引の詳細を表示しています + + Details for %1 + %1 の詳細 + + + + TransactionTableModel + + Date + 日付 + + + Type + タイプ + + + Label + ラベル + + + Open for %n more block(s) + %n 以上のブロックを開く + + + Open until %1 + ユニット %1 を開く + + + Offline + オフライン + + + Unconfirmed + 未検証 + + + Abandoned + 中止 + + + Confirming (%1 of %2 recommended confirmations) + 検証中(%2の推奨検証数のうち、%1検証が完了) + + + Confirmed (%1 confirmations) + 検証されました (%1 検証済み) + + + Conflicted + 衝突 + + + Immature (%1 confirmations, will be available after %2) + 未成熟(%1検証。%2検証完了後に使用可能となります) + + + This block was not received by any other nodes and will probably not be accepted! + このブロックは他のどのノードによっても受け取られないで、多分受け入れられないでしょう! + + + Generated but not accepted + 生成されましたが承認されませんでした + + + Received with + 送り主 + + + Received from + 送り主 + + + Sent to + 送り先 + + + Payment to yourself + 自分自身への支払い + + + Mined + 発掘した + + + watch-only + 監視限定 + + + (n/a) + (n/a) + + + (no label) + (ラベル無し) + + + Transaction status. Hover over this field to show number of confirmations. + 取引の状況。このフィールドの上にカーソルを置くと検証の数を表示します。 + + + Date and time that the transaction was received. + 取引を受信した日時。 + + + Type of transaction. + 取引の種類。 + + + Whether or not a watch-only address is involved in this transaction. + 監視限定アドレスがこのトランザクションに含まれているかどうか + + + User-defined intent/purpose of the transaction. + ユーザ定義のトランザクションの意図や目的。 + + + Amount removed from or added to balance. + 残高に追加または削除された総額。 + + + + TransactionView + + All + すべて + + + Today + 今日 + + + This week + 今週 + + + This month + 今月 + + + Last month + 先月 + + + This year + 今年 + + + Range... + 期間... + + + Received with + 送り主 + + + Sent to + 送り先 + + + To yourself + 自分自身 + + + Mined + 発掘した + + + Other + その他 + + + Enter address or label to search + 検索するアドレスまたはラベルを入力 + + + Min amount + 最小の額 + + + Abandon transaction + 取引の中止 + + + Copy address + アドレスをコピーする + + + Copy label + ラベルをコピーする + + + Copy amount + 総額のコピー + + + Copy transaction ID + 取引 ID をコピー + + + Copy raw transaction + 生トランザクションをコピー + + + Copy full transaction details + トランザクションの詳細すべてをコピー + + + Edit label + ラベルの編集 + + + Show transaction details + 取引の詳細を表示 + + + Export Transaction History + トランザクション履歴をエクスポートする + + + Comma separated file (*.csv) + テキスト CSV (*.csv) + + + Confirmed + 検証済み + + + Watch-only + 監視限定 + + + Date + 日付 + + + Type + タイプ + + + Label + ラベル + + + Address + アドレス + + + ID + ID + + + Exporting Failed + エクスポートに失敗しました + + + There was an error trying to save the transaction history to %1. + トランザクション履歴を %1 へ保存する際にエラーが発生しました。 + + + Exporting Successful + エクスポートに成功しました + + + The transaction history was successfully saved to %1. + トランザクション履歴は正常に%1に保存されました。 + + + Range: + 期間: + + + to + から + UnitDisplayStatusBarControl @@ -1728,6 +2872,55 @@ 金額を表示する際の単位。クリックすることで他の単位を選択します。 + + WalletFrame + + No wallet has been loaded. + ウォレットがロードされていません + + + + WalletModel + + Send Coins + コインを送る + + + + WalletView + + &Export + エクスポート (&E) + + + Export the data in the current tab to a file + ファイルに現在のタブのデータをエクスポート + + + Backup Wallet + ウォレットのバックアップ + + + Wallet Data (*.dat) + ウォレット データ (*.dat) + + + Backup Failed + バックアップに失敗しました + + + There was an error trying to save the wallet data to %1. + ウォレットデータを%1へ保存する際にエラーが発生しました。 + + + Backup Successful + バックアップ成功 + + + The wallet data was successfully saved to %1. + ウォレット データは正常に%1に保存されました。 + + bitcoin-core @@ -1846,10 +3039,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) 時間オフセット調整値のピア中央値に対する最大の許容値。ローカル時間の見込み値は、接続するピアにより前方ないし後方へ影響されます。(初期値: %u 秒) @@ -2111,6 +3300,10 @@ Specify wallet file (within data directory) ウォレットのファイルを指定 (データ・ディレクトリの中に) + + Starting network threads... + ネットワークのスレッドを起動しています... + The source code is available from %s. ソースコードは %s より入手可能です。 @@ -2195,6 +3388,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) トランザクションの中継、採掘および作成の際には、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u) diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 80508be8e..b2b9a58e5 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -37,7 +37,10 @@ &Delete &წაშლა - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase გაიმეორეთ ახალი ფრაზა-პაროლი - + BanTableModel @@ -353,7 +356,7 @@ Priority პრიორიტეტი - + EditAddressDialog @@ -376,7 +379,7 @@ &Address მის&ამართი - + FreespaceChecker @@ -456,7 +459,7 @@ Select payment request file გადახდის მოთხოვნის ფაილის არჩევა - + OptionsDialog @@ -639,6 +642,9 @@ თქვენი სრული მიმდინარე ბალანსი + + PaymentServer + PeerTableModel @@ -661,6 +667,9 @@ მიუწვდ. + + QRImageWidget + RPCConsole @@ -842,7 +851,7 @@ Remove წაშლა - + ReceiveRequestDialog @@ -861,7 +870,10 @@ &Save Image... გამო&სახულების შენახვა... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -952,7 +964,7 @@ S&end გაგ&ზავნა - + SendCoinsEntry @@ -1011,7 +1023,10 @@ Memo: შენიშვნა: - + + + SendConfirmationDialog + ShutdownWindow @@ -1089,7 +1104,7 @@ Reset all verify message fields ვერიფიკაციის ყველა ველის წაშლა - + SplashScreen @@ -1104,16 +1119,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction ტრანსაქციის დაწვრილებითი აღწერილობა - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index ff0252126..28c994958 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -25,7 +25,10 @@ &Delete Жою - + + + AddressTableModel + AskPassphraseDialog @@ -40,7 +43,7 @@ Repeat new passphrase Жаңа құпия сөзді қайта енгізу - + BanTableModel @@ -173,7 +176,7 @@ Priority Басымдық - + EditAddressDialog @@ -184,7 +187,7 @@ &Address Адрес - + FreespaceChecker @@ -211,6 +214,9 @@ OverviewPage + + PaymentServer + PeerTableModel @@ -221,6 +227,9 @@ Саны + + QRImageWidget + RPCConsole @@ -238,6 +247,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -268,6 +280,9 @@ Саны + + SendConfirmationDialog + ShutdownWindow @@ -280,12 +295,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 8aad8df46..3fc93b7e2 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -41,7 +41,10 @@ &Delete 삭제(&D) - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase 새로운 암호 재확인 - + BanTableModel @@ -463,7 +466,7 @@ Priority 우선순위 - + EditAddressDialog @@ -486,7 +489,7 @@ &Address 주소(&A) - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file 지불 요청 파일을 선택하세요 - + OptionsDialog @@ -937,6 +940,9 @@ 모니터링 지갑의 현재 잔액 + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1361,7 @@ Remove 삭제 - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... 이미지 저장(&S)... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end 보내기(&E) - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: 메모: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1714,7 @@ Reset all verify message fields 모든 검증 메시지 필드 재설정 - + SplashScreen @@ -1714,13 +1729,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction 이 창은 거래의 세부내역을 보여줍니다 - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1728,6 +1752,15 @@ 거래액을 표시하는 단위. 클릭해서 다른 단위를 선택할 수 있습니다. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1842,10 +1875,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 피어들이 로컬 중계 정책을 위반하더라도 화이트 리스트에 포함된 피어인경우 강제로 중계하기 (기본값: %d) - Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) 하나의 지갑 트랜잭션에서의 총 수수료(%s)의 최대치; 너무 낮게 설정하면 큰 트랜잭션이 중지 됩니다 (기본값: %s) diff --git a/src/qt/locale/bitcoin_ku_IQ.ts b/src/qt/locale/bitcoin_ku_IQ.ts index da5e41a35..9e52770aa 100644 --- a/src/qt/locale/bitcoin_ku_IQ.ts +++ b/src/qt/locale/bitcoin_ku_IQ.ts @@ -25,7 +25,10 @@ &Delete &سڕینەوە - + + + AddressTableModel + AskPassphraseDialog @@ -89,7 +92,7 @@ Priority لەپێشی - + EditAddressDialog @@ -135,6 +138,9 @@ گشتی + + PaymentServer + PeerTableModel @@ -145,6 +151,9 @@ سەرجەم + + QRImageWidget + RPCConsole @@ -202,10 +211,13 @@ Remove سڕینەوە - + ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -232,6 +244,9 @@ پەیام: + + SendConfirmationDialog + ShutdownWindow @@ -244,12 +259,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 14cb9c202..b9be5f8ec 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -9,7 +9,10 @@ &Delete Ө&чүрүү - + + + AddressTableModel + AskPassphraseDialog @@ -72,7 +75,7 @@ &Address &Дарек - + FreespaceChecker @@ -135,12 +138,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -182,6 +191,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -192,7 +204,7 @@ S&end &Жөнөтүү - + SendCoinsEntry @@ -204,6 +216,9 @@ Билдирүү: + + SendConfirmationDialog + ShutdownWindow @@ -224,12 +239,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index dc532fe01..4fff8c653 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -25,7 +25,10 @@ &Delete &Dele - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Itera novam tesseram - + BanTableModel @@ -276,7 +279,7 @@ &Address &Inscriptio - + FreespaceChecker @@ -427,6 +430,9 @@ Fossum pendendum quod nondum maturum est + + PaymentServer + PeerTableModel @@ -441,6 +447,9 @@ N/A + + QRImageWidget + RPCConsole @@ -530,6 +539,9 @@ &Copia Inscriptionem + + RecentRequestsTableModel + SendCoinsDialog @@ -572,7 +584,7 @@ S&end &Mitte - + SendCoinsEntry @@ -608,6 +620,9 @@ Pensa Ad: + + SendConfirmationDialog + ShutdownWindow @@ -677,7 +692,7 @@ Reset all verify message fields Reconstitue omnes campos verificandi nuntii - + SplashScreen @@ -688,16 +703,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Haec tabula monstrat descriptionem verbosam transactionis - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 1f6cda1f5..3ed8e2ca3 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -41,7 +41,10 @@ &Delete &Trinti - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Pakartokite naują slaptafrazę - + BanTableModel @@ -325,7 +328,7 @@ Priority Pirmumas - + EditAddressDialog @@ -340,7 +343,7 @@ &Address &Adresas - + FreespaceChecker @@ -539,6 +542,9 @@ Jūsų balansas + + PaymentServer + PeerTableModel @@ -561,6 +567,9 @@ nėra + + QRImageWidget + RPCConsole @@ -702,6 +711,9 @@ &Kopijuoti adresą + + RecentRequestsTableModel + SendCoinsDialog @@ -768,7 +780,7 @@ S&end &Siųsti - + SendCoinsEntry @@ -804,6 +816,9 @@ Mokėti gavėjui: + + SendConfirmationDialog + ShutdownWindow @@ -868,16 +883,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Šis langas sandorio detalų aprašymą - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 38333531e..ab528229c 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -37,7 +37,10 @@ &Delete &Dzēst - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Jaunā parole vēlreiz - + BanTableModel @@ -341,7 +344,7 @@ Priority Prioritāte - + EditAddressDialog @@ -356,7 +359,7 @@ &Address &Adrese - + FreespaceChecker @@ -436,7 +439,7 @@ Select payment request file Izvēlies maksājuma pieprasījuma datni - + OptionsDialog @@ -627,6 +630,9 @@ Jūsu kopējā tekošā bilance + + PaymentServer + PeerTableModel @@ -649,6 +655,9 @@ N/A + + QRImageWidget + RPCConsole @@ -810,7 +819,7 @@ Remove Noņemt - + ReceiveRequestDialog @@ -829,7 +838,10 @@ &Save Image... &Saglabāt Attēlu... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -916,7 +928,7 @@ S&end &Sūtīt - + SendCoinsEntry @@ -967,7 +979,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1041,7 +1056,7 @@ Reset all verify message fields Atiestatīt visus laukus - + SplashScreen @@ -1056,16 +1071,34 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Šis panelis parāda transakcijas detaļas - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts index b696111a5..dd1ce4d08 100644 --- a/src/qt/locale/bitcoin_mk_MK.ts +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -41,7 +41,10 @@ &Delete &Избриши - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Повторете ја новата тајна фраза - + BanTableModel @@ -287,7 +290,7 @@ Priority Приоритет - + EditAddressDialog @@ -302,7 +305,7 @@ &Address &Адреса - + FreespaceChecker @@ -381,6 +384,9 @@ Вкупно: + + PaymentServer + PeerTableModel @@ -411,6 +417,9 @@ %1 мс + + QRImageWidget + RPCConsole @@ -495,7 +504,10 @@ &Save Image... &Сними Слика... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -542,6 +554,9 @@ Порака: + + SendConfirmationDialog + ShutdownWindow @@ -554,12 +569,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index d9ef0d127..70b1b470d 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -37,7 +37,10 @@ &Delete &Устгах - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ Repeat new passphrase Шинэ нууц үгийг давтана уу - + BanTableModel @@ -212,7 +215,7 @@ &Address &Хаяг - + FreespaceChecker @@ -275,6 +278,9 @@ Хэрэглэж болох хэмжээ: + + PaymentServer + PeerTableModel @@ -289,6 +295,9 @@ Алга Байна + + QRImageWidget + RPCConsole @@ -370,7 +379,7 @@ Remove Устгах - + ReceiveRequestDialog @@ -378,6 +387,9 @@ Хаягийг &Хуулбарлах + + RecentRequestsTableModel + SendCoinsDialog @@ -424,7 +436,7 @@ S&end Яв&уул - + SendCoinsEntry @@ -460,6 +472,9 @@ Тѳлѳх хаяг: + + SendConfirmationDialog + ShutdownWindow @@ -492,16 +507,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Гүйлгээний дэлгэрэнгүйг энэ бичил цонх харуулж байна - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index acfb38e41..d680a5013 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -34,7 +34,10 @@ Alihkan fail data ke dalam tab semasa &Delete &Padam - + + + AddressTableModel + AskPassphraseDialog @@ -61,7 +64,7 @@ Alihkan fail data ke dalam tab semasa &Address Alamat - + FreespaceChecker @@ -80,12 +83,18 @@ Alihkan fail data ke dalam tab semasa OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -99,6 +108,9 @@ Alihkan fail data ke dalam tab semasa &Salin Alamat + + RecentRequestsTableModel + SendCoinsDialog @@ -109,6 +121,9 @@ Alihkan fail data ke dalam tab semasa SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -121,12 +136,30 @@ Alihkan fail data ke dalam tab semasa TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 7ec8c36d9..7ae530335 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -41,7 +41,10 @@ &Delete &Slett - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Gjenta ny adgangsfrase - + BanTableModel @@ -451,7 +454,7 @@ Priority Prioritet - + EditAddressDialog @@ -474,7 +477,7 @@ &Address &Adresse - + FreespaceChecker @@ -602,7 +605,7 @@ Select payment request file Velg fil for betalingsetterspørring - + OptionsDialog @@ -897,6 +900,9 @@ Nåværende totale balanse i kun observerbare adresser + + PaymentServer + PeerTableModel @@ -951,6 +957,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1300,7 +1309,7 @@ Remove Fjern - + ReceiveRequestDialog @@ -1319,7 +1328,10 @@ &Save Image... &Lagre Bilde... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1470,7 +1482,7 @@ S&end S&end - + SendCoinsEntry @@ -1549,7 +1561,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1643,7 +1658,7 @@ Reset all verify message fields Tilbakestill alle felter for meldingsverifikasjon - + SplashScreen @@ -1658,13 +1673,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Her vises en detaljert beskrivelse av transaksjonen - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1672,6 +1696,15 @@ Enhet å vise beløper i. Klikk for å velge en annen enhet. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ne.ts b/src/qt/locale/bitcoin_ne.ts index 6ffde979f..0cffd96f9 100644 --- a/src/qt/locale/bitcoin_ne.ts +++ b/src/qt/locale/bitcoin_ne.ts @@ -41,7 +41,10 @@ &Delete &amp;मेटाउनुहोस् - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase नयाँ पासफ्रेज दोहोर्याउनुहोस् - + BanTableModel @@ -255,6 +258,9 @@ हेर्ने-मात्र ठेगानामा रहेको हालको जम्मा ब्यालेन्स + + PaymentServer + PeerTableModel @@ -277,6 +283,9 @@ रकम + + QRImageWidget + RPCConsole @@ -294,6 +303,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -308,6 +320,9 @@ बिटकोइनमा संलग्न गरिएको सन्देश: तपाईंको मध्यस्थको लागि कारोबारको साथमा भण्डारण गरिने URI । नोट: यो सन्देश बिटकोइन नेटवर्क मार्फत पठाइने छैन । + + SendConfirmationDialog + ShutdownWindow @@ -324,12 +339,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 80de2103c..272714fc7 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -41,6 +41,77 @@ &Delete &Verwijder + + Choose the address to send coins to + Kies het adres om munten naar te versturen + + + Choose the address to receive coins with + Kies het adres om munten op te ontvangen + + + C&hoose + K&iezen + + + Sending addresses + Verzendadressen + + + Receiving addresses + Ontvangstadressen + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvangstadres voordat u uw bitcoins verzendt. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dit zijn uw Bitcoin-adressen waarmee u betalingen kunt ontvangen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. + + + &Copy Address + &Kopiëer Adres + + + Copy &Label + Kopieer &Label + + + &Edit + &Bewerk + + + Export Address List + Exporteer adreslijst + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + Exporting Failed + Export mislukt + + + There was an error trying to save the address list to %1. Please try again. + Een fout is opgetreden tijdens het opslaan van deze adreslijst naar %1. Probeer het nogmaals. + + + + AddressTableModel + + Label + Label + + + Address + Adres + + + (no label) + (geen label) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Herhaal nieuw wachtwoord + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Voer een nieuw wachtwoord in voor uw portemonnee.<br/>Gebruik een wachtwoord van <b>tien of meer willekeurige karakters</b>, of <b>acht of meer woorden</b>. + + + Encrypt wallet + Versleutel portemonnee + + + This operation needs your wallet passphrase to unlock the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te openen. + + + Unlock wallet + Open portemonnee + + + This operation needs your wallet passphrase to decrypt the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te ontsleutelen + + + Decrypt wallet + Ontsleutel portemonnee + + + Change passphrase + Wijzig wachtwoord + + + Enter the old passphrase and new passphrase to the wallet. + Voer het oude en nieuwe wachtwoord in voor uw portemonnee. + + + Confirm wallet encryption + Bevestig versleuteling van de portemonnee + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Waarschuwing: Als u uw portemonnee versleutelt en uw wachtwoord vergeet, zult u <b>AL UW BITCOINS VERLIEZEN</b>! + + + Are you sure you wish to encrypt your wallet? + Weet u zeker dat u uw portemonnee wilt versleutelen? + + + Wallet encrypted + Portemonnee versleuteld + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 zal nu afsluiten om het versleutelingsproces te voltooien. Onthoud dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + BELANGRIJK: Elke eerder gemaakte backup van uw portemonneebestand dient u te vervangen door het nieuw gegenereerde, versleutelde portemonneebestand. Om veiligheidsredenen zullen eerdere backups van het niet-versleutelde portemonneebestand onbruikbaar worden zodra u uw nieuwe, versleutelde, portemonnee begint te gebruiken. + + + Wallet encryption failed + Portemonneeversleuteling mislukt + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Portemonneeversleuteling mislukt door een interne fout. Uw portemonnee is niet versleuteld. + + + The supplied passphrases do not match. + De opgegeven wachtwoorden komen niet overeen + + + Wallet unlock failed + Portemonnee openen mislukt + + + The passphrase entered for the wallet decryption was incorrect. + Het opgegeven wachtwoord voor de portemonnee-ontsleuteling is niet correct. + + + Wallet decryption failed + Portemonnee-ontsleuteling mislukt + + + Wallet passphrase was successfully changed. + Portemonneewachtwoord is met succes gewijzigd. + + + Warning: The Caps Lock key is on! + Waarschuwing: De Caps-Lock-toets staat aan! + BanTableModel @@ -463,6 +622,150 @@ Priority Prioriteit + + Copy address + Kopieer adres + + + Copy label + Kopieer label + + + Copy amount + Kopieer bedrag + + + Copy transaction ID + Kopieer transactie-ID + + + Lock unspent + Blokeer ongebruikte + + + Unlock unspent + Deblokkeer ongebruikte + + + Copy quantity + Kopieer aantal + + + Copy fee + Kopieer vergoeding + + + Copy after fee + Kopieer na vergoeding + + + Copy bytes + Kopieer bytes + + + Copy priority + Kopieer prioriteit + + + Copy dust + Kopieër stof + + + Copy change + Kopieer wijziging + + + highest + hoogste + + + higher + hoger + + + high + hoog + + + medium-high + gemiddeld hoog + + + medium + gemiddeld + + + low-medium + laag gemiddeld + + + low + laag + + + lower + lager + + + lowest + laagste + + + (%1 locked) + (%1 geblokkeerd) + + + none + geen + + + yes + ja + + + no + nee + + + This label turns red if the transaction size is greater than 1000 bytes. + Dit label wordt rood als de transactie groter is dan 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Dit betekent dat een vergoeding van minimaal %1 per kB nodig is. + + + Can vary +/- 1 byte per input. + Kan +/- 1 byte per invoer variëren. + + + Transactions with higher priority are more likely to get included into a block. + Transacties met een hogere prioriteit zullen eerder in een blok gezet worden. + + + This label turns red if the priority is smaller than "medium". + Dit label wordt rood als de prioriteit lager is dan "gemiddeld". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Dit label wordt rood, als een ontvanger een bedrag van minder dan de huidige dust-drempel gekregen heeft. + + + Can vary +/- %1 satoshi(s) per input. + Kan per input +/- %1 satoshi(s) variëren. + + + (no label) + (geen label) + + + change from %1 (%2) + wijzig van %1 (%2) + + + (change) + (wijzig) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Adres + + New receiving address + Nieuw ontvangstadres + + + New sending address + Nieuw verzendadres + + + Edit receiving address + Bewerk ontvangstadres + + + Edit sending address + Bewerk verzendadres + + + The entered address "%1" is not a valid Bitcoin address. + Het opgegeven adres "%1" is een ongeldig Bitcoinadres. + + + The entered address "%1" is already in the address book. + Het opgegeven adres "%1" bestaat al in uw adresboek. + + + Could not unlock wallet. + Kon de portemonnee niet openen. + + + New key generation failed. + Genereren nieuwe sleutel mislukt. + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file Selecteer betalingsverzoek bestand + + Select payment request file to open + Selecteer betalingsverzoekbestand om te openen + OptionsDialog @@ -937,6 +1276,97 @@ Huidige balans in alleen-bekijkbare adressen. + + PaymentServer + + Payment request error + Fout bij betalingsverzoek + + + Cannot start bitcoin: click-to-pay handler + Kan bitcoin niet starten: click-to-pay handler + + + URI handling + URI-behandeling + + + Payment request fetch URL is invalid: %1 + URL om betalingsverzoek te verkrijgen is ongeldig: %1 + + + Invalid payment address %1 + Ongeldig betalingsadres %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters. + + + Payment request file handling + Betalingsverzoek bestandsafhandeling + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoekbestand. + + + Payment request rejected + Betalingsverzoek geweigerd + + + Payment request network doesn't match client network. + Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk. + + + Payment request expired. + Betalingsverzoek verlopen. + + + Payment request is not initialized. + Betalingsaanvraag is niet geïnitialiseerd. + + + Unverified payment requests to custom payment scripts are unsupported. + Niet-geverifieerde betalingsverzoeken naar aangepaste betalingsscripts worden niet ondersteund. + + + Invalid payment request. + Ongeldig betalingsverzoek. + + + Requested payment amount of %1 is too small (considered dust). + Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof). + + + Refund from %1 + Restitutie van %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Betalingsverzoek %1 is te groot (%2 bytes, toegestaan ​​%3 bytes). + + + Error communicating with %1: %2 + Fout bij communiceren met %1: %2 + + + Payment request cannot be parsed! + Betalingsverzoek kan niet worden verwerkt! + + + Bad response from server %1 + Ongeldige respons van server %1 + + + Network request error + Fout bij netwerkverzoek + + + Payment acknowledged + Betaling bevestigd + + PeerTableModel @@ -991,6 +1421,25 @@ %1 ms + + QRImageWidget + + &Save Image... + &Sla afbeelding op... + + + &Copy Image + &Afbeelding kopiëren + + + Save QR Code + Sla QR-code op + + + PNG Image (*.png) + PNG afbeelding (*.png) + + RPCConsole @@ -1352,6 +1801,18 @@ Remove Verwijder + + Copy label + Kopieer label + + + Copy message + Kopieer bericht + + + Copy amount + Kopieer bedrag + ReceiveRequestDialog @@ -1371,6 +1832,73 @@ &Save Image... &Sla afbeelding op... + + Request payment to %1 + Betalingsverzoek tot %1 + + + Payment information + Betalingsinformatie + + + URI + URI + + + Address + Adres + + + Amount + Bedrag + + + Label + Label + + + Message + Bericht + + + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI te lang, probeer de tekst korter te maken voor het label/bericht. + + + Error encoding URI into QR Code. + Fout tijdens encoderen URI in QR-code + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Label + + + Message + Bericht + + + (no label) + (geen label) + + + (no message) + (geen bericht) + + + (no amount requested) + (geen bedrag aangevraagd) + + + Requested + Verzoek ingediend + SendCoinsDialog @@ -1522,6 +2050,110 @@ S&end V&erstuur + + Copy quantity + Kopieer aantal + + + Copy amount + Kopieer bedrag + + + Copy fee + Kopieer vergoeding + + + Copy after fee + Kopieer na vergoeding + + + Copy bytes + Kopieer bytes + + + Copy priority + Kopieer prioriteit + + + Copy dust + Kopieër stof + + + Copy change + Kopieer wijziging + + + %1 to %2 + %1 tot %2 + + + Are you sure you want to send? + Weet u zeker dat u wilt verzenden? + + + added as transaction fee + toegevoegd als transactiekosten + + + Total Amount %1 + Totaalbedrag %1 + + + or + of + + + Confirm send coins + Bevestig versturen munten + + + The recipient address is not valid. Please recheck. + Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren. + + + The amount to pay must be larger than 0. + Het ingevoerde bedrag moet groter zijn dan 0. + + + The amount exceeds your balance. + Het bedrag is hoger dan uw huidige saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + Het totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend. + + + Duplicate address found: addresses should only be used once each. + Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden. + + + Transaction creation failed! + Transactiecreatie mislukt + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet. + + + Payment request expired. + Betalingsverzoek verlopen. + + + Pay only the required fee of %1 + Betaal alleen de verplichte transactiekosten van %1 + + + Warning: Invalid Bitcoin address + Waarschuwing: Ongeldig Bitcoinadres + + + Warning: Unknown change address + Waarschuwing: Onbekend wisselgeldadres + + + (no label) + (geen label) + SendCoinsEntry @@ -1601,6 +2233,17 @@ Memo: Memo: + + Enter a label for this address to add it to your address book + Vul een label in voor dit adres om het toe te voegen aan uw adresboek + + + + SendConfirmationDialog + + Yes + Ja + ShutdownWindow @@ -1699,6 +2342,58 @@ Reset all verify message fields Verwijder alles in de invulvelden + + Click "Sign Message" to generate signature + Klik op "Onderteken Bericht" om de handtekening te genereren + + + The entered address is invalid. + Het opgegeven adres is ongeldig. + + + Please check the address and try again. + Controleer het adres en probeer het opnieuw. + + + The entered address does not refer to a key. + Het opgegeven adres verwijst niet naar een sleutel. + + + Wallet unlock was cancelled. + Portemonnee-ontsleuteling is geannuleerd. + + + Private key for the entered address is not available. + Geheime sleutel voor het ingevoerde adres is niet beschikbaar. + + + Message signing failed. + Ondertekenen van het bericht is mislukt. + + + Message signed. + Bericht ondertekend. + + + The signature could not be decoded. + De handtekening kon niet worden gedecodeerd. + + + Please check the signature and try again. + Controleer de handtekening en probeer het opnieuw. + + + The signature did not match the message digest. + De handtekening hoort niet bij het bericht. + + + Message verification failed. + Berichtverificatie mislukt. + + + Message verified. + Bericht geverifiëerd. + SplashScreen @@ -1714,12 +2409,457 @@ KB/s + + TransactionDesc + + Open for %n more block(s) + Open voor nog %n blok(ken)Open voor nog %n blok(ken) + + + Open until %1 + Open tot %1 + + + conflicted with a transaction with %1 confirmations + geconflicteerd met een transactie met %1 confirmaties + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/onbevestigd, %1 + + + in memory pool + in geheugenpoel + + + not in memory pool + niet in geheugenpoel + + + abandoned + opgegeven + + + %1/unconfirmed + %1/onbevestigd + + + %1 confirmations + %1 bevestigingen + + + Status + Status + + + , has not been successfully broadcast yet + , is nog niet met succes uitgezonden + + + , broadcast through %n node(s) + , uitgezonden naar %n node(s), uitgezonden naar %n node(s) + + + Date + Datum + + + Source + Bron + + + Generated + Gegenereerd + + + From + Van + + + unknown + onbekend + + + To + Aan + + + own address + eigen adres + + + watch-only + alleen-bekijkbaar + + + label + label + + + Credit + Credit + + + matures in %n more block(s) + komt beschikbaar na %n nieuwe blokkenkomt beschikbaar na %n nieuwe blokken + + + not accepted + niet geaccepteerd + + + Debit + Debet + + + Total debit + Totaal debit + + + Total credit + Totaal credit + + + Transaction fee + Transactiekosten + + + Net amount + Netto bedrag + + + Message + Bericht + + + Comment + Opmerking + + + Transaction ID + Transactie-ID + + + Output index + Output index + + + Merchant + Handelaar + + + 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. + Gegenereerde munten moeten %1 blokken rijpen voordat ze kunnen worden besteed. Toen dit blok gegenereerd werd, werd het uitgezonden naar het netwerk om aan de blokketen toegevoegd te worden. Als het niet lukt om in de keten toegevoegd te worden, zal de status te veranderen naar "niet geaccepteerd" en zal het niet besteedbaar zijn. Dit kan soms gebeuren als een ander knooppunt een blok genereert binnen een paar seconden na die van u. + + + Debug information + Debug-informatie + + + Transaction + Transactie + + + Inputs + Inputs + + + Amount + Bedrag + + + true + waar + + + false + onwaar + + TransactionDescDialog This pane shows a detailed description of the transaction Dit venster laat een uitgebreide beschrijving van de transactie zien + + Details for %1 + Details voor %1 + + + + TransactionTableModel + + Date + Datum + + + Type + Type + + + Label + Label + + + Open for %n more block(s) + Open voor nog %n blok(ken)Open voor nog %n blok(ken) + + + Open until %1 + Open tot %1 + + + Offline + Offline + + + Unconfirmed + Onbevestigd + + + Abandoned + Opgegeven + + + Confirming (%1 of %2 recommended confirmations) + Bevestigen (%1 van %2 aanbevolen bevestigingen) + + + Confirmed (%1 confirmations) + Bevestigd (%1 bevestigingen) + + + Conflicted + Conflicterend + + + Immature (%1 confirmations, will be available after %2) + Niet beschikbaar (%1 bevestigingen, zal beschikbaar zijn na %2) + + + This block was not received by any other nodes and will probably not be accepted! + Dit blok is niet ontvangen bij andere nodes en zal waarschijnlijk niet worden geaccepteerd! + + + Generated but not accepted + Gegenereerd maar niet geaccepteerd + + + Received with + Ontvangen met + + + Received from + Ontvangen van + + + Sent to + Verzonden aan + + + Payment to yourself + Betaling aan uzelf + + + Mined + Gedolven + + + watch-only + alleen-bekijkbaar + + + (n/a) + (nvt) + + + (no label) + (geen label) + + + Transaction status. Hover over this field to show number of confirmations. + Transactiestatus. Houd de cursor boven dit veld om het aantal bevestigingen te laten zien. + + + Date and time that the transaction was received. + Datum en tijd waarop deze transactie is ontvangen. + + + Type of transaction. + Type transactie. + + + Whether or not a watch-only address is involved in this transaction. + Of er een alleen-bekijken-adres is betrokken bij deze transactie. + + + User-defined intent/purpose of the transaction. + Door gebruiker gedefinieerde intentie/doel van de transactie. + + + Amount removed from or added to balance. + Bedrag verwijderd van of toegevoegd aan saldo. + + + + TransactionView + + All + Alles + + + Today + Vandaag + + + This week + Deze week + + + This month + Deze maand + + + Last month + Vorige maand + + + This year + Dit jaar + + + Range... + Bereik... + + + Received with + Ontvangen met + + + Sent to + Verzonden aan + + + To yourself + Aan uzelf + + + Mined + Gedolven + + + Other + Anders + + + Enter address or label to search + Vul adres of label in om te zoeken + + + Min amount + Min. bedrag + + + Abandon transaction + Doe afstand van transactie + + + Copy address + Kopieer adres + + + Copy label + Kopieer label + + + Copy amount + Kopieer bedrag + + + Copy transaction ID + Kopieer transactie-ID + + + Copy raw transaction + Kopieer ruwe transactie + + + Copy full transaction details + Kopieer volledige transactiedetials + + + Edit label + Bewerk label + + + Show transaction details + Toon transactiedetails + + + Export Transaction History + Exporteer transactiegeschiedenis + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + Confirmed + Bevestigd + + + Watch-only + Alleen-bekijkbaar + + + Date + Datum + + + Type + Type + + + Label + Label + + + Address + Adres + + + ID + ID + + + Exporting Failed + Export mislukt + + + There was an error trying to save the transaction history to %1. + Er is een fout opgetreden bij het opslaan van de transactiegeschiedenis naar %1. + + + Exporting Successful + Export succesvol + + + The transaction history was successfully saved to %1. + De transactiegeschiedenis was succesvol bewaard in %1. + + + Range: + Bereik: + + + to + naar + UnitDisplayStatusBarControl @@ -1728,6 +2868,55 @@ Eenheid om bedragen uit te drukken. Klik om een andere eenheid te selecteren. + + WalletFrame + + No wallet has been loaded. + Er is geen portemonnee geladen. + + + + WalletModel + + Send Coins + Verstuur munten + + + + WalletView + + &Export + &Exporteer + + + Export the data in the current tab to a file + Exporteer de data in de huidige tab naar een bestand + + + Backup Wallet + Portemonnee backuppen + + + Wallet Data (*.dat) + Portemonneedata (*.dat) + + + Backup Failed + Backup mislukt + + + There was an error trying to save the wallet data to %1. + Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1. + + + Backup Successful + Backup succesvol + + + The wallet data was successfully saved to %1. + De portemonneedata is succesvol opgeslagen in %1. + + bitcoin-core @@ -1842,10 +3031,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuur regels (standaard: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximum toegestane peer tijd compensatie. Lokaal perspectief van tijd mag worden beinvloed door peers die met deze hoeveelheid voor of achter lopen. (standaard: %u seconden) @@ -2102,6 +3287,10 @@ Specify wallet file (within data directory) Specificeer het portemonnee bestand (vanuit de gegevensmap) + + Starting network threads... + Netwerkthread starten... + The source code is available from %s. De broncode is beschikbaar van %s. @@ -2186,6 +3375,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Transactiekosten (in %s/kB) kleiner dan dit worden beschouw dat geen transactiekosten in rekening worden gebracht voor doorgeven, mijnen en transactiecreatie (standaard: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuurregels (standaard: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Als paytxfee niet is ingesteld, voeg voldoende transactiekosten toe zodat transacties starten met bevestigingen binnen in n blokken (standaard: %u) diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 535154333..674c1b1d9 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -33,7 +33,10 @@ &Delete &Ilako - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ Repeat new passphrase Pasibayuan ya ing bayung passphrase - + BanTableModel @@ -256,7 +259,7 @@ &Address &Address - + FreespaceChecker @@ -411,6 +414,9 @@ Ing kekang kasalungsungan kabuuang balanse + + PaymentServer + PeerTableModel @@ -425,6 +431,9 @@ N/A + + QRImageWidget + RPCConsole @@ -510,6 +519,9 @@ &Kopyan ing address + + RecentRequestsTableModel + SendCoinsDialog @@ -552,7 +564,7 @@ S&end Ipadala - + SendCoinsEntry @@ -588,6 +600,9 @@ Ibayad kang: + + SendConfirmationDialog + ShutdownWindow @@ -657,7 +672,7 @@ Reset all verify message fields Ibalik king dati reng ngan fields na ning pamag beripikang mensayi - + SplashScreen @@ -668,16 +683,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ining pane a ini magpakit yang detalyadung description ning transaksion - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index b902e69f5..57c336c85 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -41,7 +41,10 @@ &Delete &Usuń - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Powtórz nowe hasło - + BanTableModel @@ -463,7 +466,7 @@ Priority Priorytet - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Adres - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Otwórz żądanie zapłaty z pliku - + OptionsDialog @@ -937,6 +940,9 @@ Łączna kwota na podglądanych adresach + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1361,7 @@ Remove Usuń - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... &Zapisz obraz... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end Wy&syłka - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: Notatka: - + + + SendConfirmationDialog + ShutdownWindow @@ -1700,7 +1715,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Reset all verify message fields Resetuje wszystkie pola weryfikacji wiadomości - + SplashScreen @@ -1715,13 +1730,22 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ten panel pokazuje szczegółowy opis transakcji - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1729,6 +1753,15 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Jednostka w jakiej pokazywane są kwoty. Kliknij aby wybrać inną. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1823,10 +1856,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Wymuś przekazywanie transakcji od osób z białej listy, nawet jeśli narusza to lokalną politykę przekazywania (default: %d) - Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, %s nie będzie działał prawidłowo. diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 12da991ad..2dbd28dc6 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -23,7 +23,7 @@ C&lose - &Fechar + Fechar Delete the currently selected address from the list @@ -41,7 +41,10 @@ &Delete &Excluir - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repita a nova frase de segurança - + BanTableModel @@ -463,7 +466,7 @@ Priority Prioridade - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Endereço - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Selecione o arquivo de cobrança - + OptionsDialog @@ -937,6 +940,9 @@ Balanço total em endereços monitorados + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1361,7 @@ Remove Remover - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... &Salvar Imagem... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end Enviar - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: Memorizar: - + + + SendConfirmationDialog + ShutdownWindow @@ -1695,7 +1710,7 @@ Reset all verify message fields Limpar todos os campos de assinatura da mensagem - + SplashScreen @@ -1710,13 +1725,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Este painel mostra uma descrição detalhada da transação - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1724,6 +1748,15 @@ Unidade para mostrar. Clique para selecionar outra unidade. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1834,13 +1867,9 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) - A mediana máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos) + A media máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos) Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) @@ -1918,6 +1947,10 @@ Cannot resolve -%s address: '%s' Impossível resolver -%s endereço: '%s' + + Change index out of range + Índice de mudança fora da faixa. + Connect only to the specified node(s) Conectar apenas a cliente(s) específico(s) @@ -2056,7 +2089,7 @@ Print version and exit - Mostra a versão e sai + Imprimir versão e sair Prune cannot be configured with a negative value. diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 834067897..cbecf9058 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -41,7 +41,10 @@ &Delete &Eliminar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repita a nova frase de palavra-passe - + BanTableModel @@ -455,7 +458,7 @@ Priority Prioridade - + EditAddressDialog @@ -478,7 +481,7 @@ &Address E&ndereço - + FreespaceChecker @@ -606,7 +609,7 @@ Select payment request file Seleccione o ficheiro de pedido de pagamento - + OptionsDialog @@ -910,6 +913,9 @@ Saldo disponivél em enderços modo-verificação + + PaymentServer + PeerTableModel @@ -964,6 +970,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1317,7 +1326,7 @@ Remove Remover - + ReceiveRequestDialog @@ -1336,7 +1345,10 @@ &Save Image... &Salvar Imagem... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1487,7 +1499,7 @@ S&end E&nviar - + SendCoinsEntry @@ -1566,7 +1578,10 @@ Memo: Memorando: - + + + SendConfirmationDialog + ShutdownWindow @@ -1664,7 +1679,7 @@ Reset all verify message fields Repor todos os campos de verificação de mensagem - + SplashScreen @@ -1679,13 +1694,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Esta janela mostra uma descrição detalhada da transação - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1693,6 +1717,15 @@ Unidade de valores recebidos. Clique para selecionar outra unidade. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1791,10 +1824,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Forçar retransmissão das transações a partir dos pares da lista branca, mesmo que estes violem a política de retransmissão local (predefinição: %d) - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Defina o número de processos de verificação (%u até %d, 0 = automático, <0 = ldisponibiliza esse número de núcleos livres, por defeito: %d) diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index 9f6ba2709..d1f17e29c 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -41,7 +41,10 @@ &Delete Șterge - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetati noua parolă - + BanTableModel @@ -353,7 +356,7 @@ Priority Prioritate - + EditAddressDialog @@ -364,7 +367,7 @@ &Address &Adresa - + FreespaceChecker @@ -527,6 +530,9 @@ Tranzacții recente + + PaymentServer + PeerTableModel @@ -537,6 +543,9 @@ Cantitate + + QRImageWidget + RPCConsole @@ -650,14 +659,17 @@ Remove Elimină - + ReceiveRequestDialog &Save Image... &Salvează imaginea... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -692,6 +704,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -704,12 +719,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index afd3cc5f1..a16a497fb 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -41,7 +41,10 @@ &Delete &Şterge - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetaţi noua frază de acces - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritate - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adresă - + FreespaceChecker @@ -582,7 +585,7 @@ Select payment request file Selectaţi fişierul cerere de plată - + OptionsDialog @@ -857,6 +860,9 @@ Soldul dvs. total în adresele doar-supraveghere + + PaymentServer + PeerTableModel @@ -911,6 +917,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1216,7 +1225,7 @@ Remove Înlătură - + ReceiveRequestDialog @@ -1235,7 +1244,10 @@ &Save Image... &Salvează imaginea... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1366,7 +1378,7 @@ S&end Trimit&e - + SendCoinsEntry @@ -1429,7 +1441,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1519,7 +1534,7 @@ Reset all verify message fields Resetează toate cîmpurile mesajelor semnate - + SplashScreen @@ -1534,13 +1549,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Acest panou arată o descriere detaliată a tranzacţiei - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1548,6 +1572,15 @@ Unitatea în care sînt arătate sumele. Faceţi clic pentru a selecta o altă unitate. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 25fe77bee..5e1a5ee9d 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -41,6 +41,77 @@ &Delete &Удалить + + Choose the address to send coins to + Выберите адрес для отправки перевода + + + Choose the address to receive coins with + Выберите адрес для получения перевода + + + C&hoose + &Выбрать + + + Sending addresses + Адреса отправки + + + Receiving addresses + Адреса получения + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте количество и адрес получателя перед отправкой перевода. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Это ваши адреса Bitcoin для приёма платежей. Рекомендуется использовать новый адрес получения для каждой транзакции. + + + &Copy Address + Копировать &адрес + + + Copy &Label + Копировать &метку + + + &Edit + &Правка + + + Export Address List + Экспортировать список адресов + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + Exporting Failed + Экспорт не удался + + + There was an error trying to save the address list to %1. Please try again. + Произошла ошибка при сохранении списка адресов в %1. Пожалуйста, попробуйте еще раз. + + + + AddressTableModel + + Label + Метка + + + Address + Адрес + + + (no label) + (нет метки) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Повторите новый пароль + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Введите новый пароль бумажника.<br/>Используйте пароль, состоящий из <b>десяти или более случайных символов</b>, или <b>восьми или более слов</b>. + + + Encrypt wallet + Зашифровать бумажник + + + This operation needs your wallet passphrase to unlock the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + Unlock wallet + Разблокировать бумажник + + + This operation needs your wallet passphrase to decrypt the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + Decrypt wallet + Расшифровать бумажник + + + Change passphrase + Сменить пароль + + + Enter the old passphrase and new passphrase to the wallet. + Введите старый и новый пароль для бумажника. + + + Confirm wallet encryption + Подтвердите шифрование бумажника + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Предупреждение: если вы зашифруете бумажник и потеряете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОИНЫ</b>! + + + Are you sure you wish to encrypt your wallet? + Вы уверены, что хотите зашифровать ваш бумажник? + + + Wallet encrypted + Бумажник зашифрован + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Сейчас %1 закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник. + + + Wallet encryption failed + Не удалось зашифровать бумажник + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Шифрование бумажника не удалось из-за внутренней ошибки. Ваш бумажник не был зашифрован. + + + The supplied passphrases do not match. + Введённые пароли не совпадают. + + + Wallet unlock failed + Разблокировка бумажника не удалась + + + The passphrase entered for the wallet decryption was incorrect. + Неверный пароль для расшифровки бумажника. + + + Wallet decryption failed + Расшифровка бумажника не удалась + + + Wallet passphrase was successfully changed. + Пароль бумажника успешно изменён. + + + Warning: The Caps Lock key is on! + Внимание: Caps Lock включен! + BanTableModel @@ -463,6 +622,150 @@ Priority Приоритет + + Copy address + Копировать адрес + + + Copy label + Копировать метку + + + Copy amount + Копировать сумму + + + Copy transaction ID + Копировать ID транзакции + + + Lock unspent + Заблокировать непотраченное + + + Unlock unspent + Разблокировать непотраченное + + + Copy quantity + Копировать количество + + + Copy fee + Копировать комиссию + + + Copy after fee + Копировать после комиссии + + + Copy bytes + Копировать байты + + + Copy priority + Копировать приоритет + + + Copy dust + Копировать пыль + + + Copy change + Копировать сдачу + + + highest + самый высокий + + + higher + выше + + + high + высокий + + + medium-high + выше среднего + + + medium + средний + + + low-medium + ниже среднего + + + low + низкий + + + lower + ниже + + + lowest + самый низкий + + + (%1 locked) + (%1 заблокировано) + + + none + ничего + + + yes + да + + + no + нет + + + This label turns red if the transaction size is greater than 1000 bytes. + Эта метка станет красной, если размер транзакции будет больше 1000 байт. + + + This means a fee of at least %1 per kB is required. + Это значит, что требуется комиссия как минимум %1 на КБ. + + + Can vary +/- 1 byte per input. + Может отличаться на +/- 1 байт на вход. + + + Transactions with higher priority are more likely to get included into a block. + Транзакции с более высоким приоритетом будут вероятнее других включены в блок. + + + This label turns red if the priority is smaller than "medium". + Эта метка станет красной, если приоритет будет ниже "среднего". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Эта метка станет красной, если любой получатель получит сумму меньше, чем текущий порог пыли. + + + Can vary +/- %1 satoshi(s) per input. + Может отличаться на +/- %1 сатоши на вход. + + + (no label) + (нет метки) + + + change from %1 (%2) + сдача с %1 (%2) + + + (change) + (сдача) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Адрес + + New receiving address + Новый адрес получения + + + New sending address + Новый адрес отправки + + + Edit receiving address + Изменить адрес получения + + + Edit sending address + Изменить адрес отправки + + + The entered address "%1" is not a valid Bitcoin address. + Введённый адрес "%1" не является правильным Bitcoin-адресом. + + + The entered address "%1" is already in the address book. + Введённый адрес "%1" уже находится в адресной книге. + + + Could not unlock wallet. + Не удается разблокировать бумажник. + + + New key generation failed. + Генерация нового ключа не удалась. + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file Выбрать файл запроса платежа + + Select payment request file to open + Выберите файл запроса платежа + OptionsDialog @@ -937,6 +1276,97 @@ Текущий общий баланс на адресах наблюдения + + PaymentServer + + Payment request error + Ошибка запроса платежа + + + Cannot start bitcoin: click-to-pay handler + Не удаётся запустить bitcoin: обработчик click-to-pay + + + URI handling + Обработка URI + + + Payment request fetch URL is invalid: %1 + Неверный URL запроса платежа: %1 + + + Invalid payment address %1 + Неверный адрес платежа %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + Не удалось обработать URI! Это может быть связано с неверным адресом Bitcoin или неправильными параметрами URI. + + + Payment request file handling + Обработка файла запроса платежа + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа. + + + Payment request rejected + Запрос платежа отклонён + + + Payment request network doesn't match client network. + Сеть запроса платежа не совпадает с сетью клиента. + + + Payment request expired. + Запрос платежа просрочен. + + + Payment request is not initialized. + Запрос платежа не инициализирован. + + + Unverified payment requests to custom payment scripts are unsupported. + Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются. + + + Invalid payment request. + Неверный запрос платежа. + + + Requested payment amount of %1 is too small (considered dust). + Запрошенная сумма платежа %1 слишком мала (считается пылью). + + + Refund from %1 + Возврат от %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Запрос платежа %1 слишком большой (%2 байтов, разрешено %3 байтов). + + + Error communicating with %1: %2 + Ошибка связи с %1: %2 + + + Payment request cannot be parsed! + Запрос платежа не может быть разобран! + + + Bad response from server %1 + Плохой ответ сервера %1 + + + Network request error + Ошибка сетевого запроса + + + Payment acknowledged + Платёж принят + + PeerTableModel @@ -991,6 +1421,25 @@ %1 мс + + QRImageWidget + + &Save Image... + &Сохранить изображение... + + + &Copy Image + Копировать &изображение + + + Save QR Code + Сохранить QR-код + + + PNG Image (*.png) + Изображение PNG (*.png) + + RPCConsole @@ -1352,6 +1801,18 @@ Remove Удалить + + Copy label + Копировать метку + + + Copy message + Копировать сообщение + + + Copy amount + Копировать сумму + ReceiveRequestDialog @@ -1371,6 +1832,73 @@ &Save Image... &Сохранить изображение... + + Request payment to %1 + Запросить платёж на %1 + + + Payment information + Информация платежа + + + URI + URI + + + Address + Адрес + + + Amount + Сумма + + + Label + Метка + + + Message + Сообщение + + + Resulting URI too long, try to reduce the text for label / message. + Получившийся URI слишком длинный, попробуйте сократить текст метки / сообщения. + + + Error encoding URI into QR Code. + Ошибка кодирования URI в QR-код + + + + RecentRequestsTableModel + + Date + Дата + + + Label + Метка + + + Message + Сообщение + + + (no label) + (нет метки) + + + (no message) + (нет сообщения) + + + (no amount requested) + (нет запрошенной суммы) + + + Requested + Запрошено + SendCoinsDialog @@ -1522,6 +2050,114 @@ S&end &Отправить + + Copy quantity + Копировать количество + + + Copy amount + Копировать сумму + + + Copy fee + Копировать комиссию + + + Copy after fee + Копировать после комиссии + + + Copy bytes + Копировать байты + + + Copy priority + Копировать приоритет + + + Copy dust + Копировать пыль + + + Copy change + Копировать сдачу + + + %1 to %2 + С %1 на %2 + + + Are you sure you want to send? + Вы уверены, что хотите отправить? + + + added as transaction fee + добавлено как комиссия + + + Total Amount %1 + Общая сумма %1 + + + or + или + + + Confirm send coins + Подтвердите отправку монет + + + The recipient address is not valid. Please recheck. + Адрес получателя неверный. Пожалуйста, перепроверьте. + + + The amount to pay must be larger than 0. + Сумма для отправки должна быть больше 0. + + + The amount exceeds your balance. + Сумма превышает ваш баланс. + + + The total exceeds your balance when the %1 transaction fee is included. + Сумма с учётом комиссии %1 превысит ваш баланс. + + + Duplicate address found: addresses should only be used once each. + Обнаружен дублирующийся адрес: используйте каждый адрес только один раз. + + + Transaction creation failed! + Не удалось создать транзакцию! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. + + + A fee higher than %1 is considered an absurdly high fee. + Комиссия больше чем %1 считается невероятно большой. + + + Payment request expired. + Запрос платежа просрочен. + + + Pay only the required fee of %1 + Заплатить только обязательную комиссию %1 + + + Warning: Invalid Bitcoin address + Внимание: неверный адрес Bitcoin + + + Warning: Unknown change address + Внимание: неизвестный адрес для сдачи + + + (no label) + (нет метки) + SendCoinsEntry @@ -1601,6 +2237,17 @@ Memo: Примечание: + + Enter a label for this address to add it to your address book + Введите метку для данного адреса, чтобы добавить его в адресную книгу + + + + SendConfirmationDialog + + Yes + Да + ShutdownWindow @@ -1699,6 +2346,58 @@ Reset all verify message fields Сбросить все поля проверки сообщения + + Click "Sign Message" to generate signature + Нажмите "Подписать сообщение" для создания подписи + + + The entered address is invalid. + Введённый адрес неверен. + + + Please check the address and try again. + Пожалуйста, проверьте адрес и попробуйте ещё раз. + + + The entered address does not refer to a key. + Введённый адрес не связан с ключом. + + + Wallet unlock was cancelled. + Разблокировка бумажника была отменена. + + + Private key for the entered address is not available. + Недоступен секретный ключ для введённого адреса. + + + Message signing failed. + Не удалось подписать сообщение. + + + Message signed. + Сообщение подписано. + + + The signature could not be decoded. + Подпись не может быть раскодирована. + + + Please check the signature and try again. + Пожалуйста, проверьте подпись и попробуйте ещё раз. + + + The signature did not match the message digest. + Подпись не соответствует отпечатку сообщения. + + + Message verification failed. + Сообщение не прошло проверку. + + + Message verified. + Сообщение проверено. + SplashScreen @@ -1714,12 +2413,453 @@ КБ/сек + + TransactionDesc + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + + + Open until %1 + Открыто до %1 + + + conflicted with a transaction with %1 confirmations + конфликт с транзакцией с %1 подтверждений + + + %1/offline + %1/отключен + + + 0/unconfirmed, %1 + 0/не подтверждено, %1 + + + in memory pool + В памяти + + + not in memory pool + Не в памяти + + + abandoned + заброшено + + + %1/unconfirmed + %1/не подтверждено + + + %1 confirmations + %1 подтверждений + + + Status + Статус + + + , has not been successfully broadcast yet + , ещё не было успешно разослано + + + , broadcast through %n node(s) + , разослано через %n узел, разослано через %n узла, разослано через %n узлов, разослано через %n узлов + + + Date + Дата + + + Source + Источник + + + Generated + Сгенерированно + + + From + От + + + unknown + неизвестно + + + To + Для + + + own address + свой адрес + + + watch-only + только наблюдение + + + label + метка + + + Credit + Кредит + + + matures in %n more block(s) + будет доступно через %n блокбудет доступно через %n блокабудет доступно через %n блоковбудет доступно через %n блоков + + + not accepted + не принято + + + Debit + Дебет + + + Total debit + Всего дебет + + + Total credit + Всего кредит + + + Transaction fee + Комиссия + + + Net amount + Чистая сумма + + + Message + Сообщение + + + Comment + Комментарий + + + Transaction ID + ID транзакции + + + Output index + Номер выхода + + + Merchant + Продавец + + + 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. + Сгенерированные монеты должны подождать %1 блоков, прежде чем они могут быть потрачены. Когда вы сгенерировали этот блок, он был отправлен в сеть для добавления в цепочку блоков. Если он не попадёт в цепь, его статус изменится на "не принят", и монеты будут недействительны. Это иногда происходит в случае, если другой узел сгенерирует блок на несколько секунд раньше вас. + + + Debug information + Отладочная информация + + + Transaction + Транзакция + + + Inputs + Входы + + + Amount + Сумма + + + true + истина + + + false + ложь + + TransactionDescDialog This pane shows a detailed description of the transaction Эта панель отображает детальное описание транзакции. + + Details for %1 + Подробности %1 + + + + TransactionTableModel + + Date + Дата + + + Type + Тип + + + Label + Метка + + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + + + Open until %1 + Открыто до %1 + + + Offline + Отключен + + + Unconfirmed + Не подтверждено + + + Abandoned + Заброшено + + + Confirmed (%1 confirmations) + Подтверждено (%1 подтверждений) + + + Conflicted + В противоречии + + + Immature (%1 confirmations, will be available after %2) + Незрелый (%1 подтверждений, будет доступно после %2) + + + This block was not received by any other nodes and will probably not be accepted! + Этот блок не был получен другими узлами и, возможно, не будет принят! + + + Generated but not accepted + Сгенерировано, но не принято + + + Received with + Получено на + + + Received from + Получено от + + + Sent to + Отправлено на + + + Payment to yourself + Отправлено себе + + + Mined + Добыто + + + watch-only + только наблюдение + + + (n/a) + (недоступно) + + + (no label) + (нет метки) + + + Transaction status. Hover over this field to show number of confirmations. + Статус транзакции. Подведите курсор к этому полю, чтобы увидеть количество подтверждений. + + + Date and time that the transaction was received. + Дата и время получения транзакции. + + + Type of transaction. + Тип транзакции. + + + Whether or not a watch-only address is involved in this transaction. + Использовался ли в транзакции адрес для наблюдения. + + + User-defined intent/purpose of the transaction. + Определяемое пользователем намерение/цель транзакции. + + + Amount removed from or added to balance. + Снятая или добавленная к балансу сумма. + + + + TransactionView + + All + Все + + + Today + Сегодня + + + This week + На этой неделе + + + This month + В этом месяце + + + Last month + В прошлом месяце + + + This year + В этом году + + + Range... + Диапазон... + + + Received with + Получено на + + + Sent to + Отправлено на + + + To yourself + Себе + + + Mined + Добыто + + + Other + Другое + + + Enter address or label to search + Введите адрес или метку для поиска + + + Min amount + Мин. сумма + + + Abandon transaction + Отказаться от транзакции + + + Copy address + Копировать адрес + + + Copy label + Копировать метку + + + Copy amount + Копировать сумму + + + Copy transaction ID + Копировать ID транзакции + + + Copy raw transaction + Копировать исходный код транзакции + + + Copy full transaction details + Копировать все подробности транзакции + + + Edit label + Изменить метку + + + Show transaction details + Показать подробности транзакции + + + Export Transaction History + Экспортировать историю транзакций + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + Confirmed + Подтверждено + + + Watch-only + Для наблюдения + + + Date + Дата + + + Type + Тип + + + Label + Метка + + + Address + Адрес + + + ID + ID + + + Exporting Failed + Экспорт не удался + + + There was an error trying to save the transaction history to %1. + Произошла ошибка при сохранении истории транзакций в %1. + + + Exporting Successful + Экспорт успешно завершён + + + The transaction history was successfully saved to %1. + История транзакций была успешно сохранена в %1. + + + Range: + Диапазон: + + + to + до + UnitDisplayStatusBarControl @@ -1728,6 +2868,55 @@ Единица измерения количества монет. Щёлкните для выбора другой единицы. + + WalletFrame + + No wallet has been loaded. + Не был загружен ни один бумажник. + + + + WalletModel + + Send Coins + Отправка + + + + WalletView + + &Export + &Экспорт + + + Export the data in the current tab to a file + Экспортировать данные текущей вкладки в файл + + + Backup Wallet + Резервная копия бумажника + + + Wallet Data (*.dat) + Данные бумажника (*.dat) + + + Backup Failed + Резервное копирование не удалось + + + There was an error trying to save the wallet data to %1. + Произошла ошибка при сохранении данных бумажника в %1. + + + Backup Successful + Резервное копирование успешно завершено + + + The wallet data was successfully saved to %1. + Данные бумажника были успешно сохранены в %1. + + bitcoin-core @@ -1842,10 +3031,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Всегда разрешать транзакции, полученные от участников из белого списка (по умолчанию: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Максимально допустимое среднее отклонение времени участников. Локальное представление времени может меняться вперед или назад на это количество. (по умолчанию: %u секунд) @@ -2098,6 +3283,10 @@ Specify wallet file (within data directory) Укажите файл бумажника (внутри каталога данных) + + Starting network threads... + Запускаем сетевые потоки... + The source code is available from %s. Исходный код доступен в %s. @@ -2182,6 +3371,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми для создания, ретрансляции, получения транзакции (по умолчанию: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Всегда ретранслировать транзакции, полученные из белого списка участников, даже если они нарушают локальную политику ретрансляции (по умолчанию: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 52a0020c5..db9b2e8c8 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -41,14 +41,17 @@ &Delete Удалить - + + + AddressTableModel + AskPassphraseDialog Repeat new passphrase Повторите новый пароль - + BanTableModel @@ -139,12 +142,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -158,12 +167,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -176,12 +191,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 60eeba702..ee0568ed5 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -41,7 +41,10 @@ &Delete &Zmazať - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Zopakujte nové heslo - + BanTableModel @@ -463,7 +466,7 @@ Priority Priorita - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Adresa - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Vyberte súbor s výzvou k platbe - + OptionsDialog @@ -937,6 +940,9 @@ Aktuálny celkový zostatok pre adries ktoré sa iba sledujú + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1353,7 +1362,7 @@ Remove Odstrániť - + ReceiveRequestDialog @@ -1372,7 +1381,10 @@ &Save Image... Uložiť obrázok... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1523,7 +1535,7 @@ S&end &Odoslať - + SendCoinsEntry @@ -1602,7 +1614,10 @@ Memo: Poznámka: - + + + SendConfirmationDialog + ShutdownWindow @@ -1692,7 +1707,7 @@ Reset all verify message fields Obnoviť všetky polia v overiť správu - + SplashScreen @@ -1707,13 +1722,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Táto časť obrazovky zobrazuje detailný popis transakcie - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1721,6 +1745,15 @@ Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 94e219636..8c8cf94a9 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -41,7 +41,10 @@ &Delete I&zbriši - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ponovite novo geslo - + BanTableModel @@ -447,7 +450,7 @@ Priority Prioriteta - + EditAddressDialog @@ -470,7 +473,7 @@ &Address &Naslov - + FreespaceChecker @@ -586,7 +589,7 @@ Select payment request file Izbiranje datoteke z zahtevkom za plačilo - + OptionsDialog @@ -853,6 +856,9 @@ Trenutno skupno stanje sredstev na opazovanih naslovih + + PaymentServer + PeerTableModel @@ -907,6 +913,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1176,7 +1185,7 @@ Remove Odstrani - + ReceiveRequestDialog @@ -1195,7 +1204,10 @@ &Save Image... &Shrani sliko ... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1346,7 +1358,7 @@ S&end &Pošlji - + SendCoinsEntry @@ -1425,7 +1437,10 @@ Memo: Opomba: - + + + SendConfirmationDialog + ShutdownWindow @@ -1519,7 +1534,7 @@ Reset all verify message fields Počisti vsa polja za vnos v oknu za preverjanje - + SplashScreen @@ -1534,13 +1549,22 @@ KiB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction V tem podoknu so prikazane podrobnosti o transakciji - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1548,6 +1572,15 @@ Merska enota za prikaz zneskov. Kliknite za izbiro druge enote. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 6c86b7d9f..5a1f4d64a 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -33,7 +33,10 @@ &Delete &Fshi - + + + AddressTableModel + AskPassphraseDialog @@ -48,7 +51,7 @@ Repeat new passphrase Përsërisni frazkalimin e ri - + BanTableModel @@ -200,7 +203,7 @@ &Address &Adresa - + FreespaceChecker @@ -247,6 +250,9 @@ Formilarë + + PaymentServer + PeerTableModel @@ -257,6 +263,9 @@ Sasia + + QRImageWidget + RPCConsole @@ -302,6 +311,9 @@ &Kopjo adresen + + RecentRequestsTableModel + SendCoinsDialog @@ -360,6 +372,9 @@ Paguaj drejt: + + SendConfirmationDialog + ShutdownWindow @@ -388,16 +403,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ky panel tregon një përshkrim të detajuar të transaksionit - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 729bd08b3..c43e91247 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -37,7 +37,10 @@ &Delete &Избриши - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ Repeat new passphrase Поновите нову лозинку - + BanTableModel @@ -200,7 +203,7 @@ &Address &Адреса - + FreespaceChecker @@ -247,6 +250,9 @@ Форма + + PaymentServer + PeerTableModel @@ -257,6 +263,9 @@ iznos + + QRImageWidget + RPCConsole @@ -282,6 +291,9 @@ Kopirajte adresu + + RecentRequestsTableModel + SendCoinsDialog @@ -300,7 +312,7 @@ S&end &Пошаљи - + SendCoinsEntry @@ -324,6 +336,9 @@ Poruka: + + SendConfirmationDialog + ShutdownWindow @@ -348,16 +363,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ovaj odeljak pokazuje detaljan opis transakcije - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts index 229618e34..933e2ad35 100644 --- a/src/qt/locale/bitcoin_sr@latin.ts +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -41,7 +41,10 @@ &Delete &Izbrisati - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,55 @@ Repeat new passphrase Ponovo unesite pristupnu frazu - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Unesite novu pristupnu frazu u novčanik. <br/>Molimo, koristite pristupnu frazu koja ima <b> deset ili više nasumičnih znakova</b>, ili <b>osam ili više reči</b>. + + + Encrypt wallet + Šifrujte novčanik + + + This operation needs your wallet passphrase to unlock the wallet. + Da biste otključali novčanik potrebno je da unesete svoju pristupnu frazu. + + + Unlock wallet + Otključajte novčanik + + + This operation needs your wallet passphrase to decrypt the wallet. + Da biste dešifrovali novčanik, potrebno je da unesete svoju pristupnu frazu. + + + Decrypt wallet + Dešifrujte novčanik + + + Change passphrase + Promenite pristupnu frazu + + + Enter the old passphrase and new passphrase to the wallet. + Unesite u novčanik staru pristupnu frazu i novu pristupnu frazu. + + + Confirm wallet encryption + Potvrdite šifrovanje novčanika + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Upozorenje: Ako šifrujete svoj novčanik, i potom izgubite svoju pristupnu frazu <b>IZGUBIĆETE SVE SVOJE BITKOINE</b>! + + + Are you sure you wish to encrypt your wallet? + Da li ste sigurni da želite da šifrujete svoj novčanik? + + + Wallet encrypted + Novčanik je šifrovan + + BanTableModel @@ -227,7 +278,7 @@ Priority Prioritet - + EditAddressDialog @@ -242,7 +293,7 @@ &Address &Adresa - + FreespaceChecker @@ -265,6 +316,9 @@ OverviewPage + + PaymentServer + PeerTableModel @@ -275,6 +329,9 @@ Kolicina + + QRImageWidget + RPCConsole @@ -284,6 +341,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -310,6 +370,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -322,12 +385,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index bcee9768f..5b122f76c 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -41,7 +41,42 @@ &Delete &Radera - + + Choose the address to send coins to + Välj en adress att sända betalning till + + + Choose the address to receive coins with + Välj en adress att ta emot betalning till + + + C&hoose + V&älj + + + Sending addresses + Avsändaradresser + + + Receiving addresses + Mottagaradresser + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Detta är dina Bitcoin adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Detta är dina Bitcoin adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion. + + + &Copy Address + &Kopiera adress + + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +95,7 @@ Repeat new passphrase Upprepa nytt lösenord - + BanTableModel @@ -463,7 +498,7 @@ Priority Prioritet - + EditAddressDialog @@ -486,7 +521,7 @@ &Address &Adress - + FreespaceChecker @@ -626,7 +661,7 @@ Select payment request file Välj betalningsbegäransfil - + OptionsDialog @@ -937,6 +972,9 @@ Nuvarande total balans i granska-bara adresser + + PaymentServer + PeerTableModel @@ -991,6 +1029,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1393,7 @@ Remove Ta bort - + ReceiveRequestDialog @@ -1371,7 +1412,10 @@ &Save Image... &Spara Bild... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1566,7 @@ S&end &Skicka - + SendCoinsEntry @@ -1601,7 +1645,10 @@ Memo: PM: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1746,7 @@ Reset all verify message fields Rensa alla fält - + SplashScreen @@ -1714,13 +1761,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Den här panelen visar en detaljerad beskrivning av transaktionen - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1728,6 +1784,15 @@ &Enhet att visa belopp i. Klicka för att välja annan enhet. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1842,10 +1907,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Vidarebefodra alltid transaktioner från vitlistade noder även om de bryter mot lokala reläpolicyn (förvalt: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximalt tillåten median-peer tidsoffset justering. Lokalt perspektiv av tiden kan bli påverkad av partners, framåt eller bakåt denna tidsrymd. (förvalt: %u sekunder) diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index 921171c54..699ded2c6 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -25,7 +25,10 @@ &Delete &அழி - + + + AddressTableModel + AskPassphraseDialog @@ -205,7 +208,7 @@ Priority முன்னுரிமை - + EditAddressDialog @@ -331,6 +334,9 @@ மொத்தம்: + + PaymentServer + PeerTableModel @@ -369,6 +375,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -530,7 +539,7 @@ Remove நீக்கு - + ReceiveRequestDialog @@ -549,7 +558,10 @@ &Save Image... &படத்தை சேமி... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -600,7 +612,7 @@ S&end &அனுப்பு - + SendCoinsEntry @@ -624,6 +636,9 @@ செய்தி: + + SendConfirmationDialog + ShutdownWindow @@ -652,12 +667,30 @@ KB/s + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 34c752634..9c4a26798 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -41,7 +41,10 @@ &Delete &ลบ - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase กรุณากรอกรหัสผ่านใหม่อีกครั้งหนึ่ง - + BanTableModel @@ -463,7 +466,7 @@ Priority ระดับความสำคัญ - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &ที่เก็บ - + FreespaceChecker @@ -622,7 +625,7 @@ Select payment request file เลือก ไฟล์การเรียกการชำระเงิน - + OptionsDialog @@ -797,6 +800,9 @@ รูป + + PaymentServer + PeerTableModel @@ -807,6 +813,9 @@ จำนวน + + QRImageWidget + RPCConsole @@ -820,6 +829,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -866,6 +878,9 @@ &ชื่อ: + + SendConfirmationDialog + ShutdownWindow @@ -882,12 +897,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index 8e9ec36b0..7a4b95a22 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -41,7 +41,10 @@ &Delete &Sil - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Yeni parolayı tekrarlayınız - + BanTableModel @@ -463,7 +466,7 @@ Priority Öncelik - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Adres - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Ödeme talebi dosyasını seç - + OptionsDialog @@ -937,6 +940,9 @@ Sadece izlenen adreslerdeki güncel toplam bakiye + + PaymentServer + PeerTableModel @@ -991,6 +997,9 @@ %1 ms + + QRImageWidget + RPCConsole @@ -1352,7 +1361,7 @@ Remove Kaldır - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... Resmi ka&ydet... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end G&önder - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: Not: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1714,7 @@ Reset all verify message fields Tüm mesaj kontrolü alanlarını sıfırla - + SplashScreen @@ -1714,13 +1729,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Bu pano muamelenin ayrıntılı açıklamasını gösterir - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1728,6 +1752,15 @@ Meblağları göstermek için birim. Başka bir birim seçmek için tıklayınız. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1846,10 +1879,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Yerel aktarma politikasını ihlal ettiklerinde bile beyaz listedeki eşlerden gelen muamelelerin aktarılmasını zorla (varsayılan: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Müsaade edilen azami medyan eş zamanı değişiklik sınırının ayarlaması. Zamanın yerel perspektifi bu miktar kadar ileri ya da geri eşler tarafından etkilenebilir. (Varsayılan %u saniye) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index 344309c25..bc99091fb 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -41,7 +41,10 @@ &Delete &Sil - + + + AddressTableModel + AskPassphraseDialog @@ -68,7 +71,7 @@ &Address Adres - + FreespaceChecker @@ -87,12 +90,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -106,12 +115,18 @@ &Adresi Kopyala + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -124,12 +139,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index bdfe3f57e..09c167dfc 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -41,7 +41,10 @@ &Delete &Видалити - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Повторіть пароль - + BanTableModel @@ -439,7 +442,7 @@ Priority Пріоритет - + EditAddressDialog @@ -462,7 +465,7 @@ &Address &Адреса - + FreespaceChecker @@ -582,7 +585,7 @@ Select payment request file Виберіть файл запиту платежу - + OptionsDialog @@ -873,6 +876,9 @@ Поточний сукупний баланс в адресах для спостереження + + PaymentServer + PeerTableModel @@ -927,6 +933,9 @@ %1 мс + + QRImageWidget + RPCConsole @@ -1268,7 +1277,7 @@ Remove Вилучити - + ReceiveRequestDialog @@ -1287,7 +1296,10 @@ &Save Image... &Зберегти зображення... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1438,7 +1450,7 @@ S&end &Відправити - + SendCoinsEntry @@ -1517,7 +1529,10 @@ Memo: Нотатка: - + + + SendConfirmationDialog + ShutdownWindow @@ -1611,7 +1626,7 @@ Reset all verify message fields Скинути всі поля перевірки повідомлення - + SplashScreen @@ -1626,13 +1641,22 @@ КБ/с + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Даний діалог показує детальну статистику по вибраній транзакції - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1640,6 +1664,15 @@ Одиниця виміру монет. Натисніть для вибору іншої. + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index 6b43bf63e..60311ac41 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -41,7 +41,10 @@ &Delete مٹا - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase نیا پاس فریز دہرائیں - + BanTableModel @@ -92,7 +95,7 @@ &Address پتہ - + FreespaceChecker @@ -115,6 +118,9 @@ OverviewPage + + PaymentServer + PeerTableModel @@ -125,6 +131,9 @@ رقم + + QRImageWidget + RPCConsole @@ -138,6 +147,9 @@ کاپی پتہ + + RecentRequestsTableModel + SendCoinsDialog @@ -156,6 +168,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -168,12 +183,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 0062abfc1..2503ed4a1 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -41,7 +41,10 @@ &Delete &Ўчириш - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Янги махфий сузни такрорланг - + BanTableModel @@ -381,7 +384,7 @@ Priority Муҳимлиги - + EditAddressDialog @@ -404,7 +407,7 @@ &Address &Манзил - + FreespaceChecker @@ -492,7 +495,7 @@ Select payment request file Тўлов сўрови файлини танлаш - + OptionsDialog @@ -683,6 +686,9 @@ Жорий умумий баланс фақат кўринадиган манзилларда + + PaymentServer + PeerTableModel @@ -725,6 +731,9 @@ %1 мс + + QRImageWidget + RPCConsole @@ -962,7 +971,7 @@ Remove Ўчириш - + ReceiveRequestDialog @@ -977,7 +986,10 @@ &Save Image... Расмни &сақлаш - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1088,7 +1100,7 @@ S&end Жў&натиш - + SendCoinsEntry @@ -1132,6 +1144,9 @@ Тўлов олувчи: + + SendConfirmationDialog + ShutdownWindow @@ -1172,16 +1187,34 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction Ушбу ойна операциянинг батафсил таърифини кўрсатади - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index e8bf01ab1..46bf75f58 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -21,7 +21,10 @@ &Delete &Xóa - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -71,6 +74,9 @@ OverviewPage + + PaymentServer + PeerTableModel @@ -81,6 +87,9 @@ Số lượng + + QRImageWidget + RPCConsole @@ -94,6 +103,9 @@ Sao chép địa chỉ + + RecentRequestsTableModel + SendCoinsDialog @@ -104,6 +116,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -116,12 +131,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index e5f955eb4..5774f5b9b 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -41,7 +41,10 @@ &Delete &Xó&a - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Điền lại passphrase - + BanTableModel @@ -415,7 +418,7 @@ Priority Tầm quan trọng - + EditAddressDialog @@ -430,7 +433,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -597,6 +600,9 @@ Tổng: + + PaymentServer + PeerTableModel @@ -611,6 +617,9 @@ Lượng + + QRImageWidget + RPCConsole @@ -652,6 +661,9 @@ &Copy Địa Chỉ + + RecentRequestsTableModel + SendCoinsDialog @@ -694,6 +706,9 @@ Lượng: + + SendConfirmationDialog + ShutdownWindow @@ -706,12 +721,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts index bceba9dfd..61b95f4b6 100644 --- a/src/qt/locale/bitcoin_zh.ts +++ b/src/qt/locale/bitcoin_zh.ts @@ -2,6 +2,9 @@ AddressBookPage + + AddressTableModel + AskPassphraseDialog @@ -51,12 +54,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -66,6 +75,9 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog @@ -80,6 +92,9 @@ SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -92,12 +107,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index b8296649b..b8d3cadc2 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -41,7 +41,10 @@ &Delete 删除(&D) - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase 重复新密码 - + BanTableModel @@ -459,7 +462,7 @@ Priority 优先级 - + EditAddressDialog @@ -482,7 +485,7 @@ &Address 地址(&A) - + FreespaceChecker @@ -619,7 +622,7 @@ Select payment request file 选择付款请求文件 - + OptionsDialog @@ -910,6 +913,9 @@ 观察地址(watch-only address)中的当前总余额 + + PaymentServer + PeerTableModel @@ -964,6 +970,9 @@ %1 毫秒 + + QRImageWidget + RPCConsole @@ -1301,7 +1310,7 @@ Remove 移除 - + ReceiveRequestDialog @@ -1320,7 +1329,10 @@ &Save Image... 保存图片(&S)... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1471,7 +1483,7 @@ S&end 发送(&E) - + SendCoinsEntry @@ -1550,7 +1562,10 @@ Memo: 便条: - + + + SendConfirmationDialog + ShutdownWindow @@ -1644,7 +1659,7 @@ Reset all verify message fields 清空所有验证消息栏 - + SplashScreen @@ -1659,13 +1674,22 @@ KB/s + + TransactionDesc + TransactionDescDialog This pane shows a detailed description of the transaction 当前面板显示了交易的详细信息 - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1673,6 +1697,15 @@ 金额单位。单击选择别的单位。 + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core @@ -1776,10 +1809,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 强制关联来自白名单同行的交易即使他们违反本地关联政策(默认: %d) - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d) diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index aa014db0b..ecc00f3a2 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -41,7 +41,10 @@ &Delete 刪除 &D - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase 重複新密碼 - + BanTableModel @@ -223,12 +226,18 @@ OverviewPage + + PaymentServer + PeerTableModel QObject + + QRImageWidget + RPCConsole @@ -238,12 +247,18 @@ ReceiveRequestDialog + + RecentRequestsTableModel + SendCoinsDialog SendCoinsEntry + + SendConfirmationDialog + ShutdownWindow @@ -256,12 +271,30 @@ TrafficGraphWidget + + TransactionDesc + TransactionDescDialog + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + + WalletFrame + + + WalletModel + + + WalletView + bitcoin-core diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index efea3da9e..4b1e81e96 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -41,6 +41,77 @@ &Delete 刪掉 + + Choose the address to send coins to + 選擇要付錢過去的位址 + + + Choose the address to receive coins with + 選擇要收錢進來的位址 + + + C&hoose + 選取 + + + Sending addresses + 付款位址 + + + Receiving addresses + 收款位址 + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + 這些是你要付款過去的 Bitcoin 位址。在付錢之前,務必要檢查金額和收款位址是否正確。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 + + + &Copy Address + 複製位址 + + + Copy &Label + 複製標記 + + + &Edit + 編輯 + + + Export Address List + 匯出位址清單 + + + Comma separated file (*.csv) + 逗點分隔資料檔(*.csv) + + + Exporting Failed + 匯出失敗 + + + There was an error trying to save the address list to %1. Please try again. + 儲存位址列表到 %1 時發生錯誤。請重試一次。 + + + + AddressTableModel + + Label + 標記 + + + Address + 位址 + + + (no label) + (無標記) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase 重複新密碼 + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 輸入錢包的新密碼。<br/>密碼請用<b>10 個以上的隨機字元</b>,或是<b>8 個以上的字詞</b>。 + + + Encrypt wallet + 加密錢包 + + + This operation needs your wallet passphrase to unlock the wallet. + 這個動作需要你的錢包密碼來解鎖錢包。 + + + Unlock wallet + 解鎖錢包 + + + This operation needs your wallet passphrase to decrypt the wallet. + 這個動作需要你的錢包密碼來把錢包解密。 + + + Decrypt wallet + 解密錢包 + + + Change passphrase + 改變密碼 + + + Enter the old passphrase and new passphrase to the wallet. + 請輸入錢包的舊密碼和新密碼。 + + + Confirm wallet encryption + 確認錢包加密 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: 如果把錢包加密後又忘記密碼,你就會從此<b>失去其中所有的 Bitcoin 了</b>! + + + Are you sure you wish to encrypt your wallet? + 你確定要把錢包加密嗎? + + + Wallet encrypted + 錢包已加密 + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取錢幣。 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。 + + + Wallet encryption failed + 錢包加密失敗 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 因為內部錯誤導致錢包加密失敗。你的錢包還是沒加密。 + + + The supplied passphrases do not match. + 提供的密碼不一樣。 + + + Wallet unlock failed + 錢包解鎖失敗 + + + The passphrase entered for the wallet decryption was incorrect. + 輸入要用來解密錢包的密碼不對。 + + + Wallet decryption failed + 錢包解密失敗 + + + Wallet passphrase was successfully changed. + 錢包密碼改成功了。 + + + Warning: The Caps Lock key is on! + 警告: 大寫字母鎖定作用中! + BanTableModel @@ -463,6 +622,150 @@ Priority 優先度 + + Copy address + 複製位址 + + + Copy label + 複製標記 + + + Copy amount + 複製金額 + + + Copy transaction ID + 複製交易識別碼 + + + Lock unspent + 鎖定不用 + + + Unlock unspent + 解鎖可用 + + + Copy quantity + 複製數目 + + + Copy fee + 複製手續費 + + + Copy after fee + 複製計費後金額 + + + Copy bytes + 複製位元組數 + + + Copy priority + 複製優先度 + + + Copy dust + 複製零散金額 + + + Copy change + 複製找零金額 + + + highest + 最高 + + + higher + 很高 + + + high + + + + medium-high + 中高 + + + medium + 中等 + + + low-medium + 中低 + + + low + + + + lower + 很低 + + + lowest + 最低 + + + (%1 locked) + (鎖定 %1 枚) + + + none + + + + yes + + + + no + + + + This label turns red if the transaction size is greater than 1000 bytes. + 當交易大小大於 1000 位元組時,文字會變紅色。 + + + This means a fee of at least %1 per kB is required. + 表示每一千位元組(kB)需要至少 %1 的手續費。 + + + Can vary +/- 1 byte per input. + 每組輸入可能會誤差多或少 1 個位元組。 + + + Transactions with higher priority are more likely to get included into a block. + 優先度較高的交易比較有可能被接受放進區塊中。 + + + This label turns red if the priority is smaller than "medium". + 當優先度低於「中等」時,文字會變紅色。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 當任何一個收款金額小於目前的零散金額上限時,文字會變紅色。 + + + Can vary +/- %1 satoshi(s) per input. + 每組輸入可能有 +/- %1 個 satoshi 的誤差。 + + + (no label) + (無標記) + + + change from %1 (%2) + 找零前是 %1 (%2) + + + (change) + (找零) + EditAddressDialog @@ -486,6 +789,38 @@ &Address 位址 + + New receiving address + 造新的收款位址 + + + New sending address + 造新的付款位址 + + + Edit receiving address + 編輯收款位址 + + + Edit sending address + 編輯付款位址 + + + The entered address "%1" is not a valid Bitcoin address. + 輸入的位址 %1 並不是有效的 Bitcoin 位址。 + + + The entered address "%1" is already in the address book. + 輸入的位址 %1 在位址簿中已經有了。 + + + Could not unlock wallet. + 沒辦法把錢包解鎖。 + + + New key generation failed. + 產生新的密鑰失敗了。 + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file 選擇付款要求資料檔 + + Select payment request file to open + 選擇要開啟的付款要求資料檔 + OptionsDialog @@ -937,6 +1276,97 @@ 所有只能看位址的目前全部餘額 + + PaymentServer + + Payment request error + 要求付款時發生錯誤 + + + Cannot start bitcoin: click-to-pay handler + 沒辦法啟動 bitcoin 協議的「按就付」處理器 + + + URI handling + URI 處理 + + + Payment request fetch URL is invalid: %1 + 取得付款要求的 URL 無效: %1 + + + Invalid payment address %1 + 無效的付款位址 %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + 沒辦法解析 URI 位址!可能是因為 Bitcoin 位址無效,或是 URI 參數格式錯誤。 + + + Payment request file handling + 處理付款要求檔案 + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 沒辦法讀取付款要求檔案!可能是無效的檔案造成的。 + + + Payment request rejected + 付款的要求被拒絕了 + + + Payment request network doesn't match client network. + 付款要求的網路類型跟客戶端不符。 + + + Payment request expired. + 付款的要求過期了。 + + + Payment request is not initialized. + 付款的要求沒有完成初始化。 + + + Unverified payment requests to custom payment scripts are unsupported. + 不支援含有自訂付款指令碼,且沒驗證過的付款要求。 + + + Invalid payment request. + 付款的要求無效。 + + + Requested payment amount of %1 is too small (considered dust). + 要求付款的金額 %1 太少(會被網路認為是沒必要的零散錢)。 + + + Refund from %1 + 來自 %1 的退款 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + 付款要求 %1 過大 (%2 位元組, 上限 %3 位元組). + + + Error communicating with %1: %2 + 跟 %1 通訊時發生錯誤: %2 + + + Payment request cannot be parsed! + 沒辦法解析付款要求內容! + + + Bad response from server %1 + 伺服器 %1 的回應有誤 + + + Network request error + 發出要求時發生網路錯誤 + + + Payment acknowledged + 付款已確認 + + PeerTableModel @@ -991,6 +1421,25 @@ %1 毫秒 + + QRImageWidget + + &Save Image... + 儲存圖片... + + + &Copy Image + 複製圖片 + + + Save QR Code + 儲存 QR Code + + + PNG Image (*.png) + PNG 圖檔(*.png) + + RPCConsole @@ -1352,6 +1801,18 @@ Remove 刪掉 + + Copy label + 複製標記 + + + Copy message + 複製訊息 + + + Copy amount + 複製金額 + ReceiveRequestDialog @@ -1371,6 +1832,73 @@ &Save Image... 儲存圖片... + + Request payment to %1 + 付款給 %1 的要求 + + + Payment information + 付款資訊 + + + URI + URI + + + Address + 位址 + + + Amount + 金額 + + + Label + 標記: + + + Message + 訊息 + + + Resulting URI too long, try to reduce the text for label / message. + 產生的 URI 過長,請試著縮短標記或訊息的文字內容。 + + + Error encoding URI into QR Code. + 把 URI 編碼成 QR Code 時發生錯誤。 + + + + RecentRequestsTableModel + + Date + 日期 + + + Label + 標記: + + + Message + 訊息 + + + (no label) + (無標記) + + + (no message) + (無訊息) + + + (no amount requested) + (無要求金額) + + + Requested + 要求金額 + SendCoinsDialog @@ -1522,6 +2050,114 @@ S&end 付款 + + Copy quantity + 複製數目 + + + Copy amount + 複製金額 + + + Copy fee + 複製手續費 + + + Copy after fee + 複製計費後金額 + + + Copy bytes + 複製位元組數 + + + Copy priority + 複製優先度 + + + Copy dust + 複製零散金額 + + + Copy change + 複製找零金額 + + + %1 to %2 + %1 給 %2 + + + Are you sure you want to send? + 你確定要付錢出去嗎? + + + added as transaction fee + 加做交易手續費 + + + Total Amount %1 + 總金額 %1 + + + or + + + + Confirm send coins + 確認付款金額 + + + The recipient address is not valid. Please recheck. + 收款位址無效。請再檢查看看。 + + + The amount to pay must be larger than 0. + 付款金額必須大於零。 + + + The amount exceeds your balance. + 金額超過餘額了。 + + + The total exceeds your balance when the %1 transaction fee is included. + 包含 %1 的交易手續費後,總金額超過你的餘額了。 + + + Duplicate address found: addresses should only be used once each. + 發現有重複的位址: 每個位址只能出現一次。 + + + Transaction creation failed! + 製造交易失敗了! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + 交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。 + + + A fee higher than %1 is considered an absurdly high fee. + 高於 %1 的手續費會被認為是不合理。 + + + Payment request expired. + 付款的要求過期了。 + + + Pay only the required fee of %1 + 只付必要的手續費 %1 + + + Warning: Invalid Bitcoin address + 警告: Bitcoin 位址無效 + + + Warning: Unknown change address + 警告: 不明的找零位址 + + + (no label) + (無標記) + SendCoinsEntry @@ -1601,6 +2237,17 @@ Memo: 備註: + + Enter a label for this address to add it to your address book + 請輸入這個位址的標記來把它加進位址簿中 + + + + SendConfirmationDialog + + Yes + + ShutdownWindow @@ -1699,6 +2346,58 @@ Reset all verify message fields 重設所有訊息驗證欄位 + + Click "Sign Message" to generate signature + 請按一下「簽署訊息」來產生簽章 + + + The entered address is invalid. + 輸入的位址無效。 + + + Please check the address and try again. + 請檢查位址是否正確後再試一次。 + + + The entered address does not refer to a key. + 輸入的位址沒有對應到你的任何密鑰。 + + + Wallet unlock was cancelled. + 錢包解鎖已取消。 + + + Private key for the entered address is not available. + 沒有對應輸入位址的密鑰。 + + + Message signing failed. + 訊息簽署失敗。 + + + Message signed. + 訊息簽署好了。 + + + The signature could not be decoded. + 沒辦法把這個簽章解碼。 + + + Please check the signature and try again. + 請檢查簽章是否正確後再試一次。 + + + The signature did not match the message digest. + 這個簽章跟訊息的數位摘要不符。 + + + Message verification failed. + 訊息驗證失敗。 + + + Message verified. + 訊息驗證沒錯。 + SplashScreen @@ -1714,12 +2413,457 @@ KB/s + + TransactionDesc + + Open for %n more block(s) + 到下 %n 個區塊生出來前可修改 + + + Open until %1 + 到 %1 前可修改 + + + conflicted with a transaction with %1 confirmations + 跟一個目前確認 %1 次的交易互相衝突 + + + %1/offline + %1 次/離線中 + + + 0/unconfirmed, %1 + 0 次/未確認,%1 + + + in memory pool + 在記憶池中 + + + not in memory pool + 不在記憶池中 + + + abandoned + 已中止 + + + %1/unconfirmed + %1 次/未確認 + + + %1 confirmations + 確認 %1 次 + + + Status + 狀態 + + + , has not been successfully broadcast yet + ,還沒成功公告出去 + + + , broadcast through %n node(s) + ,已公告給 %n 個節點 + + + Date + 日期 + + + Source + 來源 + + + Generated + 生產出來 + + + From + 來源 + + + unknown + 未知 + + + To + 目的 + + + own address + 自己的位址 + + + watch-only + 只能看 + + + label + 標記 + + + Credit + 入帳 + + + matures in %n more block(s) + 再等 %n 個區塊生出來後成熟 + + + not accepted + 不被接受 + + + Debit + 出帳 + + + Total debit + 出帳總額 + + + Total credit + 入帳總額 + + + Transaction fee + 交易手續費 + + + Net amount + 淨額 + + + Message + 訊息 + + + Comment + 附註 + + + Transaction ID + 交易識別碼 + + + Output index + 輸出索引 + + + Merchant + 商家 + + + 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. + 生產出來的錢要再等 %1 個區塊生出來後才成熟可以用。當區塊生產出來時會公布到網路上,來被加進區塊鏈。如果加失敗了,狀態就會變成「不被接受」,而且不能夠花。如果在你生產出區塊的幾秒鐘內,也有其他節點生產出來的話,就有可能會發生這種情形。 + + + Debug information + 除錯資訊 + + + Transaction + 交易 + + + Inputs + 輸入 + + + Amount + 金額 + + + true + + + + false + + + TransactionDescDialog This pane shows a detailed description of the transaction 這個版面顯示這次交易的詳細說明 + + Details for %1 + 交易 %1 的明細 + + + + TransactionTableModel + + Date + 日期 + + + Type + 種類 + + + Label + 標記: + + + Open for %n more block(s) + 到下 %n 個區塊生出來前可修改 + + + Open until %1 + 到 %1 前可修改 + + + Offline + 離線中 + + + Unconfirmed + 未確認 + + + Abandoned + 已中止 + + + Confirming (%1 of %2 recommended confirmations) + 確認中(已經 %1 次,建議至少 %2 次) + + + Confirmed (%1 confirmations) + 已確認(%1 次) + + + Conflicted + 有衝突 + + + Immature (%1 confirmations, will be available after %2) + 未成熟(確認 %1 次,會在 %2 次後可用) + + + This block was not received by any other nodes and will probably not be accepted! + 沒有其他節點收到這個區塊,也許它不會被接受! + + + Generated but not accepted + 生產出來但是不被接受 + + + Received with + 收款 + + + Received from + 收款自 + + + Sent to + 付款 + + + Payment to yourself + 付給自己 + + + Mined + 開採所得 + + + watch-only + 只能看 + + + (n/a) + (不適用) + + + (no label) + (無標記) + + + Transaction status. Hover over this field to show number of confirmations. + 交易狀態。把游標停在欄位上會顯示確認次數。 + + + Date and time that the transaction was received. + 收到交易的日期和時間。 + + + Type of transaction. + 交易的種類。 + + + Whether or not a watch-only address is involved in this transaction. + 不論如何有一個只能觀看的地只有參與這次的交易 + + + User-defined intent/purpose of the transaction. + 使用者定義的交易動機或理由。 + + + Amount removed from or added to balance. + 要減掉或加進餘額的金額。 + + + + TransactionView + + All + 全部 + + + Today + 今天 + + + This week + 這星期 + + + This month + 這個月 + + + Last month + 上個月 + + + This year + 今年 + + + Range... + 指定範圍... + + + Received with + 收款 + + + Sent to + 付款 + + + To yourself + 給自己 + + + Mined + 開採所得 + + + Other + 其它 + + + Enter address or label to search + 請輸入要搜尋的位址或標記 + + + Min amount + 最小金額 + + + Abandon transaction + 中止交易 + + + Copy address + 複製位址 + + + Copy label + 複製標記 + + + Copy amount + 複製金額 + + + Copy transaction ID + 複製交易識別碼 + + + Copy raw transaction + 複製交易原始資料 + + + Copy full transaction details + 複製完整交易明細 + + + Edit label + 編輯標記 + + + Show transaction details + 顯示交易明細 + + + Export Transaction History + 匯出交易記錄 + + + Comma separated file (*.csv) + 逗點分隔資料檔(*.csv) + + + Confirmed + 已確認 + + + Watch-only + 只能觀看的 + + + Date + 日期 + + + Type + 種類 + + + Label + 標記: + + + Address + 位址 + + + ID + 識別碼 + + + Exporting Failed + 匯出失敗 + + + There was an error trying to save the transaction history to %1. + 儲存交易記錄到 %1 時發生錯誤。 + + + Exporting Successful + 匯出成功 + + + The transaction history was successfully saved to %1. + 交易記錄已經成功儲存到 %1 了。 + + + Range: + 範圍: + + + to + + UnitDisplayStatusBarControl @@ -1728,6 +2872,55 @@ 金額顯示單位。可以點選其他單位。 + + WalletFrame + + No wallet has been loaded. + 沒有載入錢包。 + + + + WalletModel + + Send Coins + 付款 + + + + WalletView + + &Export + 匯出 + + + Export the data in the current tab to a file + 將目前分頁的資料匯出存成檔案 + + + Backup Wallet + 備份錢包 + + + Wallet Data (*.dat) + 錢包資料檔(*.dat) + + + Backup Failed + 備份失敗 + + + There was an error trying to save the wallet data to %1. + 儲存錢包資料到 %1 時發生錯誤。 + + + Backup Successful + 備份成功 + + + The wallet data was successfully saved to %1. + 錢包的資料已經成功儲存到 %1 了。 + + bitcoin-core @@ -1847,10 +3040,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) 跟其他節點的時間差最高可接受的中位數值。本機所認為的時間可能會被其他節點影響,往前或往後在這個值之內。(預設值: %u 秒) @@ -2093,7 +3282,7 @@ Rewinding blocks... - 倒轉回區塊鏈之前的狀態... + 正在倒轉回區塊鏈之前的狀態... Set database cache size in megabytes (%d to %d, default: %d) @@ -2111,6 +3300,10 @@ Specify wallet file (within data directory) 指定錢包檔(會在資料目錄中) + + Starting network threads... + 正在啟動網路執行緒... + The source code is available from %s. 原始碼可以在 %s 取得。 @@ -2195,6 +3388,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) 當處理轉發的交易、挖礦、或製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u) From 8b66659921e6170831f3a043e9a54fa45776aa68 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 17 Oct 2016 13:24:37 +0200 Subject: [PATCH 1094/1223] Define start and end time for segwit deployment Github-Pull: #8937 Rebased-From: f9c23dea976465c51b9fe2cead81b707678c16bb --- src/chainparams.cpp | 8 ++++---- src/consensus/params.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7b493ed8a..3be2d2ff8 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -92,10 +92,10 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 - // Deployment of SegWit (BIP141 and BIP143) + // Deployment of SegWit (BIP141, BIP143, and BIP147) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 0; // Never / undefined + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016. + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. /** * The message start string is designed to be unlikely to occur in normal data. @@ -188,7 +188,7 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 - // Deployment of SegWit (BIP141 and BIP143) + // Deployment of SegWit (BIP141, BIP143, and BIP147) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 diff --git a/src/consensus/params.h b/src/consensus/params.h index 822ec87d6..d97017d0c 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -16,7 +16,7 @@ enum DeploymentPos { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. - DEPLOYMENT_SEGWIT, // Deployment of BIP141 and BIP143 + DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147. // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp MAX_VERSION_BITS_DEPLOYMENTS }; From 7462125724ed3b88de490ab1bc3a4c3bea65fe2d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 17 Oct 2016 18:44:23 +0200 Subject: [PATCH 1095/1223] doc: Fill in changelog and authors in release notes --- doc/release-notes.md | 150 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 4478f872a..3007815dd 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -57,13 +57,159 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. - ... fill in here +### Consensus +- #8636 `9dfa0c8` Implement NULLDUMMY softfork (BIP147) (jl2012) +- #8848 `7a34a46` Add NULLDUMMY verify flag in bitcoinconsensus.h (jl2012) +- #8937 `8b66659` Define start and end time for segwit deployment (sipa) + +### RPC and other APIs +- #8581 `526d2b0` Drop misleading option (MarcoFalke) +- #8699 `a5ec248` Remove createwitnessaddress RPC command (jl2012) +- #8780 `794b007` Deprecate getinfo (MarcoFalke) +- #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) +- #8884 `b987348` getblockchaininfo help: pruneheight is the lowest, not highest, block (luke-jr) + +### Block and transaction handling +- #8611 `a9429ca` Reduce default number of blocks to check at startup (sipa) +- #8634 `3e80ab7` Add policy: null signature for failed CHECK(MULTI)SIG (jl2012) +- #8525 `1672225` Do not store witness txn in rejection cache (sipa) +- #8499 `9777fe1` Add several policy limits and disable uncompressed keys for segwit scripts (jl2012) +- #8526 `0027672` Make non-minimal OP_IF/NOTIF argument non-standard for P2WSH (jl2012) +- #8524 `b8c79a0` Precompute sighashes (sipa) +- #8651 `b8c79a0` Predeclare PrecomputedTransactionData as struct (sipa) + +### P2P protocol and network code +- #8740 `42ea51a` No longer send local address in addrMe (laanwj) +- #8427 `69d1cd2` Ignore `notfound` P2P messages (laanwj) +- #8573 `4f84082` Set jonasschnellis dns-seeder filter flag (jonasschnelli) +- #8712 `23feab1` Remove maxuploadtargets recommended minimum (jonasschnelli) +- #8862 `7ae6242` Fix a few cases where messages were sent after requested disconnect (theuni) +- #8393 `fe1975a` Support for compact blocks together with segwit (sipa) +- #8282 `2611ad7` Feeler connections to increase online addrs in the tried table (EthanHeilman) +- #8612 `2215c22` Check for compatibility with download in FindNextBlocksToDownload (sipa) +- #8606 `bbf379b` Fix some locks (sipa) +- #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) + +### Build system +- #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) +- #8492 `8b0bdd3` Allow building bench_bitcoin by itself (luke-jr) +- #8563 `147003c` Add configure check for -latomic (ajtowns) +- #8626 `ea51b0f` Berkeley DB v6 compatibility fix (netsafe) +- #8520 `75f2065` Remove check for `openssl/ec.h` (laanwj) + +### GUI +- #8481 `d9f0d4e` Fix minimize and close bugs (adlawren) +- #8487 `a37cec5` Persist the datadir after option reset (achow101) +- #8697 `41fd852` Fix op order to append first alert (rodasmith) +- #8678 `8e03382` Fix UI bug that could result in paying unexpected fee (jonasschnelli) +- #8911 `7634d8e` Translate all files, even if wallet disabled (laanwj) +- #8540 `1db3352` Fix random segfault when closing "Choose data directory" dialog (laanwj) +- #7579 `f1c0d78` Show network/chain errors in the GUI (jonasschnelli) + +### Wallet +- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) +- #8443 `464dedd` Trivial cleanup of HD wallet changes (jonasschnelli) +- #8539 `cb07f19` CDB: fix debug output (crowning-) +- #8664 `091cdeb` Fix segwit-related wallet bug (sdaftuar) +- #8693 `c6a6291` Add witness address to address book (instagibbs) +- #8765 `6288659` Remove "unused" ThreadFlushWalletDB from removeprunedfunds (jonasschnelli) + +### Tests and QA +- #8713 `ae8c7df` create_cache: Delete temp dir when done (MarcoFalke) +- #8750 `d6ebe13` Refactor RPCTestHandler to prevent TimeoutExpired (MarcoFalke) +- #8652 `63462c2` remove root test directory for RPC tests (yurizhykin) +- #8724 `da94272` walletbackup: Sync blocks inside the loop (MarcoFalke) +- #8400 `bea02dc` enable rpcbind_test (yurizhykin) +- #8417 `f70be14` Add walletdump RPC test (including HD- & encryption-tests) (jonasschnelli) +- #8419 `a7aa3cc` Enable size accounting in mining unit tests (sdaftuar) +- #8442 `8bb1efd` Rework hd wallet dump test (MarcoFalke) +- #8528 `3606b6b` Update p2p-segwit.py to reflect correct behavior (instagibbs) +- #8531 `a27cdd8` abandonconflict: Use assert_equal (MarcoFalke) +- #8667 `6b07362` Fix SIGHASH_SINGLE bug in test_framework SignatureHash (jl2012) +- #8673 `03b0196` Fix obvious assignment/equality error in test (JeremyRubin) +- #8739 `cef633c` Fix broken sendcmpct test in p2p-compactblocks.py (sdaftuar) +- #8418 `ff893aa` Add tests for compact blocks (sdaftuar) +- #8803 `375437c` Ping regularly in p2p-segwit.py to keep connection alive (jl2012) +- #8827 `9bbe66e` Split up slow RPC calls to avoid pruning test timeouts (sdaftuar) +- #8829 `2a8bca4` Add bitcoin-tx JSON tests (jnewbery) +- #8834 `1dd1783` blockstore: Switch to dumb dbm (MarcoFalke) +- #8835 `d87227d` nulldummy.py: Don't run unused code (MarcoFalke) +- #8836 `eb18cc1` bitcoin-util-test.py should fail if the output file is empty (jnewbery) +- #8839 `31ab2f8` Avoid ConnectionResetErrors during RPC tests (laanwj) +- #8840 `cbc3fe5` Explicitly set encoding to utf8 when opening text files (laanwj) +- #8841 `3e4abb5` Fix nulldummy test (jl2012) +- #8854 `624a007` Fix race condition in p2p-compactblocks test (sdaftuar) +- #8857 `1f60d45` mininode: Only allow named args in wait_until (MarcoFalke) +- #8860 `0bee740` util: Move wait_bitcoinds() into stop_nodes() (MarcoFalke) +- #8882 `b73f065` Fix race conditions in p2p-compactblocks.py and sendheaders.py (sdaftuar) +- #8904 `cc6f551` Fix compact block shortids for a test case (dagurval) + +### Documentation +- #8754 `0e2c6bd` Target protobuf 2.6 in OS X build notes. (fanquake) +- #8461 `b17a3f9` Document return value of networkhashps for getmininginfo RPC endpoint (jlopp) +- #8512 `156e305` Corrected JSON typo on setban of net.cpp (sevastos) +- #8683 `8a7d7ff` Fix incorrect file name bitcoin.qrc (bitcoinsSG) +- #8891 `5e0dd9e` Update bips.md for Segregated Witness (fanquake) +- #8545 `863ae74` Update git-subtree-check.sh README (MarcoFalke) +- #8607 `486650a` Fix doxygen off-by-one comments, fix typos (MarcoFalke) +- #8560 `c493f43` Fix two VarInt examples in serialize.h (cbarcenas) +- #8737 `084cae9` UndoReadFromDisk works on undo files (rev), not on block files (paveljanik) +- #8625 `0a35573` Clarify statement about parallel jobs in rpc-tests.py (isle2983) +- #8624 `0e6d753` build: Mention curl (MarcoFalke) +- #8604 `b09e13c` build,doc: Update for 0.13.0+ and OpenBSD 5.9 (laanwj) + +### Miscellaneous +- #8742 `d31ac72` Specify Protobuf version 2 in paymentrequest.proto (fanquake) +- #8414,#8558,#8676,#8700,#8701,#8702 Add missing copyright headers (isle2983, kazcw) +- #8899 `4ed2627` Fix wake from sleep issue with Boost 1.59.0 (fanquake) +- #8817 `bcf3806` update bitcoin-tx to output witness data (jnewbery) +- #8513 `4e5fc31` Fix a type error that would not compile on OSX. (JeremyRubin) +- #8392 `30eac2d` Fix several node initialization issues (sipa) +- #8548 `305d8ac` Use __func__ to get function name for output printing (MarcoFalke) +- #8291 `a987431` [util] CopyrightHolders: Check for untranslated substitution (MarcoFalke) Credits ======= Thanks to everyone who directly contributed to this release: - ... fill in here +- Alexey Vesnin +- Anders Øyvind Urke-Sætre +- Andrew Chow +- Anthony Towns +- BtcDrak +- Chris Stewart +- Christian Barcenas +- Cory Fields +- Dagur Valberg Johannsson +- Ethan Heilman +- Gaurav Rana +- Gregory Maxwell +- Jameson Lopp +- Jeremy Rubin +- Johnson Lau +- Jonas Schnelli +- Justin Camarena +- Kaz Wesley +- Luke Dashjr +- MarcoFalke +- Marty Jones +- Matt Corallo +- Michael Ford +- Pavel Janík +- Pieter Wuille +- Sev +- Suhas Daftuar +- Wladimir J. van der Laan +- adlawren +- crowning- +- fanquake +- instagibbs +- isle2983 +- jnewbery +- jonnynewbs +- leijurv +- rodasmith +- whythat As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 614ef85ff97602c31f471436004210a74f2d8946 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 17 Oct 2016 18:49:28 +0200 Subject: [PATCH 1096/1223] doc: Properly sort authors list --- doc/release-notes.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3007815dd..24540bfcc 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -173,6 +173,7 @@ Credits Thanks to everyone who directly contributed to this release: +- adlawren - Alexey Vesnin - Anders Øyvind Urke-Sætre - Andrew Chow @@ -181,16 +182,23 @@ Thanks to everyone who directly contributed to this release: - Chris Stewart - Christian Barcenas - Cory Fields +- crowning- - Dagur Valberg Johannsson - Ethan Heilman +- fanquake - Gaurav Rana - Gregory Maxwell +- instagibbs +- isle2983 - Jameson Lopp - Jeremy Rubin +- jnewbery - Johnson Lau - Jonas Schnelli +- jonnynewbs - Justin Camarena - Kaz Wesley +- leijurv - Luke Dashjr - MarcoFalke - Marty Jones @@ -198,18 +206,10 @@ Thanks to everyone who directly contributed to this release: - Michael Ford - Pavel Janík - Pieter Wuille +- rodasmith - Sev - Suhas Daftuar -- Wladimir J. van der Laan -- adlawren -- crowning- -- fanquake -- instagibbs -- isle2983 -- jnewbery -- jonnynewbs -- leijurv -- rodasmith - whythat +- Wladimir J. van der Laan As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 06d15fbea6fafb714f9576664422615704ad05fb Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 17 Oct 2016 17:09:38 +0200 Subject: [PATCH 1097/1223] Update implemented bips for 0.13.1 Github-Pull: #8939 Rebased-From: 0941f556b7f228517fcb35f8b19926dfd62f481c --- doc/bips.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/bips.md b/doc/bips.md index 040439fbc..4f4161008 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -26,9 +26,9 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). -* [`BIP 141`](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki): Segregated Witness (Consensus Layer) as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). -* [`BIP 143`](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki): Transaction Signature Verification for Version 0 Witness Program as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 141`](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki): Segregated Witness (Consensus Layer) as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)), and defined for mainnet as of **v0.13.1** ([PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). +* [`BIP 143`](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki): Transaction Signature Verification for Version 0 Witness Program as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)) and defined for mainnet as of **v0.13.1** ([PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). * [`BIP 144`](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki): Segregated Witness as of **0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). * [`BIP 145`](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki): getblocktemplate updates for Segregated Witness as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). -* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636)). +* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636) and [PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). * [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)). From fa161e8cc1dc2b9a52e61973369c7cbe516900ac Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 17 Oct 2016 19:28:18 +0200 Subject: [PATCH 1098/1223] [doc] 0.13.1: Minor clarification to release notes --- doc/release-notes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 24540bfcc..c5719e0bd 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -63,7 +63,7 @@ git merge commit are mentioned. - #8937 `8b66659` Define start and end time for segwit deployment (sipa) ### RPC and other APIs -- #8581 `526d2b0` Drop misleading option (MarcoFalke) +- #8581 `526d2b0` Drop misleading option in importprunedfunds (MarcoFalke) - #8699 `a5ec248` Remove createwitnessaddress RPC command (jl2012) - #8780 `794b007` Deprecate getinfo (MarcoFalke) - #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) @@ -107,7 +107,6 @@ git merge commit are mentioned. - #7579 `f1c0d78` Show network/chain errors in the GUI (jonasschnelli) ### Wallet -- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) - #8443 `464dedd` Trivial cleanup of HD wallet changes (jonasschnelli) - #8539 `cb07f19` CDB: fix debug output (crowning-) - #8664 `091cdeb` Fix segwit-related wallet bug (sdaftuar) @@ -116,6 +115,7 @@ git merge commit are mentioned. ### Tests and QA - #8713 `ae8c7df` create_cache: Delete temp dir when done (MarcoFalke) +- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) - #8750 `d6ebe13` Refactor RPCTestHandler to prevent TimeoutExpired (MarcoFalke) - #8652 `63462c2` remove root test directory for RPC tests (yurizhykin) - #8724 `da94272` walletbackup: Sync blocks inside the loop (MarcoFalke) @@ -165,7 +165,7 @@ git merge commit are mentioned. - #8817 `bcf3806` update bitcoin-tx to output witness data (jnewbery) - #8513 `4e5fc31` Fix a type error that would not compile on OSX. (JeremyRubin) - #8392 `30eac2d` Fix several node initialization issues (sipa) -- #8548 `305d8ac` Use __func__ to get function name for output printing (MarcoFalke) +- #8548 `305d8ac` Use `__func__` to get function name for output printing (MarcoFalke) - #8291 `a987431` [util] CopyrightHolders: Check for untranslated substitution (MarcoFalke) Credits From 9aa0c1597230ef2c50f751960865102e3c938425 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 17 Oct 2016 11:25:25 -0400 Subject: [PATCH 1099/1223] Comment that most dnsseeds only support some service bits combos Github-Pull: #8940 Rebased-From: 504c72ad346a1b619f1fc58d0edce91ec955a67d --- src/chainparams.cpp | 5 +++-- src/net.cpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3be2d2ff8..4344ec930 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -114,12 +114,13 @@ public: assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille + // Note that of those with the service bits flag, most only support a subset of possible options + vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik - vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli + vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); diff --git a/src/net.cpp b/src/net.cpp index 5e38ec077..e44c66c2a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1489,6 +1489,7 @@ static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredSe return data.host; } + // See chainparams.cpp, most dnsseeds only support one or two possible servicebits hostnames return strprintf("x%x.%s", *requiredServiceBits, data.host); } From 3d770a88d3863220742776f02f3c35aa274e1e0c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 17 Oct 2016 11:25:52 -0400 Subject: [PATCH 1100/1223] Add x9 service bit support to dnsseed.bluematt.me Github-Pull: #8940 Rebased-From: ffb4713920205db39bfd219b6162986a52ddf32b --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4344ec930..bd0406016 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -116,7 +116,7 @@ public: // Note that of those with the service bits flag, most only support a subset of possible options vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd - vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo + vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9 vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik From 5b4192bc4c401245e9c225c99c21efd0808e6162 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 17 Oct 2016 13:27:23 -0400 Subject: [PATCH 1101/1223] My DNS seed supports filtering Currently supports filtering by any combination of the 4 least significant bits. Github-Pull: #8940 Rebased-From: 2449e12681ab549695f143d9b3ad2c24be03a78d --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index bd0406016..3ad9f4d2d 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -118,7 +118,7 @@ public: vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9 vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr - vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker + vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd From e1169b052991671db1043f432a85b31f9245a4c2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 17 Oct 2016 19:49:52 +0200 Subject: [PATCH 1102/1223] doc: Update release notes for last-minute pulls --- doc/release-notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index c5719e0bd..3d83be964 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -89,6 +89,7 @@ git merge commit are mentioned. - #8612 `2215c22` Check for compatibility with download in FindNextBlocksToDownload (sipa) - #8606 `bbf379b` Fix some locks (sipa) - #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) +- #8940 `5b4192b` Add x9 service bit support to dnsseed.bluematt.me, seed.bitcoinstats.com (TheBlueMatt, cdecker) ### Build system - #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) @@ -157,6 +158,7 @@ git merge commit are mentioned. - #8625 `0a35573` Clarify statement about parallel jobs in rpc-tests.py (isle2983) - #8624 `0e6d753` build: Mention curl (MarcoFalke) - #8604 `b09e13c` build,doc: Update for 0.13.0+ and OpenBSD 5.9 (laanwj) +- #8939 `06d15fb` Update implemented bips for 0.13.1 (sipa) ### Miscellaneous - #8742 `d31ac72` Specify Protobuf version 2 in paymentrequest.proto (fanquake) @@ -181,6 +183,7 @@ Thanks to everyone who directly contributed to this release: - BtcDrak - Chris Stewart - Christian Barcenas +- Christian Decker - Cory Fields - crowning- - Dagur Valberg Johannsson From 5f9c7b0abd080862d1fa0b410996eced0884a96f Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Mon, 17 Oct 2016 13:52:20 -0400 Subject: [PATCH 1103/1223] Release notes: add info about segwit and null dummy soft forks [no ci] --- doc/release-notes.md | 82 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3d83be964..609fd6def 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 0.13.x is now available from: +Bitcoin Core version 0.13.1 is now available from: - + This is a new major version release, including new features, various bugfixes and performance improvements, as well as updated translations. @@ -38,8 +38,82 @@ report issues about Windows XP to the issue tracker. Notable changes =============== -Example item --------------- +Segregated witness soft fork +---------------------------- + +Segregated witness (segwit) is a soft fork that, if activated, will +allow transaction-producing software to separate (segregate) transaction +signatures (witnesses) from the rest of the data in a transaction, and +to allow miners to place those witnesses outside of the traditional +block structure. This provides two immediate benefits: + +- **Elimination of malleability:** Segregating the witness allows both + existing software and upgraded software that receives transactions to + calculate the transaction identifier (txid) of segwit-using + transactions without referencing the witness. This solves all known + cases of unwanted third-party transaction malleability, which is a + problem that makes programming Bitcoin wallet software more difficult + and which seriously complicates the design of smart contracts for + Bitcoin. + +- **Capacity increase:** Moving witness data outside of the traditional + block structure (but still inside a new-style block structure) means + new-style blocks can hold more data than older-style blocks, allowing + a modest increase to the amount of transaction data that can fit in a + block. + +Segwit also simplifies the ability to add new features to Bitcoin and +improves the efficiency of full nodes, which will help provide long-term +benefits to Bitcoin users. + +Activation for the segwit soft fork is being managed using BIP9 versionbits. +The earliest activation date is set to 15 November 2016 (UTC) and +its versionbit is bit 1. + +For more information about segwit, please see the [segwit FAQ][], the +[segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], +[144][BIP144], and [145][BIP145]. If you're a miner or mining pool +operator, please see the [versionbits FAQ][] for information about +signaling support for a soft fork. + +[Segwit FAQ]: https://bitcoincore.org/en/2016/01/26/segwit-benefits/ +[segwit wallet developers guide]: https://bitcoincore.org/en/segwit_wallet_dev/ +[BIP141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki +[BIP143]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki +[BIP144]: https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki +[BIP145]: https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki +[versionbits FAQ]: https://bitcoincore.org/en/2016/06/08/version-bits-miners-faq/ + + +Null dummy soft fork +------------------- + +Combined with the segwit soft fork is a soft fork that turns a +long-existing network relay policy into a consensus rule. The +`OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY` opcodes consume an extra +stack element ("dummy element") after signature validation. The dummy +element is not inspected in any manner, and could be replaced by any +value without invalidating the script. + +Because any value can be used for this dummy element, it's possible for +a third-party to insert data into other people's transactions, changing +the transaction's txid (called transaction malleability) and possibly +causing other problems. + +Since Bitcoin Core 0.10.0, nodes have defaulted to only relaying and +mining transactions whose dummy element was a null value (0x00, also +called OP_0). The null dummy soft fork turns this relay rule into a +consensus rule both for non-segwit transactions and segwit transactions, +so that this method of mutating transactions is permanently eliminated +from the network. + +Signaling for the null dummy soft fork is done by signaling support +for segwit, and the null dummy soft fork will activate at the same time +as segwit. + +For more information, please see [BIP147][]. + +[BIP147]: https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki Low-level RPC changes --------------------- From 2de93f0a9bf244d23aa9ebbea99c412d6de82473 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Mon, 17 Oct 2016 14:05:21 -0400 Subject: [PATCH 1104/1223] Relase notes: correct segwit activation point --- doc/release-notes.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 609fd6def..55c764d7c 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -66,9 +66,12 @@ Segwit also simplifies the ability to add new features to Bitcoin and improves the efficiency of full nodes, which will help provide long-term benefits to Bitcoin users. -Activation for the segwit soft fork is being managed using BIP9 versionbits. -The earliest activation date is set to 15 November 2016 (UTC) and -its versionbit is bit 1. +Activation for the segwit soft fork is being managed using BIP9 +versionbits. Segwit's version bit is bit 1, and nodes will begin +tracking which blocks signal support for segwit on 15 November 2016 +(UTC). If 95% of blocks within a 2,016-block retarget period (about two +weeks) signal support for segwit, the soft fork will be locked in. +After another 2,016 blocks, segwit will activate. For more information about segwit, please see the [segwit FAQ][], the [segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], From bf86073e45b475c37bc250c03d1f05a18fc9a190 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Mon, 17 Oct 2016 14:14:14 -0400 Subject: [PATCH 1105/1223] Release notes: correct segwit signalling period start conditions [ci skip] --- doc/release-notes.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 55c764d7c..d107f305d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -68,10 +68,11 @@ benefits to Bitcoin users. Activation for the segwit soft fork is being managed using BIP9 versionbits. Segwit's version bit is bit 1, and nodes will begin -tracking which blocks signal support for segwit on 15 November 2016 -(UTC). If 95% of blocks within a 2,016-block retarget period (about two -weeks) signal support for segwit, the soft fork will be locked in. -After another 2,016 blocks, segwit will activate. +tracking which blocks signal support for segwit at the beginning of the +first retarget period after segwit's start date of 15 November 2016. If +95% of blocks within a 2,016-block retarget period (about two weeks) +signal support for segwit, the soft fork will be locked in. After +another 2,016 blocks, segwit will activate. For more information about segwit, please see the [segwit FAQ][], the [segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], From c9ffe9044da08773039060983632cc3fbd4f0eb8 Mon Sep 17 00:00:00 2001 From: Micha Date: Tue, 18 Oct 2016 00:04:06 +0300 Subject: [PATCH 1106/1223] Add historical release notes for v0.13.0 [skip ci] --- doc/release-notes/release-notes-0.13.0.md | 863 ++++++++++++++++++++++ 1 file changed, 863 insertions(+) create mode 100644 doc/release-notes/release-notes-0.13.0.md diff --git a/doc/release-notes/release-notes-0.13.0.md b/doc/release-notes/release-notes-0.13.0.md new file mode 100644 index 000000000..f9bf3d75d --- /dev/null +++ b/doc/release-notes/release-notes-0.13.0.md @@ -0,0 +1,863 @@ +Bitcoin Core version 0.13.0 is now available from: + + + +This is a new major version release, including new features, various bugfixes +and performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer verion of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +Notable changes +=============== + +Database cache memory increased +-------------------------------- + +As a result of growth of the UTXO set, performance with the prior default +database cache of 100 MiB has suffered. +For this reason the default was changed to 300 MiB in this release. + +For nodes on low-memory systems, the database cache can be changed back to +100 MiB (or to another value) by either: + +- Adding `dbcache=100` in bitcoin.conf +- Changing it in the GUI under `Options → Size of database cache` + +Note that the database cache setting has the most performance impact +during initial sync of a node, and when catching up after downtime. + + +bitcoin-cli: arguments privacy +------------------------------ + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ src/bitcoin-cli -stdin walletpassphrase + mysecretcode + 120 + ..... press Ctrl-D here to end input + $ + +It is recommended to use this for sensitive information such as wallet +passphrases, as command-line arguments can usually be read from the process +table by any user on the system. + + +C++11 and Python 3 +------------------ + +Various code modernizations have been done. The Bitcoin Core code base has +started using C++11. This means that a C++11-capable compiler is now needed for +building. Effectively this means GCC 4.7 or higher, or Clang 3.3 or higher. + +When cross-compiling for a target that doesn't have C++11 libraries, configure with +`./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++`. + +For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now +required. + + +Linux ARM builds +---------------- + +Due to popular request, Linux ARM builds have been added to the uploaded +executables. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries for the most + common 32-bit ARM architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries for the most + common 64-bit ARM architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + + +Compact Block support (BIP 152) +------------------------------- + +Support for block relay using the Compact Blocks protocol has been implemented +in PR 8068. + +The primary goal is reducing the bandwidth spikes at relay time, though in many +cases it also reduces propagation delay. It is automatically enabled between +compatible peers. +[BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) + +As a side-effect, ordinary non-mining nodes will download and upload blocks +faster if those blocks were produced by miners using similar transaction +filtering policies. This means that a miner who produces a block with many +transactions discouraged by your node will be relayed slower than one with +only transactions already in your memory pool. The overall effect of such +relay differences on the network may result in blocks which include widely- +discouraged transactions losing a stale block race, and therefore miners may +wish to configure their node to take common relay policies into consideration. + + +Hierarchical Deterministic Key Generation +----------------------------------------- +Newly created wallets will use hierarchical deterministic key generation +according to BIP32 (keypath m/0'/0'/k'). +Existing wallets will still use traditional key generation. + +Backups of HD wallets, regardless of when they have been created, can +therefore be used to re-generate all possible private keys, even the +ones which haven't already been generated during the time of the backup. +**Attention:** Encrypting the wallet will create a new seed which requires +a new backup! + +Wallet dumps (created using the `dumpwallet` RPC) will contain the deterministic +seed. This is expected to allow future versions to import the seed and all +associated funds, but this is not yet implemented. + +HD key generation for new wallets can be disabled by `-usehd=0`. Keep in +mind that this flag only has affect on newly created wallets. +You can't disable HD key generation once you have created a HD wallet. + +There is no distinction between internal (change) and external keys. + +HD wallets are incompatible with older versions of Bitcoin Core. + +[Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + + +Segregated Witness +------------------ + +The code preparations for Segregated Witness ("segwit"), as described in [BIP +141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP +143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP +144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki), and [BIP +145](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki) are +finished and included in this release. However, BIP 141 does not yet specify +activation parameters on mainnet, and so this release does not support segwit +use on mainnet. Testnet use is supported, and after BIP 141 is updated with +proposed parameters, a future release of Bitcoin Core is expected that +implements those parameters for mainnet. + +Furthermore, because segwit activation is not yet specified for mainnet, +version 0.13.0 will behave similarly as other pre-segwit releases even after a +future activation of BIP 141 on the network. Upgrading from 0.13.0 will be +required in order to utilize segwit-related features on mainnet (such as signal +BIP 141 activation, mine segwit blocks, fully validate segwit blocks, relay +segwit blocks to other segwit nodes, and use segwit transactions in the +wallet, etc). + + +Mining transaction selection ("Child Pays For Parent") +------------------------------------------------------ + +The mining transaction selection algorithm has been replaced with an algorithm +that selects transactions based on their feerate inclusive of unconfirmed +ancestor transactions. This means that a low-fee transaction can become more +likely to be selected if a high-fee transaction that spends its outputs is +relayed. + +With this change, the `-blockminsize` command line option has been removed. + +The command line option `-blockmaxsize` remains an option to specify the +maximum number of serialized bytes in a generated block. In addition, the new +command line option `-blockmaxweight` has been added, which specifies the +maximum "block weight" of a generated block, as defined by [BIP 141 (Segregated +Witness)] (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki). + +In preparation for Segregated Witness, the mining algorithm has been modified +to optimize transaction selection for a given block weight, rather than a given +number of serialized bytes in a block. In this release, transaction selection +is unaffected by this distinction (as BIP 141 activation is not supported on +mainnet in this release, see above), but in future releases and after BIP 141 +activation, these calculations would be expected to differ. + +For optimal runtime performance, miners using this release should specify +`-blockmaxweight` on the command line, and not specify `-blockmaxsize`. +Additionally (or only) specifying `-blockmaxsize`, or relying on default +settings for both, may result in performance degradation, as the logic to +support `-blockmaxsize` performs additional computation to ensure that +constraint is met. (Note that for mainnet, in this release, the equivalent +parameter for `-blockmaxweight` would be four times the desired +`-blockmaxsize`. See [BIP 141] +(https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) for additional +details.) + +In the future, the `-blockmaxsize` option may be removed, as block creation is +no longer optimized for this metric. Feedback is requested on whether to +deprecate or keep this command line option in future releases. + + +Reindexing changes +------------------ + +In earlier versions, reindexing did validation while reading through the block +files on disk. These two have now been split up, so that all blocks are known +before validation starts. This was necessary to make certain optimizations that +are available during normal synchronizations also available during reindexing. + +The two phases are distinct in the Bitcoin-Qt GUI. During the first one, +"Reindexing blocks on disk" is shown. During the second (slower) one, +"Processing blocks on disk" is shown. + +It is possible to only redo validation now, without rebuilding the block index, +using the command line option `-reindex-chainstate` (in addition to +`-reindex` which does both). This new option is useful when the blocks on disk +are assumed to be fine, but the chainstate is still corrupted. It is also +useful for benchmarks. + + +Removal of internal miner +-------------------------- + +As CPU mining has been useless for a long time, the internal miner has been +removed in this release, and replaced with a simpler implementation for the +test framework. + +The overall result of this is that `setgenerate` RPC call has been removed, as +well as the `-gen` and `-genproclimit` command-line options. + +For testing, the `generate` call can still be used to mine a block, and a new +RPC call `generatetoaddress` has been added to mine to a specific address. This +works with wallet disabled. + + +New bytespersigop implementation +-------------------------------- + +The former implementation of the bytespersigop filter accidentally broke bare +multisig (which is meant to be controlled by the `permitbaremultisig` option), +since the consensus protocol always counts these older transaction forms as 20 +sigops for backwards compatibility. Simply fixing this bug by counting more +accurately would have reintroduced a vulnerability. It has therefore been +replaced with a new implementation that rather than filter such transactions, +instead treats them (for fee purposes only) as if they were in fact the size +of a transaction actually using all 20 sigops. + + +Low-level P2P changes +---------------------- + +- The optional new p2p message "feefilter" is implemented and the protocol + version is bumped to 70013. Upon receiving a feefilter message from a peer, + a node will not send invs for any transactions which do not meet the filter + feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) + +- The P2P alert system has been removed in PR #7692 and the `alert` P2P message + is no longer supported. + +- The transaction relay mechanism used to relay one quarter of all transactions + instantly, while queueing up the rest and sending them out in batch. As + this resulted in chains of dependent transactions being reordered, it + systematically hurt transaction relay. The relay code was redesigned in PRs + \#7840 and #8082, and now always batches transactions announcements while also + sorting them according to dependency order. This significantly reduces orphan + transactions. To compensate for the removal of instant relay, the frequency of + batch sending was doubled for outgoing peers. + +- Since PR #7840 the BIP35 `mempool` command is also subject to batch processing. + Also the `mempool` message is no longer handled for non-whitelisted peers when + `NODE_BLOOM` is disabled through `-peerbloomfilters=0`. + +- The maximum size of orphan transactions that are kept in memory until their + ancestors arrive has been raised in PR #8179 from 5000 to 99999 bytes. They + are now also removed from memory when they are included in a block, conflict + with a block, and time out after 20 minutes. + +- We respond at most once to a getaddr request during the lifetime of a + connection since PR #7856. + +- Connections to peers who have recently been the first one to give us a valid + new block or transaction are protected from disconnections since PR #8084. + + +Low-level RPC changes +---------------------- + +- RPC calls have been added to output detailed statistics for individual mempool + entries, as well as to calculate the in-mempool ancestors or descendants of a + transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. + +- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between + 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been + fixed, but this means that the output will be different than from previous versions. + +- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, + wallet labels have always been malformed because they weren't taken into account + properly in JSON RPC processing. This is no longer the case. This also affects + the GUI debug console. + +- Asm script outputs replacements for OP_NOP2 and OP_NOP3 + + - OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP +65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) + + - OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP +112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) + + - The following outputs are affected by this change: + + - RPC `getrawtransaction` (in verbose mode) + - RPC `decoderawtransaction` + - RPC `decodescript` + - REST `/rest/tx/` (JSON format) + - REST `/rest/block/` (JSON format when including extended tx details) + - `bitcoin-tx -json` + +- The sorting of the output of the `getrawmempool` output has changed. + +- New RPC commands: `generatetoaddress`, `importprunedfunds`, `removeprunedfunds`, `signmessagewithprivkey`, + `getmempoolancestors`, `getmempooldescendants`, `getmempoolentry`, + `createwitnessaddress`, `addwitnessaddress`. + +- Removed RPC commands: `setgenerate`, `getgenerate`. + +- New options were added to `fundrawtransaction`: `includeWatching`, `changeAddress`, `changePosition` and `feeRate`. + + +Low-level ZMQ changes +---------------------- + +- Each ZMQ notification now contains an up-counting sequence number that allows + listeners to detect lost notifications. + The sequence number is always the last element in a multi-part ZMQ notification and + therefore backward compatible. Each message type has its own counter. + PR [#7762](https://github.com/bitcoin/bitcoin/pull/7762). + + +0.13.0 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### RPC and other APIs + +- #7156 `9ee02cf` Remove cs_main lock from `createrawtransaction` (laanwj) +- #7326 `2cd004b` Fix typo, wrong information in gettxout help text (paveljanik) +- #7222 `82429d0` Indicate which transactions are signaling opt-in RBF (sdaftuar) +- #7480 `b49a623` Changed getnetworkhps value to double to avoid overflow (instagibbs) +- #7550 `8b958ab` Input-from-stdin mode for bitcoin-cli (laanwj) +- #7670 `c9a1265` Use cached block hash in blockToJSON() (rat4) +- #7726 `9af69fa` Correct importaddress help reference to importpubkey (CypherGrue) +- #7766 `16555b6` Register calls where they are defined (laanwj) +- #7797 `e662a76` Fix generatetoaddress failing to parse address (mruddy) +- #7774 `916b15a` Add versionHex in getblock and getblockheader JSON results (mruddy) +- #7863 `72c54e3` Getblockchaininfo: make bip9_softforks an object, not an array (rustyrussell) +- #7842 `d97101e` Do not print minping time in getpeerinfo when no ping received yet (paveljanik) +- #7518 `be14ca5` Add multiple options to fundrawtransaction (promag) +- #7756 `9e47fce` Add cursor to iterate over utxo set, use this in `gettxoutsetinfo` (laanwj) +- #7848 `88616d2` Divergence between 32- and 64-bit when hashing >4GB affects `gettxoutsetinfo` (laanwj) +- #7827 `4205ad7` Speed up `getchaintips` (mrbandrews) +- #7762 `a1eb344` Append a message sequence number to every ZMQ notification (jonasschnelli) +- #7688 `46880ed` List solvability in listunspent output and improve help (sipa) +- #7926 `5725807` Push back `getaddednodeinfo` dead value (instagibbs) +- #7953 `0630353` Create `signmessagewithprivkey` rpc (achow101) +- #8049 `c028c7b` Expose information on whether transaction relay is enabled in `getnetworkinfo` (laanwj) +- #7967 `8c1e49b` Add feerate option to `fundrawtransaction` (jonasschnelli) +- #8118 `9b6a48c` Reduce unnecessary hashing in `signrawtransaction` (jonasnick) +- #7957 `79004d4` Add support for transaction sequence number (jonasschnelli) +- #8153 `75ec320` `fundrawtransaction` feeRate: Use BTC/kB (MarcoFalke) +- #7292 `7ce9ac5` Expose ancestor/descendant information over RPC (sdaftuar) +- #8171 `62fcf27` Fix createrawtx sequence number unsigned int parsing (jonasschnelli) +- #7892 `9c3d0fa` Add full UTF-8 support to RPC (laanwj) +- #8317 `304eff3` Don't use floating point in rpcwallet (MarcoFalke) +- #8258 `5a06ebb` Hide softfork in `getblockchaininfo` if timeout is 0 (jl2012) +- #8244 `1922e5a` Remove unnecessary LOCK(cs_main) in getrawmempool (dcousens) + +### Block and transaction handling + +- #7056 `6a07208` Save last db read (morcos) +- #6842 `0192806` Limitfreerelay edge case bugfix (ptschip) +- #7084 `11d74f6` Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee in mempool (MarcoFalke) +- #7539 `9f33dba` Add tags to mempool's mapTx indices (sdaftuar) +- #7592 `26a2a72` Re-remove ERROR logging for mempool rejects (laanwj) +- #7187 `14d6324` Keep reorgs fast for SequenceLocks checks (morcos) +- #7594 `01f4267` Mempool: Add tracking of ancestor packages (sdaftuar) +- #7904 `fc9e334` Txdb: Fix assert crash in new UTXO set cursor (laanwj) +- #7927 `f9c2ac7` Minor changes to dbwrapper to simplify support for other databases (laanwj) +- #7933 `e26b620` Fix OOM when deserializing UTXO entries with invalid length (sipa) +- #8020 `5e374f7` Use SipHash-2-4 for various non-cryptographic hashes (sipa) +- #8076 `d720980` VerifyDB: don't check blocks that have been pruned (sdaftuar) +- #8080 `862fd24` Do not use mempool for GETDATA for tx accepted after the last mempool req (gmaxwell) +- #7997 `a82f033` Replace mapNextTx with slimmer setSpends (kazcw) +- #8220 `1f86d64` Stop trimming when mapTx is empty (sipa) +- #8273 `396f9d6` Bump `-dbcache` default to 300MiB (laanwj) +- #7225 `eb33179` Eliminate unnecessary call to CheckBlock (sdaftuar) +- #7907 `006cdf6` Optimize and Cleanup CScript::FindAndDelete (pstratem) +- #7917 `239d419` Optimize reindex (sipa) +- #7763 `3081fb9` Put hex-encoded version in UpdateTip (sipa) +- #8149 `d612837` Testnet-only segregated witness (sipa) +- #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) +- #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) +- #8381 `f84ee3d` Make witness v0 outputs non-standard (jl2012) +- #8364 `3f65ba2` Treat high-sigop transactions as larger rather than rejecting them (sipa) + +### P2P protocol and network code + +- #6589 `dc0305d` Log bytes recv/sent per command (jonasschnelli) +- #7164 `3b43cad` Do not download transactions during initial blockchain sync (ptschip) +- #7458 `898fedf` peers.dat, banlist.dat recreated when missing (kirkalx) +- #7637 `3da5d1b` Fix memleak in TorController (laanwj, jonasschnelli) +- #7553 `9f14e5a` Remove vfReachable and modify IsReachable to only use vfLimited (pstratem) +- #7708 `9426632` De-neuter NODE_BLOOM (pstratem) +- #7692 `29b2be6` Remove P2P alert system (btcdrak) +- #7542 `c946a15` Implement "feefilter" P2P message (morcos) +- #7573 `352fd57` Add `-maxtimeadjustment` command line option (mruddy) +- #7570 `232592a` Add IPv6 Link-Local Address Support (mruddy) +- #7874 `e6a4d48` Improve AlreadyHave (morcos) +- #7856 `64e71b3` Only send one GetAddr response per connection (gmaxwell) +- #7868 `7daa3ad` Split DNS resolving functionality out of net structures (theuni) +- #7919 `7617682` Fix headers announcements edge case (sdaftuar) +- #7514 `d9594bf` Fix IsInitialBlockDownload for testnet (jmacwhyte) +- #7959 `03cf6e8` fix race that could fail to persist a ban (kazcw) +- #7840 `3b9a0bf` Several performance and privacy improvements to inv/mempool handling (sipa) +- #8011 `65aecda` Don't run ThreadMessageHandler at lowered priority (kazcw) +- #7696 `5c3f8dd` Fix de-serialization bug where AddrMan is left corrupted (EthanHeilman) +- #7932 `ed749bd` CAddrMan::Deserialize handle corrupt serializations better (pstratem) +- #7906 `83121cc` Prerequisites for p2p encapsulation changes (theuni) +- #8033 `18436d8` Fix Socks5() connect failures to be less noisy and less unnecessarily scary (wtogami) +- #8082 `01d8359` Defer inserting into maprelay until just before relaying (gmaxwell) +- #7960 `6a22373` Only use AddInventoryKnown for transactions (sdaftuar) +- #8078 `2156fa2` Disable the mempool P2P command when bloom filters disabled (petertodd) +- #8065 `67c91f8` Addrman offline attempts (gmaxwell) +- #7703 `761cddb` Tor: Change auth order to only use password auth if -torpassword (laanwj) +- #8083 `cd0c513` Add support for dnsseeds with option to filter by servicebits (jonasschnelli) +- #8173 `4286f43` Use SipHash for node eviction (sipa) +- #8154 `1445835` Drop vAddrToSend after sending big addr message (kazcw) +- #7749 `be9711e` Enforce expected outbound services (sipa) +- #8208 `0a64777` Do not set extra flags for unfiltered DNS seed results (sipa) +- #8084 `e4bb4a8` Add recently accepted blocks and txn to AttemptToEvictConnection (gmaxwell) +- #8113 `3f89a53` Rework addnode behaviour (sipa) +- #8179 `94ab58b` Evict orphans which are included or precluded by accepted blocks (gmaxwell) +- #8068 `e9d76a1` Compact Blocks (TheBlueMatt) +- #8204 `0833894` Update petertodd's testnet seed (petertodd) +- #8247 `5cd35d3` Mark my dnsseed as supporting filtering (sipa) +- #8275 `042c323` Remove bad chain alert partition check (btcdrak) +- #8271 `1bc9c80` Do not send witnesses in cmpctblock (sipa) +- #8312 `ca40ef6` Fix mempool DoS vulnerability from malleated transactions (sdaftuar) +- #7180 `16ccb74` Account for `sendheaders` `verack` messages (laanwj) +- #8102 `425278d` Bugfix: use global ::fRelayTxes instead of CNode in version send (sipa) +- #8408 `b7e2011` Prevent fingerprinting, disk-DoS with compact blocks (sdaftuar) + +### Build system + +- #7302 `41f1a3e` C++11 build/runtime fixes (theuni) +- #7322 `fd9356b` c++11: add scoped enum fallbacks to CPPFLAGS rather than defining them locally (theuni) +- #7441 `a6771fc` Use Debian 8.3 in gitian build guide (fanquake) +- #7349 `152a821` Build against system UniValue when available (luke-jr) +- #7520 `621940e` LibreSSL doesn't define OPENSSL_VERSION, use LIBRESSL_VERSION_TEXT instead (paveljanik) +- #7528 `9b9bfce` autogen.sh: warn about needing autoconf if autoreconf is not found (knocte) +- #7504 `19324cf` Crystal clean make clean (paveljanik) +- #7619 `18b3f1b` Add missing sudo entry in gitian VM setup (btcdrak) +- #7616 `639ec58` [depends] Delete unused patches (MarcoFalke) +- #7658 `c15eb28` Add curl to Gitian setup instructions (btcdrak) +- #7710 `909b72b` [Depends] Bump miniupnpc and config.guess+sub (fanquake) +- #7723 `5131005` build: python 3 compatibility (laanwj) +- #7477 `28ad4d9` Fix quoting of copyright holders in configure.ac (domob1812) +- #7711 `a67bc5e` [build-aux] Update Boost & check macros to latest serials (fanquake) +- #7788 `4dc1b3a` Use relative paths instead of absolute paths in protoc calls (paveljanik) +- #7809 `bbd210d` depends: some base fixes/changes (theuni) +- #7603 `73fc922` Build System: Use PACKAGE_TARNAME in NSIS script (JeremyRand) +- #7905 `187186b` test: move accounting_tests and rpc_wallet_tests to wallet/test (laanwj) +- #7911 `351abf9` leveldb: integrate leveldb into our buildsystem (theuni) +- #7944 `a407807` Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035 (randy-waterhouse) +- #7920 `c3e3cfb` Switch Travis to Trusty (theuni) +- #7954 `08b37c5` build: quiet annoying warnings without adding new ones (theuni) +- #7165 `06162f1` build: Enable C++11 in build, require C++11 compiler (laanwj) +- #7982 `559fbae` build: No need to check for leveldb atomics (theuni) +- #8002 `f9b4582` [depends] Add -stdlib=libc++ to darwin CXX flags (fanquake) +- #7993 `6a034ed` [depends] Bump Freetype, ccache, ZeroMQ, miniupnpc, expat (fanquake) +- #8167 `19ea173` Ship debug tarballs/zips with debug symbols (theuni) +- #8175 `f0299d8` Add --disable-bench to config flags for windows (laanwj) +- #7283 `fd9881a` [gitian] Default reference_datetime to commit author date (MarcoFalke) +- #8181 `9201ce8` Get rid of `CLIENT_DATE` (laanwj) +- #8133 `fde0ac4` Finish up out-of-tree changes (theuni) +- #8188 `65a9d7d` Add armhf/aarch64 gitian builds (theuni) +- #8194 `cca1c8c` [gitian] set correct PATH for wrappers (MarcoFalke) +- #8198 `5201614` Sync ax_pthread with upstream draft4 (fanquake) +- #8210 `12a541e` [Qt] Bump to Qt5.6.1 (jonasschnelli) +- #8285 `da50997` windows: Add testnet link to installer (laanwj) +- #8304 `0cca2fe` [travis] Update SDK_URL (MarcoFalke) +- #8310 `6ae20df` Require boost for bench (theuni) +- #8315 `2e51590` Don't require sudo for Linux (theuni) +- #8314 `67caef6` Fix pkg-config issues for 0.13 (theuni) +- #8373 `1fe7f40` Fix OSX non-deterministic dmg (theuni) +- #8358 `cfd1280` Gbuild: Set memory explicitly (default is too low) (MarcoFalke) + +### GUI + +- #7154 `00b4b8d` Add InMempool() info to transaction details (jonasschnelli) +- #7068 `5f3c670` [RPC-Tests] add simple way to run rpc test over QT clients (jonasschnelli) +- #7218 `a1c185b` Fix misleading translation (MarcoFalke) +- #7214 `be9a9a3` qt5: Use the fixed font the system recommends (MarcoFalke) +- #7256 `08ab906` Add note to coin control dialog QT5 workaround (fanquake) +- #7255 `e289807` Replace some instances of formatWithUnit with formatHtmlWithUnit (fanquake) +- #7317 `3b57e9c` Fix RPCTimerInterface ordering issue (jonasschnelli) +- #7327 `c079d79` Transaction View: LastMonth calculation fixed (crowning-) +- #7334 `e1060c5` coincontrol workaround is still needed in qt5.4 (fixed in qt5.5) (MarcoFalke) +- #7383 `ae2db67` Rename "amount" to "requested amount" in receive coins table (jonasschnelli) +- #7396 `cdcbc59` Add option to increase/decrease font size in the console window (jonasschnelli) +- #7437 `9645218` Disable tab navigation for peers tables (Kefkius) +- #7604 `354b03d` build: Remove spurious dollar sign. Fixes #7189 (dooglus) +- #7605 `7f001bd` Remove openssl info from init/log and from Qt debug window (jonasschnelli) +- #7628 `87d6562` Add 'copy full transaction details' option (ericshawlinux) +- #7613 `3798e5d` Add autocomplete to bitcoin-qt's console window (GamerSg) +- #7668 `b24266c` Fix history deletion bug after font size change (achow101) +- #7680 `41d2dfa` Remove reflection from `about` icon (laanwj) +- #7686 `f034bce` Remove 0-fee from send dialog (MarcoFalke) +- #7506 `b88e0b0` Use CCoinControl selection in CWallet::FundTransaction (promag) +- #7732 `0b98dd7` Debug window: replace "Build date" with "Datadir" (jonasschnelli) +- #7761 `60db51d` remove trailing output-index from transaction-id (jonasschnelli) +- #7772 `6383268` Clear the input line after activating autocomplete (paveljanik) +- #7925 `f604bf6` Fix out-of-tree GUI builds (laanwj) +- #7939 `574ddc6` Make it possible to show details for multiple transactions (laanwj) +- #8012 `b33824b` Delay user confirmation of send (Tyler-Hardin) +- #8006 `7c8558d` Add option to disable the system tray icon (Tyler-Hardin) +- #8046 `169d379` Fix Cmd-Q / Menu Quit shutdown on OSX (jonasschnelli) +- #8042 `6929711` Don't allow to open the debug window during splashscreen & verification state (jonasschnelli) +- #8014 `77b49ac` Sort transactions by date (Tyler-Hardin) +- #8073 `eb2f6f7` askpassphrasedialog: Clear pass fields on accept (rat4) +- #8129 `ee1533e` Fix RPC console auto completer (UdjinM6) +- #7636 `fb0ac48` Add bitcoin address label to request payment QR code (makevoid) +- #8231 `760a6c7` Fix a bug where the SplashScreen will not be hidden during startup (jonasschnelli) +- #8256 `af2421c` BUG: bitcoin-qt crash (fsb4000) +- #8257 `ff03c50` Do not ask a UI question from bitcoind (sipa) +- #8288 `91abb77` Network-specific example address (laanwj) +- #7707 `a914968` UI support for abandoned transactions (jonasschnelli) +- #8207 `f7a403b` Add a link to the Bitcoin-Core repository and website to the About Dialog (MarcoFalke) +- #8281 `6a87eb0` Remove client name from debug window (laanwj) +- #8407 `45eba4b` Add dbcache migration path (jonasschnelli) + +### Wallet + +- #7262 `fc08994` Reduce inefficiency of GetAccountAddress() (dooglus) +- #7537 `78e81b0` Warn on unexpected EOF while salvaging wallet (laanwj) +- #7521 `3368895` Don't resend wallet txs that aren't in our own mempool (morcos) +- #7576 `86a1ec5` Move wallet help string creation to CWallet (jonasschnelli) +- #7577 `5b3b5a7` Move "load wallet phase" to CWallet (jonasschnelli) +- #7608 `0735c0c` Move hardcoded file name out of log messages (MarcoFalke) +- #7649 `4900641` Prevent multiple calls to CWallet::AvailableCoins (promag) +- #7646 `e5c3511` Fix lockunspent help message (promag) +- #7558 `b35a591` Add import/removeprunedfunds rpc call (instagibbs) +- #6215 `48c5adf` add bip32 pub key serialization (jonasschnelli) +- #7913 `bafd075` Fix for incorrect locking in GetPubKey() (keystore.cpp) (yurizhykin) +- #8036 `41138f9` init: Move berkeleydb version reporting to wallet (laanwj) +- #8028 `373b50d` Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk (pstratem) +- #8061 `f6b7df3` Improve Wallet encapsulation (pstratem) +- #7891 `950be19` Always require OS randomness when generating secret keys (sipa) +- #7689 `b89ef13` Replace OpenSSL AES with ctaes-based version (sipa) +- #7825 `f972b04` Prevent multiple calls to ExtractDestination (pedrobranco) +- #8137 `243ac0c` Improve CWallet API with new AccountMove function (pstratem) +- #8142 `52c3f34` Improve CWallet API with new GetAccountPubkey function (pstratem) +- #8035 `b67a472` Add simplest BIP32/deterministic key generation implementation (jonasschnelli) +- #7687 `a6ddb19` Stop treating importaddress'ed scripts as change (sipa) +- #8298 `aef3811` wallet: Revert input selection post-pruning (laanwj) +- #8324 `bc94b87` Keep HD seed during salvagewallet (jonasschnelli) +- #8323 `238300b` Add HD keypath to CKeyMetadata, report metadata in validateaddress (jonasschnelli) +- #8367 `3b38a6a` Ensure <0.13 clients can't open HD wallets (jonasschnelli) +- #8378 `ebea651` Move SetMinVersion for FEATURE_HD to SetHDMasterKey (pstratem) +- #8390 `73adfe3` Correct hdmasterkeyid/masterkeyid name confusion (jonasschnelli) +- #8206 `18b8ee1` Add HD xpriv to dumpwallet (jonasschnelli) +- #8389 `c3c82c4` Create a new HD seed after encrypting the wallet (jonasschnelli) + +### Tests and QA + +- #7320 `d3dfc6d` Test walletpassphrase timeout (MarcoFalke) +- #7208 `47c5ed1` Make max tip age an option instead of chainparam (laanwj) +- #7372 `21376af` Trivial: [qa] wallet: Print maintenance (MarcoFalke) +- #7280 `668906f` [travis] Fail when documentation is outdated (MarcoFalke) +- #7177 `93b0576` [qa] Change default block priority size to 0 (MarcoFalke) +- #7236 `02676c5` Use createrawtx locktime parm in txn_clone (dgenr8) +- #7212 `326ffed` Adds unittests for CAddrMan and CAddrinfo, removes source of non-determinism (EthanHeilman) +- #7490 `d007511` tests: Remove May15 test (laanwj) +- #7531 `18cb2d5` Add bip68-sequence.py to extended rpc tests (btcdrak) +- #7536 `ce5fc02` test: test leading spaces for ParseHex (laanwj) +- #7620 `1b68de3` [travis] Only run check-doc.py once (MarcoFalke) +- #7455 `7f96671` [travis] Exit early when check-doc.py fails (MarcoFalke) +- #7667 `56d2c4e` Move GetTempPath() to testutil (musalbas) +- #7517 `f1ca891` test: script_error checking in script_invalid tests (laanwj) +- #7684 `3d0dfdb` Extend tests (MarcoFalke) +- #7697 `622fe6c` Tests: make prioritise_transaction.py more robust (sdaftuar) +- #7709 `efde86b` Tests: fix missing import in mempool_packages (sdaftuar) +- #7702 `29e1131` Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke) +- #7720 `3b4324b` rpc-test: Normalize assert() (MarcoFalke) +- #7757 `26794d4` wallet: Wait for reindex to catch up (MarcoFalke) +- #7764 `a65b36c` Don't run pruning.py twice (MarcoFalke) +- #7773 `7c80e72` Fix comments in tests (btcdrak) +- #7489 `e9723cb` tests: Make proxy_test work on travis servers without IPv6 (laanwj) +- #7801 `70ac71b` Remove misleading "errorString syntax" (MarcoFalke) +- #7803 `401c65c` maxblocksinflight: Actually enable test (MarcoFalke) +- #7802 `3bc71e1` httpbasics: Actually test second connection (MarcoFalke) +- #7849 `ab8586e` tests: add varints_bitpatterns test (laanwj) +- #7846 `491171f` Clean up lockorder data of destroyed mutexes (sipa) +- #7853 `6ef5e00` py2: Unfiddle strings into bytes explicitly (MarcoFalke) +- #7878 `53adc83` [test] bctest.py: Revert faa41ee (MarcoFalke) +- #7798 `cabba24` [travis] Print the commit which was evaluated (MarcoFalke) +- #7833 `b1bf511` tests: Check Content-Type header returned from RPC server (laanwj) +- #7851 `fa9d86f` pull-tester: Don't mute zmq ImportError (MarcoFalke) +- #7822 `0e6fd5e` Add listunspent() test for spendable/unspendable UTXO (jpdffonseca) +- #7912 `59ad568` Tests: Fix deserialization of reject messages (sdaftuar) +- #7941 `0ea3941` Fixing comment in script_test.json test case (Christewart) +- #7807 `0ad1041` Fixed miner test values, gave constants for less error-prone values (instagibbs) +- #7980 `88b77c7` Smartfees: Properly use ordered dict (MarcoFalke) +- #7814 `77b637f` Switch to py3 (MarcoFalke) +- #8030 `409a8a1` Revert fatal-ness of missing python-zmq (laanwj) +- #8018 `3e90fe6` Autofind rpc tests --srcdir (jonasschnelli) +- #8016 `5767e80` Fix multithread CScheduler and reenable test (paveljanik) +- #7972 `423ca30` pull-tester: Run rpc test in parallel (MarcoFalke) +- #8039 `69b3a6d` Bench: Add crypto hash benchmarks (laanwj) +- #8041 `5b736dd` Fix bip9-softforks blockstore issue (MarcoFalke) +- #7994 `1f01443` Add op csv tests to script_tests.json (Christewart) +- #8038 `e2bf830` Various minor fixes (MarcoFalke) +- #8072 `1b87e5b` Travis: 'make check' in parallel and verbose (theuni) +- #8056 `8844ef1` Remove hardcoded "4 nodes" from test_framework (MarcoFalke) +- #8047 `37f9a1f` Test_framework: Set wait-timeout for bitcoind procs (MarcoFalke) +- #8095 `6700cc9` Test framework: only cleanup on successful test runs (sdaftuar) +- #8098 `06bd4f6` Test_framework: Append portseed to tmpdir (MarcoFalke) +- #8104 `6ff2c8d` Add timeout to sync_blocks() and sync_mempools() (sdaftuar) +- #8111 `61b8684` Benchmark SipHash (sipa) +- #8107 `52b803e` Bench: Added base58 encoding/decoding benchmarks (yurizhykin) +- #8115 `0026e0e` Avoid integer division in the benchmark inner-most loop (gmaxwell) +- #8090 `a2df115` Adding P2SH(p2pkh) script test case (Christewart) +- #7992 `ec45cc5` Extend #7956 with one more test (TheBlueMatt) +- #8139 `ae5575b` Fix interrupted HTTP RPC connection workaround for Python 3.5+ (sipa) +- #8164 `0f24eaf` [Bitcoin-Tx] fix missing test fixtures, fix 32bit atoi issue (jonasschnelli) +- #8166 `0b5279f` Src/test: Do not shadow local variables (paveljanik) +- #8141 `44c1b1c` Continuing port of java comparison tool (mrbandrews) +- #8201 `36b7400` fundrawtransaction: Fix race, assert amounts (MarcoFalke) +- #8214 `ed2cd59` Mininode: fail on send_message instead of silent return (MarcoFalke) +- #8215 `a072d1a` Don't use floating point in wallet tests (MarcoFalke) +- #8066 `65c2058` Test_framework: Use different rpc_auth_pair for each node (MarcoFalke) +- #8216 `0d41d70` Assert 'changePosition out of bounds' (MarcoFalke) +- #8222 `961893f` Enable mempool consistency checks in unit tests (sipa) +- #7751 `84370d5` test_framework: python3.4 authproxy compat (laanwj) +- #7744 `d8e862a` test_framework: detect failure of bitcoind startup (laanwj) +- #8280 `115735d` Increase sync_blocks() timeouts in pruning.py (MarcoFalke) +- #8340 `af9b7a9` Solve trivial merge conflict in p2p-segwit.py (MarcoFalke) +- #8067 `3e4cf8f` Travis: use slim generic image, and some fixups (theuni) +- #7951 `5c7df70` Test_framework: Properly print exception (MarcoFalke) +- #8070 `7771aa5` Remove non-determinism which is breaking net_tests #8069 (EthanHeilman) +- #8309 `bb2646a` Add wallet-hd test (MarcoFalke) +- #8444 `cd0910b` Fix p2p-feefilter.py for changed tx relay behavior (sdaftuar) + +### Mining + +- #7507 `11c7699` Remove internal miner (Leviathn) +- #7663 `c87f51e` Make the generate RPC call function for non-regtest (sipa) +- #7671 `e2ebd25` Add generatetoaddress RPC to mine to an address (achow101) +- #7935 `66ed450` Versionbits: GBT support (luke-jr) +- #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) +- #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) +- #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) +- #8362 `86edc20` Scale legacy sigop count in CreateNewBlock (sdaftuar) +- #8489 `8b0eee6` Bugfix: Use pre-BIP141 sigops until segwit activates (GBT) (luke-jr) + +### Documentation and miscellaneous + +- #7423 `69e2a40` Add example for building with constrained resources (jarret) +- #8254 `c2c69ed` Add OSX ZMQ requirement to QA readme (fanquake) +- #8203 `377d131` Clarify documentation for running a tor node (nathaniel-mahieu) +- #7428 `4b12266` Add example for listing ./configure flags (nathaniel-mahieu) +- #7847 `3eae681` Add arch linux build example (mruddy) +- #7968 `ff69aaf` Fedora build requirements (wtogami) +- #8013 `fbedc09` Fedora build requirements, add gcc-c++ and fix typo (wtogami) +- #8009 `fbd8478` Fixed invalid example paths in gitian-building.md (JeremyRand) +- #8240 `63fbdbc` Mention Windows XP end of support in release notes (laanwj) +- #8303 `5077d2c` Update bips.md for CSV softfork (fanquake) +- #7789 `e0b3e19` Add note about using the Qt official binary installer (paveljanik) +- #7791 `e30a5b0` Change Precise to Trusty in gitian-building.md (JeremyRand) +- #7838 `8bb5d3d` Update gitian build guide to debian 8.4.0 (fanquake) +- #7855 `b778e59` Replace precise with trusty (MarcoFalke) +- #7975 `fc23fee` Update bitcoin-core GitHub links (MarcoFalke) +- #8034 `e3a8207` Add basic git squash workflow (fanquake) +- #7813 `214ec0b` Update port in tor.md (MarcoFalke) +- #8193 `37c9830` Use Debian 8.5 in the gitian-build guide (fanquake) +- #8261 `3685e0c` Clarify help for `getblockchaininfo` (paveljanik) +- #7185 `ea0f5a2` Note that reviewers should mention the id of the commits they reviewed (pstratem) +- #7290 `c851d8d` [init] Add missing help for args (MarcoFalke) +- #7281 `f9fd4c2` Improve CheckInputs() comment about sig verification (petertodd) +- #7417 `1e06bab` Minor improvements to the release process (PRabahy) +- #7444 `4cdbd42` Improve block validity/ConnectBlock() comments (petertodd) +- #7527 `db2e1c0` Fix and cleanup listreceivedbyX documentation (instagibbs) +- #7541 `b6e00af` Clarify description of blockindex (pinheadmz) +- #7590 `f06af57` Improving wording related to Boost library requirements [updated] (jonathancross) +- #7635 `0fa88ef` Add dependency info to test docs (elliotolds) +- #7609 `3ba07bd` RPM spec file project (AliceWonderMiscreations) +- #7850 `229a17c` Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp` (alexreg) +- #7888 `ec870e1` Prevector: fix 2 bugs in currently unreached code paths (kazcw) +- #7922 `90653bc` CBase58Data::SetString: cleanse the full vector (kazcw) +- #7881 `c4e8390` Update release process (laanwj) +- #7952 `a9c8b74` Log invalid block hash to make debugging easier (paveljanik) +- #7974 `8206835` More comments on the design of AttemptToEvictConnection (gmaxwell) +- #7795 `47a7cfb` UpdateTip: log only one line at most per block (laanwj) +- #8110 `e7e25ea` Add benchmarking notes (fanquake) +- #8121 `58f0c92` Update implemented BIPs list (fanquake) +- #8029 `58725ba` Simplify OS X build notes (fanquake) +- #8143 `d46b8b5` comment nit: miners don't vote (instagibbs) +- #8136 `22e0b35` Log/report in 10% steps during VerifyDB (jonasschnelli) +- #8168 `d366185` util: Add ParseUInt32 and ParseUInt64 (laanwj) +- #8178 `f7b1bfc` Add git and github tips and tricks to developer notes (sipa) +- #8177 `67db011` developer notes: updates for C++11 (kazcw) +- #8229 `8ccdac1` [Doc] Update OS X build notes for 10.11 SDK (fanquake) +- #8233 `9f1807a` Mention Linux ARM executables in release process and notes (laanwj) +- #7540 `ff46dd4` Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY (btcdrak) +- #8289 `26316ff` bash-completion: Adapt for 0.12 and 0.13 (roques) +- #7453 `3dc3149` Missing patches from 0.12 (MarcoFalke) +- #7113 `54a550b` Switch to a more efficient rolling Bloom filter (sipa) +- #7257 `de9e5ea` Combine common error strings for different options so translations can be shared and reused (luke-jr) +- #7304 `b8f485c` [contrib] Add clang-format-diff.py (MarcoFalke) +- #7378 `e6f97ef` devtools: replace github-merge with python version (laanwj) +- #7395 `0893705` devtools: show pull and commit information in github-merge (laanwj) +- #7402 `6a5932b` devtools: github-merge get toplevel dir without extra whitespace (achow101) +- #7425 `20a408c` devtools: Fix utf-8 support in messages for github-merge (laanwj) +- #7632 `409f843` Delete outdated test-patches reference (Lewuathe) +- #7662 `386f438` remove unused NOBLKS_VERSION_{START,END} constants (rat4) +- #7737 `aa0d2b2` devtools: make github-merge.py use py3 (laanwj) +- #7781 `55db5f0` devtools: Auto-set branch to merge to in github-merge (laanwj) +- #7934 `f17032f` Improve rolling bloom filter performance and benchmark (sipa) +- #8004 `2efe38b` signal handling: fReopenDebugLog and fRequestShutdown should be type sig_atomic_t (catilac) +- #7713 `f6598df` Fixes for verify-commits script (petertodd) +- #8412 `8360d5b` libconsensus: Expose a flag for BIP112 (jtimon) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 21E14 +- accraze +- Adam Brown +- Alexander Regueiro +- Alex Morcos +- Alfie John +- Alice Wonder +- AlSzacrel +- Andrew Chow +- Andrés G. Aragoneses +- Bob McElrath +- BtcDrak +- calebogden +- Cédric Félizard +- Chirag Davé +- Chris Moore +- Chris Stewart +- Christian von Roques +- Chris Wheeler +- Cory Fields +- crowning- +- Daniel Cousens +- Daniel Kraft +- Denis Lukianov +- Elias Rohrer +- Elliot Olds +- Eric Shaw +- error10 +- Ethan Heilman +- face +- fanquake +- Francesco 'makevoid' Canessa +- fsb4000 +- Gavin Andresen +- gladoscc +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- James O'Beirne +- Jannes Faber +- Jarret Dyrbye +- Jeremy Rand +- jloughry +- jmacwhyte +- Joao Fonseca +- Johnson Lau +- Jonas Nick +- Jonas Schnelli +- Jonathan Cross +- João Barbosa +- Jorge Timón +- Kaz Wesley +- Kefkius +- kirkalx +- Krzysztof Jurewicz +- Leviathn +- lewuathe +- Luke Dashjr +- Luv Khemani +- Marcel Krüger +- Marco Falke +- Mark Friedenbach +- Matt +- Matt Bogosian +- Matt Corallo +- Matthew English +- Matthew Zipkin +- mb300sd +- Mitchell Cash +- mrbandrews +- mruddy +- Murch +- Mustafa +- Nathaniel Mahieu +- Nicolas Dorier +- Patrick Strateman +- Paul Rabahy +- paveljanik +- Pavel Janík +- Pavel Vasin +- Pedro Branco +- Peter Todd +- Philip Kaufmann +- Pieter Wuille +- Prayag Verma +- ptschip +- Puru +- randy-waterhouse +- R E Broadley +- Rusty Russell +- Suhas Daftuar +- Suriyaa Kudo +- TheLazieR Yip +- Thomas Kerin +- Tom Harding +- Tyler Hardin +- UdjinM6 +- Warren Togami +- Will Binns +- Wladimir J. van der Laan +- Yuri Zhykin + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From a5cef7b0777f13ac83312759ebf576c9d773599f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 18 Oct 2016 00:15:59 +0200 Subject: [PATCH 1107/1223] Bump version to 0.13.1 --- configure.ac | 2 +- doc/Doxyfile | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- src/clientversion.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index a545bc57b..97b330449 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 13) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 1) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2016) diff --git a/doc/Doxyfile b/doc/Doxyfile index 93da55fbb..b088c7623 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.13.0 +PROJECT_NUMBER = 0.13.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index 7aa82e1d5..25a280155 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.0 +Bitcoin Core 0.13.1 ===================== Setup diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 3f41db14b..1127ea766 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.0 +Bitcoin Core 0.13.1 ===================== Intro diff --git a/src/clientversion.h b/src/clientversion.h index 30f557526..74d0a94bf 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,7 +16,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 13 -#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_REVISION 1 #define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build From 3f508edcfb92f80092ed1ac4ccc3c33b2f20d207 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 1 Oct 2016 16:57:25 +0200 Subject: [PATCH 1108/1223] rpc: Generate auth cookie in hex instead of base64 Base64 contains '/', and the '/' character in credentials is problematic for AuthServiceProxy which represents the RPC endpoint as an URI with user and password embedded. Closes #8399. Github-Pull: #8858 Rebased-From: 1c80386bceb216ca5b5da657e03a29f9c779d58b --- src/rpc/protocol.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index f5275062a..bb885bb5a 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -77,9 +77,10 @@ boost::filesystem::path GetAuthCookieFile() bool GenerateAuthCookie(std::string *cookie_out) { - unsigned char rand_pwd[32]; - GetRandBytes(rand_pwd, 32); - std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32); + const size_t COOKIE_SIZE = 32; + unsigned char rand_pwd[COOKIE_SIZE]; + GetRandBytes(rand_pwd, COOKIE_SIZE); + std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE); /** the umask determines what permissions are used to create this file - * these are set to 077 in init.cpp unless overridden with -sysperms. From 685e4c78f8ed3c25043f395125d7fc57d8183fef Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 17 Oct 2016 16:29:03 -0400 Subject: [PATCH 1109/1223] Remove bogus assert on number of oubound connections. This value can be significantly higher if the users uses addnode Github-Pull: #8944 Rebased-From: 1ab21cf344ed0547de5ae679b7e479cb4b1a923b --- src/net.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index e44c66c2a..42fde4353 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1655,7 +1655,6 @@ void ThreadOpenConnections() } } } - assert(nOutbound <= (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS)); // Feeler Connections // From d179eed6ca9555da6d78e2ccf41e2454951d18e3 Mon Sep 17 00:00:00 2001 From: mruddy Date: Tue, 18 Oct 2016 11:20:47 -0400 Subject: [PATCH 1110/1223] doc: update 0.13.1 release note info on linux arm builds [skip ci] --- doc/release-notes.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index d107f305d..0868fbc3d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -127,6 +127,33 @@ Low-level RPC changes than two arguments. +Linux ARM builds +---------------- + +With the 0.13.0 release, pre-built Linux ARM binaries were added to the set of +uploaded executables. Additional detail on the ARM architecture targeted by each +is provided below. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries targeting + the 32-bit ARMv7-A architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries targeting + the 64-bit ARMv8-A architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. Note that the device you use must be (backward) +compatible with the architecture targeted by the binary that you use. +For example, a Raspberry Pi 2 Model B or Raspberry Pi 3 Model B (in its 32-bit +execution state) device, can run the 32-bit ARMv7-A targeted binary. However, +no model of Raspberry Pi 1 device can run either binary because they are all +ARMv6 architecture devices that are not compatible with ARMv7-A or ARMv8-A. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + + 0.13.1 Change log ================= From 33cd5539b2f96a1cc4f7a660e317d3484eb6ffc4 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 17 Oct 2016 23:08:52 +0000 Subject: [PATCH 1111/1223] Be more aggressive in connecting to peers with relevant services. Only allow skipping relevant services until there are four outbound connections up. This avoids quickly filling up with peers lacking the relevant services when addrman has few or none of them. Github-Pull: #8949 Rebased-From: 9583477288072e203541b747fcffe8d50cfefb8d --- src/net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 42fde4353..b28ce0b8a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1707,8 +1707,8 @@ void ThreadOpenConnections() if (nANow - addr.nLastTry < 600 && nTries < 30) continue; - // only consider nodes missing relevant services after 40 failed attempts - if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) + // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up. + if ((addr.nServices & nRelevantServices) != nRelevantServices && (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) continue; // do not allow non-default ports, unless after 50 invalid addresses selected already From 91ae0b06b9d56a06bd0aae498571a7785ee385ee Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 17 Oct 2016 23:11:35 +0000 Subject: [PATCH 1112/1223] Make dnsseed's definition of acute need include relevant services. We normally prefer to connect to peers offering the relevant services. If we're not connected to enough peers with relevant services, we probably don't know about them and could use dnsseed's help. Github-Pull: #8949 Rebased-From: 46304791353d2bb61004a035869612620c30b4eb --- src/net.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index b28ce0b8a..9bfdb9bc2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1497,12 +1497,19 @@ static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredSe void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute + // Avoiding DNS seeds when we don't need them improves user privacy by + // creating fewer identifying DNS requests, reduces trust by giving seeds + // less influence on the network topology, and reduces traffic to the seeds. if ((addrman.size() > 0) && (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); - if (vNodes.size() >= 2) { + int nRelevant = 0; + for (auto pnode : vNodes) { + nRelevant += pnode->fSuccessfullyConnected && ((pnode->nServices & nRelevantServices) == nRelevantServices); + } + if (nRelevant >= 2) { LogPrintf("P2P peers available. Skipped DNS seeding.\n"); return; } From 7c2bf4b1759b4d2fe7291649ed25bb8e90ad9dc2 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 18 Oct 2016 07:17:19 +0000 Subject: [PATCH 1113/1223] RPC/Mining: getblocktemplate: Update and fix formatting of help Github-Pull: #8951 Rebased-From: 59daa58d6a17bb1170c724f2d01d43c2ec21a9b4 --- src/rpc/mining.cpp | 66 +++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index a26340f3e..14a61a55d 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -320,67 +320,73 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( - "getblocktemplate ( \"jsonrequestobject\" )\n" + "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" - "For full specification, see BIPs 22 and 9:\n" + "For full specification, see BIPs 22, 23, 9, and 145:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" + " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" + " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" "\nArguments:\n" - "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n" + "1. TemplateRequest (json object, optional) A json object in the following spec\n" " {\n" - " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n" - " \"capabilities\":[ (array, optional) A list of strings\n" - " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" + " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" + " \"capabilities\":[ (array, optional) A list of strings\n" + " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" - " ]\n" + " ],\n" + " \"rules\":[ (array, optional) A list of strings\n" + " \"support\" (string) client side supported softfork deployment\n" + " ,...\n" + " ]\n" " }\n" "\n" "\nResult:\n" "{\n" - " \"version\" : n, (numeric) The block version\n" + " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" - " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" + " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" - " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" + " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" - " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" - " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" - " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" - " \"depends\" : [ (array) array of numbers \n" - " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" + " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" + " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" + " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" + " \"depends\" : [ (array) array of numbers \n" + " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" - " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" - " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" - " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" - " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" + " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" + " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" + " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" + " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" " }\n" " ,...\n" " ],\n" - " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" - " \"flags\" : \"flags\" (string) \n" + " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" + " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" - " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" - " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" - " \"target\" : \"xxxx\", (string) The hash target\n" - " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" - " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" - " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" + " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" + " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" + " \"target\" : \"xxxx\", (string) The hash target\n" + " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" + " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" - " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n" - " \"sigoplimit\" : n, (numeric) cost limit of sigops in blocks\n" + " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" + " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" - " \"bits\" : \"xxx\", (string) compressed target of next block\n" + " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" "}\n" From 53e6196a90a8503c5a79a3542421878bd6109a9d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 19 Oct 2016 09:34:44 +0000 Subject: [PATCH 1114/1223] qt: pre-rc2 translations update --- src/qt/locale/bitcoin_es.ts | 186 +++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 3 deletions(-) diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index aa0ebd292..a0b188e5b 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -41,10 +41,74 @@ &Delete &Eliminar - + + Choose the address to send coins to + Seleccione la dirección a la que enviar monedas + + + Choose the address to receive coins with + Seleccione la dirección de la que recibir monedas + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son sus direcciones Bitcoin para enviar pagos. Verifique siempre la cantidad y la dirección de recibimiento antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son sus direcciones Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recibimiento para cada transacción + + + &Copy Address + &Copiar Dirección + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the address list to %1. Please try again. + Había un error intentando guardar la lista de direcciones en %1. Por favor inténtelo de nuevo. + + AddressTableModel - + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + + AskPassphraseDialog @@ -63,6 +127,74 @@ Repeat new passphrase Repita la nueva contraseña + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduzca la nueva frase clave del monedero. <br/>Por favor utilice una frase clave de <b>diez o más carácteres aleatorios</b>, o <b>ocho o más palabras</b>. + + + Encrypt wallet + Monedero encriptado + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita su frase clave de monedero para desbloquear el monedero. + + + Unlock wallet + Desbloquear monedero + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita su frase clave de cartera para desencriptar el monedero. + + + Decrypt wallet + Desencriptar monedero + + + Change passphrase + Cambiar frase clave + + + Enter the old passphrase and new passphrase to the wallet. + Introduzca la vieja frase clave y la nueva flase clave para el monedero. + + + Confirm wallet encryption + Confirmar encriptación del monedero + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advertencia: Si encripta su monedero y pierde su frase clave <b>PERDERÁ TODOS SUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + ¿Seguro que desea encriptar su monedero? + + + Wallet encrypted + Monedero encriptado + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 se cerrará ahora para terminar el proceso de encriptación. Recuerde que encriptar su monedero no puede proteger completamente su monedero de ser robado por malware que infecte su ordenador. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Cualquier copia de seguridad anterior que haya hecho en su archivo de monedero debería ser reemplazada con el archivo de monedero encriptado generado recientemente. Por razones de seguridad, las copias de seguridad anteriores del archivo de monedero desencriptado serán inútiles en cuanto empiece a utilizar el nuevo monedero encriptado. + + + Wallet encryption failed + Fracasó la encriptación de monedero + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falló la encriptación del monedero debido a un error interno. Su monedero no fue encriptado. + + + The supplied passphrases do not match. + La frase clave introducida no coincide. + BanTableModel @@ -466,6 +598,10 @@ Priority Prioridad + + (no label) + (sin etiqueta) + EditAddressDialog @@ -1376,9 +1512,25 @@ &Save Image... Guardar Imagen... + + Address + Dirección + + + Label + Etiqueta + RecentRequestsTableModel + + Label + Etiqueta + + + (no label) + (sin etiqueta) + SendCoinsDialog @@ -1530,7 +1682,11 @@ S&end &Enviar - + + (no label) + (sin etiqueta) + + SendCoinsEntry @@ -1737,9 +1893,33 @@ TransactionTableModel + + Label + Etiqueta + + + (no label) + (sin etiqueta) + TransactionView + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Label + Etiqueta + + + Address + Dirección + + + Exporting Failed + Falló la exportación + UnitDisplayStatusBarControl From 0dbc48a5bd831816870940287dc1131b30cf613d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 19 Oct 2016 11:48:23 +0200 Subject: [PATCH 1115/1223] nMaxOutbound is MAX_OUTBOUND_CONNECTIONS on 0.13 Github-Pull: #8949 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 9bfdb9bc2..06fc3fdb8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1715,7 +1715,7 @@ void ThreadOpenConnections() continue; // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up. - if ((addr.nServices & nRelevantServices) != nRelevantServices && (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) + if ((addr.nServices & nRelevantServices) != nRelevantServices && (nTries < 40 || nOutbound >= (MAX_OUTBOUND_CONNECTIONS >> 1))) continue; // do not allow non-default ports, unless after 50 invalid addresses selected already From 6e8936032fb865c0448bec0e0f168e041a586285 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 19 Oct 2016 11:58:19 +0200 Subject: [PATCH 1116/1223] doc: Update release notes for rc2 --- doc/release-notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0868fbc3d..ba6f0ed60 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -173,6 +173,8 @@ git merge commit are mentioned. - #8780 `794b007` Deprecate getinfo (MarcoFalke) - #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) - #8884 `b987348` getblockchaininfo help: pruneheight is the lowest, not highest, block (luke-jr) +- #8858 `3f508ed` rpc: Generate auth cookie in hex instead of base64 (laanwj) +- #8951 `7c2bf4b` RPC/Mining: getblocktemplate: Update and fix formatting of help (luke-jr) ### Block and transaction handling - #8611 `a9429ca` Reduce default number of blocks to check at startup (sipa) @@ -195,6 +197,8 @@ git merge commit are mentioned. - #8606 `bbf379b` Fix some locks (sipa) - #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) - #8940 `5b4192b` Add x9 service bit support to dnsseed.bluematt.me, seed.bitcoinstats.com (TheBlueMatt, cdecker) +- #8944 `685e4c7` Remove bogus assert on number of oubound connections. (TheBlueMatt) +- #8949 `0dbc48a` Be more agressive in getting connections to peers with relevant services (gmaxwell) ### Build system - #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) @@ -292,6 +296,7 @@ Thanks to everyone who directly contributed to this release: - Cory Fields - crowning- - Dagur Valberg Johannsson +- David A. Harding - Ethan Heilman - fanquake - Gaurav Rana @@ -311,7 +316,9 @@ Thanks to everyone who directly contributed to this release: - MarcoFalke - Marty Jones - Matt Corallo +- Micha - Michael Ford +- mruddy - Pavel Janík - Pieter Wuille - rodasmith From 5f6b312e51dadaf40ea68c0f85bbb4e51fa987f1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 20 Oct 2016 12:26:42 +0200 Subject: [PATCH 1117/1223] doc: Add missing credit to release notes (Eric participated in Segwit work but has no direct commits, so should be mentioned) --- doc/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index ba6f0ed60..9f12dca78 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -297,6 +297,7 @@ Thanks to everyone who directly contributed to this release: - crowning- - Dagur Valberg Johannsson - David A. Harding +- Eric Lombrozo - Ethan Heilman - fanquake - Gaurav Rana From c9a5baddeef3d8721a7c71acf070f92a3d8d43a3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 20 Oct 2016 13:02:07 +0200 Subject: [PATCH 1118/1223] doc: Update blurb in release notes Minor version, not major version. --- doc/release-notes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 9f12dca78..dbb3d5f3f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -2,8 +2,9 @@ Bitcoin Core version 0.13.1 is now available from: -This is a new major version release, including new features, various bugfixes -and performance improvements, as well as updated translations. +This is a new minor version release, including activation parameters for the +segwit softfork, various bugfixes and performance improvements, as well as +updated translations. Please report bugs using the issue tracker at github: From 99f5cf189313c6056b06410dc858363ba6fc2807 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 25 Oct 2016 11:30:28 +0000 Subject: [PATCH 1119/1223] release-notes: Update from blog draft --- doc/release-notes.md | 116 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 21 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index dbb3d5f3f..0941290c8 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -44,28 +44,102 @@ Segregated witness soft fork Segregated witness (segwit) is a soft fork that, if activated, will allow transaction-producing software to separate (segregate) transaction -signatures (witnesses) from the rest of the data in a transaction, and -to allow miners to place those witnesses outside of the traditional -block structure. This provides two immediate benefits: +signatures (witnesses) from the part of the data in a transaction that is +covered by the txid. This provides several immediate benefits: -- **Elimination of malleability:** Segregating the witness allows both - existing software and upgraded software that receives transactions to - calculate the transaction identifier (txid) of segwit-using - transactions without referencing the witness. This solves all known - cases of unwanted third-party transaction malleability, which is a - problem that makes programming Bitcoin wallet software more difficult - and which seriously complicates the design of smart contracts for - Bitcoin. +- **Elimination of unwanted transaction malleability:** Segregating the witness + allows both existing and upgraded software to calculate the transaction + identifier (txid) of transactions without referencing the witness, which can + sometimes be changed by third-parties (such as miners) or by co-signers in a + multisig spend. This solves all known cases of unwanted transaction + malleability, which is a problem that makes programming Bitcoin wallet + software more difficult and which seriously complicates the design of smart + contracts for Bitcoin. -- **Capacity increase:** Moving witness data outside of the traditional - block structure (but still inside a new-style block structure) means - new-style blocks can hold more data than older-style blocks, allowing - a modest increase to the amount of transaction data that can fit in a - block. +- **Capacity increase:** Segwit transactions contain new fields that are not + part of the data currently used to calculate the size of a block, which + allows a block containing segwit transactions to hold more data than allowed + by the current maximum block size. Estimates based on the transactions + currently found in blocks indicate that if all wallets switch to using + segwit, the network will be able to support about 70% more transactions. The + network will also be able to support more of the advanced-style payments + (such as multisig) than it can support now because of the different weighting + given to different parts of a transaction after segwit activates (see the + following section for details). -Segwit also simplifies the ability to add new features to Bitcoin and -improves the efficiency of full nodes, which will help provide long-term -benefits to Bitcoin users. +- **Weighting data based on how it affects node performance:** Some parts of + each Bitcoin block need to be stored by nodes in order to validate future + blocks; other parts of a block can be immediately forgotten (pruned) or used + only for helping other nodes sync their copy of the block chain. One large + part of the immediately prunable data are transaction signatures (witnesses), + and segwit makes it possible to give a different "weight" to segregated + witnesses to correspond with the lower demands they place on node resources. + Specifically, each byte of a segregated witness is given a weight of 1, each + other byte in a block is given a weight of 4, and the maximum allowed weight + of a block is 4 million. Weighting the data this way better aligns the most + profitable strategy for creating blocks with the long-term costs of block + validation. + +- **Signature covers value:** A simple improvement in the way signatures are + generated in segwit simplifies the design of secure signature generators + (such as hardware wallets), reduces the amount of data the signature + generator needs to download, and allows the signature generator to operate + more quickly. This is made possible by having the generator sign the amount + of bitcoins they think they are spending, and by having full nodes refuse to + accept those signatures unless the amount of bitcoins being spent is exactly + the same as was signed. For non-segwit transactions, wallets instead had to + download the complete previous transactions being spent for every payment + they made, which could be a slow operation on hardware wallets and in other + situations where bandwidth or computation speed was constrained. + +- **Linear scaling of sighash operations:** In 2015 a block was produced that + required about 25 seconds to validate on modern hardware because of the way + transaction signature hashes are performed. Other similar blocks, or blocks + that could take even longer to validate, can still be produced today. The + problem that caused this can't be fixed in a soft fork without unwanted + side-effects, but transactions that opt-in to using segwit will now use a + different signature method that doesn't suffer from this problem and doesn't + have any unwanted side-effects. + +- **Increased security for multisig:** Bitcoin addresses (both P2PKH addresses + that start with a '1' and P2SH addresses that start with a '3') use a hash + function known as RIPEMD-160. For P2PKH addresses, this provides about 160 + bits of security---which is beyond what cryptographers believe can be broken + today. But because P2SH is more flexible, only about 80 bits of security is + provided per address. Although 80 bits is very strong security, it is within + the realm of possibility that it can be broken by a powerful adversary. + Segwit allows advanced transactions to use the SHA256 hash function instead, + which provides about 128 bits of security (that is 281 trillion times as + much security as 80 bits and is equivalent to the maximum bits of security + believed to be provided by Bitcoin's choice of parameters for its Elliptic + Curve Digital Security Algorithm [ECDSA].) + +- **More efficient almost-full-node security** Satoshi Nakamoto's original + Bitcoin paper describes a method for allowing newly-started full nodes to + skip downloading and validating some data from historic blocks that are + protected by large amounts of proof of work. Unfortunately, Nakamoto's + method can't guarantee that a newly-started node using this method will + produce an accurate copy of Bitcoin's current ledger (called the UTXO set), + making the node vulnerable to falling out of consensus with other nodes. + Although the problems with Nakamoto's method can't be fixed in a soft fork, + Segwit accomplishes something similar to his original proposal: it makes it + possible for a node to optionally skip downloading some blockchain data + (specifically, the segregated witnesses) while still ensuring that the node + can build an accurate copy of the UTXO set for the block chain with the most + proof of work. Segwit enables this capability at the consensus layer, but + note that Bitcoin Core does not provide an option to use this capability as + of this 0.13.1 release. + +- **Script versioning:** Segwit makes it easy for future soft forks to allow + Bitcoin users to individually opt-in to almost any change in the Bitcoin + Script language when those users receive new transactions. Features + currently being researched by Bitcoin Core contributors that may use this + capability include support for Schnorr signatures, which can improve the + privacy and efficiency of multisig transactions (or transactions with + multiple inputs), and Merklized Abstract Syntax Trees (MAST), which can + improve the privacy and efficiency of scripts with two or more conditions. + Other Bitcoin community members are studying several other improvements + that can be made using script versioning. Activation for the segwit soft fork is being managed using BIP9 versionbits. Segwit's version bit is bit 1, and nodes will begin @@ -93,8 +167,8 @@ signaling support for a soft fork. Null dummy soft fork ------------------- -Combined with the segwit soft fork is a soft fork that turns a -long-existing network relay policy into a consensus rule. The +Combined with the segwit soft fork is an additional change that turns a +long-existing network relay policy into a consensus rule. The `OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY` opcodes consume an extra stack element ("dummy element") after signature validation. The dummy element is not inspected in any manner, and could be replaced by any From 58d4fa7da30cb57e5fc3dca62f49a64e126c76cd Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 24 Oct 2016 21:38:20 +0200 Subject: [PATCH 1120/1223] [net] Remove assert(nMaxInbound > 0) nMaxInbound might very well be 0 or -1, if the user prefers to keep a small number of maxconnections. Note: nMaxInbound of -1 means that the user set maxconnections to 8 or less, but we still want to keep an additional slot for the feeler connection. Github-Pull: #9008 Rebased-From: fa1c3c2eb0a1853ed0e0662fc2bdbca51e05ccf5 --- src/net.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 06fc3fdb8..faa7b0028 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1021,7 +1021,6 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { CAddress addr; int nInbound = 0; int nMaxInbound = nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); - assert(nMaxInbound > 0); if (hSocket != INVALID_SOCKET) if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) From a32d7c23fc0eedebe3579edb5d488a4c63b67b70 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 25 Oct 2016 14:04:33 -0400 Subject: [PATCH 1121/1223] release: bump required osx version to 10.8. Credit jonasschnelli. libc++ on 10.7 causes too many issues. See #8577 for discussion/details. Github-Pull: #9015 Rebased-From: 339c4b6c3a8e68e4bba1969d144e413a462b68f1 --- share/qt/Info.plist.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 6a34d64cd..5ca6d9d01 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 10.7.0 + 10.8.0 LSArchitecturePriority From 1d1246314f761b3f84c869cb7b0af49cc25b55b3 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Wed, 26 Oct 2016 18:04:27 +0800 Subject: [PATCH 1122/1223] Update release notes for dropping osx 10.7 support --- doc/build-osx.md | 2 +- doc/release-notes.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/build-osx.md b/doc/build-osx.md index bc90a3056..63a7ee28c 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -90,6 +90,6 @@ Uncheck everything except Qt Creator during the installation process. Notes ----- -* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only. +* Tested on OS X 10.8 through 10.12 on 64-bit Intel processors only. * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0941290c8..75c2d61be 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -36,6 +36,10 @@ No attempt is made to prevent installing or running the software on Windows XP, you can still do so at your own risk, but do not expect it to work: do not report issues about Windows XP to the issue tracker. +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + Notable changes =============== From 9ef38758a69abfb6166099bf8dea1d69e258ae00 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 21 Oct 2016 12:15:19 -0400 Subject: [PATCH 1123/1223] Add missing cs_main lock to ::GETBLOCKTXN processing Note that this is not a major issue as, in order for the missing lock to cause issues, you have to receive a GETBLOCKTXN message while reindexing, adding a block header via RPC, etc, which results in either a table rehash or an insert into the bucket which you are currently looking at. Github-Pull: #8995 Rebased-From: dfe79060a62c8de098e75d527d97b99c3b10de50 --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 61d0aaf0b..84f4607db 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5388,6 +5388,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, BlockTransactionsRequest req; vRecv >> req; + LOCK(cs_main); + BlockMap::iterator it = mapBlockIndex.find(req.blockhash); if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) { LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id); From ce0d817b9b59baa243c3ac0844a654704872aa2f Mon Sep 17 00:00:00 2001 From: maiiz Date: Mon, 18 Jul 2016 15:01:34 +0800 Subject: [PATCH 1124/1223] Fix relaypriority calculation error Github-Pull: #8357 Rebased-From: 94a34a5d951cee59ef9c9274c5ad49ac2a91ab8a --- src/coins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coins.cpp b/src/coins.cpp index 39db7dedf..8ff652b47 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -275,7 +275,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount assert(coins); if (!coins->IsAvailable(txin.prevout.n)) continue; if (coins->nHeight <= nHeight) { - dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); + dResult += (double)(coins->vout[txin.prevout.n].nValue) * (nHeight-coins->nHeight); inChainInputValue += coins->vout[txin.prevout.n].nValue; } } From 1d048b917b83489f9e56d8fab522475544b98793 Mon Sep 17 00:00:00 2001 From: jnewbery Date: Mon, 26 Sep 2016 17:01:10 -0400 Subject: [PATCH 1125/1223] Don't return the address of a P2SH of a P2SH. Github-Pull: #8845 Rebased-From: d51f18246165b580761af824f1bb4a49b6908f28 --- src/rpc/rawtransaction.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 3270cd384..b2bbb8b3e 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -535,7 +535,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) " \"address\" (string) bitcoin address\n" " ,...\n" " ],\n" - " \"p2sh\",\"address\" (string) script address\n" + " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n" "}\n" "\nExamples:\n" + HelpExampleCli("decodescript", "\"hexstring\"") @@ -554,7 +554,15 @@ UniValue decodescript(const UniValue& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + UniValue type; + type = find_value(r, "type"); + + if (type.isStr() && type.get_str() != "scripthash") { + // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, + // don't return the address for a P2SH of the P2SH. + r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + } + return r; } From 6d05fe115b07588f41631663ace2f3f14c3ed3d7 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 21 Sep 2016 22:31:23 +0000 Subject: [PATCH 1126/1223] Add MIT license to Makefiles Github-Pull: #8784 Rebased-From: f4dffdd6bffc58377b7505b639f0431244321c32 --- Makefile.am | 4 ++++ src/Makefile.am | 4 ++++ src/Makefile.bench.include | 4 ++++ src/Makefile.leveldb.include | 4 ++++ src/Makefile.qt.include | 4 ++++ src/Makefile.qttest.include | 4 ++++ src/Makefile.test.include | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/Makefile.am b/Makefile.am index b10d08506..f3dc016b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src .PHONY: deploy FORCE diff --git a/src/Makefile.am b/src/Makefile.am index e3eaacdb4..1e033de9d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 4067ceb39..8c024a8c4 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -1,3 +1,7 @@ +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += bench/bench_bitcoin BENCH_SRCDIR = bench BENCH_BINARY = bench/bench_bitcoin$(EXEEXT) diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 4b3cd6364..d7346aa18 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -1,3 +1,7 @@ +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + LIBLEVELDB_INT = leveldb/libleveldb.a LIBMEMENV_INT = leveldb/libmemenv.a diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index bbef64176..8e6805d4a 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += qt/bitcoin-qt EXTRA_LIBRARIES += qt/libbitcoinqt.a diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 813a343ff..a071fe136 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += qt/test/test_bitcoin-qt TESTS += qt/test/test_bitcoin-qt diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 27e769474..ef30eeb4a 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + TESTS += test/test_bitcoin bin_PROGRAMS += test/test_bitcoin TEST_SRCDIR = test From fa58e55cef9a901b433544338dccd562dbe461ee Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 21 Sep 2016 22:35:21 +0000 Subject: [PATCH 1127/1223] Add MIT license to autogen.sh and share/genbuild.sh Github-Pull: #8784 Rebased-From: 3b4b6dcdd77f3ba76fb0cda6f2c277ec1629d8d3 --- autogen.sh | 4 ++++ share/genbuild.sh | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/autogen.sh b/autogen.sh index 46e36ff5b..27417daf7 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + set -e srcdir="$(dirname $0)" cd "$srcdir" diff --git a/share/genbuild.sh b/share/genbuild.sh index 1ef77d706..eecac4bd0 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + if [ $# -gt 1 ]; then cd "$2" fi From 2cfcca7ca6f4036845f8e845cb4b55bd4e07ed64 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 21 Sep 2016 22:54:49 +0000 Subject: [PATCH 1128/1223] Trivial: build-aux/m4/l_atomic: Fix typo Github-Pull: #8784 Rebased-From: 3f8a5d8f6e95c3c1aa62433abc5edb0c93caae11 --- build-aux/m4/l_atomic.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 index 906724b64..1cb13587a 100644 --- a/build-aux/m4/l_atomic.m4 +++ b/build-aux/m4/l_atomic.m4 @@ -32,7 +32,7 @@ AC_DEFUN([CHECK_ATOMIC], [ AC_MSG_RESULT([yes]) ],[ AC_MSG_RESULT([no]) - AC_MSG_FAILURE([cannot figure our how to use std::atomic]) + AC_MSG_FAILURE([cannot figure out how to use std::atomic]) ]) ]) From b16cdb71ff20ebf23372d116e9bb4bbe84d30fce Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 21 Sep 2016 22:54:41 +0000 Subject: [PATCH 1129/1223] Add MIT license to build-aux/m4 scripts Github-Pull: #8784 Rebased-From: 0c4e6ce88f58c13ed81807e3a5bef28b673aa503 --- build-aux/m4/bitcoin_find_bdb48.m4 | 4 ++++ build-aux/m4/bitcoin_qt.m4 | 4 ++++ build-aux/m4/bitcoin_subdir_to_include.m4 | 4 ++++ build-aux/m4/l_atomic.m4 | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index 2aa493a6a..0c3d49c2b 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2015 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_MSG_CHECKING([for Berkeley DB C++ headers]) BDB_CPPFLAGS= diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index d26136cbe..509283a0b 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2016 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + dnl Helper for cases where a qt dependency is not met. dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit. AC_DEFUN([BITCOIN_QT_FAIL],[ diff --git a/build-aux/m4/bitcoin_subdir_to_include.m4 b/build-aux/m4/bitcoin_subdir_to_include.m4 index 66f106c7d..7841042ac 100644 --- a/build-aux/m4/bitcoin_subdir_to_include.m4 +++ b/build-aux/m4/bitcoin_subdir_to_include.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2014 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + dnl BITCOIN_SUBDIR_TO_INCLUDE([CPPFLAGS-VARIABLE-NAME],[SUBDIRECTORY-NAME],[HEADER-FILE]) dnl SUBDIRECTORY-NAME must end with a path separator AC_DEFUN([BITCOIN_SUBDIR_TO_INCLUDE],[ diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 index 1cb13587a..75c43f9a9 100644 --- a/build-aux/m4/l_atomic.m4 +++ b/build-aux/m4/l_atomic.m4 @@ -1,3 +1,9 @@ +dnl Copyright (c) 2015 Tim Kosse +dnl Copying and distribution of this file, with or without modification, are +dnl permitted in any medium without royalty provided the copyright notice +dnl and this notice are preserved. This file is offered as-is, without any +dnl warranty. + # Some versions of gcc/libstdc++ require linking with -latomic if # using the C++ atomic library. # From 2e2388a5cbb9a6e101b36e4501698fec538a5738 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 27 Oct 2016 14:53:30 +0200 Subject: [PATCH 1130/1223] Move release notes to release-notes/release-notes-0.13.1.md And clean out current release notes, ready for next release from this branch. --- doc/release-notes.md | 363 +------------------ doc/release-notes/release-notes-0.13.1.md | 410 ++++++++++++++++++++++ 2 files changed, 419 insertions(+), 354 deletions(-) create mode 100644 doc/release-notes/release-notes-0.13.1.md diff --git a/doc/release-notes.md b/doc/release-notes.md index 75c2d61be..e54f9ac02 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,10 +1,9 @@ -Bitcoin Core version 0.13.1 is now available from: +Bitcoin Core version 0.13.x is now available from: - + -This is a new minor version release, including activation parameters for the -segwit softfork, various bugfixes and performance improvements, as well as -updated translations. +This is a new minor version release, including ..., various bugfixes and +performance improvements, as well as updated translations. Please report bugs using the issue tracker at github: @@ -43,197 +42,10 @@ but severe issues with the libc++ version on 10.7.x keep it from running reliabl Notable changes =============== -Segregated witness soft fork ----------------------------- +Example item +--------------- -Segregated witness (segwit) is a soft fork that, if activated, will -allow transaction-producing software to separate (segregate) transaction -signatures (witnesses) from the part of the data in a transaction that is -covered by the txid. This provides several immediate benefits: - -- **Elimination of unwanted transaction malleability:** Segregating the witness - allows both existing and upgraded software to calculate the transaction - identifier (txid) of transactions without referencing the witness, which can - sometimes be changed by third-parties (such as miners) or by co-signers in a - multisig spend. This solves all known cases of unwanted transaction - malleability, which is a problem that makes programming Bitcoin wallet - software more difficult and which seriously complicates the design of smart - contracts for Bitcoin. - -- **Capacity increase:** Segwit transactions contain new fields that are not - part of the data currently used to calculate the size of a block, which - allows a block containing segwit transactions to hold more data than allowed - by the current maximum block size. Estimates based on the transactions - currently found in blocks indicate that if all wallets switch to using - segwit, the network will be able to support about 70% more transactions. The - network will also be able to support more of the advanced-style payments - (such as multisig) than it can support now because of the different weighting - given to different parts of a transaction after segwit activates (see the - following section for details). - -- **Weighting data based on how it affects node performance:** Some parts of - each Bitcoin block need to be stored by nodes in order to validate future - blocks; other parts of a block can be immediately forgotten (pruned) or used - only for helping other nodes sync their copy of the block chain. One large - part of the immediately prunable data are transaction signatures (witnesses), - and segwit makes it possible to give a different "weight" to segregated - witnesses to correspond with the lower demands they place on node resources. - Specifically, each byte of a segregated witness is given a weight of 1, each - other byte in a block is given a weight of 4, and the maximum allowed weight - of a block is 4 million. Weighting the data this way better aligns the most - profitable strategy for creating blocks with the long-term costs of block - validation. - -- **Signature covers value:** A simple improvement in the way signatures are - generated in segwit simplifies the design of secure signature generators - (such as hardware wallets), reduces the amount of data the signature - generator needs to download, and allows the signature generator to operate - more quickly. This is made possible by having the generator sign the amount - of bitcoins they think they are spending, and by having full nodes refuse to - accept those signatures unless the amount of bitcoins being spent is exactly - the same as was signed. For non-segwit transactions, wallets instead had to - download the complete previous transactions being spent for every payment - they made, which could be a slow operation on hardware wallets and in other - situations where bandwidth or computation speed was constrained. - -- **Linear scaling of sighash operations:** In 2015 a block was produced that - required about 25 seconds to validate on modern hardware because of the way - transaction signature hashes are performed. Other similar blocks, or blocks - that could take even longer to validate, can still be produced today. The - problem that caused this can't be fixed in a soft fork without unwanted - side-effects, but transactions that opt-in to using segwit will now use a - different signature method that doesn't suffer from this problem and doesn't - have any unwanted side-effects. - -- **Increased security for multisig:** Bitcoin addresses (both P2PKH addresses - that start with a '1' and P2SH addresses that start with a '3') use a hash - function known as RIPEMD-160. For P2PKH addresses, this provides about 160 - bits of security---which is beyond what cryptographers believe can be broken - today. But because P2SH is more flexible, only about 80 bits of security is - provided per address. Although 80 bits is very strong security, it is within - the realm of possibility that it can be broken by a powerful adversary. - Segwit allows advanced transactions to use the SHA256 hash function instead, - which provides about 128 bits of security (that is 281 trillion times as - much security as 80 bits and is equivalent to the maximum bits of security - believed to be provided by Bitcoin's choice of parameters for its Elliptic - Curve Digital Security Algorithm [ECDSA].) - -- **More efficient almost-full-node security** Satoshi Nakamoto's original - Bitcoin paper describes a method for allowing newly-started full nodes to - skip downloading and validating some data from historic blocks that are - protected by large amounts of proof of work. Unfortunately, Nakamoto's - method can't guarantee that a newly-started node using this method will - produce an accurate copy of Bitcoin's current ledger (called the UTXO set), - making the node vulnerable to falling out of consensus with other nodes. - Although the problems with Nakamoto's method can't be fixed in a soft fork, - Segwit accomplishes something similar to his original proposal: it makes it - possible for a node to optionally skip downloading some blockchain data - (specifically, the segregated witnesses) while still ensuring that the node - can build an accurate copy of the UTXO set for the block chain with the most - proof of work. Segwit enables this capability at the consensus layer, but - note that Bitcoin Core does not provide an option to use this capability as - of this 0.13.1 release. - -- **Script versioning:** Segwit makes it easy for future soft forks to allow - Bitcoin users to individually opt-in to almost any change in the Bitcoin - Script language when those users receive new transactions. Features - currently being researched by Bitcoin Core contributors that may use this - capability include support for Schnorr signatures, which can improve the - privacy and efficiency of multisig transactions (or transactions with - multiple inputs), and Merklized Abstract Syntax Trees (MAST), which can - improve the privacy and efficiency of scripts with two or more conditions. - Other Bitcoin community members are studying several other improvements - that can be made using script versioning. - -Activation for the segwit soft fork is being managed using BIP9 -versionbits. Segwit's version bit is bit 1, and nodes will begin -tracking which blocks signal support for segwit at the beginning of the -first retarget period after segwit's start date of 15 November 2016. If -95% of blocks within a 2,016-block retarget period (about two weeks) -signal support for segwit, the soft fork will be locked in. After -another 2,016 blocks, segwit will activate. - -For more information about segwit, please see the [segwit FAQ][], the -[segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], -[144][BIP144], and [145][BIP145]. If you're a miner or mining pool -operator, please see the [versionbits FAQ][] for information about -signaling support for a soft fork. - -[Segwit FAQ]: https://bitcoincore.org/en/2016/01/26/segwit-benefits/ -[segwit wallet developers guide]: https://bitcoincore.org/en/segwit_wallet_dev/ -[BIP141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki -[BIP143]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki -[BIP144]: https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki -[BIP145]: https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki -[versionbits FAQ]: https://bitcoincore.org/en/2016/06/08/version-bits-miners-faq/ - - -Null dummy soft fork -------------------- - -Combined with the segwit soft fork is an additional change that turns a -long-existing network relay policy into a consensus rule. The -`OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY` opcodes consume an extra -stack element ("dummy element") after signature validation. The dummy -element is not inspected in any manner, and could be replaced by any -value without invalidating the script. - -Because any value can be used for this dummy element, it's possible for -a third-party to insert data into other people's transactions, changing -the transaction's txid (called transaction malleability) and possibly -causing other problems. - -Since Bitcoin Core 0.10.0, nodes have defaulted to only relaying and -mining transactions whose dummy element was a null value (0x00, also -called OP_0). The null dummy soft fork turns this relay rule into a -consensus rule both for non-segwit transactions and segwit transactions, -so that this method of mutating transactions is permanently eliminated -from the network. - -Signaling for the null dummy soft fork is done by signaling support -for segwit, and the null dummy soft fork will activate at the same time -as segwit. - -For more information, please see [BIP147][]. - -[BIP147]: https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki - -Low-level RPC changes ---------------------- - -- `importprunedfunds` only accepts two required arguments. Some versions accept - an optional third arg, which was always ignored. Make sure to never pass more - than two arguments. - - -Linux ARM builds ----------------- - -With the 0.13.0 release, pre-built Linux ARM binaries were added to the set of -uploaded executables. Additional detail on the ARM architecture targeted by each -is provided below. - -The following extra files can be found in the download directory or torrent: - -- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries targeting - the 32-bit ARMv7-A architecture. -- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries targeting - the 64-bit ARMv8-A architecture. - -ARM builds are still experimental. If you have problems on a certain device or -Linux distribution combination please report them on the bug tracker, it may be -possible to resolve them. Note that the device you use must be (backward) -compatible with the architecture targeted by the binary that you use. -For example, a Raspberry Pi 2 Model B or Raspberry Pi 3 Model B (in its 32-bit -execution state) device, can run the 32-bit ARMv7-A targeted binary. However, -no model of Raspberry Pi 1 device can run either binary because they are all -ARMv6 architecture devices that are not compatible with ARMv7-A or ARMv8-A. - -Note that Android is not considered ARM Linux in this context. The executables -are not expected to work out of the box on Android. - - -0.13.1 Change log +0.13.x Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -241,170 +53,13 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -### Consensus -- #8636 `9dfa0c8` Implement NULLDUMMY softfork (BIP147) (jl2012) -- #8848 `7a34a46` Add NULLDUMMY verify flag in bitcoinconsensus.h (jl2012) -- #8937 `8b66659` Define start and end time for segwit deployment (sipa) - -### RPC and other APIs -- #8581 `526d2b0` Drop misleading option in importprunedfunds (MarcoFalke) -- #8699 `a5ec248` Remove createwitnessaddress RPC command (jl2012) -- #8780 `794b007` Deprecate getinfo (MarcoFalke) -- #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) -- #8884 `b987348` getblockchaininfo help: pruneheight is the lowest, not highest, block (luke-jr) -- #8858 `3f508ed` rpc: Generate auth cookie in hex instead of base64 (laanwj) -- #8951 `7c2bf4b` RPC/Mining: getblocktemplate: Update and fix formatting of help (luke-jr) - -### Block and transaction handling -- #8611 `a9429ca` Reduce default number of blocks to check at startup (sipa) -- #8634 `3e80ab7` Add policy: null signature for failed CHECK(MULTI)SIG (jl2012) -- #8525 `1672225` Do not store witness txn in rejection cache (sipa) -- #8499 `9777fe1` Add several policy limits and disable uncompressed keys for segwit scripts (jl2012) -- #8526 `0027672` Make non-minimal OP_IF/NOTIF argument non-standard for P2WSH (jl2012) -- #8524 `b8c79a0` Precompute sighashes (sipa) -- #8651 `b8c79a0` Predeclare PrecomputedTransactionData as struct (sipa) - -### P2P protocol and network code -- #8740 `42ea51a` No longer send local address in addrMe (laanwj) -- #8427 `69d1cd2` Ignore `notfound` P2P messages (laanwj) -- #8573 `4f84082` Set jonasschnellis dns-seeder filter flag (jonasschnelli) -- #8712 `23feab1` Remove maxuploadtargets recommended minimum (jonasschnelli) -- #8862 `7ae6242` Fix a few cases where messages were sent after requested disconnect (theuni) -- #8393 `fe1975a` Support for compact blocks together with segwit (sipa) -- #8282 `2611ad7` Feeler connections to increase online addrs in the tried table (EthanHeilman) -- #8612 `2215c22` Check for compatibility with download in FindNextBlocksToDownload (sipa) -- #8606 `bbf379b` Fix some locks (sipa) -- #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) -- #8940 `5b4192b` Add x9 service bit support to dnsseed.bluematt.me, seed.bitcoinstats.com (TheBlueMatt, cdecker) -- #8944 `685e4c7` Remove bogus assert on number of oubound connections. (TheBlueMatt) -- #8949 `0dbc48a` Be more agressive in getting connections to peers with relevant services (gmaxwell) - -### Build system -- #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) -- #8492 `8b0bdd3` Allow building bench_bitcoin by itself (luke-jr) -- #8563 `147003c` Add configure check for -latomic (ajtowns) -- #8626 `ea51b0f` Berkeley DB v6 compatibility fix (netsafe) -- #8520 `75f2065` Remove check for `openssl/ec.h` (laanwj) - -### GUI -- #8481 `d9f0d4e` Fix minimize and close bugs (adlawren) -- #8487 `a37cec5` Persist the datadir after option reset (achow101) -- #8697 `41fd852` Fix op order to append first alert (rodasmith) -- #8678 `8e03382` Fix UI bug that could result in paying unexpected fee (jonasschnelli) -- #8911 `7634d8e` Translate all files, even if wallet disabled (laanwj) -- #8540 `1db3352` Fix random segfault when closing "Choose data directory" dialog (laanwj) -- #7579 `f1c0d78` Show network/chain errors in the GUI (jonasschnelli) - -### Wallet -- #8443 `464dedd` Trivial cleanup of HD wallet changes (jonasschnelli) -- #8539 `cb07f19` CDB: fix debug output (crowning-) -- #8664 `091cdeb` Fix segwit-related wallet bug (sdaftuar) -- #8693 `c6a6291` Add witness address to address book (instagibbs) -- #8765 `6288659` Remove "unused" ThreadFlushWalletDB from removeprunedfunds (jonasschnelli) - -### Tests and QA -- #8713 `ae8c7df` create_cache: Delete temp dir when done (MarcoFalke) -- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) -- #8750 `d6ebe13` Refactor RPCTestHandler to prevent TimeoutExpired (MarcoFalke) -- #8652 `63462c2` remove root test directory for RPC tests (yurizhykin) -- #8724 `da94272` walletbackup: Sync blocks inside the loop (MarcoFalke) -- #8400 `bea02dc` enable rpcbind_test (yurizhykin) -- #8417 `f70be14` Add walletdump RPC test (including HD- & encryption-tests) (jonasschnelli) -- #8419 `a7aa3cc` Enable size accounting in mining unit tests (sdaftuar) -- #8442 `8bb1efd` Rework hd wallet dump test (MarcoFalke) -- #8528 `3606b6b` Update p2p-segwit.py to reflect correct behavior (instagibbs) -- #8531 `a27cdd8` abandonconflict: Use assert_equal (MarcoFalke) -- #8667 `6b07362` Fix SIGHASH_SINGLE bug in test_framework SignatureHash (jl2012) -- #8673 `03b0196` Fix obvious assignment/equality error in test (JeremyRubin) -- #8739 `cef633c` Fix broken sendcmpct test in p2p-compactblocks.py (sdaftuar) -- #8418 `ff893aa` Add tests for compact blocks (sdaftuar) -- #8803 `375437c` Ping regularly in p2p-segwit.py to keep connection alive (jl2012) -- #8827 `9bbe66e` Split up slow RPC calls to avoid pruning test timeouts (sdaftuar) -- #8829 `2a8bca4` Add bitcoin-tx JSON tests (jnewbery) -- #8834 `1dd1783` blockstore: Switch to dumb dbm (MarcoFalke) -- #8835 `d87227d` nulldummy.py: Don't run unused code (MarcoFalke) -- #8836 `eb18cc1` bitcoin-util-test.py should fail if the output file is empty (jnewbery) -- #8839 `31ab2f8` Avoid ConnectionResetErrors during RPC tests (laanwj) -- #8840 `cbc3fe5` Explicitly set encoding to utf8 when opening text files (laanwj) -- #8841 `3e4abb5` Fix nulldummy test (jl2012) -- #8854 `624a007` Fix race condition in p2p-compactblocks test (sdaftuar) -- #8857 `1f60d45` mininode: Only allow named args in wait_until (MarcoFalke) -- #8860 `0bee740` util: Move wait_bitcoinds() into stop_nodes() (MarcoFalke) -- #8882 `b73f065` Fix race conditions in p2p-compactblocks.py and sendheaders.py (sdaftuar) -- #8904 `cc6f551` Fix compact block shortids for a test case (dagurval) - -### Documentation -- #8754 `0e2c6bd` Target protobuf 2.6 in OS X build notes. (fanquake) -- #8461 `b17a3f9` Document return value of networkhashps for getmininginfo RPC endpoint (jlopp) -- #8512 `156e305` Corrected JSON typo on setban of net.cpp (sevastos) -- #8683 `8a7d7ff` Fix incorrect file name bitcoin.qrc (bitcoinsSG) -- #8891 `5e0dd9e` Update bips.md for Segregated Witness (fanquake) -- #8545 `863ae74` Update git-subtree-check.sh README (MarcoFalke) -- #8607 `486650a` Fix doxygen off-by-one comments, fix typos (MarcoFalke) -- #8560 `c493f43` Fix two VarInt examples in serialize.h (cbarcenas) -- #8737 `084cae9` UndoReadFromDisk works on undo files (rev), not on block files (paveljanik) -- #8625 `0a35573` Clarify statement about parallel jobs in rpc-tests.py (isle2983) -- #8624 `0e6d753` build: Mention curl (MarcoFalke) -- #8604 `b09e13c` build,doc: Update for 0.13.0+ and OpenBSD 5.9 (laanwj) -- #8939 `06d15fb` Update implemented bips for 0.13.1 (sipa) - -### Miscellaneous -- #8742 `d31ac72` Specify Protobuf version 2 in paymentrequest.proto (fanquake) -- #8414,#8558,#8676,#8700,#8701,#8702 Add missing copyright headers (isle2983, kazcw) -- #8899 `4ed2627` Fix wake from sleep issue with Boost 1.59.0 (fanquake) -- #8817 `bcf3806` update bitcoin-tx to output witness data (jnewbery) -- #8513 `4e5fc31` Fix a type error that would not compile on OSX. (JeremyRubin) -- #8392 `30eac2d` Fix several node initialization issues (sipa) -- #8548 `305d8ac` Use `__func__` to get function name for output printing (MarcoFalke) -- #8291 `a987431` [util] CopyrightHolders: Check for untranslated substitution (MarcoFalke) +(to be filled in at release time) Credits ======= Thanks to everyone who directly contributed to this release: -- adlawren -- Alexey Vesnin -- Anders Øyvind Urke-Sætre -- Andrew Chow -- Anthony Towns -- BtcDrak -- Chris Stewart -- Christian Barcenas -- Christian Decker -- Cory Fields -- crowning- -- Dagur Valberg Johannsson -- David A. Harding -- Eric Lombrozo -- Ethan Heilman -- fanquake -- Gaurav Rana -- Gregory Maxwell -- instagibbs -- isle2983 -- Jameson Lopp -- Jeremy Rubin -- jnewbery -- Johnson Lau -- Jonas Schnelli -- jonnynewbs -- Justin Camarena -- Kaz Wesley -- leijurv -- Luke Dashjr -- MarcoFalke -- Marty Jones -- Matt Corallo -- Micha -- Michael Ford -- mruddy -- Pavel Janík -- Pieter Wuille -- rodasmith -- Sev -- Suhas Daftuar -- whythat -- Wladimir J. van der Laan +(to be filled in at release time) As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.13.1.md b/doc/release-notes/release-notes-0.13.1.md new file mode 100644 index 000000000..75c2d61be --- /dev/null +++ b/doc/release-notes/release-notes-0.13.1.md @@ -0,0 +1,410 @@ +Bitcoin Core version 0.13.1 is now available from: + + + +This is a new minor version release, including activation parameters for the +segwit softfork, various bugfixes and performance improvements, as well as +updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer version of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + +Notable changes +=============== + +Segregated witness soft fork +---------------------------- + +Segregated witness (segwit) is a soft fork that, if activated, will +allow transaction-producing software to separate (segregate) transaction +signatures (witnesses) from the part of the data in a transaction that is +covered by the txid. This provides several immediate benefits: + +- **Elimination of unwanted transaction malleability:** Segregating the witness + allows both existing and upgraded software to calculate the transaction + identifier (txid) of transactions without referencing the witness, which can + sometimes be changed by third-parties (such as miners) or by co-signers in a + multisig spend. This solves all known cases of unwanted transaction + malleability, which is a problem that makes programming Bitcoin wallet + software more difficult and which seriously complicates the design of smart + contracts for Bitcoin. + +- **Capacity increase:** Segwit transactions contain new fields that are not + part of the data currently used to calculate the size of a block, which + allows a block containing segwit transactions to hold more data than allowed + by the current maximum block size. Estimates based on the transactions + currently found in blocks indicate that if all wallets switch to using + segwit, the network will be able to support about 70% more transactions. The + network will also be able to support more of the advanced-style payments + (such as multisig) than it can support now because of the different weighting + given to different parts of a transaction after segwit activates (see the + following section for details). + +- **Weighting data based on how it affects node performance:** Some parts of + each Bitcoin block need to be stored by nodes in order to validate future + blocks; other parts of a block can be immediately forgotten (pruned) or used + only for helping other nodes sync their copy of the block chain. One large + part of the immediately prunable data are transaction signatures (witnesses), + and segwit makes it possible to give a different "weight" to segregated + witnesses to correspond with the lower demands they place on node resources. + Specifically, each byte of a segregated witness is given a weight of 1, each + other byte in a block is given a weight of 4, and the maximum allowed weight + of a block is 4 million. Weighting the data this way better aligns the most + profitable strategy for creating blocks with the long-term costs of block + validation. + +- **Signature covers value:** A simple improvement in the way signatures are + generated in segwit simplifies the design of secure signature generators + (such as hardware wallets), reduces the amount of data the signature + generator needs to download, and allows the signature generator to operate + more quickly. This is made possible by having the generator sign the amount + of bitcoins they think they are spending, and by having full nodes refuse to + accept those signatures unless the amount of bitcoins being spent is exactly + the same as was signed. For non-segwit transactions, wallets instead had to + download the complete previous transactions being spent for every payment + they made, which could be a slow operation on hardware wallets and in other + situations where bandwidth or computation speed was constrained. + +- **Linear scaling of sighash operations:** In 2015 a block was produced that + required about 25 seconds to validate on modern hardware because of the way + transaction signature hashes are performed. Other similar blocks, or blocks + that could take even longer to validate, can still be produced today. The + problem that caused this can't be fixed in a soft fork without unwanted + side-effects, but transactions that opt-in to using segwit will now use a + different signature method that doesn't suffer from this problem and doesn't + have any unwanted side-effects. + +- **Increased security for multisig:** Bitcoin addresses (both P2PKH addresses + that start with a '1' and P2SH addresses that start with a '3') use a hash + function known as RIPEMD-160. For P2PKH addresses, this provides about 160 + bits of security---which is beyond what cryptographers believe can be broken + today. But because P2SH is more flexible, only about 80 bits of security is + provided per address. Although 80 bits is very strong security, it is within + the realm of possibility that it can be broken by a powerful adversary. + Segwit allows advanced transactions to use the SHA256 hash function instead, + which provides about 128 bits of security (that is 281 trillion times as + much security as 80 bits and is equivalent to the maximum bits of security + believed to be provided by Bitcoin's choice of parameters for its Elliptic + Curve Digital Security Algorithm [ECDSA].) + +- **More efficient almost-full-node security** Satoshi Nakamoto's original + Bitcoin paper describes a method for allowing newly-started full nodes to + skip downloading and validating some data from historic blocks that are + protected by large amounts of proof of work. Unfortunately, Nakamoto's + method can't guarantee that a newly-started node using this method will + produce an accurate copy of Bitcoin's current ledger (called the UTXO set), + making the node vulnerable to falling out of consensus with other nodes. + Although the problems with Nakamoto's method can't be fixed in a soft fork, + Segwit accomplishes something similar to his original proposal: it makes it + possible for a node to optionally skip downloading some blockchain data + (specifically, the segregated witnesses) while still ensuring that the node + can build an accurate copy of the UTXO set for the block chain with the most + proof of work. Segwit enables this capability at the consensus layer, but + note that Bitcoin Core does not provide an option to use this capability as + of this 0.13.1 release. + +- **Script versioning:** Segwit makes it easy for future soft forks to allow + Bitcoin users to individually opt-in to almost any change in the Bitcoin + Script language when those users receive new transactions. Features + currently being researched by Bitcoin Core contributors that may use this + capability include support for Schnorr signatures, which can improve the + privacy and efficiency of multisig transactions (or transactions with + multiple inputs), and Merklized Abstract Syntax Trees (MAST), which can + improve the privacy and efficiency of scripts with two or more conditions. + Other Bitcoin community members are studying several other improvements + that can be made using script versioning. + +Activation for the segwit soft fork is being managed using BIP9 +versionbits. Segwit's version bit is bit 1, and nodes will begin +tracking which blocks signal support for segwit at the beginning of the +first retarget period after segwit's start date of 15 November 2016. If +95% of blocks within a 2,016-block retarget period (about two weeks) +signal support for segwit, the soft fork will be locked in. After +another 2,016 blocks, segwit will activate. + +For more information about segwit, please see the [segwit FAQ][], the +[segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], +[144][BIP144], and [145][BIP145]. If you're a miner or mining pool +operator, please see the [versionbits FAQ][] for information about +signaling support for a soft fork. + +[Segwit FAQ]: https://bitcoincore.org/en/2016/01/26/segwit-benefits/ +[segwit wallet developers guide]: https://bitcoincore.org/en/segwit_wallet_dev/ +[BIP141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki +[BIP143]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki +[BIP144]: https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki +[BIP145]: https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki +[versionbits FAQ]: https://bitcoincore.org/en/2016/06/08/version-bits-miners-faq/ + + +Null dummy soft fork +------------------- + +Combined with the segwit soft fork is an additional change that turns a +long-existing network relay policy into a consensus rule. The +`OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY` opcodes consume an extra +stack element ("dummy element") after signature validation. The dummy +element is not inspected in any manner, and could be replaced by any +value without invalidating the script. + +Because any value can be used for this dummy element, it's possible for +a third-party to insert data into other people's transactions, changing +the transaction's txid (called transaction malleability) and possibly +causing other problems. + +Since Bitcoin Core 0.10.0, nodes have defaulted to only relaying and +mining transactions whose dummy element was a null value (0x00, also +called OP_0). The null dummy soft fork turns this relay rule into a +consensus rule both for non-segwit transactions and segwit transactions, +so that this method of mutating transactions is permanently eliminated +from the network. + +Signaling for the null dummy soft fork is done by signaling support +for segwit, and the null dummy soft fork will activate at the same time +as segwit. + +For more information, please see [BIP147][]. + +[BIP147]: https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki + +Low-level RPC changes +--------------------- + +- `importprunedfunds` only accepts two required arguments. Some versions accept + an optional third arg, which was always ignored. Make sure to never pass more + than two arguments. + + +Linux ARM builds +---------------- + +With the 0.13.0 release, pre-built Linux ARM binaries were added to the set of +uploaded executables. Additional detail on the ARM architecture targeted by each +is provided below. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries targeting + the 32-bit ARMv7-A architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries targeting + the 64-bit ARMv8-A architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. Note that the device you use must be (backward) +compatible with the architecture targeted by the binary that you use. +For example, a Raspberry Pi 2 Model B or Raspberry Pi 3 Model B (in its 32-bit +execution state) device, can run the 32-bit ARMv7-A targeted binary. However, +no model of Raspberry Pi 1 device can run either binary because they are all +ARMv6 architecture devices that are not compatible with ARMv7-A or ARMv8-A. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + + +0.13.1 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### Consensus +- #8636 `9dfa0c8` Implement NULLDUMMY softfork (BIP147) (jl2012) +- #8848 `7a34a46` Add NULLDUMMY verify flag in bitcoinconsensus.h (jl2012) +- #8937 `8b66659` Define start and end time for segwit deployment (sipa) + +### RPC and other APIs +- #8581 `526d2b0` Drop misleading option in importprunedfunds (MarcoFalke) +- #8699 `a5ec248` Remove createwitnessaddress RPC command (jl2012) +- #8780 `794b007` Deprecate getinfo (MarcoFalke) +- #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) +- #8884 `b987348` getblockchaininfo help: pruneheight is the lowest, not highest, block (luke-jr) +- #8858 `3f508ed` rpc: Generate auth cookie in hex instead of base64 (laanwj) +- #8951 `7c2bf4b` RPC/Mining: getblocktemplate: Update and fix formatting of help (luke-jr) + +### Block and transaction handling +- #8611 `a9429ca` Reduce default number of blocks to check at startup (sipa) +- #8634 `3e80ab7` Add policy: null signature for failed CHECK(MULTI)SIG (jl2012) +- #8525 `1672225` Do not store witness txn in rejection cache (sipa) +- #8499 `9777fe1` Add several policy limits and disable uncompressed keys for segwit scripts (jl2012) +- #8526 `0027672` Make non-minimal OP_IF/NOTIF argument non-standard for P2WSH (jl2012) +- #8524 `b8c79a0` Precompute sighashes (sipa) +- #8651 `b8c79a0` Predeclare PrecomputedTransactionData as struct (sipa) + +### P2P protocol and network code +- #8740 `42ea51a` No longer send local address in addrMe (laanwj) +- #8427 `69d1cd2` Ignore `notfound` P2P messages (laanwj) +- #8573 `4f84082` Set jonasschnellis dns-seeder filter flag (jonasschnelli) +- #8712 `23feab1` Remove maxuploadtargets recommended minimum (jonasschnelli) +- #8862 `7ae6242` Fix a few cases where messages were sent after requested disconnect (theuni) +- #8393 `fe1975a` Support for compact blocks together with segwit (sipa) +- #8282 `2611ad7` Feeler connections to increase online addrs in the tried table (EthanHeilman) +- #8612 `2215c22` Check for compatibility with download in FindNextBlocksToDownload (sipa) +- #8606 `bbf379b` Fix some locks (sipa) +- #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) +- #8940 `5b4192b` Add x9 service bit support to dnsseed.bluematt.me, seed.bitcoinstats.com (TheBlueMatt, cdecker) +- #8944 `685e4c7` Remove bogus assert on number of oubound connections. (TheBlueMatt) +- #8949 `0dbc48a` Be more agressive in getting connections to peers with relevant services (gmaxwell) + +### Build system +- #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) +- #8492 `8b0bdd3` Allow building bench_bitcoin by itself (luke-jr) +- #8563 `147003c` Add configure check for -latomic (ajtowns) +- #8626 `ea51b0f` Berkeley DB v6 compatibility fix (netsafe) +- #8520 `75f2065` Remove check for `openssl/ec.h` (laanwj) + +### GUI +- #8481 `d9f0d4e` Fix minimize and close bugs (adlawren) +- #8487 `a37cec5` Persist the datadir after option reset (achow101) +- #8697 `41fd852` Fix op order to append first alert (rodasmith) +- #8678 `8e03382` Fix UI bug that could result in paying unexpected fee (jonasschnelli) +- #8911 `7634d8e` Translate all files, even if wallet disabled (laanwj) +- #8540 `1db3352` Fix random segfault when closing "Choose data directory" dialog (laanwj) +- #7579 `f1c0d78` Show network/chain errors in the GUI (jonasschnelli) + +### Wallet +- #8443 `464dedd` Trivial cleanup of HD wallet changes (jonasschnelli) +- #8539 `cb07f19` CDB: fix debug output (crowning-) +- #8664 `091cdeb` Fix segwit-related wallet bug (sdaftuar) +- #8693 `c6a6291` Add witness address to address book (instagibbs) +- #8765 `6288659` Remove "unused" ThreadFlushWalletDB from removeprunedfunds (jonasschnelli) + +### Tests and QA +- #8713 `ae8c7df` create_cache: Delete temp dir when done (MarcoFalke) +- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) +- #8750 `d6ebe13` Refactor RPCTestHandler to prevent TimeoutExpired (MarcoFalke) +- #8652 `63462c2` remove root test directory for RPC tests (yurizhykin) +- #8724 `da94272` walletbackup: Sync blocks inside the loop (MarcoFalke) +- #8400 `bea02dc` enable rpcbind_test (yurizhykin) +- #8417 `f70be14` Add walletdump RPC test (including HD- & encryption-tests) (jonasschnelli) +- #8419 `a7aa3cc` Enable size accounting in mining unit tests (sdaftuar) +- #8442 `8bb1efd` Rework hd wallet dump test (MarcoFalke) +- #8528 `3606b6b` Update p2p-segwit.py to reflect correct behavior (instagibbs) +- #8531 `a27cdd8` abandonconflict: Use assert_equal (MarcoFalke) +- #8667 `6b07362` Fix SIGHASH_SINGLE bug in test_framework SignatureHash (jl2012) +- #8673 `03b0196` Fix obvious assignment/equality error in test (JeremyRubin) +- #8739 `cef633c` Fix broken sendcmpct test in p2p-compactblocks.py (sdaftuar) +- #8418 `ff893aa` Add tests for compact blocks (sdaftuar) +- #8803 `375437c` Ping regularly in p2p-segwit.py to keep connection alive (jl2012) +- #8827 `9bbe66e` Split up slow RPC calls to avoid pruning test timeouts (sdaftuar) +- #8829 `2a8bca4` Add bitcoin-tx JSON tests (jnewbery) +- #8834 `1dd1783` blockstore: Switch to dumb dbm (MarcoFalke) +- #8835 `d87227d` nulldummy.py: Don't run unused code (MarcoFalke) +- #8836 `eb18cc1` bitcoin-util-test.py should fail if the output file is empty (jnewbery) +- #8839 `31ab2f8` Avoid ConnectionResetErrors during RPC tests (laanwj) +- #8840 `cbc3fe5` Explicitly set encoding to utf8 when opening text files (laanwj) +- #8841 `3e4abb5` Fix nulldummy test (jl2012) +- #8854 `624a007` Fix race condition in p2p-compactblocks test (sdaftuar) +- #8857 `1f60d45` mininode: Only allow named args in wait_until (MarcoFalke) +- #8860 `0bee740` util: Move wait_bitcoinds() into stop_nodes() (MarcoFalke) +- #8882 `b73f065` Fix race conditions in p2p-compactblocks.py and sendheaders.py (sdaftuar) +- #8904 `cc6f551` Fix compact block shortids for a test case (dagurval) + +### Documentation +- #8754 `0e2c6bd` Target protobuf 2.6 in OS X build notes. (fanquake) +- #8461 `b17a3f9` Document return value of networkhashps for getmininginfo RPC endpoint (jlopp) +- #8512 `156e305` Corrected JSON typo on setban of net.cpp (sevastos) +- #8683 `8a7d7ff` Fix incorrect file name bitcoin.qrc (bitcoinsSG) +- #8891 `5e0dd9e` Update bips.md for Segregated Witness (fanquake) +- #8545 `863ae74` Update git-subtree-check.sh README (MarcoFalke) +- #8607 `486650a` Fix doxygen off-by-one comments, fix typos (MarcoFalke) +- #8560 `c493f43` Fix two VarInt examples in serialize.h (cbarcenas) +- #8737 `084cae9` UndoReadFromDisk works on undo files (rev), not on block files (paveljanik) +- #8625 `0a35573` Clarify statement about parallel jobs in rpc-tests.py (isle2983) +- #8624 `0e6d753` build: Mention curl (MarcoFalke) +- #8604 `b09e13c` build,doc: Update for 0.13.0+ and OpenBSD 5.9 (laanwj) +- #8939 `06d15fb` Update implemented bips for 0.13.1 (sipa) + +### Miscellaneous +- #8742 `d31ac72` Specify Protobuf version 2 in paymentrequest.proto (fanquake) +- #8414,#8558,#8676,#8700,#8701,#8702 Add missing copyright headers (isle2983, kazcw) +- #8899 `4ed2627` Fix wake from sleep issue with Boost 1.59.0 (fanquake) +- #8817 `bcf3806` update bitcoin-tx to output witness data (jnewbery) +- #8513 `4e5fc31` Fix a type error that would not compile on OSX. (JeremyRubin) +- #8392 `30eac2d` Fix several node initialization issues (sipa) +- #8548 `305d8ac` Use `__func__` to get function name for output printing (MarcoFalke) +- #8291 `a987431` [util] CopyrightHolders: Check for untranslated substitution (MarcoFalke) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- adlawren +- Alexey Vesnin +- Anders Øyvind Urke-Sætre +- Andrew Chow +- Anthony Towns +- BtcDrak +- Chris Stewart +- Christian Barcenas +- Christian Decker +- Cory Fields +- crowning- +- Dagur Valberg Johannsson +- David A. Harding +- Eric Lombrozo +- Ethan Heilman +- fanquake +- Gaurav Rana +- Gregory Maxwell +- instagibbs +- isle2983 +- Jameson Lopp +- Jeremy Rubin +- jnewbery +- Johnson Lau +- Jonas Schnelli +- jonnynewbs +- Justin Camarena +- Kaz Wesley +- leijurv +- Luke Dashjr +- MarcoFalke +- Marty Jones +- Matt Corallo +- Micha +- Michael Ford +- mruddy +- Pavel Janík +- Pieter Wuille +- rodasmith +- Sev +- Suhas Daftuar +- whythat +- Wladimir J. van der Laan + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 82905069bfd763f16a63649eb51ed3a566bca2c5 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 26 Oct 2016 13:03:30 -0400 Subject: [PATCH 1131/1223] [qa] Test that invalid compactblocks don't result in ban --- qa/rpc-tests/p2p-compactblocks.py | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 131654c33..9ecced0dd 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -708,6 +708,33 @@ class CompactBlocksTest(BitcoinTestFramework): l.last_cmpctblock.header_and_shortids.header.calc_sha256() assert_equal(l.last_cmpctblock.header_and_shortids.header.sha256, block.sha256) + # Test that we don't get disconnected if we relay a compact block with valid header, + # but invalid transactions. + def test_invalid_tx_in_compactblock(self, node, test_node, use_segwit): + assert(len(self.utxos)) + utxo = self.utxos[0] + + block = self.build_block_with_transactions(node, utxo, 5) + del block.vtx[3] + block.hashMerkleRoot = block.calc_merkle_root() + if use_segwit: + # If we're testing with segwit, also drop the coinbase witness, + # but include the witness commitment. + add_witness_commitment(block) + block.vtx[0].wit.vtxinwit = [] + block.solve() + + # Now send the compact block with all transactions prefilled, and + # verify that we don't get disconnected. + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, prefill_list=[0, 1, 2, 3, 4], use_witness=use_segwit) + msg = msg_cmpctblock(comp_block.to_p2p()) + test_node.send_and_ping(msg) + + # Check that the tip didn't advance + assert(int(node.getbestblockhash(), 16) is not block.sha256) + test_node.sync_with_ping() + # Helper for enabling cb announcements # Send the sendcmpct request and sync headers def request_cb_announcements(self, peer, node, version): @@ -798,6 +825,11 @@ class CompactBlocksTest(BitcoinTestFramework): self.test_end_to_end_block_relay(self.nodes[0], [self.segwit_node, self.test_node, self.old_node]) self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + print("\tTesting handling of invalid compact blocks...") + self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, False) + # Advance to segwit activation print ("\nAdvancing to segwit activation\n") self.activate_segwit(self.nodes[1]) @@ -844,6 +876,11 @@ class CompactBlocksTest(BitcoinTestFramework): self.request_cb_announcements(self.segwit_node, self.nodes[1], 2) self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + print("\tTesting handling of invalid compact blocks...") + self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, True) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, True) + print("\tTesting invalid index in cmpctblock message...") self.test_invalid_cmpctblock_message() From 015865ee9e5dd450ceb6cece489f924aaa1137e3 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Mon, 31 Oct 2016 10:03:49 -0400 Subject: [PATCH 1132/1223] Fix compact block handling to not ban if block is invalid --- src/blockencodings.cpp | 2 +- src/blockencodings.h | 2 ++ src/main.cpp | 47 ++++++++++++++++++++++++++------------- src/main.h | 2 +- src/rpc/mining.cpp | 4 ++-- src/test/miner_tests.cpp | 2 +- src/test/test_bitcoin.cpp | 2 +- 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 93d3fa372..737102f16 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -167,7 +167,7 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< // check its own merkle root and cache that check. if (state.CorruptionPossible()) return READ_STATUS_FAILED; // Possible Short ID collision - return READ_STATUS_INVALID; + return READ_STATUS_CHECKBLOCK_FAILED; } LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size()); diff --git a/src/blockencodings.h b/src/blockencodings.h index 2f87c6d31..cab847ee3 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -124,6 +124,8 @@ typedef enum ReadStatus_t READ_STATUS_OK, READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap READ_STATUS_FAILED, // Failed to process object + READ_STATUS_CHECKBLOCK_FAILED, // Used only by FillBlock to indicate a + // failure in CheckBlock. } ReadStatus; class CBlockHeaderAndShortTxIDs { diff --git a/src/main.cpp b/src/main.cpp index 61d0aaf0b..850380abb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -178,8 +178,10 @@ namespace { * Sources of received blocks, saved to be able to send them reject * messages or ban them when processing happens afterwards. Protected by * cs_main. + * Set mapBlockSource[hash].second to false if the node should not be + * punished if the block is invalid. */ - map mapBlockSource; + map> mapBlockSource; /** * Filter for transactions that were recently rejected by @@ -1885,13 +1887,13 @@ void static InvalidChainFound(CBlockIndex* pindexNew) void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) { int nDoS = 0; if (state.IsInvalid(nDoS)) { - std::map::iterator it = mapBlockSource.find(pindex->GetBlockHash()); - if (it != mapBlockSource.end() && State(it->second)) { + std::map>::iterator it = mapBlockSource.find(pindex->GetBlockHash()); + if (it != mapBlockSource.end() && State(it->second.first)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()}; - State(it->second)->rejects.push_back(reject); - if (nDoS > 0) - Misbehaving(it->second, nDoS); + State(it->second.first)->rejects.push_back(reject); + if (nDoS > 0 && it->second.second) + Misbehaving(it->second.first, nDoS); } } if (!state.CorruptionPossible()) { @@ -3761,7 +3763,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid) { { LOCK(cs_main); @@ -3773,7 +3775,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C bool fNewBlock = false; bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp, &fNewBlock); if (pindex && pfrom) { - mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); + mapBlockSource[pindex->GetBlockHash()] = std::make_pair(pfrom->GetId(), fMayBanPeerIfInvalid); if (fNewBlock) pfrom->nLastBlockTime = GetTime(); } CheckBlockIndex(chainparams.GetConsensus()); @@ -4717,7 +4719,6 @@ std::string GetWarnings(const std::string& strFor) ////////////////////////////////////////////////////////////////////////////// -// // Messages // @@ -5791,17 +5792,33 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()), resp.blockhash)); pfrom->PushMessage(NetMsgType::GETDATA, invs); } else { + // Block is either okay, or possibly we received + // READ_STATUS_CHECKBLOCK_FAILED. + // Note that CheckBlock can only fail for one of a few reasons: + // 1. bad-proof-of-work (impossible here, because we've already + // accepted the header) + // 2. merkleroot doesn't match the transactions given (already + // caught in FillBlock with READ_STATUS_FAILED, so + // impossible here) + // 3. the block is otherwise invalid (eg invalid coinbase, + // block is too big, too many legacy sigops, etc). + // So if CheckBlock failed, #3 is the only possibility. + // Under BIP 152, we don't DoS-ban unless proof of work is + // invalid (we don't require all the stateless checks to have + // been run). This is handled below, so just treat this as + // though the block was successfully read, and rely on the + // handling in ProcessNewBlock to ensure the block index is + // updated, reject messages go out, etc. CValidationState state; - ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL); + // BIP 152 permits peers to relay compact blocks after validating + // the header only; we should not punish peers if the block turns + // out to be invalid. + ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL, false); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash()); - if (nDoS > 0) { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), nDoS); - } } } } @@ -5968,7 +5985,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Such an unrequested block may still be processed, subject to the // conditions in AcceptBlock(). bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); - ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL); + ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, true); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes diff --git a/src/main.h b/src/main.h index 0ca13d82d..daf884337 100644 --- a/src/main.h +++ b/src/main.h @@ -222,7 +222,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @param[out] dbp The already known disk position of pblock, or NULL if not yet stored. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 14a61a55d..e6901bc77 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -131,7 +131,7 @@ UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nG continue; } CValidationState state; - if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL, false)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -760,7 +760,7 @@ UniValue submitblock(const UniValue& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL); + bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL, false); UnregisterValidationInterface(&sc); if (fBlockPresent) { diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 15fceb963..70ba70779 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; CValidationState state; - BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)); + BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL, false)); BOOST_CHECK(state.IsValid()); pblock->hashPrevBlock = pblock->GetHash(); } diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 056f2982c..09f9a362d 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -118,7 +118,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector& while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; CValidationState state; - ProcessNewBlock(state, chainparams, NULL, &block, true, NULL); + ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, false); CBlock result = block; delete pblocktemplate; From e8ef50ba51968da67a36c9fae6938d868b434da2 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 1 Nov 2016 11:12:43 -0400 Subject: [PATCH 1133/1223] Bump the protocol version to distinguish new banning behavior. This allows future software that would relay compact blocks before full validation to announce only to peers that will not ban if the block turns out to be invalid. --- src/version.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 68ccd6d37..497f82be2 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70014; +static const int PROTOCOL_VERSION = 70015; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -42,4 +42,7 @@ static const int FEEFILTER_VERSION = 70013; //! shord-id-based block download starts with this version static const int SHORT_IDS_BLOCKS_VERSION = 70014; +//! not banning for invalid compact blocks starts with this version +static const int INVALID_CB_NO_BAN_VERSION = 70015; + #endif // BITCOIN_VERSION_H From 3107280e14f7ca63c693937aac490794ae746a09 Mon Sep 17 00:00:00 2001 From: mrbandrews Date: Tue, 15 Nov 2016 15:37:46 -0500 Subject: [PATCH 1134/1223] [qa] add assert_raises_message to check specific error message Github-Pull: #9168 Rebased-From: 307acdd3df03082295ac0f7fe9eba7dd35973bc4 --- qa/rpc-tests/test_framework/util.py | 8 ++++++-- qa/rpc-tests/wallet.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 47cebf4f6..c5f270591 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -508,10 +508,14 @@ def assert_greater_than(thing1, thing2): raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) def assert_raises(exc, fun, *args, **kwds): + assert_raises_message(exc, None, fun, *args, **kwds) + +def assert_raises_message(exc, message, fun, *args, **kwds): try: fun(*args, **kwds) - except exc: - pass + except exc as e: + if message is not None and message not in e.error['message']: + raise AssertionError("Expected substring not found:"+e.error['message']) except Exception as e: raise AssertionError("Unexpected exception raised: "+type(e).__name__) else: diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index e43f6ea5d..3c0dc0f4e 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -71,7 +71,7 @@ class WalletTest (BitcoinTestFramework): unspent_0 = self.nodes[2].listunspent()[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) - assert_raises(JSONRPCException, self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) + assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) From 1d4c884cd325150c68b8b129e4dc18a933866509 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 2 Nov 2016 09:46:55 -0400 Subject: [PATCH 1135/1223] [qa] Increase wallet-dump RPC timeout Increase wallet-dump RPC timeout from 30 seconds to 1 minute. This avoids a timeout error that seemed to happen regularly (around 50% of builds) on a particular jenkins server during the first getnewaddress RPC call made by the test. The failing stack trace looked like: Unexpected exception caught during testing: timeout('timed out',) File ".../bitcoin/qa/rpc-tests/test_framework/test_framework.py", line 146, in main self.run_test() File ".../bitcoin/qa/rpc-tests/wallet-dump.py", line 73, in run_test addr = self.nodes[0].getnewaddress() File ".../bitcoin/qa/rpc-tests/test_framework/coverage.py", line 49, in __call__ return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs) File ".../bitcoin/qa/rpc-tests/test_framework/authproxy.py", line 145, in __call__ response = self._request('POST', self.__url.path, postdata.encode('utf-8')) File ".../bitcoin/qa/rpc-tests/test_framework/authproxy.py", line 121, in _request return self._get_response() File ".../bitcoin/qa/rpc-tests/test_framework/authproxy.py", line 160, in _get_response http_response = self.__conn.getresponse() File "/usr/lib/python3.4/http/client.py", line 1171, in getresponse response.begin() File "/usr/lib/python3.4/http/client.py", line 351, in begin version, status, reason = self._read_status() File "/usr/lib/python3.4/http/client.py", line 313, in _read_status line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") File "/usr/lib/python3.4/socket.py", line 374, in readinto return self._sock.recv_into(b) Github-Pull: #9077 Rebased-From: 8463aaa63c5ac76421c4d2754ea9e17a31584c93 --- qa/rpc-tests/test_framework/util.py | 4 ++-- qa/rpc-tests/wallet-dump.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index c5f270591..bf3f2b2db 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -327,7 +327,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= return proxy -def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): +def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): """ Start multiple bitcoinds, return RPC connections to them """ @@ -336,7 +336,7 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): rpcs = [] try: for i in range(num_nodes): - rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i])) + rpcs.append(start_node(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i])) except: # If one node failed to start, stop the others stop_nodes(rpcs) raise diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py index a37096a40..c6dc2e3d1 100755 --- a/qa/rpc-tests/wallet-dump.py +++ b/qa/rpc-tests/wallet-dump.py @@ -61,7 +61,11 @@ class WalletDumpTest(BitcoinTestFramework): self.extra_args = [["-keypool=90"]] def setup_network(self, split=False): - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) + # Use 1 minute timeout because the initial getnewaddress RPC can take + # longer than the default 30 seconds due to an expensive + # CWallet::TopUpKeyPool call, and the encryptwallet RPC made later in + # the test often takes even longer. + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args, timewait=60) def run_test (self): tmpdir = self.options.tmpdir From da4926b1d28c600076d3eb35df60981298194697 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 2 Nov 2016 15:08:54 -0400 Subject: [PATCH 1136/1223] [qa] Add more helpful RPC timeout message Replace previous timeout('timed out',) exception with more detailed error. Github-Pull: #9077 Rebased-From: e89614b6abf28d7fe201c3db44a0df6e4db6de03 --- qa/rpc-tests/test_framework/authproxy.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 1a94bf5fe..7b051545c 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -42,6 +42,7 @@ import base64 import decimal import json import logging +import socket try: import urllib.parse as urlparse except ImportError: @@ -157,7 +158,15 @@ class AuthServiceProxy(object): return self._request('POST', self.__url.path, postdata.encode('utf-8')) def _get_response(self): - http_response = self.__conn.getresponse() + try: + http_response = self.__conn.getresponse() + except socket.timeout as e: + raise JSONRPCException({ + 'code': -344, + 'message': '%r RPC took longer than %f seconds. Consider ' + 'using larger timeout for calls that take ' + 'longer to return.' % (self._service_name, + self.__conn.timeout)}) if http_response is None: raise JSONRPCException({ 'code': -342, 'message': 'missing HTTP response from server'}) From dccdc3aa34218eecd4a37988857b5d4f3dd884ef Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 13:08:30 +0100 Subject: [PATCH 1137/1223] test: Fix use-after-free in scheduler tests Make a copy of the boost time-point to wait for, otherwise the head of the queue may be deleted by another thread while this one is waiting, while the boost function still has a reference to it. Although this problem is in non-test code, this is not an actual problem outside of the tests because we use the thread scheduler with only one service thread, so there will never be threads fighting at the head of the queue. The old boost fallback escapes this problem because it passes a scalar value to wait_until instead of a const object reference. Found by running the tests in LLVM-4.0-master asan. Github-Pull: #9186 Rebased-From: 12519bf62b8c49b1c1744eca6ea5b3162a61f962 --- src/scheduler.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 52777b61f..27c03f154 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -54,9 +54,10 @@ void CScheduler::serviceQueue() #else // Some boost versions have a conflicting overload of wait_until that returns void. // Explicitly use a template here to avoid hitting that overload. - while (!shouldStop() && !taskQueue.empty() && - newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) { - // Keep waiting until timeout + while (!shouldStop() && !taskQueue.empty()) { + boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first; + if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout) + break; // Exit loop after timeout, it means we reached the time of the event } #endif // If there are multiple threads, the queue can empty while we're waiting (another From eca9b4653788570c25e646dcdfa9ba088e89f20e Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 14 Nov 2016 09:58:30 -0500 Subject: [PATCH 1138/1223] [qa] Wait for specific block announcement in p2p-compactblocks Change check_announcement_of_new_block() to wait specifically for the announcement of the newly created block, instead of waiting for any announcement at all. A difficult to reproduce failure in check_announcement_of_new_block() that happened in a travis build (https://travis-ci.org/bitcoin/bitcoin/jobs/175198367) might have happened because an older announcement was mistaken for the expected one. The error looked like: Assertion failed: Failed File ".../bitcoin/qa/rpc-tests/test_framework/test_framework.py", line 145, in main self.run_test() File ".../bitcoin/build/../qa/rpc-tests/p2p-compactblocks.py", line 787, in run_test self.test_sendcmpct(self.nodes[1], self.segwit_node, 2, old_node=self.old_node) File ".../bitcoin/build/../qa/rpc-tests/p2p-compactblocks.py", line 201, in test_sendcmpct check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None and p.last_inv is not None) File ".../bitcoin/build/../qa/rpc-tests/p2p-compactblocks.py", line 194, in check_announcement_of_new_block assert(predicate(peer)) This commit also changes the assertion failed message above to include more detailed information for debug. Github-Pull: #9159 Rebased-From: dfa44d1b07a6d1022005dba63dd6372739eee8a0 --- qa/rpc-tests/p2p-compactblocks.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 9ecced0dd..c20cbede5 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -186,12 +186,15 @@ class CompactBlocksTest(BitcoinTestFramework): def check_announcement_of_new_block(node, peer, predicate): peer.clear_block_announcement() - node.generate(1) - got_message = wait_until(lambda: peer.block_announced, timeout=30) + block_hash = int(node.generate(1)[0], 16) + peer.wait_for_block_announcement(block_hash, timeout=30) assert(peer.block_announced) assert(got_message) + with mininode_lock: - assert(predicate(peer)) + assert predicate(peer), ( + "block_hash={!r}, cmpctblock={!r}, inv={!r}".format( + block_hash, peer.last_cmpctblock, peer.last_inv)) # We shouldn't get any block announcements via cmpctblock yet. check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) From 2ba5d784276783716bbf27b458514c4c3f44f4b6 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 24 Oct 2016 15:33:14 -0400 Subject: [PATCH 1139/1223] [qa] Fix bug in compactblocks v2 merge Bug caused the wait_for_block_announcement to be called on the wrong node, leading to nondeterminism and occasional test failures. Bug was introduced in merge commit: d075479 Merge #8882: [qa] Fix race conditions in p2p-compactblocks.py and sendheaders.py Underlying commits which conflicted were: 27acfc1 [qa] Update p2p-compactblocks.py for compactblocks v2 6976db2 [qa] Another attempt to fix race condition in p2p-compactblocks.py The first commit changed the test_compactblock_construction function signature and second commit added code which wasn't updated during the merge to use the new arguments. Suhas Daftuar noticed the bug and suggested the fix. Github-Pull: #9058 Rebased-From: 47e9659ecfbe07077a4564591095bd5510e0f917 --- qa/rpc-tests/p2p-compactblocks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index c20cbede5..0abb9f986 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -303,8 +303,8 @@ class CompactBlocksTest(BitcoinTestFramework): assert(segwit_tx_generated) # check that our test is not broken # Wait until we've seen the block announcement for the resulting tip - tip = int(self.nodes[0].getbestblockhash(), 16) - assert(self.test_node.wait_for_block_announcement(tip)) + tip = int(node.getbestblockhash(), 16) + assert(test_node.wait_for_block_announcement(tip)) # Now mine a block, and look at the resulting compact block. test_node.clear_block_announcement() From 286e548d87266f3b394d75182f04fb701b2263e8 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 26 Oct 2016 14:15:16 -0400 Subject: [PATCH 1140/1223] [qa] Fix stale data bug in test_compactblocks_not_at_tip Clear test_node.last_block before requesting blocks in the compactblocks_not_at_tip test so comparisons won't fail if a blocks were received before the test started. The bug doesn't currently cause any problems due to the order tests run, but this will change in the next commit. Github-Pull: #9058 Rebased-From: 55bfddcabbf9e8a3743f77167ba4a43aaba9f948 --- qa/rpc-tests/p2p-compactblocks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 0abb9f986..249afec2b 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -651,6 +651,8 @@ class CompactBlocksTest(BitcoinTestFramework): node.generate(1) wait_until(test_node.received_block_announcement, timeout=30) test_node.clear_block_announcement() + with mininode_lock: + test_node.last_block = None test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) success = wait_until(lambda: test_node.last_block is not None, timeout=30) assert(success) From 36e3b951039b98508badaafa0bbec166c22900d3 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 21 Jun 2016 13:08:29 -0700 Subject: [PATCH 1141/1223] Dont remove a "preferred" cmpctblock peer if they provide a block Github-Pull: #8637 Rebased-From: 02a337defdd854efc78ecba6d1fb19cb1c075f16 --- src/main.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 96734b839..3436caaf1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -495,9 +495,13 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf return; } if (nodestate->fProvidesHeaderAndIDs) { - BOOST_FOREACH(const NodeId nodeid, lNodesAnnouncingHeaderAndIDs) - if (nodeid == pfrom->GetId()) + for (std::list::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) { + if (*it == pfrom->GetId()) { + lNodesAnnouncingHeaderAndIDs.erase(it); + lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId()); return; + } + } bool fAnnounceUsingCMPCTBLOCK = false; uint64_t nCMPCTBLOCKVersion = (nLocalServices & NODE_WITNESS) ? 2 : 1; if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { @@ -5727,6 +5731,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } + if (!fAlreadyInFlight && mapBlocksInFlight.size() == 1 && pindex->pprev->IsValid(BLOCK_VALID_CHAIN)) { + // We seem to be rather well-synced, so it appears pfrom was the first to provide us + // with this block! Let's get them to announce using compact blocks in the future. + MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom, connman); + } + BlockTransactionsRequest req; for (size_t i = 0; i < cmpctblock.BlockTxCount(); i++) { if (!partialBlock.IsTxAvailable(i)) From 76ba1c973948a33bbf87d13c4bd2f2b81fb466a2 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 21 Jun 2016 16:28:38 -0700 Subject: [PATCH 1142/1223] More agressively filter compact block requests Unit test adaptations by Pieter Wuille. Github-Pull: #8637 Rebased-From: fe998e962dc015978f104b782afb7daec3c4d4df --- qa/rpc-tests/p2p-compactblocks.py | 4 ++-- src/main.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 249afec2b..402966978 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -594,7 +594,7 @@ class CompactBlocksTest(BitcoinTestFramework): def test_getblocktxn_handler(self, node, test_node, version): # bitcoind won't respond for blocks whose height is more than 15 blocks # deep. - MAX_GETBLOCKTXN_DEPTH = 15 + MAX_GETBLOCKTXN_DEPTH = 10 chain_height = node.getblockcount() current_height = chain_height while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): @@ -635,7 +635,7 @@ class CompactBlocksTest(BitcoinTestFramework): def test_compactblocks_not_at_tip(self, node, test_node): # Test that requesting old compactblocks doesn't work. - MAX_CMPCTBLOCK_DEPTH = 11 + MAX_CMPCTBLOCK_DEPTH = 6 new_blocks = [] for i in range(MAX_CMPCTBLOCK_DEPTH): test_node.clear_block_announcement() diff --git a/src/main.cpp b/src/main.cpp index 3436caaf1..2e09b6cf7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4855,7 +4855,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness; - if (mi->second->nHeight >= chainActive.Height() - 10) { + if (CanDirectFetch(Params().GetConsensus()) && mi->second->nHeight >= chainActive.Height() - 5) { CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness); pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); } else @@ -5401,8 +5401,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - if (it->second->nHeight < chainActive.Height() - 15) { - LogPrint("net", "Peer %d sent us a getblocktxn for a block > 15 deep", pfrom->id); + if (it->second->nHeight < chainActive.Height() - 10) { + LogPrint("net", "Peer %d sent us a getblocktxn for a block > 10 deep", pfrom->id); return true; } From 3d23a0eaa3cfa349833e42345daf954e9530bdfd Mon Sep 17 00:00:00 2001 From: instagibbs Date: Wed, 22 Jun 2016 08:18:22 -0400 Subject: [PATCH 1143/1223] Add cmpctblock to debug help list Github-Pull: #8637 Rebased-From: b2e93a343ec2dc7d255b970e6ee45e9c390f7ed0 --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index f2b13b627..eab8de8d0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -412,7 +412,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified bip9 deployment (regtest-only)"); } - string debugCategories = "addrman, alert, bench, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + From 2cad5db6f752ad8fa2d047b67a137de76eb9c982 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 31 Aug 2016 17:35:59 +0200 Subject: [PATCH 1144/1223] Align constant names for maximum compact block / blocktxn depth Github-Pull: #8637 Rebased-From: 3ac6de0a045cc9b2047ceb19af970e7ffbf905fa --- qa/rpc-tests/p2p-compactblocks.py | 4 ++-- src/main.cpp | 6 +++--- src/main.h | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 402966978..0c73032c9 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -635,9 +635,9 @@ class CompactBlocksTest(BitcoinTestFramework): def test_compactblocks_not_at_tip(self, node, test_node): # Test that requesting old compactblocks doesn't work. - MAX_CMPCTBLOCK_DEPTH = 6 + MAX_CMPCTBLOCK_DEPTH = 5 new_blocks = [] - for i in range(MAX_CMPCTBLOCK_DEPTH): + for i in range(MAX_CMPCTBLOCK_DEPTH + 1): test_node.clear_block_announcement() new_blocks.append(node.generate(1)[0]) wait_until(test_node.received_block_announcement, timeout=30) diff --git a/src/main.cpp b/src/main.cpp index 2e09b6cf7..db020a449 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4855,7 +4855,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness; - if (CanDirectFetch(Params().GetConsensus()) && mi->second->nHeight >= chainActive.Height() - 5) { + if (CanDirectFetch(consensusParams) && mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) { CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness); pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); } else @@ -5401,8 +5401,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - if (it->second->nHeight < chainActive.Height() - 10) { - LogPrint("net", "Peer %d sent us a getblocktxn for a block > 10 deep", pfrom->id); + if (it->second->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) { + LogPrint("net", "Peer %d sent us a getblocktxn for a block > %i deep", pfrom->id, MAX_BLOCKTXN_DEPTH); return true; } diff --git a/src/main.h b/src/main.h index daf884337..024f35cd3 100644 --- a/src/main.h +++ b/src/main.h @@ -89,6 +89,11 @@ static const unsigned int BLOCK_STALLING_TIMEOUT = 2; /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ static const unsigned int MAX_HEADERS_RESULTS = 2000; +/** Maximum depth of blocks we're willing to serve as compact blocks to peers + * when requested. For older blocks, a regular BLOCK response will be sent. */ +static const int MAX_CMPCTBLOCK_DEPTH = 5; +/** Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for. */ +static const int MAX_BLOCKTXN_DEPTH = 10; /** Size of the "block download window": how far ahead of our current height do we fetch? * Larger windows tolerate larger download speed differences between peer, but increase the potential * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning From e8461666ecd7f0f89fba92a377c0f8beffa233e9 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Wed, 26 Oct 2016 14:53:18 -0400 Subject: [PATCH 1145/1223] Modify getblocktxn handler not to drop requests for old blocks The current getblocktxn implementation drops and ignores requests for old blocks, which causes occasional sync_block timeouts during the p2p-compactblocks.py test as reported in https://github.com/bitcoin/bitcoin/issues/8842. The p2p-compactblocks.py test setup creates many new blocks in a short period of time, which can lead to getblocktxn requests for blocks below the hardcoded depth limit of 10 blocks. This commit changes the getblocktxn handler not to ignore these requests, so the peer nodes in the test setup will reliably be able to sync. The protocol change is documented in BIP-152 update "Allow block responses to getblocktxn requests" at https://github.com/bitcoin/bips/pull/469. The protocol change is not expected to affect nodes running outside the test environment, because there shouldn't normally be lots of new blocks being rapidly added that need to be synced. Github-Pull: #9058 Rebased-From: dac53b58b555183ccc0d5e64c428528267cd98b3 Github-Pull: #9160 Rebased-From: ec34648766c4052816e4072cc61ad429430bcfd9 --- qa/rpc-tests/p2p-compactblocks.py | 12 +++++++++--- src/main.cpp | 14 +++++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 0c73032c9..e0b72e684 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -592,8 +592,8 @@ class CompactBlocksTest(BitcoinTestFramework): assert_equal(int(node.getbestblockhash(), 16), block.sha256) def test_getblocktxn_handler(self, node, test_node, version): - # bitcoind won't respond for blocks whose height is more than 15 blocks - # deep. + # bitcoind will not send blocktxn responses for blocks whose height is + # more than 10 blocks deep. MAX_GETBLOCKTXN_DEPTH = 10 chain_height = node.getblockcount() current_height = chain_height @@ -626,11 +626,17 @@ class CompactBlocksTest(BitcoinTestFramework): test_node.last_blocktxn = None current_height -= 1 - # Next request should be ignored, as we're past the allowed depth. + # Next request should send a full block response, as we're past the + # allowed depth for a blocktxn response. block_hash = node.getblockhash(current_height) msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0]) + with mininode_lock: + test_node.last_block = None + test_node.last_blocktxn = None test_node.send_and_ping(msg) with mininode_lock: + test_node.last_block.block.calc_sha256() + assert_equal(test_node.last_block.block.sha256, int(block_hash, 16)) assert_equal(test_node.last_blocktxn, None) def test_compactblocks_not_at_tip(self, node, test_node): diff --git a/src/main.cpp b/src/main.cpp index db020a449..191bcff4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5402,7 +5402,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (it->second->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) { + // If an older block is requested (should never happen in practice, + // but can happen in tests) send a block response instead of a + // blocktxn response. Sending a full block response instead of a + // small blocktxn response is preferable in the case where a peer + // might maliciously send lots of getblocktxn requests to trigger + // expensive disk reads, because it will require the peer to + // actually receive all the data read from disk over the network. LogPrint("net", "Peer %d sent us a getblocktxn for a block > %i deep", pfrom->id, MAX_BLOCKTXN_DEPTH); + CInv inv; + inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK; + inv.hash = req.blockhash; + pfrom->vRecvGetData.push_back(inv); + ProcessGetData(pfrom, chainparams.GetConsensus()); return true; } @@ -5734,7 +5746,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!fAlreadyInFlight && mapBlocksInFlight.size() == 1 && pindex->pprev->IsValid(BLOCK_VALID_CHAIN)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. - MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom, connman); + MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); } BlockTransactionsRequest req; From 94531b53509470e01dcbd90275577cb37a794fa8 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 28 Nov 2016 17:13:51 +0100 Subject: [PATCH 1146/1223] torcontrol: Explicitly request RSA1024 private key When generating a new service key, explicitly request a RSA1024 one. The bitcoin P2P protocol has no support for the longer hidden service names that will come with ed25519 keys, until it does, we depend on the old hidden service type so make this explicit. See #9214. Rebased-From: 7d3b627395582ae7c9d54ebdbc68096d7042162b Github-Pull: #9234 --- src/torcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 0d6b65567..261da728a 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -469,7 +469,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r // Finally - now create the service if (private_key.empty()) // No private key, generate one - private_key = "NEW:BEST"; + private_key = "NEW:RSA1024"; // Explicitly request RSA1024 - see issue #9214 // Request hidden service, redirect port. // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // choice. TODO; refactor the shutdown sequence some day. From b172377857f9b5a0b2f43e0e57be9acf82a6c50a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 1 Dec 2016 14:31:38 -0800 Subject: [PATCH 1147/1223] Revert "Use async name resolving to improve net thread responsiveness" This reverts commit caf6150e9785da408f1e603ae70eae25b5202d98. getaddrinfo_a has a nasty tendency to segfault internally in its background thread, on every version of glibc I tested, especially under helgrind. See https://sourceware.org/bugzilla/show_bug.cgi?id=20874 Github-Pull: #9229 Rebased-From: 10ae7a7b2316f8052ec58ef237ce6dd987300900 --- configure.ac | 2 -- src/netbase.cpp | 48 +----------------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/configure.ac b/configure.ac index 97b330449..b091c74b7 100644 --- a/configure.ac +++ b/configure.ac @@ -527,8 +527,6 @@ if test x$TARGET_OS = xdarwin; then fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) -AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])]) -AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])]) AC_CHECK_DECLS([strnlen]) diff --git a/src/netbase.cpp b/src/netbase.cpp index e2a516986..ebf30d43e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -96,30 +96,9 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign } } -#ifdef HAVE_GETADDRINFO_A - struct in_addr ipv4_addr; -#ifdef HAVE_INET_PTON - if (inet_pton(AF_INET, pszName, &ipv4_addr) > 0) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } - - struct in6_addr ipv6_addr; - if (inet_pton(AF_INET6, pszName, &ipv6_addr) > 0) { - vIP.push_back(CNetAddr(ipv6_addr)); - return true; - } -#else - ipv4_addr.s_addr = inet_addr(pszName); - if (ipv4_addr.s_addr != INADDR_NONE) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } -#endif -#endif - struct addrinfo aiHint; memset(&aiHint, 0, sizeof(struct addrinfo)); + aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; @@ -128,33 +107,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign #else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif - struct addrinfo *aiRes = NULL; -#ifdef HAVE_GETADDRINFO_A - struct gaicb gcb, *query = &gcb; - memset(query, 0, sizeof(struct gaicb)); - gcb.ar_name = pszName; - gcb.ar_request = &aiHint; - int nErr = getaddrinfo_a(GAI_NOWAIT, &query, 1, NULL); - if (nErr) - return false; - - do { - // Should set the timeout limit to a reasonable value to avoid - // generating unnecessary checking call during the polling loop, - // while it can still response to stop request quick enough. - // 2 seconds looks fine in our situation. - struct timespec ts = { 2, 0 }; - gai_suspend(&query, 1, &ts); - boost::this_thread::interruption_point(); - - nErr = gai_error(query); - if (0 == nErr) - aiRes = query->ar_result; - } while (nErr == EAI_INPROGRESS); -#else int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); -#endif if (nErr) return false; From d1b4da9259ded1776479ac97b30d8eaa6747ee71 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 15 Nov 2016 16:12:17 -0500 Subject: [PATCH 1148/1223] build: fix qt5.7 build under macOS OBJCXX's std flags don't get defined by our cxx macro. Rather than hard-coding to c++11, just force OBJCXX to be the same as CXX unless the user specified otherwise. Github-Pull: #9169 Rebased-From: 70266e98292bf9c8f019ca4b11d681b575f71448 --- configure.ac | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b091c74b7..41b42126e 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,6 @@ else CXXFLAGS_overridden=no fi AC_PROG_CXX -m4_ifdef([AC_PROG_OBJCXX],[AC_PROG_OBJCXX]) dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since @@ -60,6 +59,15 @@ AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) dnl Check if -latomic is required for CHECK_ATOMIC +dnl Unless the user specified OBJCXX, force it to be the same as CXX. This ensures +dnl that we get the same -std flags for both. +m4_ifdef([AC_PROG_OBJCXX],[ +if test "x${OBJCXX+set}" = "x"; then + OBJCXX="${CXX}" +fi +AC_PROG_OBJCXX +]) + dnl Libtool init checks. LT_INIT([pic-only]) From 094848baf01ae7f2ab8dbac4a625a8c956f2a760 Mon Sep 17 00:00:00 2001 From: jnewbery Date: Tue, 27 Sep 2016 13:40:16 -0400 Subject: [PATCH 1149/1223] log block size and weight correctly. Github-Pull: #8838 Rebased-From: 5f274a1749acfdf331bc2931e25ac80c346e5faa --- src/miner.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 957585884..6cb40dae8 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -168,7 +168,6 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; nLastBlockWeight = nBlockWeight; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOpsCost); // Create coinbase transaction. CMutableTransaction coinbaseTx; @@ -182,6 +181,9 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; + uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); + LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost); + // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); From da5a16b11dca8f61d75f92bb08f1dd19a7800158 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 22 Nov 2016 02:50:24 +0000 Subject: [PATCH 1150/1223] Always drop the least preferred HB peer when adding a new one. When a BIP152 HB-mode peer is in the least preferred position and disconnects, they will not be by ForNode on the next loop. They will continue to sit in that position and prevent deactivating HB mode for peers that are still connected. There is no reason for them to stay in the list if already gone, so drop the first element unconditionally if there are too many. Fixes issue #9163. Github-Pull: #9199 Rebased-From: ca8549d2bd32f17f8b69d1edbe3f2976fba504b4 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 191bcff4c..6ad430428 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -510,8 +510,8 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf CNode* pnodeStop = FindNode(lNodesAnnouncingHeaderAndIDs.front()); if (pnodeStop) { pnodeStop->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); - lNodesAnnouncingHeaderAndIDs.pop_front(); } + lNodesAnnouncingHeaderAndIDs.pop_front(); } fAnnounceUsingCMPCTBLOCK = true; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); From 99477c71c4cdb5127e0fd6e12f29507320432d9f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 18 Nov 2016 12:15:01 -0800 Subject: [PATCH 1151/1223] Always add default_witness_commitment with GBT client support Github-Pull: #9189 Rebased-From: ad04d1cb35b9612d36078c62213bdbb13f56d73d --- src/main.cpp | 9 +-------- src/rpc/mining.cpp | 4 +++- src/test/miner_tests.cpp | 1 + 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6ad430428..addc0f93a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3503,15 +3503,8 @@ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBloc { std::vector commitment; int commitpos = GetWitnessCommitmentIndex(block); - bool fHaveWitness = false; - for (size_t t = 1; t < block.vtx.size(); t++) { - if (!block.vtx[t].wit.IsNull()) { - fHaveWitness = true; - break; - } - } std::vector ret(32, 0x00); - if (fHaveWitness && IsWitnessEnabled(pindexPrev, consensusParams)) { + if (consensusParams.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { if (commitpos == -1) { uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL); CHash256().Write(witnessroot.begin(), 32).Write(&ret[0], 32).Finalize(witnessroot.begin()); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e6901bc77..ba48079c0 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -683,7 +683,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - if (!pblocktemplate->vchCoinbaseCommitment.empty()) { + + const struct BIP9DeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; + if (!pblocktemplate->vchCoinbaseCommitment.empty() && setClientRules.find(segwit_info.name) != setClientRules.end()) { result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()))); } diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 70ba70779..f2bd082cb 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -213,6 +213,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce); txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); + txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() == 0) From b96a8f7df23956cc4c41c414a01964c9cad54699 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Sat, 19 Nov 2016 06:55:25 -0500 Subject: [PATCH 1152/1223] [qa] Test getblocktemplate default_witness_commitment Github-Pull: #9189 Rebased-From: 95f4a03777ec2ad82a94a3e2890192a93ad83509 --- qa/rpc-tests/p2p-segwit.py | 68 ++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index 7218ae83d..fddd2627b 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -182,11 +182,6 @@ class SegWitTest(BitcoinTestFramework): def setup_chain(self): initialize_chain_clean(self.options.tmpdir, 3) - def add_options(self, parser): - parser.add_option("--oldbinary", dest="oldbinary", - default=None, - help="pre-segwit bitcoind binary for upgrade testing") - def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1"])) @@ -194,12 +189,9 @@ class SegWitTest(BitcoinTestFramework): self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1", "-acceptnonstdtxn=0"])) connect_nodes(self.nodes[0], 1) - # If an old bitcoind is given, do the upgrade-after-activation test. - self.test_upgrade = False - if (self.options.oldbinary != None): - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1"], binary=self.options.oldbinary)) - connect_nodes(self.nodes[0], 2) - self.test_upgrade = True + # Disable segwit's bip9 parameter to simulate upgrading after activation. + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1", "-bip9params=segwit:0:0"])) + connect_nodes(self.nodes[0], 2) ''' Helpers ''' # Build a block on top of node0's tip. @@ -1164,7 +1156,7 @@ class SegWitTest(BitcoinTestFramework): if segwit_activated: # tx and tx2 were both accepted. Don't bother trying to reclaim the # P2PKH output; just send tx's first output back to an anyone-can-spend. - sync_mempools(self.nodes) + sync_mempools([self.nodes[0], self.nodes[1]]) tx3.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] tx3.vout = [CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))] tx3.wit.vtxinwit.append(CTxInWitness()) @@ -1693,19 +1685,53 @@ class SegWitTest(BitcoinTestFramework): def test_getblocktemplate_before_lockin(self): print("\tTesting getblocktemplate setting of segwit versionbit (before lockin)") - block_version = (self.nodes[0].getblocktemplate())['version'] - assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + # Node0 is segwit aware, node2 is not. + for node in [self.nodes[0], self.nodes[2]]: + gbt_results = node.getblocktemplate() + block_version = gbt_results['version'] + # If we're not indicating segwit support, we should not be signalling + # for segwit activation, nor should we get a witness commitment. + assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + assert('default_witness_commitment' not in gbt_results) # Workaround: # Can either change the tip, or change the mempool and wait 5 seconds # to trigger a recomputation of getblocktemplate. - self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + txid = int(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1), 16) # Using mocktime lets us avoid sleep() + sync_mempools(self.nodes) self.nodes[0].setmocktime(int(time.time())+10) + self.nodes[2].setmocktime(int(time.time())+10) - block_version = self.nodes[0].getblocktemplate({"rules" : ["segwit"]})['version'] - assert(block_version & (1 << VB_WITNESS_BIT) != 0) - self.nodes[0].setmocktime(0) # undo mocktime + for node in [self.nodes[0], self.nodes[2]]: + gbt_results = node.getblocktemplate({"rules" : ["segwit"]}) + block_version = gbt_results['version'] + if node == self.nodes[2]: + # If this is a non-segwit node, we should still not get a witness + # commitment, nor a version bit signalling segwit. + assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + assert('default_witness_commitment' not in gbt_results) + else: + # For segwit-aware nodes, check the version bit and the witness + # commitment are correct. + assert(block_version & (1 << VB_WITNESS_BIT) != 0) + assert('default_witness_commitment' in gbt_results) + witness_commitment = gbt_results['default_witness_commitment'] + + # TODO: this duplicates some code from blocktools.py, would be nice + # to refactor. + # Check that default_witness_commitment is present. + block = CBlock() + witness_root = block.get_merkle_root([ser_uint256(0), ser_uint256(txid)]) + check_commitment = uint256_from_str(hash256(ser_uint256(witness_root)+ser_uint256(0))) + from test_framework.blocktools import WITNESS_COMMITMENT_HEADER + output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(check_commitment) + script = CScript([OP_RETURN, output_data]) + assert_equal(witness_commitment, bytes_to_hex_str(script)) + + # undo mocktime + self.nodes[0].setmocktime(0) + self.nodes[2].setmocktime(0) # Uncompressed pubkeys are no longer supported in default relay policy, # but (for now) are still valid in blocks. @@ -1945,6 +1971,7 @@ class SegWitTest(BitcoinTestFramework): # Advance to segwit being 'started' self.advance_to_segwit_started() + sync_blocks(self.nodes) self.test_getblocktemplate_before_lockin() sync_blocks(self.nodes) @@ -1987,10 +2014,7 @@ class SegWitTest(BitcoinTestFramework): self.test_signature_version_1() self.test_non_standard_witness() sync_blocks(self.nodes) - if self.test_upgrade: - self.test_upgrade_after_activation(self.nodes[2], 2) - else: - print("\tSkipping upgrade-after-activation test (use --oldbinary to enable)") + self.test_upgrade_after_activation(self.nodes[2], 2) self.test_witness_sigops() From ca1fd7521e86b016f2aa92048a13a297bab3c074 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 18 Nov 2016 19:11:08 +0000 Subject: [PATCH 1153/1223] Make orphan parent fetching ask for witnesses. In 0.13 orphan transactions began being treated as implicit INVs for their parents. But the resulting getdata were not getting the witness flag. This fixes issue #9182 reported by chjj and roasbeef on IRC. Github-Pull: #9188 Rebased-From: 5b0150a060208faf436c09b0ca9463407a869c72 --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index addc0f93a..962960a15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5586,10 +5586,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } if (!fRejectedParents) { + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - CInv inv(MSG_TX, txin.prevout.hash); - pfrom->AddInventoryKnown(inv); - if (!AlreadyHave(inv)) pfrom->AskFor(inv); + CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash); + pfrom->AddInventoryKnown(_inv); + if (!AlreadyHave(_inv)) pfrom->AskFor(_inv); } AddOrphanTx(tx, pfrom->GetId()); From 3a3bcbf775840be34b27523bba9e5ab6321b4ffb Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 1 Nov 2016 00:08:47 +0000 Subject: [PATCH 1154/1223] Use RelevantServices instead of node_network in AttemptToEvict. Use of node_network here is really meant to be a proxy of "likely to send us blocks in the future". RelevantServices is the right criteria now. Github-Pull: #9052 Rebased-From: d32036a47d9ccdc38628a7a75bb8b711af462e4f --- src/net.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index faa7b0028..7cb612ee9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -877,7 +877,7 @@ struct NodeEvictionCandidate int64_t nMinPingUsecTime; int64_t nLastBlockTime; int64_t nLastTXTime; - bool fNetworkNode; + bool fRelevantServices; bool fRelayTxes; bool fBloomFilter; CAddress addr; @@ -902,7 +902,7 @@ static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvict { // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block. if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime; - if (a.fNetworkNode != b.fNetworkNode) return b.fNetworkNode; + if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices; return a.nTimeConnected > b.nTimeConnected; } @@ -936,7 +936,8 @@ static bool AttemptToEvictConnection() { if (node->fDisconnect) continue; NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, - node->nLastBlockTime, node->nLastTXTime, node->fNetworkNode, + node->nLastBlockTime, node->nLastTXTime, + (node->nServices & nRelevantServices) == nRelevantServices, node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } From 975ab1254eec5a191f22ba1d63863c00c88bdfcf Mon Sep 17 00:00:00 2001 From: randy-waterhouse Date: Thu, 6 Oct 2016 12:27:23 +1300 Subject: [PATCH 1155/1223] Update INSTALL landing redirection notice for build instructions. Github-Pull: #8896 Rebased-From: 2920be2a6994cfbffd93e72c6cf4c1ed19ac4339 --- INSTALL | 5 ----- INSTALL.md | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 INSTALL create mode 100644 INSTALL.md diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 07ee48427..000000000 --- a/INSTALL +++ /dev/null @@ -1,5 +0,0 @@ -Building Bitcoin - -See doc/build-*.md for instructions on building bitcoind, -the intended-for-services, no-graphical-interface, reference -implementation of Bitcoin. \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..520a47d96 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,5 @@ +Building Bitcoin +================ + +See doc/build-*.md for instructions on building the various +elements of the Bitcoin Core reference implementation of Bitcoin. From 4a974b2837150097e20076e10edb24b65fb8e7f8 Mon Sep 17 00:00:00 2001 From: matthias Date: Mon, 17 Oct 2016 17:45:36 +0200 Subject: [PATCH 1156/1223] Simple Update to File 'bitcoin-qt.desktop' Github-Pull: #8908 Rebased-From: 164196b7c8aecb72dd20c8681bb24b81b18aecaa --- contrib/debian/bitcoin-qt.desktop | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop index 61e1aca6a..593d7584a 100644 --- a/contrib/debian/bitcoin-qt.desktop +++ b/contrib/debian/bitcoin-qt.desktop @@ -1,7 +1,8 @@ [Desktop Entry] Encoding=UTF-8 -Name=Bitcoin -Comment=Bitcoin P2P Cryptocurrency +Name=Bitcoin Core +Comment=Connect to the Bitcoin P2P Network +Comment[de]=Verbinde mit dem Bitcoin peer-to-peer Netzwerk Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi Exec=bitcoin-qt %u From c134d9206d2629b479f4e0071ecafd9ec517ec04 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 17 Oct 2016 11:43:24 +0800 Subject: [PATCH 1157/1223] [build-aux] Boost_Base serial 27 Github-Pull: #8920 Rebased-From: 282abd8358e254d976cad05d0eb48586db276bcd --- build-aux/m4/ax_boost_base.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 45d948933..650c94fa6 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 26 +#serial 27 AC_DEFUN([AX_BOOST_BASE], [ @@ -96,7 +96,7 @@ if test "x$want_boost" = "xyes"; then libsubdirs="lib64 libx32 lib lib64" ;; ppc64|s390x|sparc64|aarch64|ppc64le) - libsubdirs="lib64 lib lib64 ppc64le" + libsubdirs="lib64 lib lib64" ;; esac From 40169dcda9f8e26090807a53b03d10ca22c6395c Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 17 Oct 2016 11:43:59 +0800 Subject: [PATCH 1158/1223] Set minimum required Boost to 1.47.0 Github-Pull: #8920 Rebased-From: 6dd37237222f7102e223ece948150cb5c5087e3c --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 41b42126e..e76a3c722 100644 --- a/configure.ac +++ b/configure.ac @@ -615,8 +615,11 @@ fi if test x$use_boost = xyes; then +dnl Minimum required Boost version +define(MINIMUM_REQUIRED_BOOST, 1.47.0) + dnl Check for boost libs -AX_BOOST_BASE +AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS From 12428b4d8a3dff3c32c909964536ed69f043f9d3 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 15 Oct 2016 13:57:19 -0400 Subject: [PATCH 1159/1223] add software-properties-common This allows using `add-apt-repository`. Github-Pull: #8929 Rebased-From: aa9d3c9a503952589b359624bbb0da11dd7a5e3f --- doc/build-unix.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/build-unix.md b/doc/build-unix.md index 62e3e793e..d607d2a59 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -82,6 +82,7 @@ install necessary parts of boost: BerkeleyDB is required for the wallet. db4.8 packages are available [here](https://launchpad.net/~bitcoin/+archive/bitcoin). You can add the repository and install using the following commands: + sudo apt-get install software-properties-common sudo add-apt-repository ppa:bitcoin/bitcoin sudo apt-get update sudo apt-get install libdb4.8-dev libdb4.8++-dev From 106da691a5b935289dfecb25ee4fe2f085cee77f Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 26 Aug 2016 22:35:46 +0100 Subject: [PATCH 1160/1223] Sync bitcoin-tx with tx version policy Github-Pull: #8932 Rebased-From: b0aea8057921f0ed2288cf07048f652c7d6d9cf3 --- src/bitcoin-tx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 8e8ac4745..b24f29553 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -164,7 +164,7 @@ static void RegisterLoad(const string& strInput) static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal) { int64_t newVersion = atoi64(cmdVal); - if (newVersion < 1 || newVersion > CTransaction::CURRENT_VERSION) + if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION) throw runtime_error("Invalid TX version requested"); tx.nVersion = (int) newVersion; From 6f86b5364345b238a812c9dffca13fe9f11a0073 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 30 Nov 2015 20:57:20 +0100 Subject: [PATCH 1161/1223] [Qt] make warnings label selectable Github-Pull: #8972 Rebased-From: ef0c9ee2960fda58b2fe5b0c3b4c672231b30322 --- src/qt/forms/overviewpage.ui | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 6d792d147..4a6ee9250 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -20,7 +20,7 @@ false - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; + QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; } true @@ -28,6 +28,9 @@ 3 + + Qt::TextSelectableByMouse + From 973ca1e4912e7ad85e0d06e9490c5939232de6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 21 Oct 2016 23:42:37 +0200 Subject: [PATCH 1162/1223] Fix doxygen comment: the transaction is returned in txOut Github-Pull: #8993 Rebased-From: 1d8e12ba48154b2c59213e92efb50958d430a007 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 962960a15..cf96efbe8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1591,7 +1591,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return res; } -/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ +/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; From 5bcb05d4e1304ac3582f1779a25693c0065c69e9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 30 Oct 2016 16:58:13 +0100 Subject: [PATCH 1163/1223] [rpc] ParseHash: Fail when length is not 64 Github-Pull: #9042 Rebased-From: fa326193ad739d1f93da456b3fa73af0bbf9fdd1 --- src/rpc/server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 23149baa6..102c77631 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -146,6 +146,8 @@ uint256 ParseHashV(const UniValue& v, string strName) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); + if (64 != strHex.length()) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length())); uint256 result; result.SetHex(strHex); return result; From f85ee01303b3d5127a31285b2682fcae2f8df64d Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 2 Nov 2016 21:59:09 +0300 Subject: [PATCH 1164/1223] Fix exit codes: - `--help`, `--version` etc should exit with `0` i.e. no error ("not enough args" case should still trigger an error) - error reading config file should exit with `1` Slightly refactor AppInitRPC/AppInitRawTx to return standard exit codes (EXIT_FAILURE/EXIT_SUCCESS) or CONTINUE_EXECUTION (-1) Github-Pull: #9067 Rebased-From: bd0de1386e1c7f9b875d52290de0d561c8d56bc9 --- src/bitcoin-cli.cpp | 28 +++++++++++++++++++--------- src/bitcoin-tx.cpp | 20 +++++++++++++++----- src/bitcoind.cpp | 2 +- src/qt/bitcoin.cpp | 4 ++-- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index a04101d3e..bf6f11a50 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -28,6 +28,7 @@ using namespace std; static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; +static const int CONTINUE_EXECUTION=-1; std::string HelpMessageCli() { @@ -67,7 +68,11 @@ public: }; -static bool AppInitRPC(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRPC(int argc, char* argv[]) { // // Parameters @@ -85,31 +90,35 @@ static bool AppInitRPC(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); - return false; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); - return false; + return EXIT_FAILURE; } // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) try { SelectBaseParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } if (GetBoolArg("-rpcssl", false)) { fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return false; + return EXIT_FAILURE; } - return true; + return CONTINUE_EXECUTION; } @@ -318,8 +327,9 @@ int main(int argc, char* argv[]) } try { - if(!AppInitRPC(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRPC(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index b24f29553..384eae963 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -30,8 +30,13 @@ using namespace std; static bool fCreateBlank; static map registers; +static const int CONTINUE_EXECUTION=-1; -static bool AppInitRawTx(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRawTx(int argc, char* argv[]) { // // Parameters @@ -89,9 +94,13 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING")); fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } - return true; + return CONTINUE_EXECUTION; } static void RegisterSetJson(const string& key, const string& rawJson) @@ -680,8 +689,9 @@ int main(int argc, char* argv[]) SetupEnvironment(); try { - if(!AppInitRawTx(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRawTx(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRawTx()"); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 28bc374ac..b534caffa 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -93,7 +93,7 @@ bool AppInit(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + return true; } try diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 430e6dd0e..595fa4825 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -573,7 +573,7 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 1; + return 0; } /// 5. Now that settings and translations are available, ask user for data directory @@ -594,7 +594,7 @@ int main(int argc, char *argv[]) } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return false; + return 1; } /// 7. Determine network (and switch to network specific options) From f27596a7ec3c625c3b0f25d66fc1bc804c250e7f Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 7 Nov 2016 21:31:38 +0300 Subject: [PATCH 1165/1223] Every main()/exit() should return/use one of EXIT_ codes instead of magic numbers Github-Pull: #9067 Rebased-From: 4441018d0860fce64ee74fa78da79bbb21114ca9 --- src/bitcoind.cpp | 4 ++-- src/qt/bitcoin.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b534caffa..823b9ce58 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -127,7 +127,7 @@ bool AppInit(int argc, char* argv[]) if (fCommandLine) { fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n"); - exit(1); + exit(EXIT_FAILURE); } #ifndef WIN32 fDaemon = GetBoolArg("-daemon", false); @@ -187,5 +187,5 @@ int main(int argc, char* argv[]) // Connect bitcoind signal handlers noui_connect(); - return (AppInit(argc, argv) ? 0 : 1); + return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 595fa4825..d3d13423f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -496,7 +496,7 @@ void BitcoinApplication::shutdownResult(int retval) void BitcoinApplication::handleRunawayException(const QString &message) { QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message); - ::exit(1); + ::exit(EXIT_FAILURE); } WId BitcoinApplication::getMainWinId() const @@ -573,13 +573,13 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 0; + return EXIT_SUCCESS; } /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory if (!Intro::pickDataDirectory()) - return 0; + return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes @@ -587,14 +587,14 @@ int main(int argc, char *argv[]) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); - return 1; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return 1; + return EXIT_FAILURE; } /// 7. Determine network (and switch to network specific options) @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) SelectParams(ChainNameFromCommandLine()); } catch(std::exception &e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); - return 1; + return EXIT_FAILURE; } #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() @@ -630,7 +630,7 @@ int main(int argc, char *argv[]) // - Do this after creating app and setting up translations, so errors are // translated properly. if (PaymentServer::ipcSendCommandLine()) - exit(0); + exit(EXIT_SUCCESS); // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: From 08d1c90113efb51d4fb2fcea36171181a66aea36 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 10 Nov 2016 00:53:55 +0300 Subject: [PATCH 1166/1223] Missed one "return false" in recent refactoring in #9067 Github-Pull: #9120 Rebased-From: 45d372f88900bda74835a20a44246746c2ac94e6 --- src/bitcoin-tx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 384eae963..c5ae33da8 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -48,7 +48,7 @@ static int AppInitRawTx(int argc, char* argv[]) SelectParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } fCreateBlank = GetBoolArg("-create", false); From 5f3a12c97c25f811083679cd3f284059cf7ea54f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Nov 2016 12:11:59 +0100 Subject: [PATCH 1167/1223] qt: Use correct conversion function for boost::path datadir Fixes #9089. Github-Pull: #9094 Rebased-From: e760b307f6210bee293796d606bcca87f86be200 --- src/qt/clientmodel.cpp | 3 ++- src/qt/paymentserver.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 14661b857..9530b63a2 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -6,6 +6,7 @@ #include "bantablemodel.h" #include "guiconstants.h" +#include "guiutil.h" #include "peertablemodel.h" #include "chainparams.h" @@ -186,7 +187,7 @@ QString ClientModel::formatClientStartupTime() const QString ClientModel::dataDir() const { - return QString::fromStdString(GetDataDir().string()); + return GUIUtil::boostPathToQString(GetDataDir()); } void ClientModel::updateBanlist() diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index c80aebb00..96627710e 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -80,7 +80,7 @@ static QString ipcServerName() // Append a simple hash of the datadir // Note that GetDataDir(true) returns a different path // for -testnet versus main net - QString ddir(QString::fromStdString(GetDataDir(true).string())); + QString ddir(GUIUtil::boostPathToQString(GetDataDir(true))); name.append(QString::number(qHash(ddir))); return name; From 6fe3981ac8267f9f045b0d518399d943d3147268 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 9 Nov 2016 12:45:13 -0500 Subject: [PATCH 1168/1223] net: don't send feefilter messages before the version handshake is complete Github-Pull: #9117 Rebased-From: 46625538d674a5aaf1bcfa7c8be8a49e5a23fa9e --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index cf96efbe8..083ea194a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6856,7 +6856,7 @@ bool SendMessages(CNode* pto) // Message: feefilter // // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay - if (pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && + if (!pto->fDisconnect && pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && !(pto->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { CAmount currentFilter = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); int64_t timeNow = GetTimeMicros(); From f82c81b177dfb540c086ccccc39c030b8d9ca81f Mon Sep 17 00:00:00 2001 From: Masahiko Hyuga Date: Thu, 10 Nov 2016 18:18:52 +0900 Subject: [PATCH 1169/1223] fix getnettotals RPC description about timemillis. Github-Pull: #9122 Rebased-From: a79f864945d7abe05e777a942864c181311e5070 --- src/rpc/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 89035aaa8..51f9d1c33 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -344,7 +344,7 @@ UniValue getnettotals(const UniValue& params, bool fHelp) "{\n" " \"totalbytesrecv\": n, (numeric) Total bytes received\n" " \"totalbytessent\": n, (numeric) Total bytes sent\n" - " \"timemillis\": t, (numeric) Total cpu time\n" + " \"timemillis\": t, (numeric) Current UNIX time in milliseconds\n" " \"uploadtarget\":\n" " {\n" " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n" From 3fffbf7ef0a224d10119551ed39cd3215001a46f Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 17 Nov 2016 14:41:18 +0100 Subject: [PATCH 1170/1223] Doxygen: Set PROJECT_NAME = "Bitcoin Core" Github-Pull: #9178 Rebased-From: fa63ee8e3eeef8379360c125eeb690a37f097da2 --- doc/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index b088c7623..a5f0aa6c7 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = Bitcoin +PROJECT_NAME = "Bitcoin Core" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or From 6d70a73968695ee34e15e31a79d889db6f53b734 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 18 Nov 2016 10:26:38 +0100 Subject: [PATCH 1171/1223] [Qt] fix coincontrol sort issue Github-Pull: #9185 Rebased-From: 76af4eb876814a916dd4f26cf71faa20bdc54f2d --- src/qt/coincontroldialog.cpp | 21 +++++++++++++++------ src/qt/coincontroldialog.h | 12 ++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 837f8ba6c..2a482baa6 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -35,6 +35,15 @@ QList CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; +bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { + int column = treeWidget()->sortColumn(); + if (column == CoinControlDialog::COLUMN_AMOUNT_INT64 || column == CoinControlDialog::COLUMN_AMOUNT_INT64) + return data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong(); + if (column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_DATE_INT64) + return data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong(); + return QTreeWidgetItem::operator<(other); +} + CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), @@ -708,7 +717,7 @@ void CoinControlDialog::updateView() model->listCoins(mapCoins); BOOST_FOREACH(const PAIRTYPE(QString, std::vector)& coins, mapCoins) { - QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); + CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); QString sWalletAddress = coins.first; QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); @@ -739,9 +748,9 @@ void CoinControlDialog::updateView() nSum += out.tx->vout[out.i].nValue; nChildren++; - QTreeWidgetItem *itemOutput; - if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress); - else itemOutput = new QTreeWidgetItem(ui->treeWidget); + CCoinControlWidgetItem *itemOutput; + if (treeMode) itemOutput = new CCoinControlWidgetItem(itemWalletAddress); + else itemOutput = new CCoinControlWidgetItem(ui->treeWidget); itemOutput->setFlags(flgCheckbox); itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); @@ -779,11 +788,11 @@ void CoinControlDialog::updateView() // amount itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); - itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly + itemOutput->setData(COLUMN_AMOUNT_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly // date itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); - itemOutput->setText(COLUMN_DATE_INT64, strPad(QString::number(out.tx->GetTxTime()), 20, " ")); + itemOutput->setData(COLUMN_DATE_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->GetTxTime())); // confirmations itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 1a467eb2f..6229d21da 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -28,6 +28,17 @@ namespace Ui { #define ASYMP_UTF8 "\xE2\x89\x88" +class CCoinControlWidgetItem : public QTreeWidgetItem +{ +public: + CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + + bool operator<(const QTreeWidgetItem &other) const; +}; + + class CoinControlDialog : public QDialog { Q_OBJECT @@ -79,6 +90,7 @@ private: COLUMN_PRIORITY_INT64, COLUMN_DATE_INT64 }; + friend class CCoinControlWidgetItem; // some columns have a hidden column containing the value used for sorting int getMappedColumn(int column, bool fVisibleColumn = true) From ff423cc6b0323854b93810fa7a9a479a746f6d5d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 14:33:34 +0100 Subject: [PATCH 1172/1223] [Qt] Clean up and fix coincontrol tree widget handling - Do sorting for date, amount and confirmations column as longlong, not unsigned longlong. - Use `UserRole` to store our own data. This makes it treated as ancillary data prevents it from being displayed. - Get rid of `getMappedColumn` `strPad` - these are no longer necessary. - Get rid of hidden `_INT64` columns. - Start enumeration from 0 (otherwise values are undefined). Github-Pull: #9185 Rebased-From: 4231032bfcb9728f0f629b3d67884ba9de63e4ff --- src/qt/coincontroldialog.cpp | 39 +++++++++++------------------------- src/qt/coincontroldialog.h | 31 +--------------------------- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 2a482baa6..81cd098bf 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -37,10 +37,8 @@ bool CoinControlDialog::fSubtractFeeFromAmount = false; bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { int column = treeWidget()->sortColumn(); - if (column == CoinControlDialog::COLUMN_AMOUNT_INT64 || column == CoinControlDialog::COLUMN_AMOUNT_INT64) - return data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong(); - if (column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_DATE_INT64) - return data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong(); + if (column == CoinControlDialog::COLUMN_AMOUNT || column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_CONFIRMATIONS) + return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong(); return QTreeWidgetItem::operator<(other); } @@ -141,12 +139,9 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but don't show it // default view is sorted by amount desc - sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); + sortView(COLUMN_AMOUNT, Qt::DescendingOrder); // restore list mode and sortorder as a convenience feature QSettings settings; @@ -178,15 +173,6 @@ void CoinControlDialog::setModel(WalletModel *model) } } -// helper function str_pad -QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding) -{ - while (s.length() < nPadLength) - s = sPadding + s; - - return s; -} - // ok button void CoinControlDialog::buttonBoxClicked(QAbstractButton* button) { @@ -358,7 +344,7 @@ void CoinControlDialog::sortView(int column, Qt::SortOrder order) sortColumn = column; sortOrder = order; ui->treeWidget->sortItems(column, order); - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } // treeview: clicked on header @@ -366,12 +352,10 @@ void CoinControlDialog::headerSectionClicked(int logicalIndex) { if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing { - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } else { - logicalIndex = getMappedColumn(logicalIndex, false); - if (sortColumn == logicalIndex) sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder); else @@ -788,19 +772,20 @@ void CoinControlDialog::updateView() // amount itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); - itemOutput->setData(COLUMN_AMOUNT_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly + itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly // date itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); - itemOutput->setData(COLUMN_DATE_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->GetTxTime())); + itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime())); // confirmations - itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); + itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth)); + itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth)); // priority double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); - itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); + itemOutput->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPriority)); dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); nInputSum += nInputSize; @@ -831,9 +816,9 @@ void CoinControlDialog::updateView() dPrioritySum = dPrioritySum / (nInputSum + 78); itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); - itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); + itemWalletAddress->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum)); itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); - itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); + itemWalletAddress->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPrioritySum)); } } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 6229d21da..785079b1a 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -71,13 +71,12 @@ private: const PlatformStyle *platformStyle; - QString strPad(QString, int, QString); void sortView(int, Qt::SortOrder); void updateView(); enum { - COLUMN_CHECKBOX, + COLUMN_CHECKBOX = 0, COLUMN_AMOUNT, COLUMN_LABEL, COLUMN_ADDRESS, @@ -86,37 +85,9 @@ private: COLUMN_PRIORITY, COLUMN_TXHASH, COLUMN_VOUT_INDEX, - COLUMN_AMOUNT_INT64, - COLUMN_PRIORITY_INT64, - COLUMN_DATE_INT64 }; friend class CCoinControlWidgetItem; - // some columns have a hidden column containing the value used for sorting - int getMappedColumn(int column, bool fVisibleColumn = true) - { - if (fVisibleColumn) - { - if (column == COLUMN_AMOUNT_INT64) - return COLUMN_AMOUNT; - else if (column == COLUMN_PRIORITY_INT64) - return COLUMN_PRIORITY; - else if (column == COLUMN_DATE_INT64) - return COLUMN_DATE; - } - else - { - if (column == COLUMN_AMOUNT) - return COLUMN_AMOUNT_INT64; - else if (column == COLUMN_PRIORITY) - return COLUMN_PRIORITY_INT64; - else if (column == COLUMN_DATE) - return COLUMN_DATE_INT64; - } - - return column; - } - private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); From dc46b10a087921343bb5a05d08393ece061d6303 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 15:47:20 +0100 Subject: [PATCH 1173/1223] qt: Plug many memory leaks None of these are very serious, and are leaks in objects that are created at most one time. In most cases this means properly using the QObject parent hierarchy, except for BanTablePriv/PeerTablePriv which are not QObject, so use a std::unique_ptr instead. Github-Pull: #9190 Rebased-From: 47db07537746940ee7dd0739a8c73e328837813f --- src/qt/addressbookpage.cpp | 2 +- src/qt/bantablemodel.cpp | 7 ++++++- src/qt/bantablemodel.h | 3 ++- src/qt/bitcoingui.cpp | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/guiutil.cpp | 3 ++- src/qt/guiutil.h | 2 +- src/qt/overviewpage.cpp | 11 +++++------ src/qt/overviewpage.h | 3 ++- src/qt/peertablemodel.cpp | 9 +++++++-- src/qt/peertablemodel.h | 3 ++- src/qt/receivecoinsdialog.cpp | 5 +++-- src/qt/receiverequestdialog.cpp | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 4 ++-- src/qt/transactionview.cpp | 6 +++--- 16 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 135f15ffa..727956c88 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -83,7 +83,7 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, deleteAction = new QAction(ui->deleteAddress->text(), this); // Build context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(editAction); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index d95106b5a..7707ce7b6 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -86,7 +86,7 @@ BanTableModel::BanTableModel(ClientModel *parent) : clientModel(parent) { columns << tr("IP/Netmask") << tr("Banned Until"); - priv = new BanTablePriv(); + priv.reset(new BanTablePriv()); // default to unsorted priv->sortColumn = -1; @@ -94,6 +94,11 @@ BanTableModel::BanTableModel(ClientModel *parent) : refresh(); } +BanTableModel::~BanTableModel() +{ + // Intentionally left empty +} + int BanTableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index fe9600ac0..3c03d05c0 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -40,6 +40,7 @@ class BanTableModel : public QAbstractTableModel public: explicit BanTableModel(ClientModel *parent = 0); + ~BanTableModel(); void startAutoRefresh(); void stopAutoRefresh(); @@ -66,7 +67,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - BanTablePriv *priv; + std::unique_ptr priv; }; #endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2afefb733..169ca5008 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1147,7 +1147,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */ void UnitDisplayStatusBarControl::createContextMenu() { - menu = new QMenu(); + menu = new QMenu(this); Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 81cd098bf..866d3872c 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -59,7 +59,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 947a4c682..dec3e56ec 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -591,7 +591,8 @@ void TableViewLastColumnResizingFixer::on_geometriesChanged() * Initializes all internal variables and prepares the * the resize modes of the last 2 columns of the table and */ -TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) : +TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent) : + QObject(parent), tableView(table), lastColumnMinimumWidth(lastColMinimumWidth), allColumnsMinimumWidth(allColsMinimumWidth) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 9267e0a6c..83cd6b5d4 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -150,7 +150,7 @@ namespace GUIUtil Q_OBJECT public: - TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth); + TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent); void stretchColumnWidth(int column); private: diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 6a0404cbf..a010f0102 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -25,8 +25,8 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(const PlatformStyle *platformStyle): - QAbstractItemDelegate(), unit(BitcoinUnits::BTC), + TxViewDelegate(const PlatformStyle *platformStyle, QObject *parent=nullptr): + QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), platformStyle(platformStyle) { @@ -119,8 +119,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate(platformStyle)), - filter(0) + txdelegate(new TxViewDelegate(platformStyle, this)) { ui->setupUi(this); @@ -213,7 +212,7 @@ void OverviewPage::setWalletModel(WalletModel *model) if(model && model->getOptionsModel()) { // Set up transaction list - filter = new TransactionFilterProxy(); + filter.reset(new TransactionFilterProxy()); filter->setSourceModel(model->getTransactionTableModel()); filter->setLimit(NUM_ITEMS); filter->setDynamicSortFilter(true); @@ -221,7 +220,7 @@ void OverviewPage::setWalletModel(WalletModel *model) filter->setShowInactive(false); filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); - ui->listTransactions->setModel(filter); + ui->listTransactions->setModel(filter.get()); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); // Keep up to date with wallet diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 911443c76..23746a6b4 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -8,6 +8,7 @@ #include "amount.h" #include +#include class ClientModel; class TransactionFilterProxy; @@ -55,7 +56,7 @@ private: CAmount currentWatchImmatureBalance; TxViewDelegate *txdelegate; - TransactionFilterProxy *filter; + std::unique_ptr filter; private Q_SLOTS: void updateDisplayUnit(); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 84ad0052f..3829696e0 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -115,12 +115,12 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : timer(0) { columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time"); - priv = new PeerTablePriv(); + priv.reset(new PeerTablePriv()); // default to unsorted priv->sortColumn = -1; // set up timer for auto refresh - timer = new QTimer(); + timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(refresh())); timer->setInterval(MODEL_UPDATE_DELAY); @@ -128,6 +128,11 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : refresh(); } +PeerTableModel::~PeerTableModel() +{ + // Intentionally left empty +} + void PeerTableModel::startAutoRefresh() { timer->start(); diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index a2aaaa5d2..8227b5ec7 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -46,6 +46,7 @@ class PeerTableModel : public QAbstractTableModel public: explicit PeerTableModel(ClientModel *parent = 0); + ~PeerTableModel(); const CNodeCombinedStats *getNodeStats(int idx); int getRowByNodeId(NodeId nodeid); void startAutoRefresh(); @@ -74,7 +75,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - PeerTablePriv *priv; + std::unique_ptr priv; QTimer *timer; }; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 0b355837a..752a05a40 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -25,6 +25,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), + columnResizingFixer(0), model(0), platformStyle(platformStyle) { @@ -48,7 +49,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg QAction *copyAmountAction = new QAction(tr("Copy amount"), this); // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyMessageAction); contextMenu->addAction(copyAmountAction); @@ -88,7 +89,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); } } diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index b13ea3df7..04cc2003c 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -32,7 +32,7 @@ QRImageWidget::QRImageWidget(QWidget *parent): QLabel(parent), contextMenu(0) { - contextMenu = new QMenu(); + contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); contextMenu->addAction(saveImageAction); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 2335d6b28..35d37bb22 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -14,7 +14,7 @@ #include RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel *parent) : - walletModel(parent) + QAbstractTableModel(parent), walletModel(parent) { Q_UNUSED(wallet); nReceiveRequestsMaxId = 0; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 650ff8b00..751ce552d 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -389,7 +389,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); // create peer table context menu - peersTableContextMenu = new QMenu(); + peersTableContextMenu = new QMenu(this); peersTableContextMenu->addAction(disconnectAction); peersTableContextMenu->addAction(banAction1h); peersTableContextMenu->addAction(banAction24h); @@ -435,7 +435,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* unbanAction = new QAction(tr("&Unban Node"), this); // create ban table context menu - banTableContextMenu = new QMenu(); + banTableContextMenu = new QMenu(this); banTableContextMenu->addAction(unbanAction); // ban table context menu signals diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 48cf94050..79af4a1f9 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -37,7 +37,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0), abandonAction(0) + transactionView(0), abandonAction(0), columnResizingFixer(0) { // Build filter row setContentsMargins(0,0,0,0); @@ -147,7 +147,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); @@ -212,7 +212,7 @@ void TransactionView::setModel(WalletModel *model) transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH); transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this); if (model->getOptionsModel()) { From c12f4e93b9be01ba2d6e96f0a851562549049686 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 16:35:14 +0100 Subject: [PATCH 1174/1223] qt: Prevent thread/memory leak on exiting RPCConsole Make ownership of the QThread object clear, so that the RPCConsole can wait for the executor thread to quit before shutdown is called. This increases overall thread safety, and prevents some objects from leaking on exit. Github-Pull: #9190 Rebased-From: 693384eedb1ac7f449e226edd53e2cb52a86e279 --- src/qt/bitcoin.cpp | 8 +++++--- src/qt/bitcoingui.cpp | 6 ++++++ src/qt/rpcconsole.cpp | 24 ++++++++++++++---------- src/qt/rpcconsole.h | 2 ++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d3d13423f..ca017b2f7 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -409,6 +409,11 @@ void BitcoinApplication::requestInitialize() void BitcoinApplication::requestShutdown() { + // Show a simple window indicating shutdown status + // Do this first as some of the steps may take some time below, + // for example the RPC console may still be executing a command. + ShutdownWindow::showShutdownWindow(window); + qDebug() << __func__ << ": Requesting shutdown"; startThread(); window->hide(); @@ -423,9 +428,6 @@ void BitcoinApplication::requestShutdown() delete clientModel; clientModel = 0; - // Show a simple window indicating shutdown status - ShutdownWindow::showShutdownWindow(window); - // Request shutdown from core thread Q_EMIT requestedShutdown(); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 169ca5008..1a5d27f6e 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -496,6 +496,12 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Disable context menu on tray icon trayIconMenu->clear(); } + // Propagate cleared model to child objects + rpcConsole->setClientModel(nullptr); +#ifdef ENABLE_WALLET + walletFrame->setClientModel(nullptr); +#endif // ENABLE_WALLET + unitDisplayControl->setOptionsModel(nullptr); } } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 751ce552d..167a3474c 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -288,7 +288,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : // based timer interface RPCSetTimerInterfaceIfUnset(rpcTimerInterface); - startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); ui->detailWidget->hide(); @@ -302,7 +301,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); - Q_EMIT stopExecutor(); RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; @@ -466,6 +464,14 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); autoCompleter->popup()->installEventFilter(this); + // Start thread to execute RPC commands. + startExecutor(); + } + if (!model) { + // Client model is being set to 0, this means shutdown() is about to be called. + // Make sure we clean up the executor thread + Q_EMIT stopExecutor(); + thread.wait(); } } @@ -646,9 +652,8 @@ void RPCConsole::browseHistory(int offset) void RPCConsole::startExecutor() { - QThread *thread = new QThread; RPCExecutor *executor = new RPCExecutor(); - executor->moveToThread(thread); + executor->moveToThread(&thread); // Replies from executor object must go to this object connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); @@ -656,16 +661,15 @@ void RPCConsole::startExecutor() connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString))); // On stopExecutor signal - // - queue executor for deletion (in execution thread) // - quit the Qt event loop in the execution thread - connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater())); - connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit())); - // Queue the thread for deletion (in this thread) when it is finished - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit())); + // - queue executor for deletion (in execution thread) + connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection); + connect(&thread, SIGNAL(finished()), this, SLOT(test()), Qt::DirectConnection); // Default implementation of QThread::run() simply spins up an event loop in the thread, // which is what we want. - thread->start(); + thread.start(); } void RPCConsole::on_tabWidget_currentChanged(int index) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 28affa954..c1efa95f8 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -12,6 +12,7 @@ #include #include +#include class ClientModel; class PlatformStyle; @@ -140,6 +141,7 @@ private: QMenu *banTableContextMenu; int consoleFontSize; QCompleter *autoCompleter; + QThread thread; }; #endif // BITCOIN_QT_RPCCONSOLE_H From e4bea4fb84dceab44f8a8de4f8b974ba8bb98529 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 11:08:19 +0100 Subject: [PATCH 1175/1223] qt: Avoid splash-screen related memory leak Make splash screen queue its own deletion when it receives the finished command, instead of relying on WA_DeleteOnClose which doesn't work under these circumstances. Github-Pull: #9190 Rebased-From: e4f126a7ba66e7317718c30276dff6db92dc1986 --- src/qt/bitcoin.cpp | 5 ++--- src/qt/splashscreen.cpp | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index ca017b2f7..d708f4b11 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -365,9 +365,8 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { SplashScreen *splash = new SplashScreen(0, networkStyle); - // We don't hold a direct pointer to the splash screen after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - splash->setAttribute(Qt::WA_DeleteOnClose); + // We don't hold a direct pointer to the splash screen after creation, but the splash + // screen will take care of deleting itself when slotFinish happens. splash->show(); connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index e36d86fdd..68e9ffeb9 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -147,6 +147,7 @@ void SplashScreen::slotFinish(QWidget *mainWin) if (isMinimized()) showNormal(); hide(); + deleteLater(); // No more need for this } static void InitMessage(SplashScreen *splash, const std::string &message) From e5ad693f91632219407b15137b8863223919849b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 14:28:55 +0100 Subject: [PATCH 1176/1223] qt: Avoid shutdownwindow-related memory leak Store a reference to the shutdown window on BitcoinApplication, so that it will be deleted when exiting the main loop. Github-Pull: #9190 Rebased-From: 5204598f8d07d7432d91e9b8781806d2f3d16415 --- src/qt/bitcoin.cpp | 3 ++- src/qt/utilitydialog.cpp | 8 +++----- src/qt/utilitydialog.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d708f4b11..dbf372b12 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -245,6 +245,7 @@ private: #endif int returnValue; const PlatformStyle *platformStyle; + std::unique_ptr shutdownWindow; void startThread(); }; @@ -411,7 +412,7 @@ void BitcoinApplication::requestShutdown() // Show a simple window indicating shutdown status // Do this first as some of the steps may take some time below, // for example the RPC console may still be executing a command. - ShutdownWindow::showShutdownWindow(window); + shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); qDebug() << __func__ << ": Requesting shutdown"; startThread(); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 947bcdb15..4ec022881 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -171,22 +171,20 @@ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): setLayout(layout); } -void ShutdownWindow::showShutdownWindow(BitcoinGUI *window) +QWidget *ShutdownWindow::showShutdownWindow(BitcoinGUI *window) { if (!window) - return; + return nullptr; // Show a simple window indicating shutdown status QWidget *shutdownWindow = new ShutdownWindow(); - // We don't hold a direct pointer to the shutdown window after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - shutdownWindow->setAttribute(Qt::WA_DeleteOnClose); shutdownWindow->setWindowTitle(window->windowTitle()); // Center shutdown window at where main window was const QPoint global = window->mapToGlobal(window->rect().center()); shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); shutdownWindow->show(); + return shutdownWindow; } void ShutdownWindow::closeEvent(QCloseEvent *event) diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 843bd7f67..b93042957 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -43,7 +43,7 @@ class ShutdownWindow : public QWidget public: ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); - static void showShutdownWindow(BitcoinGUI *window); + static QWidget *showShutdownWindow(BitcoinGUI *window); protected: void closeEvent(QCloseEvent *event); From 6f7841c4d490de01c2e458d45ba5cd1ac8ee97d5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 16:12:23 +0100 Subject: [PATCH 1177/1223] qt: Avoid OpenSSL certstore-related memory leak - Correctly manage the X509 and X509_STORE objects lifetime. Github-Pull: #9190 Rebased-From: ed998ea7a0ecf294211b06e9ef82f1548a621a1d --- src/qt/paymentserver.cpp | 43 ++++++++++++++++++++++------------------ src/qt/paymentserver.h | 5 +---- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 96627710e..1ef224b52 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -58,14 +58,19 @@ const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest" // BIP70 max payment request size in bytes (DoS protection) const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; -X509_STORE* PaymentServer::certStore = NULL; -void PaymentServer::freeCertStore() +struct X509StoreDeleter { + void operator()(X509_STORE* b) { + X509_STORE_free(b); + } +}; + +struct X509Deleter { + void operator()(X509* b) { X509_free(b); } +}; + +namespace // Anon namespace { - if (PaymentServer::certStore != NULL) - { - X509_STORE_free(PaymentServer::certStore); - PaymentServer::certStore = NULL; - } + std::unique_ptr certStore; } // @@ -107,20 +112,15 @@ static void ReportInvalidCertificate(const QSslCertificate& cert) // void PaymentServer::LoadRootCAs(X509_STORE* _store) { - if (PaymentServer::certStore == NULL) - atexit(PaymentServer::freeCertStore); - else - freeCertStore(); - // Unit tests mostly use this, to pass in fake root CAs: if (_store) { - PaymentServer::certStore = _store; + certStore.reset(_store); return; } // Normal execution, use either -rootcertificates or system certs: - PaymentServer::certStore = X509_STORE_new(); + certStore.reset(X509_STORE_new()); // Note: use "-system-" default here so that users can pass -rootcertificates="" // and get 'I don't like X.509 certificates, don't trust anybody' behavior: @@ -167,11 +167,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) QByteArray certData = cert.toDer(); const unsigned char *data = (const unsigned char *)certData.data(); - X509* x509 = d2i_X509(0, &data, certData.size()); - if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509)) + std::unique_ptr x509(d2i_X509(0, &data, certData.size())); + if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) { - // Note: X509_STORE_free will free the X509* objects when - // the PaymentServer is destroyed + // Note: X509_STORE increases the reference count to the X509 object, + // we still have to release our reference to it. ++nRootCerts; } else @@ -550,7 +550,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen recipient.paymentRequest = request; recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); - request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant); + request.getMerchant(certStore.get(), recipient.authenticatedMerchant); QList > sendingTos = request.getPayTo(); QStringList addresses; @@ -807,3 +807,8 @@ bool PaymentServer::verifyAmount(const CAmount& requestAmount) } return fVerified; } + +X509_STORE* PaymentServer::getCertStore() +{ + return certStore.get(); +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 2d27ed078..7202e7dad 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -83,7 +83,7 @@ public: static void LoadRootCAs(X509_STORE* store = NULL); // Return certificate store - static X509_STORE* getCertStore() { return certStore; } + static X509_STORE* getCertStore(); // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); @@ -140,9 +140,6 @@ private: bool saveURIs; // true during startup QLocalServer* uriServer; - static X509_STORE* certStore; // Trusted root certificates - static void freeCertStore(); - QNetworkAccessManager* netManager; // Used to fetch payment requests OptionsModel *optionsModel; From 0c09d9f00e39c4b1aee0fcb091fba068845b8edd Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 25 Oct 2016 15:30:55 -0400 Subject: [PATCH 1178/1223] Send tip change notification from invalidateblock This change is needed to prevent sync_blocks timeouts in the mempool_reorg test after the sync_blocks update in the upcoming commit "[qa] Change sync_blocks to pick smarter maxheight". This change was initially suggested by Suhas Daftuar in https://github.com/bitcoin/bitcoin/pull/8680#r78209060 Github-Pull: #9196 Rebased-From: 67c6326abd1788e6f411feb4f44b69774e76aae2 --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 083ea194a..10e2fa983 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3176,6 +3176,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C InvalidChainFound(pindex); mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev); return true; } From eebc699d3070c71365a0f3542e2f5f6eca3fd281 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 22 Nov 2016 09:59:50 +0100 Subject: [PATCH 1179/1223] bench: Fix subtle counting issue when rescaling iteration count Make sure that the count is a zero modulo the new mask before scaling, otherwise the next time until a measure triggers will take only 1/2 as long as accounted for. This caused the 'min time' to be potentially off by as much as 100%. Github-Pull: #9200 Rebased-From: e0a9cb25b0af87723d50cb8d8cffa10f1ebf7dcc --- src/bench/bench.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 227546a7a..8942da8c7 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -64,8 +64,11 @@ bool State::KeepRunning() return true; } if (elapsed*16 < maxElapsed) { - countMask = ((countMask<<1)|1) & ((1LL<<60)-1); - countMaskInv = 1./(countMask+1); + uint64_t newCountMask = ((countMask<<1)|1) & ((1LL<<60)-1); + if ((count & newCountMask)==0) { + countMask = newCountMask; + countMaskInv = 1./(countMask+1); + } } } lastTime = now; From 396c405e7b4911eea3eceecd001840ffa8c38e95 Mon Sep 17 00:00:00 2001 From: Ivo van der Sangen Date: Sun, 27 Nov 2016 12:08:39 +0100 Subject: [PATCH 1180/1223] Include select.h when WIN32 is not defined Github-Pull: #9224 Rebased-From: 498a1d75e75649b02caeca7b1bc9bbc19e51a566 --- src/compat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compat.h b/src/compat.h index 79a297e5e..2578d6d34 100644 --- a/src/compat.h +++ b/src/compat.h @@ -34,6 +34,7 @@ #else #include #include +#include #include #include #include From 28d0f224fda3ec375c07aaa18f786ce18f674f29 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 17:49:08 -0800 Subject: [PATCH 1181/1223] Fix calculation of number of bound sockets to use Github-Pull: #9253 Rebased-From: 9e1f46821d5bb69e2cbf25738eefa7c6cb99c838 --- src/init.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index eab8de8d0..4a837018b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -854,7 +854,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } // Make sure enough file descriptors are available - int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); + int nBind = std::max( + (mapMultiArgs.count("-bind") ? mapMultiArgs.at("-bind").size() : 0) + + (mapMultiArgs.count("-whitebind") ? mapMultiArgs.at("-whitebind").size() : 0), size_t(1)); int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); From ff55a2d22e3d93a9bfe7999277a7bffcf7f60f9d Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Tue, 18 Oct 2016 13:47:34 +0800 Subject: [PATCH 1182/1223] Update gitian signing key of jl2012 Github-Pull: #8950 Rebased-From: 9b0d8efe811058928a6ed3a55c0b6d58e13b22ba --- contrib/gitian-keys/jl2012-key.pgp | 374 +++++++++++++++++++++-------- 1 file changed, 272 insertions(+), 102 deletions(-) diff --git a/contrib/gitian-keys/jl2012-key.pgp b/contrib/gitian-keys/jl2012-key.pgp index b8aad7fd8..984f555cb 100644 --- a/contrib/gitian-keys/jl2012-key.pgp +++ b/contrib/gitian-keys/jl2012-key.pgp @@ -1,105 +1,275 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - https://gpgtools.org +Version: SKS 1.1.5 +Comment: Hostname: pgp.mit.edu -mQINBFYhRd0BEAC+2VU+8+f9RTPLtl0C815oxaOCA9Tle13xNER8NjFrVwIuFQ64 -nO8Fbhd5KEEARuMS/lc5G6IV0QxBpDGE1sEjPQXrA6UnX8SDkNGhmoAsV07MP2Xl -glN9qqYUEoVD7ueh7Cp3A9rFjg7wcMJCPQDP6lZY4cPgYlE1C31TCrEdAsVVTQg+ -xIYWnhB92VxOJhk0N0h6xtCQ2MOtYDjYcBndQ5iK7L5jy5LI89YVRfbKtWqWZdwR -lgj2JCLeXKauXBI1qbedCJrz5e8nXcdqZt9TXSHo/XhNlqvsLiqBq4aXNU3xRkrv -fcweZ9jR9DjyQzefYFGaiCk37R4qLbaqQRm0luUizkCegIuTv44e/zig0im8yPAI -WtGnmBPSy4MpvvWiVVb+jHikdQG1T7g9kF6gEmj4kj9UseWnasiq+kkSNE67vLxb -uZDfA3QhavRMJbCNEY49/IX6urIsiCLFbe6C7JVWvJ7d5l3MAHE8Sut+ytjX7z7O -LFt7YD6loxGAdopEUZm50xs8PswKDajlzWGFXjDZdzQA1tb2CpHUtDkAInYDutR4 -qA29qtxaBswozzUYiDptGSkBqD1Nus7UAJYkwe2EjeszNPhmIAQXGWx2yWplPOJk -ZWDuhQtrDXZikl70q0ekIJ7bxkpMO8xUuhsBCS3Wn6GAtySy0XTttmItfQARAQAB -tBZqbDIwMTIgPGpsMjAxMkB4YnQuaGs+iQI3BBMBCgAhBQJWIUXdAhsBBQsJCAcD -BRUKCQgLBRYCAwEAAh4BAheAAAoJEMUkKhqzk2UXsbIQAJnXDjhEoKSILJRrKbg+ -MXP3Rhxc/ThXu5C8yhfYqKblqCaNNfEmrlercJKJVMvjY0tVTXYo8BEJmNN7nSNI -su8NheJ9vXacN3XrgkMPuFiUyKj9PGpSsM6Q8MjT0Bzd0pxodk+g0UEjyMktfu/3 -TqLsnoFPOtIjMOkr/uBzZn5d0AXIZQbAz4Xa2zBW+uR3OSXRRXCRJjCSWGIfDX0Y -i/Ea+3Be+y9bMqDa3nPULEkW7+RNuyjLr6QwPZ0/BpTTDcM6Vic2daFPO5B0+o3z -PMFmPcEd4nRHTPM9A5SaJtC8MjF/89mjhpxG3v8RqkqCdqdM2cezi/T4YD4jcynE -F36Ya3GuuewxEZci/N5ySG5gG8Y+80Wgc1e+sNtvIffHk3Wju2kOvNcBA2TBw36V -XCJXHROTA5+Cx4lUxOkQTJoYSVzx852WS6WHeLg1+XnDZvT7ciVIV0ExJQ9C1XOM -wjFMRsTWl+vflxmgCeHCIari57Jw3ij7ghRCgeqLp7FIXK5qSI4Tw2eajJpoTKPs -wlaO6kvOXtaCDH30FuVhKbPxII01Xi/A2ALtTkpA6mfnf19orQjv+HxX/iwUlpHM -UwsuhpZSQYIxIv/BOQnXDfw4TcjnHsqXZbqNzzFEjGurMTlOUX4KeTPscdOLUpnO -1FM4JIVybHHfhCH9Mpq+MIwCiQGBBBMBCABrBQJWpym9BYMJZgGAXhSAAAAAABUA -QGJsb2NraGFzaEBiaXRjb2luLm9yZzAwMDAwMDAwMDAwMDAwMDAwNWJiZWZkNGM3 -Mzk5OTE0OGRmZDQ1MjA5ZjA2MTUwMTljMTNjMGVjOWUwYmQ4MzUACgkQf6sRQmfk -+gQcZAgApPqnaIIE8Q5sruzua50RFRmmBtQys8sM95ciWYE4QaTXUnlhHl4QR4z/ -TQTRSBqXpdHQ9HBWrhFb6E0ykDEVx9zdEt0fvtlhHx1ItrZetfiA4PwidnyoDKs/ -/nt01RGreKSMDGInaQVEQxvEW+A0fwvcCdE8Mh3LcIydohfqUViB0c5zb7rUmize -+2Kt4Uth9T+ooo+UE87pHSJcxlcPOv6Dc7KeoUicD8DwWdsT7oxAMk9jj/ut4UNx -xOEp9Sa3sFN20tHMqyOZwnl22Py0y4ayJnceawpuka/bx7samg/2uUrO+dNKXObN -trebP83+8UFHOo7VGhesuawgwNjWW7kBjQRWIUbHAQwAy6re/3ur/fgNfE9yKivp -Bqmjq0eU5l3iT59hvKr7S+6GHUa+YvE9BBsawDSI4UILNQX0YGT1LRa20mC1okBX -5SIEpWzoZhybTMVMwS2ZHkUyO6VBAieUVojP3XQHFcDAiBvW7RRhJ2BU+v9DGo88 -HAYqKEB85P/i/E/a1xUfTWiiIhA8Dd/Hv6pzIG5QvN8XfrMIayLwpOV1G6KvBIJb -zyUVUvLyQySiZOyDczrAxzYq7b1qv8xwHDUzyUl6skPqbex1cFWIeiML9EY4DnZ9 -l3qb31Bhp+EHydv0esclM5XKQriSg/hsnJOLlCS45z/YhqGOCoD8QxXUJ71NhD/H -QR/AvGyTDcPr1/U1DJ0lG778wCOEe1Nad0G/8rcpHSY66RZR/Wf318S7uJt0mUw2 -JMt1BRxfbdgJaleUAqYjNQAMDb8LfPO6jhQnmf0nN99dpdzkwV/drVRcLDEnupDr -keBsokcuohzE0gbjUT4cNc0DuUsIELMTApG8KQCgzJy/ABEBAAGJA8QEGAEKAA8C -GwIFAlbi67wFCQGu8u4BqcDdIAQZAQoABgUCViFGxwAKCRDunlUgNL4k0qceC/91 -2ocEDwiu9kpBGCW0HD+VSyMVjLWMiClk+jPngvNEt63ZkYqRiy7fwnPuJrLFlaL0 -E0JLIweihC5AyPSJT1Q0LnOwbqCHn1s+9RfIodG/v6M48Ez4GffOtmYwW9KqogK7 -4FwdIx/wOIYDeh4rT7LRaWBNcIXO8J1+v/83u+Vx6TWKZTiZKQMEV8VOJWfSmTCE -6HVgUYvLCPB6DI+X4aVead1kayKOSuXlG/l94B5RHlJB/xQXZd1INyrZetTZxYzZ -CBhIWaZ/ji5vqFot0xVNYplRkbg1Mc96X+hwee8eiB/ySSWxUV/DDkA5ZzuE8n8R -EEjzqazjMNe50P7XKVg/eBE+TpgCDlqv69dqnOF326m6T3+FH/LDOHguQfB7pQKx -siviqjO3molBSyMHL39XFWyteVbgbbSaTRkpX//b7dQoFMiVhigcM78qoymBi6yX -qwpN13JoNuNJhEOwex5eEEUCVibFReUkBrYoGnWbwuOxiLORx/IbuNYOvsTGYEAJ -EMUkKhqzk2UXWScQAIvAgEpQpzuE1CWMBWcM/n4ruUrOVTeo6dYpUGN1LI0758xm -4VI47I8wPEy4pAbdPcqoaNnMcA/NpSYa3hV0svQDLqT96qKTrN71N1gNJa+5w+KN -rwev8MRpjuze9b4dn3avs4L9f0fkpzjSzezKwVb7loFSZqgKAaI0aSoOUTec9+OU -5ymgkYPEEF12ydkyMzLwyKrtEnIqgwQpjYTN/3P1x7Gkhv+E8Lz06TSga84yVy5I -5gO1Hklc3MW0J9jPJe3uALUtEh49KxCE2rdbIX7YbkxWaHHfK98Mu998IXr/4eUe -Zhf2CLC2cuuYbk1/rOcxPmeIJKa6S5PlWOf3Y2yLRO0VKcjD5pcGxiImoDVXC4VM -hztCVLddjU70c1ktSIBQBu9gkpPcECrzjYtpeAavOUgmpP/zQ8X2NGp6+5n9Wwii -tAgByNCg0s+PqcAZxup34b3ZY/t475tDlAmIOovH14Aa8g+0Ketj++9rPpmg9kGs -sGmn4mVItClaA7L9vZQQFnSxjyfICKsSxBhqded0lsinlzBfXDEh3N6fEXh81/Gg -zLUmTlkhcGaFXplYqrUIlkdO9PD4R2h5P6laLhK2dAf7oKavWHZQp02Yb5nVBiDc -KiVWKBP4nuTkWZCG5R966wpR1IOQQ3LykSd5SstcZX6iTpv4NZpCxI4CXpaCuQGN -BFYhSHABDADHaEJVygBdwU81c4YynyTOnWTZX+BR3EvRW51GcnfvjqkqgmlWNLET -JkswQ8+s0mjKGVnz4dkdr4cUbVegj/St7wzoO+m5mYIDMJf1j83Vo6lTo9FJFzbc -HrYC9RS7NkQmD7qzJz4KY/h0n5szFIC/JpYECBNzYrJQc8m2kZiSlyUQJve5/I5J -iI6QnM0x4kixNe32GITmKw9s3E2iRf6yXVlsrPouNS33lPXKtvmO1ae7R+G8Ve+D -JDv+TLxccy2iU9wuz4I3k20+rlmEwk17feDhfleh5Q+qjI4vkaNcXFa5coZE0HyW -SwAtLPSOv2vWkuFeYncXRyzg/CvKR57i9wnqMzNTMt3bHY2HezE13bHln5B/Jqr4 -ihhFQBqPG+UZlGYRfAI60PLh2yftX5xkm/POiLgEKF76/yIZI8wcPzzurAhFaZBp -8/MUv2ZJ/OUT4rdEVV+6XnrijNqVBU8mf8BML5CvjyhsU69yf1mvpiLQr34FNEcn -JekDGPIk97cAEQEAAYkCJQQYAQoADwIbDAUCVuLr0AUJAa7xWwAKCRDFJCoas5Nl -F8NMD/4hRoOKENEq940Z0iJg0TDvRvRnaIYsbneRQ3yg1DGVIQ+4RHmzQdpN9MW0 -5RTRLqJsW25ydWwh7y0O/oBRjaoDRAkMSIyOo/Fy+E9WWBmAwzeYCi91MyfetKIO -ocrXxpXXKnotAFDOgWGF8K+LlTDH/biOrd8ftgOVJWhz3X04ma7xvT2tQTqfFdbt -EivA+jFExq3No0Iq+Ctt/e0H2d9np62SeKBVdpbx9xAc2tPKKDSl+FyB7lj5CK5/ -FKhotl2bJhVXET48P6e+bFVwfRO7o48zuK5CJVbbdjhavQGhQoxfedW2dn9y7QoM -qayUuVIhULE/k+y3jsJBUT7p567nSdUGbc3uKt1sfPKYTdsFbHiTRltXmsIiv4bG -PslbXSvOQblFOXWrAE22CdKmGzhlEiFnbviZCCl0BFf4CwEVBJ3p9Lcoir1l9Aty -HIIFI3z1mmTz4F9BMbe6saNwBzO+Kh4+US5NV/hqvyz0aOLltb6KfI8WF8kOa1Cx -Djz/DTHnvMWO/dIOJuKsThfuxZZq3R1w3O36RB8XzDT/8NV86gfQwN07NWz1rdy4 -60fK36EjOJDqm/434/BDzWh8TqmnSamENxBTbICmWOj/25M26tA2S9zcPLJHTGMA -3yL3QlBtjWY2uNqr51cnZHgPKxBWzaRvcrZ+lUq5EG+F4J7q5rkBjQRWIUitAQwA -5A2AhW9DFxVsM105WEErD2NuM2rvtq7dTwArBEi2KdWkSGQvCE9xgyH8u5AEWxj8 -XXHE/rfunW0d9oF7Z9FbOuV+1HQOAj5hQQWLWHERwZ4gOAqG8ZKAbuwTlqitdiXE -PZiJYZSq0NXtngyeTx7XqzQSatfFOIQLzIiwPQXX0Tt+JB3B2SN/D2NP7rubzfS2 -Bg0ErhV20fPDl8YloEJFfj9lpF0ZJnJ5hXYP9Fl4MoPkyBkGPrJPooZ4FqUFHDiw -mttzP1BzFlwpAPGpI0NrkBdBlfFAtvhjreeB5Z4VYwt1xqoXgI+jYXAxoMl+rtkK -FdWaoT7wHwqDBeBWYXoyXA2dYIY8Ux1jeDBnREck7vaXhln6zXqMAQowE+F9OQnr -Wgf/LoOn5MYxsBDY9mPAO8urxUDE+Dq43JBXlS+jybMNZWdtkaBrIde7dw9IT8Fn -p8pG78DmgPxmRFH9QoypTqMfB+x7ZuB0fk1ud4ut33qLo78BWZoW0H++13CbSmrZ -ABEBAAGJAiUEGAEKAA8CGyAFAlbi690FCQGu8SoACgkQxSQqGrOTZRcNQBAAmeL1 -8Wr7vuvL5dySoYmWqHFvM8gRUwIGza5c3D29NYZJcPJRRkdGCV2IXEuUSOLtnjAN -kTM1TVMMnetqNR8Uryr7z3XjqYLnVwGqOPnFnlkE2zS3pG8AGG6OxxBhuEMvkwcd -1s3tWUlJYRWi1XhEjVZ5Km2pHsVxvoXeJCUVsa8nSXzqF8gOLm409NFMiKkp8QOG -heEV4yWrHkySi1fVfOdrHfBzu2lUmHGgSbmJIpLcK+cL3TjpJ+DkSNbniI13I/Eb -PO4Uai4a3QYz6sspZ7UzF/pjY5v6WpWXiVB5PP2Y5BrMUgWRlFxPYTc3KiIHUYVi -IjVtSOsVaRCHL/SYRq/qHs63XxlxKIhhilbR4OO+CvJ6N/vEpSbx69SqlxgDArZy -g3QQqerlLGpSFim9iWk3QBGWtQ96Ek6rjLLOn7b34I6bxXtfcOEo7gl0Y1TFkfOp -nsXAcRLrrXCpAhgC/vIQRTMKEcC18kj/vY144DwefzYCBhbI/rCSohAq8a/zhq2T -E+xlCYy931HWlUAGx/hms/0q+KQ712Zgk4XxXEx4RZiv3zl9Uph6c7SXxAMb8o2v -PzAxd3ShNOnng9hAl8zk5O1RZPa5u51ppkO1FsJ9zjb2Kvdg4ZEBtK8jETv9ckuq -yj9YmZZSRRQ2dujg81sLQ9CrO7WB3IGpwh+4lHQ= -=1irw +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 +Ww8nn+QC38ITGK9hVF+eVkuR +=j8C/ -----END PGP PUBLIC KEY BLOCK----- From b1e978cfd6de4e61659e019c52d9c4953b9791c1 Mon Sep 17 00:00:00 2001 From: "S. Matthew English" Date: Thu, 27 Oct 2016 12:13:03 +0200 Subject: [PATCH 1183/1223] instance of 'mem pool' to 'mempool' there was only one instance of 'mem pool' and not 'mempool', so I changed it to conform to the others Github-Pull: #9029 Rebased-From: 1c3ecc70c8cd6c33cf3ff4e2099c8e7d8a8ca9d2 --- src/rpc/blockchain.cpp | 2 +- src/rpc/mining.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6f97671f5..a38b3fc60 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -719,7 +719,7 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. n (numeric, required) vout number\n" - "3. includemempool (boolean, optional) Whether to include the mem pool\n" + "3. includemempool (boolean, optional) Whether to include the mempool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index ba48079c0..e5eb4b8c1 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -229,7 +229,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" " \"networkhashps\": nnn, (numeric) The network hashes per second\n" - " \"pooledtx\": n (numeric) The size of the mem pool\n" + " \"pooledtx\": n (numeric) The size of the mempool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" "}\n" From 87fbcede5ceb49fc24c3102c0f3cf81a68617ac6 Mon Sep 17 00:00:00 2001 From: matthias Date: Mon, 31 Oct 2016 01:11:46 +0100 Subject: [PATCH 1184/1223] Change all instance of 'GMT epoch' to 'Unix epoch' Github-Pull: #9041 Rebased-From: 7f61b49de82989dc692e7750860eb1ec4044db7a --- src/rpc/misc.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 06489566b..11befb529 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -57,7 +57,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"testnet\": true|false, (boolean) if the server is using testnet or not\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2ad379e46..fdb7a53d3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2274,7 +2274,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" From 387ec9d9635580fbbedc222126c5b1a68002d543 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 15 Oct 2016 23:45:07 +0800 Subject: [PATCH 1185/1223] Add script tests for FindAndDelete in pre-segwit and segwit scripts Github-Pull: #8927 Rebased-From: acf853df910339412bafb1743f42af1774f5b910 --- src/script/interpreter.cpp | 4 ++-- src/test/data/tx_invalid.json | 26 ++++++++++++++++++++++++++ src/test/data/tx_valid.json | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 836cf9ee3..0e17ddc13 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -890,7 +890,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signature, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts if (sigversion == SIGVERSION_BASE) { scriptCode.FindAndDelete(CScript(vchSig)); } @@ -951,7 +951,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signatures, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f8baee057..f7d9e1847 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -314,5 +314,31 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal scriptPubKey and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and the wrong sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"], +["by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE)"], +["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9d7ed6e161f0e255c10bbfcca0128a9e2035c2c8da58899c54d22d3a31afdef4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Should pass by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE) under OP_CHECKMULTISIG"], +["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 1ea70135b..2f299aa5f 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -487,5 +487,28 @@ [[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]], "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal P2SH and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and correct sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["Non-segwit: correct sighash (with FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Non-segwit: correct sighash (with FindAndDelete) = 1d50f00ba4db2917b903b0ec5002e017343bb38876398c9510570f5dce099295"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] From ecd7db57672d4f2dbc85ac03e571b795b0259298 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 7 Nov 2016 23:00:54 +0100 Subject: [PATCH 1186/1223] [qa] test_framework: Exit when tmpdir exists Github-Pull: #9098 Rebased-From: fae19aa1da0858678874815b344de83e1ee3a1bd --- qa/rpc-tests/test_framework/test_framework.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 9d15d8745..bb624301c 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -137,16 +137,11 @@ class BitcoinTestFramework(object): success = False try: - if not os.path.isdir(self.options.tmpdir): - os.makedirs(self.options.tmpdir) + os.makedirs(self.options.tmpdir, exist_ok=False) self.setup_chain() - self.setup_network() - self.run_test() - success = True - except JSONRPCException as e: print("JSONRPC error: "+e.error['message']) traceback.print_tb(sys.exc_info()[2]) From 58eab244fb9514b74e157b5dde9060cc8f3b77a8 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 7 Nov 2016 22:33:22 +0100 Subject: [PATCH 1187/1223] [qa] rpc-tests: Apply random offset to portseed This helps to skip over resources, which are blocked by regtest bitcoind zombie nodes Github-Pull: #9098 Rebased-From: fab0f07dec8d6e21ab70843fdce101f1703588fd --- qa/pull-tester/rpc-tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index dbd6de559..887644c51 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -243,6 +243,10 @@ class RPCTestHandler: self.test_list = test_list self.flags = flags self.num_running = 0 + # In case there is a graveyard of zombie bitcoinds, we can apply a + # pseudorandom offset to hopefully jump over them. + # (625 is PORT_RANGE/MAX_NODES) + self.portseed_offset = int(time.time() * 1000) % 625 self.jobs = [] def get_next(self): @@ -250,7 +254,7 @@ class RPCTestHandler: # Add tests self.num_running += 1 t = self.test_list.pop(0) - port_seed = ["--portseed=%s" % len(self.test_list)] + port_seed = ["--portseed={}".format(len(self.test_list) + self.portseed_offset)] log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, From 3688866880decdbe9c2b551a1b701c752f8013d2 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Tue, 29 Nov 2016 12:18:44 -0500 Subject: [PATCH 1188/1223] Disable fee estimates for a confirm target of 1 block Backport of #9239 without GUI changes and fixing conflicts in tests. --- src/policy/fees.cpp | 7 ++++++- src/rpc/mining.cpp | 2 ++ src/test/policyestimator_tests.cpp | 30 ++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 7b0e8b7d0..453b4a57d 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -495,7 +495,8 @@ void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) { // Return failure if trying to analyze a target we're not tracking - if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) + // It's not possible to get reasonable estimates for confTarget of 1 + if (confTarget <= 1 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) return CFeeRate(0); double median = feeStats.EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); @@ -514,6 +515,10 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) return CFeeRate(0); + // It's not possible to get reasonable estimates for confTarget of 1 + if (confTarget == 1) + confTarget = 2; + double median = -1; while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) { median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e6901bc77..a574709d9 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -791,6 +791,8 @@ UniValue estimatefee(const UniValue& params, bool fHelp) "\n" "A negative value is returned if not enough transactions and blocks\n" "have been observed to make an estimate.\n" + "-1 is always returned for nblocks == 1 as it is impossible to calculate\n" + "a fee that is high enough to get reliably included in the next block.\n" "\nExample:\n" + HelpExampleCli("estimatefee", "6") ); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 5c902387f..fa00a1c46 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -105,19 +105,26 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // Highest feerate is 10*baseRate and gets in all blocks, // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%, // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%, - // so estimateFee(1) should return 10*baseRate. + // so estimateFee(1) would return 10*baseRate but is hardcoded to return failure // Second highest feerate has 100% chance of being included by 2 blocks, // so estimateFee(2) should return 9*baseRate etc... for (int i = 1; i < 10;i++) { origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK()); origPriEst.push_back(mpool.estimatePriority(i)); if (i > 1) { // Fee estimates should be monotonically decreasing - BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); + if (i > 2) { + BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); + } BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]); } int mult = 11-i; - BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + if (i > 1) { + BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + } + else { + BOOST_CHECK(origFeeEst[i-1] == CFeeRate(0).GetFeePerK()); + } BOOST_CHECK(origPriEst[i-1] < pow(10,mult) * basepri + deltaPri); BOOST_CHECK(origPriEst[i-1] > pow(10,mult) * basepri - deltaPri); } @@ -127,9 +134,12 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) while (blocknum < 250) mpool.removeForBlock(block, ++blocknum, dummyConflicted); + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] + deltaFee); - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + if (i > 1) { + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] + deltaFee); + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + } BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] + deltaPri); BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } @@ -169,8 +179,10 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) } mpool.removeForBlock(block, 265, dummyConflicted); block.clear(); + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + if (i > 1) + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } @@ -190,8 +202,10 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum, dummyConflicted); block.clear(); } + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10; i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); + if (i > 1) + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri); } From a710a4304033eea581e463a5fb0502bdb8991aa1 Mon Sep 17 00:00:00 2001 From: wodry Date: Wed, 30 Nov 2016 17:19:08 +0100 Subject: [PATCH 1189/1223] Improvement of documentation of command line parameter 'whitelist' Github-Pull: #9251 Rebased-From: 8a70a9da3da0df5c376042b18b87f0a63e88d2e3 --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 4a837018b..bbdab14ee 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -376,7 +376,7 @@ std::string HelpMessage(HelpMessageMode mode) #endif #endif strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); - strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + + strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); From 21ccb9f2530af996fc0a58df418837a08b75781f Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Sun, 20 Nov 2016 09:54:51 -0500 Subject: [PATCH 1190/1223] Add option to return non-segwit serialization via rpc Github-Pull: #9194 Rebased-From: 835c75acaac004c3315395dcd7d1f193dfb9e5da --- qa/rpc-tests/segwit.py | 20 +++++++++++++++++--- src/core_io.h | 2 +- src/core_write.cpp | 4 ++-- src/init.cpp | 4 ++++ src/rpc/blockchain.cpp | 2 +- src/rpc/rawtransaction.cpp | 2 +- src/rpc/server.cpp | 8 ++++++++ src/rpc/server.h | 5 +++++ src/wallet/rpcwallet.cpp | 2 +- 9 files changed, 40 insertions(+), 9 deletions(-) diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 493ad2e67..4b4fdf8b1 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -13,6 +13,7 @@ from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COut from test_framework.address import script_to_p2sh, key_to_p2pkh from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG from io import BytesIO +from test_framework.mininode import FromHex NODE_0 = 0 NODE_1 = 1 @@ -83,8 +84,8 @@ class SegWitTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) + self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness", "-rpcserialversion=0"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=2"])) self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) connect_nodes(self.nodes[1], 0) connect_nodes(self.nodes[2], 1) @@ -210,7 +211,20 @@ class SegWitTest(BitcoinTestFramework): block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3) sync_blocks(self.nodes) assert_equal(len(self.nodes[2].getrawmempool()), 0) - assert_equal(len(self.nodes[2].getblock(block[0])["tx"]), 5) + segwit_tx_list = self.nodes[2].getblock(block[0])["tx"] + assert_equal(len(segwit_tx_list), 5) + + print("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag") + # Note: node1 has version 2, which is simply >0 and will catch future upgrades in tests + assert(self.nodes[2].getblock(block[0], False) != self.nodes[0].getblock(block[0], False)) + assert(self.nodes[1].getblock(block[0], False) == self.nodes[2].getblock(block[0], False)) + for i in range(len(segwit_tx_list)): + tx = FromHex(CTransaction(), self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[2].getrawtransaction(segwit_tx_list[i]) != self.nodes[0].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i], 0) == self.nodes[2].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) != self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i]) == self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) == bytes_to_hex_str(tx.serialize_without_witness())) print("Verify witness txs without witness data are invalid after the fork") self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False) diff --git a/src/core_io.h b/src/core_io.h index b559d44bf..44a732b69 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -25,7 +25,7 @@ extern std::vector ParseHexUV(const UniValue& v, const std::strin // core_write.cpp extern std::string FormatScript(const CScript& script); -extern std::string EncodeHexTx(const CTransaction& tx); +extern std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); diff --git a/src/core_write.cpp b/src/core_write.cpp index ea01ddc10..9f859ba9e 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -116,9 +116,9 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) return str; } -string EncodeHexTx(const CTransaction& tx) +string EncodeHexTx(const CTransaction& tx, const int serialFlags) { - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags); ssTx << tx; return HexStr(ssTx.begin(), ssTx.end()); } diff --git a/src/init.cpp b/src/init.cpp index bbdab14ee..8e40c4388 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -364,6 +364,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); + strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(>0) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); @@ -982,6 +983,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) + return InitError("rpcserialversion must be non-negative."); + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a38b3fc60..b4d53a9f3 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -607,7 +607,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (!fVerbose) { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b2bbb8b3e..2719829e6 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -209,7 +209,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - string strHex = EncodeHexTx(tx); + string strHex = EncodeHexTx(tx, RPCSerializationFlags()); if (!fVerbose) return strHex; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 102c77631..deeabcb8d 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -495,4 +495,12 @@ void RPCRunLater(const std::string& name, boost::function func, int6 deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } +int RPCSerializationFlags() +{ + int flag = 0; + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) + flag |= SERIALIZE_TRANSACTION_NO_WITNESS; + return flag; +} + CRPCTable tableRPC; diff --git a/src/rpc/server.h b/src/rpc/server.h index b5ccc153d..1ed8f2466 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -19,6 +19,8 @@ #include +static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1; + class CRPCCommand; namespace RPCServer @@ -195,4 +197,7 @@ void InterruptRPC(); void StopRPC(); std::string JSONRPCExecBatch(const UniValue& vReq); +// Retrieves any serialization flags requested in command line argument +int RPCSerializationFlags(); + #endif // BITCOIN_RPCSERVER_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fdb7a53d3..17bda050c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1780,7 +1780,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); - string strHex = EncodeHexTx(static_cast(wtx)); + string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); entry.push_back(Pair("hex", strHex)); return entry; From f26dab7e90cfb1733736c1dd63c507254de84a34 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Tue, 22 Nov 2016 15:47:07 -0500 Subject: [PATCH 1191/1223] Adapt ZMQ/rest serialization to take rpcserialversion arg Github-Pull: #9194 Rebased-From: ad5c4c93cae53a2a6f74880ca11b4d788677a378 --- src/rest.cpp | 4 ++-- src/zmq/zmqpublishnotifier.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 2dff8d7da..57cd9baeb 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -228,7 +228,7 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; switch (rf) { @@ -367,7 +367,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssTx << tx; switch (rf) { diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index b6c907980..cdef17e08 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -6,6 +6,7 @@ #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" +#include "rpc/server.h" static std::multimap mapPublishNotifiers; @@ -165,7 +166,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); const Consensus::Params& consensusParams = Params().GetConsensus(); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); { LOCK(cs_main); CBlock block; @@ -185,7 +186,7 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr { uint256 hash = transaction.GetHash(); LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ss << transaction; return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } From 4c71fc42fbf32d8994f4d2488ac4bafad93226a1 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 30 Sep 2016 18:19:57 -0400 Subject: [PATCH 1192/1223] Remove duplicate nBlocksEstimate cmp (we already checked IsIBD()) Github-Pull: #8865 Rebased-From: 0278fb5f48ae9e42ec0772f85e201051077f633c --- src/main.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 191bcff4c..cfc616201 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3110,13 +3110,10 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, } } // Relay inventory, but don't relay old inventory during initial block download. - int nBlockEstimate = 0; - if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { - if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { + if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) { BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { pnode->PushBlockHash(hash); } From ad20cddce2097c6561202777fccd257deb1a9810 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sat, 22 Oct 2016 05:33:25 +0000 Subject: [PATCH 1193/1223] IBD check uses minimumchain work instead of checkpoints. This introduces a 'minimum chain work' chainparam which is intended to be the known amount of work in the chain for the network at the time of software release. If you don't have this much work, you're not yet caught up. This is used instead of the count of blocks test from checkpoints. This criteria is trivial to keep updated as there is no element of subjectivity, trust, or position dependence to it. It is also a more reliable metric of sync status than a block count. Github-Pull: #9053 Rebased-From: fd46136dfaf68a7046cf7b8693824d73ac6b1caf --- doc/release-process.md | 1 + src/chainparams.cpp | 10 ++++++++++ src/consensus/params.h | 1 + src/main.cpp | 6 ++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index 41c1ac855..ccc4bcd23 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -10,6 +10,7 @@ Before every minor and major release: * Update [bips.md](bips.md) to account for changes since the last release. * Update version in sources (see below) * Write release notes (see below) +* Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc. Before every major release: diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3ad9f4d2d..69514617b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -97,6 +97,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016. consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90"); + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -194,6 +197,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000198b4def2baa9338d6"); + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -228,6 +234,7 @@ public: fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; + checkpointData = (CCheckpointData) { boost::assign::map_list_of ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")), @@ -270,6 +277,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; diff --git a/src/consensus/params.h b/src/consensus/params.h index d97017d0c..7aa876d65 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -61,6 +61,7 @@ struct Params { int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } + uint256 nMinimumChainWork; }; } // namespace Consensus diff --git a/src/main.cpp b/src/main.cpp index cfc616201..54eff56f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1747,7 +1747,9 @@ bool IsInitialBlockDownload() return false; if (fImporting || fReindex) return true; - if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) + if (chainActive.Tip() == NULL) + return true; + if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) return true; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge); @@ -1781,7 +1783,7 @@ void CheckForkWarningConditions() { AssertLockHeld(cs_main); // Before we get past initial download, we cannot reliably alert about forks - // (we assume we don't get stuck on a fork before the last checkpoint) + // (we assume we don't get stuck on a fork before finishing our initial sync) if (IsInitialBlockDownload()) return; From 5b93eeebb4f7fce10a12f2e83f771bc23002c224 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 2 Nov 2016 01:49:45 +0000 Subject: [PATCH 1194/1223] Remove GetTotalBlocksEstimate and checkpoint tests that test nothing. GetTotalBlocksEstimate is no longer used and it was the only thing the checkpoint tests were testing. Since checkpoints are on their way out it makes more sense to remove the test file than to cook up a new pointless test. Github-Pull: #9053 Rebased-From: 2082b5574cec783f4ff99941492d92e05680b293 --- src/Makefile.test.include | 1 - src/checkpoints.cpp | 10 ---------- src/checkpoints.h | 3 --- src/test/Checkpoints_tests.cpp | 27 --------------------------- 4 files changed, 41 deletions(-) delete mode 100644 src/test/Checkpoints_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index ef30eeb4a..0878d8234 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -50,7 +50,6 @@ BITCOIN_TESTS =\ test/bip32_tests.cpp \ test/blockencodings_tests.cpp \ test/bloom_tests.cpp \ - test/Checkpoints_tests.cpp \ test/coins_tests.cpp \ test/compress_tests.cpp \ test/crypto_tests.cpp \ diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index aefddce46..d22c188c1 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -55,16 +55,6 @@ namespace Checkpoints { return fWorkBefore / (fWorkBefore + fWorkAfter); } - int GetTotalBlocksEstimate(const CCheckpointData& data) - { - const MapCheckpoints& checkpoints = data.mapCheckpoints; - - if (checkpoints.empty()) - return 0; - - return checkpoints.rbegin()->first; - } - CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; diff --git a/src/checkpoints.h b/src/checkpoints.h index cd25ea537..04346f35f 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -19,9 +19,6 @@ struct CCheckpointData; namespace Checkpoints { -//! Return conservative estimate of total number of blocks, 0 if unknown -int GetTotalBlocksEstimate(const CCheckpointData& data); - //! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const CCheckpointData& data); diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp deleted file mode 100644 index 1b7d368e1..000000000 --- a/src/test/Checkpoints_tests.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Unit tests for block-chain checkpoints -// - -#include "checkpoints.h" - -#include "uint256.h" -#include "test/test_bitcoin.h" -#include "chainparams.h" - -#include - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(sanity) -{ - const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); - BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444); -} - -BOOST_AUTO_TEST_SUITE_END() From 5998a09546b033e8d55f2a45d35a6161b2cdc288 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 1 Nov 2016 00:37:54 +0000 Subject: [PATCH 1195/1223] IsInitialBlockDownload no longer uses header-only timestamps. This avoids a corner case (mostly visible on testnet) where bogus headers can keep nodes in IsInitialBlockDownload. Github-Pull: #9053 Rebased-From: e141beb6a9816b7e1e680fb0a8bae16d42a3e557 --- src/main.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 54eff56f4..5f04c1916 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1751,11 +1751,10 @@ bool IsInitialBlockDownload() return true; if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) return true; - bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge); - if (!state) - latchToFalse.store(true, std::memory_order_relaxed); - return state; + if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) + return true; + latchToFalse.store(true, std::memory_order_relaxed); + return false; } bool fLargeWorkForkFound = false; From 57aec3b0b5993568571c352643abb6f3d79ffdd7 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 11 Dec 2016 21:17:20 +0000 Subject: [PATCH 1196/1223] Add release notes for wallet/mempool rejections. (PR #9302 and #9290) --- doc/release-notes.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index e54f9ac02..0830e0a12 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -42,8 +42,23 @@ but severe issues with the libc++ version on 10.7.x keep it from running reliabl Notable changes =============== -Example item ---------------- +Change to wallet handling of mempool rejection +----------------------------------------------- + +When a newly created transaction failed to enter the mempool due to +the limits on chains of unconfirmed transactions the sending RPC +calls would return an error. The transaction would still be queued +in the wallet and, once some of the parent transactions were +confirmed, broadcast after the software was restarted. + +This behavior has been changed to return success and to reattempt +mempool insertion at the same time transaction rebroadcast is +attempted, avoiding a need for a restart. + +Transactions in the wallet which cannot be accepted into the mempool +can be abandoned with the previously existing abandontransaction RPC +(or in the GUI via a context menu on the transaction). + 0.13.x Change log ================= From 64dfdde0aa7f7ef24e6cbf3c57e6d24efc55367e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 13 Dec 2016 12:37:40 +0100 Subject: [PATCH 1197/1223] Squashed 'src/secp256k1/' changes from 6c527ec..8225239 8225239 Merge #433: Make the libcrypto detection fail the newer API. 12de863 Make the libcrypto detection fail the newer API. 2928420 Merge #427: Remove Schnorr from travis as well 8eecc4a Remove Schnorr from travis as well a8abae7 Merge #310: Add exhaustive test for group functions on a low-order subgroup b4ceedf Add exhaustive test for verification 83836a9 Add exhaustive tests for group arithmetic, signing, and ecmult on a small group 20b8877 Add exhaustive test for group functions on a low-order subgroup 80773a6 Merge #425: Remove Schnorr experiment e06e878 Remove Schnorr experiment 04c8ef3 Merge #407: Modify parameter order of internal functions to match API parameter order 6e06696 Merge #411: Remove guarantees about memcmp-ability 40c8d7e Merge #421: Update scalar_4x64_impl.h a922365 Merge #422: Restructure nonce clearing 3769783 Restructure nonce clearing 0f9e69d Restructure nonce clearing 9d67afa Update scalar_4x64_impl.h 7d15cd7 Merge #413: fix auto-enabled static precompuatation 00c5d2e fix auto-enabled static precompuatation 91219a1 Remove guarantees about memcmp-ability 7a49cac Merge #410: Add string.h include to ecmult_impl 0bbd5d4 Add string.h include to ecmult_impl 353c1bf Fix secp256k1_ge_set_table_gej_var parameter order 541b783 Fix secp256k1_ge_set_all_gej_var parameter order 7d893f4 Fix secp256k1_fe_inv_all_var parameter order c5b32e1 Merge #405: Make secp256k1_fe_sqrt constant time 926836a Make secp256k1_fe_sqrt constant time e2a8e92 Merge #404: Replace 3M + 4S doubling formula with 2M + 5S one 8ec49d8 Add note about 2M + 5S doubling formula 5a91bd7 Merge #400: A couple minor cleanups ac01378 build: add -DSECP256K1_BUILD to benchmark_internal build flags a6c6f99 Remove a bunch of unused stdlib #includes 65285a6 Merge #403: configure: add flag to disable OpenSSL tests a9b2a5d configure: add flag to disable OpenSSL tests b340123 Merge #402: Add support for testing quadratic residues e6e9805 Add function for testing quadratic residue field/group elements. efd953a Add Jacobi symbol test via GMP fa36a0d Merge #401: ecmult_const: unify endomorphism and non-endomorphism skew cases c6191fd ecmult_const: unify endomorphism and non-endomorphism skew cases 0b3e618 Merge #378: .gitignore build-aux cleanup 6042217 Merge #384: JNI: align shared files copyright/comments to bitcoinj's 24ad20f Merge #399: build: verify that the native compiler works for static precomp b3be852 Merge #398: Test whether ECDH and Schnorr are enabled for JNI aa0b1fd build: verify that the native compiler works for static precomp eee808d Test whether ECDH and Schnorr are enabled for JNI 7b0fb18 Merge #366: ARM assembly implementation of field_10x26 inner (rebase of #173) 001f176 ARM assembly implementation of field_10x26 inner 0172be9 Merge #397: Small fixes for sha256 3f8b78e Fix undefs in hash_impl.h 2ab4695 Fix state size in sha256 struct 6875b01 Merge #386: Add some missing `VERIFY_CHECK(ctx != NULL)` 2c52b5d Merge #389: Cast pointers through uintptr_t under JNI 43097a4 Merge #390: Update bitcoin-core GitHub links 31c9c12 Merge #391: JNI: Only call ecdsa_verify if its inputs parsed correctly 1cb2302 Merge #392: Add testcase which hits additional branch in secp256k1_scalar_sqr d2ee340 Merge #388: bench_ecdh: fix call to secp256k1_context_create 093a497 Add testcase which hits additional branch in secp256k1_scalar_sqr a40c701 JNI: Only call ecdsa_verify if its inputs parsed correctly faa2a11 Update bitcoin-core GitHub links 47b9e78 Cast pointers through uintptr_t under JNI f36f9c6 bench_ecdh: fix call to secp256k1_context_create bcc4881 Add some missing `VERIFY_CHECK(ctx != NULL)` for functions that use `ARG_CHECK` 6ceea2c align shared files copyright/comments to bitcoinj's 70141a8 Update .gitignore 7b549b1 Merge #373: build: fix x86_64 asm detection for some compilers bc7c93c Merge #374: Add note about y=0 being possible on one of the sextic twists e457018 Merge #364: JNI rebased 86e2d07 JNI library: cleanup, removed unimplemented code 3093576a JNI library bd2895f Merge pull request #371 e72e93a Add note about y=0 being possible on one of the sextic twists 3f8fdfb build: fix x86_64 asm detection for some compilers e5a9047 [Trivial] Remove double semicolons c18b869 Merge pull request #360 3026daa Merge pull request #302 03d4611 Add sage verification script for the group laws a965937 Merge pull request #361 83221ec Add experimental features to configure 5d4c5a3 Prevent damage_array in the signature test from going out of bounds. 419bf7f Merge pull request #356 03d84a4 Benchmark against OpenSSL verification git-subtree-dir: src/secp256k1 git-subtree-split: 8225239f490f79842a5a3b82ad6cc8aa11d5208e --- .gitignore | 20 +- .travis.yml | 18 +- Makefile.am | 92 +- README.md | 2 +- build-aux/m4/ax_jni_include_dir.m4 | 140 +++ build-aux/m4/bitcoin_secp.m4 | 8 +- configure.ac | 156 ++- include/secp256k1.h | 14 +- include/secp256k1_schnorr.h | 173 ---- libsecp256k1.pc.in | 2 +- sage/group_prover.sage | 322 ++++++ sage/secp256k1.sage | 306 ++++++ sage/weierstrass_prover.sage | 264 +++++ src/asm/field_10x26_arm.s | 919 ++++++++++++++++++ src/bench_ecdh.c | 3 +- src/bench_internal.c | 34 +- src/bench_verify.c | 44 + src/ecdsa_impl.h | 18 + src/ecmult_const_impl.h | 69 +- src/ecmult_gen_impl.h | 2 +- src/ecmult_impl.h | 21 +- src/field.h | 15 +- src/field_10x26_impl.h | 12 +- src/field_5x52_impl.h | 1 - src/field_5x52_int128_impl.h | 4 +- src/field_impl.h | 38 +- src/group.h | 9 +- src/group_impl.h | 112 ++- src/hash.h | 2 +- src/hash_impl.h | 10 +- src/java/org/bitcoin/NativeSecp256k1.java | 440 ++++++++- src/java/org/bitcoin/NativeSecp256k1Test.java | 226 +++++ src/java/org/bitcoin/NativeSecp256k1Util.java | 45 + src/java/org/bitcoin/Secp256k1Context.java | 51 + src/java/org_bitcoin_NativeSecp256k1.c | 378 ++++++- src/java/org_bitcoin_NativeSecp256k1.h | 106 +- src/java/org_bitcoin_Secp256k1Context.c | 15 + src/java/org_bitcoin_Secp256k1Context.h | 22 + src/modules/ecdh/Makefile.am.include | 2 +- src/modules/recovery/Makefile.am.include | 2 +- src/modules/recovery/main_impl.h | 4 +- src/modules/schnorr/Makefile.am.include | 10 - src/modules/schnorr/main_impl.h | 164 ---- src/modules/schnorr/schnorr.h | 20 - src/modules/schnorr/schnorr_impl.h | 207 ---- src/modules/schnorr/tests_impl.h | 175 ---- src/num.h | 6 + src/num_gmp_impl.h | 26 + src/scalar.h | 4 +- src/scalar_4x64_impl.h | 26 +- src/scalar_impl.h | 41 +- src/scalar_low.h | 15 + src/scalar_low_impl.h | 114 +++ src/secp256k1.c | 19 +- src/tests.c | 202 +++- src/tests_exhaustive.c | 329 +++++++ 56 files changed, 4464 insertions(+), 1015 deletions(-) create mode 100644 build-aux/m4/ax_jni_include_dir.m4 delete mode 100644 include/secp256k1_schnorr.h create mode 100644 sage/group_prover.sage create mode 100644 sage/secp256k1.sage create mode 100644 sage/weierstrass_prover.sage create mode 100644 src/asm/field_10x26_arm.s create mode 100644 src/java/org/bitcoin/NativeSecp256k1Test.java create mode 100644 src/java/org/bitcoin/NativeSecp256k1Util.java create mode 100644 src/java/org/bitcoin/Secp256k1Context.java create mode 100644 src/java/org_bitcoin_Secp256k1Context.c create mode 100644 src/java/org_bitcoin_Secp256k1Context.h mode change 100644 => 100755 src/modules/recovery/main_impl.h delete mode 100644 src/modules/schnorr/Makefile.am.include delete mode 100644 src/modules/schnorr/main_impl.h delete mode 100644 src/modules/schnorr/schnorr.h delete mode 100644 src/modules/schnorr/schnorr_impl.h delete mode 100644 src/modules/schnorr/tests_impl.h create mode 100644 src/scalar_low.h create mode 100644 src/scalar_low_impl.h mode change 100644 => 100755 src/secp256k1.c create mode 100644 src/tests_exhaustive.c diff --git a/.gitignore b/.gitignore index e0b7b7a48..87fea161b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ bench_schnorr_verify bench_recover bench_internal tests +exhaustive_tests gen_context *.exe *.so @@ -25,17 +26,24 @@ config.status libtool .deps/ .dirstamp -build-aux/ *.lo *.o *~ src/libsecp256k1-config.h src/libsecp256k1-config.h.in src/ecmult_static_context.h -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 +build-aux/config.guess +build-aux/config.sub +build-aux/depcomp +build-aux/install-sh +build-aux/ltmain.sh +build-aux/m4/libtool.m4 +build-aux/m4/lt~obsolete.m4 +build-aux/m4/ltoptions.m4 +build-aux/m4/ltsugar.m4 +build-aux/m4/ltversion.m4 +build-aux/missing +build-aux/compile +build-aux/test-driver src/stamp-h1 libsecp256k1.pc diff --git a/.travis.yml b/.travis.yml index 4e1e73c39..243952924 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,26 +6,30 @@ addons: compiler: - clang - gcc +cache: + directories: + - src/java/guava/ env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=no RECOVERY=no + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no + - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar matrix: - SCALAR=32bit RECOVERY=yes - - SCALAR=32bit FIELD=32bit ECDH=yes + - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - SCALAR=64bit - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes - - FIELD=64bit ENDOMORPHISM=yes ECDH=yes + - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit SCHNORR=yes - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes + - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes - BIGNUM=no STATICPRECOMPUTATION=no - BUILD=distcheck - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC - EXTRAFLAGS=CFLAGS=-O0 + - BUILD=check-java ECDH=yes EXPERIMENTAL=yes matrix: fast_finish: true include: @@ -55,9 +59,11 @@ matrix: packages: - gcc-multilib - libgmp-dev:i386 +before_install: mkdir -p `dirname $GUAVA_JAR` +install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi before_script: ./autogen.sh script: - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-schnorr=$SCHNORR --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD + - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD os: linux diff --git a/Makefile.am b/Makefile.am index 7772a4e9d..e5657f7f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,22 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 lib_LTLIBRARIES = libsecp256k1.la +if USE_JNI +JNI_LIB = libsecp256k1_jni.la +noinst_LTLIBRARIES = $(JNI_LIB) +else +JNI_LIB = +endif include_HEADERS = include/secp256k1.h noinst_HEADERS = noinst_HEADERS += src/scalar.h noinst_HEADERS += src/scalar_4x64.h noinst_HEADERS += src/scalar_8x32.h +noinst_HEADERS += src/scalar_low.h noinst_HEADERS += src/scalar_impl.h noinst_HEADERS += src/scalar_4x64_impl.h noinst_HEADERS += src/scalar_8x32_impl.h +noinst_HEADERS += src/scalar_low_impl.h noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h noinst_HEADERS += src/num_gmp.h @@ -32,6 +40,7 @@ noinst_HEADERS += src/field_5x52_impl.h noinst_HEADERS += src/field_5x52_int128_impl.h noinst_HEADERS += src/field_5x52_asm_impl.h noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h +noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h noinst_HEADERS += src/util.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h @@ -45,33 +54,88 @@ noinst_HEADERS += contrib/lax_der_parsing.c noinst_HEADERS += contrib/lax_der_privatekey_parsing.h noinst_HEADERS += contrib/lax_der_privatekey_parsing.c +if USE_EXTERNAL_ASM +COMMON_LIB = libsecp256k1_common.la +noinst_LTLIBRARIES = $(COMMON_LIB) +else +COMMON_LIB = +endif + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc -libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(SECP_LIBS) +if USE_EXTERNAL_ASM +if USE_ASM_ARM +libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s +endif +endif +libsecp256k1_la_SOURCES = src/secp256k1.c +libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) +libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) + +libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c +libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) noinst_PROGRAMS = if USE_BENCHMARK noinst_PROGRAMS += bench_verify bench_sign bench_internal bench_verify_SOURCES = src/bench_verify.c -bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_sign_SOURCES = src/bench_sign.c -bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_internal_SOURCES = src/bench_internal.c -bench_internal_LDADD = $(SECP_LIBS) -bench_internal_CPPFLAGS = $(SECP_INCLUDES) +bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) +bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) endif +TESTS = if USE_TESTS noinst_PROGRAMS += tests tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DVERIFY -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) -tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) +tests_CPPFLAGS = -DSECP256K1_BUILD -DVERIFY -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) tests_LDFLAGS = -static -TESTS = tests +TESTS += tests +endif + +if USE_EXHAUSTIVE_TESTS +noinst_PROGRAMS += exhaustive_tests +exhaustive_tests_SOURCES = src/tests_exhaustive.c +exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -DVERIFY -I$(top_srcdir)/src $(SECP_INCLUDES) +exhaustive_tests_LDADD = $(SECP_LIBS) +exhaustive_tests_LDFLAGS = -static +TESTS += exhaustive_tests +endif + +JAVAROOT=src/java +JAVAORG=org/bitcoin +JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar +CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) +JAVA_FILES= \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ + $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java + +if USE_JNI + +$(JAVA_GUAVA): + @echo Guava is missing. Fetch it via: \ + wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) + @false + +.stamp-java: $(JAVA_FILES) + @echo Compiling $^ + $(AM_V_at)$(CLASSPATH_ENV) javac $^ + @touch $@ + +if USE_TESTS + +check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java + $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test + +endif endif if USE_ECMULT_STATIC_PRECOMPUTATION @@ -93,19 +157,15 @@ $(bench_internal_OBJECTS): src/ecmult_static_context.h src/ecmult_static_context.h: $(gen_context_BIN) ./$(gen_context_BIN) -CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h +CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java endif -EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h +EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) if ENABLE_MODULE_ECDH include src/modules/ecdh/Makefile.am.include endif -if ENABLE_MODULE_SCHNORR -include src/modules/schnorr/Makefile.am.include -endif - if ENABLE_MODULE_RECOVERY include src/modules/recovery/Makefile.am.include endif diff --git a/README.md b/README.md index 6095db422..8cd344ea8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ libsecp256k1 ============ -[![Build Status](https://travis-ci.org/bitcoin/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin/secp256k1) +[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) Optimized C library for EC operations on curve secp256k1. diff --git a/build-aux/m4/ax_jni_include_dir.m4 b/build-aux/m4/ax_jni_include_dir.m4 new file mode 100644 index 000000000..1fc362761 --- /dev/null +++ b/build-aux/m4/ax_jni_include_dir.m4 @@ -0,0 +1,140 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_JNI_INCLUDE_DIR +# +# DESCRIPTION +# +# AX_JNI_INCLUDE_DIR finds include directories needed for compiling +# programs using the JNI interface. +# +# JNI include directories are usually in the Java distribution. This is +# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in +# that order. When this macro completes, a list of directories is left in +# the variable JNI_INCLUDE_DIRS. +# +# Example usage follows: +# +# AX_JNI_INCLUDE_DIR +# +# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS +# do +# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" +# done +# +# If you want to force a specific compiler: +# +# - at the configure.in level, set JAVAC=yourcompiler before calling +# AX_JNI_INCLUDE_DIR +# +# - at the configure level, setenv JAVAC +# +# Note: This macro can work with the autoconf M4 macros for Java programs. +# This particular macro is not part of the original set of macros. +# +# LICENSE +# +# Copyright (c) 2008 Don Anderson +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + +AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) +AC_DEFUN([AX_JNI_INCLUDE_DIR],[ + +JNI_INCLUDE_DIRS="" + +if test "x$JAVA_HOME" != x; then + _JTOPDIR="$JAVA_HOME" +else + if test "x$JAVAC" = x; then + JAVAC=javac + fi + AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) + if test "x$_ACJNI_JAVAC" = xno; then + AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) + fi + _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") + _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` +fi + +case "$host_os" in + darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + _JINC="$_JTOPDIR/Headers";; + *) _JINC="$_JTOPDIR/include";; +esac +_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) +_AS_ECHO_LOG([_JINC=$_JINC]) + +# On Mac OS X 10.6.4, jni.h is a symlink: +# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h +# -> ../../CurrentJDK/Headers/jni.h. + +AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, +[ +if test -f "$_JINC/jni.h"; then + ac_cv_jni_header_path="$_JINC" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" +else + _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + if test -f "$_JTOPDIR/include/jni.h"; then + ac_cv_jni_header_path="$_JTOPDIR/include" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" + else + ac_cv_jni_header_path=none + fi +fi +]) + + + +# get the likely subdirectories for system specific java includes +case "$host_os" in +bsdi*) _JNI_INC_SUBDIRS="bsdos";; +darwin*) _JNI_INC_SUBDIRS="darwin";; +freebsd*) _JNI_INC_SUBDIRS="freebsd";; +linux*) _JNI_INC_SUBDIRS="linux genunix";; +osf*) _JNI_INC_SUBDIRS="alpha";; +solaris*) _JNI_INC_SUBDIRS="solaris";; +mingw*) _JNI_INC_SUBDIRS="win32";; +cygwin*) _JNI_INC_SUBDIRS="win32";; +*) _JNI_INC_SUBDIRS="genunix";; +esac + +if test "x$ac_cv_jni_header_path" != "xnone"; then + # add any subdirectories that are present + for JINCSUBDIR in $_JNI_INC_SUBDIRS + do + if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" + fi + done +fi +]) + +# _ACJNI_FOLLOW_SYMLINKS +# Follows symbolic links on , +# finally setting variable _ACJNI_FOLLOWED +# ---------------------------------------- +AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ +# find the include directory relative to the javac executable +_cur="$1" +while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do + AC_MSG_CHECKING([symlink for $_cur]) + _slink=`ls -ld "$_cur" | sed 's/.* -> //'` + case "$_slink" in + /*) _cur="$_slink";; + # 'X' avoids triggering unwanted echo options. + *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; + esac + AC_MSG_RESULT([$_cur]) +done +_ACJNI_FOLLOWED="$_cur" +])# _ACJNI diff --git a/build-aux/m4/bitcoin_secp.m4 b/build-aux/m4/bitcoin_secp.m4 index d41bbb648..b74acb8c1 100644 --- a/build-aux/m4/bitcoin_secp.m4 +++ b/build-aux/m4/bitcoin_secp.m4 @@ -3,13 +3,13 @@ AC_DEFUN([SECP_INT128_CHECK],[ has_int128=$ac_cv_type___int128 ]) -dnl +dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. AC_DEFUN([SECP_64BIT_ASM_CHECK],[ AC_MSG_CHECKING(for x86_64 assembly availability) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ uint64_t a = 11, tmp; - __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); + __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) AC_MSG_RESULT([$has_64bit_asm]) ]) @@ -46,6 +46,10 @@ if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); ECDSA_verify(0, NULL, 0, NULL, 0, eckey); EC_KEY_free(eckey); + ECDSA_SIG *sig_openssl; + sig_openssl = ECDSA_SIG_new(); + (void)sig_openssl->r; + ECDSA_SIG_free(sig_openssl); ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) AC_MSG_RESULT([$has_openssl_ec]) fi diff --git a/configure.ac b/configure.ac index 786d8dcfb..ec50ffe3a 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ AC_PROG_CC_C89 if test x"$ac_cv_prog_cc_c89" = x"no"; then AC_MSG_ERROR([c89 compiler support required]) fi +AM_PROG_AS case $host_os in *darwin*) @@ -93,31 +94,46 @@ AC_ARG_ENABLE(tests, [use_tests=$enableval], [use_tests=yes]) +AC_ARG_ENABLE(openssl_tests, + AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]), + [enable_openssl_tests=$enableval], + [enable_openssl_tests=auto]) + +AC_ARG_ENABLE(experimental, + AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]), + [use_experimental=$enableval], + [use_experimental=no]) + +AC_ARG_ENABLE(exhaustive_tests, + AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]), + [use_exhaustive_tests=$enableval], + [use_exhaustive_tests=yes]) + AC_ARG_ENABLE(endomorphism, AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), [use_endomorphism=$enableval], [use_endomorphism=no]) - + AC_ARG_ENABLE(ecmult_static_precomputation, AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), [use_ecmult_static_precomputation=$enableval], - [use_ecmult_static_precomputation=yes]) + [use_ecmult_static_precomputation=auto]) AC_ARG_ENABLE(module_ecdh, - AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (default is no)]), + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (experimental)]), [enable_module_ecdh=$enableval], [enable_module_ecdh=no]) -AC_ARG_ENABLE(module_schnorr, - AS_HELP_STRING([--enable-module-schnorr],[enable Schnorr signature module (default is no)]), - [enable_module_schnorr=$enableval], - [enable_module_schnorr=no]) - AC_ARG_ENABLE(module_recovery, AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), [enable_module_recovery=$enableval], [enable_module_recovery=no]) +AC_ARG_ENABLE(jni, + AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is auto)]), + [use_jni=$enableval], + [use_jni=auto]) + AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) @@ -127,8 +143,8 @@ AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], [Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) -AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto] -[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto]) +AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto] +[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto]) AC_CHECK_TYPES([__int128]) @@ -138,6 +154,34 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], [ AC_MSG_RESULT([no]) ]) +if test x"$use_ecmult_static_precomputation" != x"no"; then + save_cross_compiling=$cross_compiling + cross_compiling=no + TEMP_CC="$CC" + CC="$CC_FOR_BUILD" + AC_MSG_CHECKING([native compiler: ${CC_FOR_BUILD}]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([], [return 0])], + [working_native_cc=yes], + [working_native_cc=no],[dnl]) + CC="$TEMP_CC" + cross_compiling=$save_cross_compiling + + if test x"$working_native_cc" = x"no"; then + set_precomp=no + if test x"$use_ecmult_static_precomputation" = x"yes"; then + AC_MSG_ERROR([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + else + AC_MSG_RESULT([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + fi + else + AC_MSG_RESULT([ok]) + set_precomp=yes + fi +else + set_precomp=no +fi + if test x"$req_asm" = x"auto"; then SECP_64BIT_ASM_CHECK if test x"$has_64bit_asm" = x"yes"; then @@ -155,6 +199,8 @@ else AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) fi ;; + arm) + ;; no) ;; *) @@ -247,10 +293,15 @@ else fi # select assembly optimization +use_external_asm=no + case $set_asm in x86_64) AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) ;; +arm) + use_external_asm=yes + ;; no) ;; *) @@ -305,16 +356,48 @@ esac if test x"$use_tests" = x"yes"; then SECP_OPENSSL_CHECK if test x"$has_openssl_ec" = x"yes"; then - AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) - SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" - SECP_TEST_LIBS="$CRYPTO_LIBS" + if test x"$enable_openssl_tests" != x"no"; then + AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) + SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" + SECP_TEST_LIBS="$CRYPTO_LIBS" - case $host in - *mingw*) - SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" - ;; - esac + case $host in + *mingw*) + SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" + ;; + esac + fi + else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available]) + fi + fi +else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled]) + fi +fi +if test x"$use_jni" != x"no"; then + AX_JNI_INCLUDE_DIR + have_jni_dependencies=yes + if test x"$enable_module_ecdh" = x"no"; then + have_jni_dependencies=no + fi + if test "x$JNI_INCLUDE_DIRS" = "x"; then + have_jni_dependencies=no + fi + if test "x$have_jni_dependencies" = "xno"; then + if test x"$use_jni" = x"yes"; then + AC_MSG_ERROR([jni support explicitly requested but headers/dependencies were not found. Enable ECDH and try again.]) + fi + AC_MSG_WARN([jni headers/dependencies not found. jni support disabled]) + use_jni=no + else + use_jni=yes + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do + JNI_INCLUDES="$JNI_INCLUDES -I$JNI_INCLUDE_DIR" + done fi fi @@ -327,7 +410,7 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi -if test x"$use_ecmult_static_precomputation" = x"yes"; then +if test x"$set_precomp" = x"yes"; then AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) fi @@ -335,38 +418,57 @@ if test x"$enable_module_ecdh" = x"yes"; then AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) fi -if test x"$enable_module_schnorr" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_SCHNORR, 1, [Define this symbol to enable the Schnorr signature module]) -fi - if test x"$enable_module_recovery" = x"yes"; then AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) fi AC_C_BIGENDIAN() +if test x"$use_external_asm" = x"yes"; then + AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +fi + +AC_MSG_NOTICE([Using static precomputation: $set_precomp]) AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) - -AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr]) AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) +AC_MSG_NOTICE([Using jni: $use_jni]) + +if test x"$enable_experimental" = x"yes"; then + AC_MSG_NOTICE([******]) + AC_MSG_NOTICE([WARNING: experimental build]) + AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) + AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) + AC_MSG_NOTICE([******]) +else + if test x"$enable_module_ecdh" = x"yes"; then + AC_MSG_ERROR([ECDH module is experimental. Use --enable-experimental to allow.]) + fi + if test x"$set_asm" = x"arm"; then + AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) + fi +fi AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) +AC_SUBST(JNI_INCLUDES) AC_SUBST(SECP_INCLUDES) AC_SUBST(SECP_LIBS) AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) +AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$use_exhaustive_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) -AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"]) +AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$set_precomp" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) -AM_CONDITIONAL([ENABLE_MODULE_SCHNORR], [test x"$enable_module_schnorr" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) +AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"]) +AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) +AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/include/secp256k1.h b/include/secp256k1.h index 7145dbcc5..f268e309d 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -47,11 +47,8 @@ typedef struct secp256k1_context_struct secp256k1_context; * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. - * - * Furthermore, it is guaranteed that identical public keys (ignoring - * compression) will have identical representation, so they can be memcmp'ed. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. */ typedef struct { unsigned char data[64]; @@ -62,12 +59,9 @@ typedef struct { * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * the secp256k1_ecdsa_signature_serialize_* and + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use the secp256k1_ecdsa_signature_serialize_* and * secp256k1_ecdsa_signature_serialize_* functions. - * - * Furthermore, it is guaranteed to identical signatures will have identical - * representation, so they can be memcmp'ed. */ typedef struct { unsigned char data[64]; diff --git a/include/secp256k1_schnorr.h b/include/secp256k1_schnorr.h deleted file mode 100644 index dc32fec1e..000000000 --- a/include/secp256k1_schnorr.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef _SECP256K1_SCHNORR_ -# define _SECP256K1_SCHNORR_ - -# include "secp256k1.h" - -# ifdef __cplusplus -extern "C" { -# endif - -/** Create a signature using a custom EC-Schnorr-SHA256 construction. It - * produces non-malleable 64-byte signatures which support public key recovery - * batch validation, and multiparty signing. - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was - * invalid. - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: sig64: pointer to a 64-byte array where the signature will be - * placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - */ -SECP256K1_API int secp256k1_schnorr_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Verify a signature created by secp256k1_schnorr_sign. - * Returns: 1: correct signature - * 0: incorrect signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig64: the 64-byte signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: the public key to verify with (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( - const secp256k1_context* ctx, - const unsigned char *sig64, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Recover an EC public key from a Schnorr signature created using - * secp256k1_schnorr_sign. - * Returns: 1: public key successfully recovered (which guarantees a correct - * signature). - * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for - * verification (cannot be NULL) - * Out: pubkey: pointer to a pubkey to set to the recovered public key - * (cannot be NULL). - * In: sig64: signature as 64 byte array (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - */ -SECP256K1_API int secp256k1_schnorr_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *sig64, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Generate a nonce pair deterministically for use with - * secp256k1_schnorr_partial_sign. - * Returns: 1: valid nonce pair was generated. - * 0: otherwise (nonce generation function failed) - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: pubnonce: public side of the nonce (cannot be NULL) - * privnonce32: private side of the nonce (32 byte) (cannot be NULL) - * In: msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - * sec32: the 32-byte private key (cannot be NULL) - * noncefp: pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * noncedata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - * - * Do not use the output as a private/public key pair for signing/validation. - */ -SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( - const secp256k1_context* ctx, - secp256k1_pubkey *pubnonce, - unsigned char *privnonce32, - const unsigned char *msg32, - const unsigned char *sec32, - secp256k1_nonce_function noncefp, - const void* noncedata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Produce a partial Schnorr signature, which can be combined using - * secp256k1_schnorr_partial_combine, to end up with a full signature that is - * verifiable using secp256k1_schnorr_verify. - * Returns: 1: signature created successfully. - * 0: no valid signature exists with this combination of keys, nonces - * and message (chance around 1 in 2^128) - * -1: invalid private key, nonce, or public nonces. - * Args: ctx: pointer to context object, initialized for signing (cannot - * be NULL) - * Out: sig64: pointer to 64-byte array to put partial signature in - * In: msg32: pointer to 32-byte message to sign - * sec32: pointer to 32-byte private key - * pubnonce_others: pointer to pubkey containing the sum of the other's - * nonces (see secp256k1_ec_pubkey_combine) - * secnonce32: pointer to 32-byte array containing our nonce - * - * The intended procedure for creating a multiparty signature is: - * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of - * private/public nonces. - * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be - * considered secret). - * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an - * Rall[i] = sum(R[0..i-1,i+1..n]). - * - All signers produce a partial signature using - * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces - * Rall[i]. - * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using - * secp256k1_schnorr_partial_combine, to obtain a full signature. - * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the - * signers' public keys (sum(Q[0..n])). - * - * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine - * function take their arguments in any order, and it is possible to - * pre-combine several inputs already with one call, and add more inputs later - * by calling the function again (they are commutative and associative). - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *sec32, - const secp256k1_pubkey *pubnonce_others, - const unsigned char *secnonce32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); - -/** Combine multiple Schnorr partial signatures. - * Returns: 1: the passed signatures were successfully combined. - * 0: the resulting signature is not valid (chance of 1 in 2^256) - * -1: some inputs were invalid, or the signatures were not created - * using the same set of nonces - * Args: ctx: pointer to a context object - * Out: sig64: pointer to a 64-byte array to place the combined signature - * (cannot be NULL) - * In: sig64sin: pointer to an array of n pointers to 64-byte input - * signatures - * n: the number of signatures to combine (at least 1) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char * const * sig64sin, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/libsecp256k1.pc.in b/libsecp256k1.pc.in index 1c72dd000..a0d006f11 100644 --- a/libsecp256k1.pc.in +++ b/libsecp256k1.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: libsecp256k1 Description: Optimized C library for EC operations on curve secp256k1 -URL: https://github.com/bitcoin/secp256k1 +URL: https://github.com/bitcoin-core/secp256k1 Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs.private: @SECP_LIBS@ diff --git a/sage/group_prover.sage b/sage/group_prover.sage new file mode 100644 index 000000000..ab580c5b2 --- /dev/null +++ b/sage/group_prover.sage @@ -0,0 +1,322 @@ +# This code supports verifying group implementations which have branches +# or conditional statements (like cmovs), by allowing each execution path +# to independently set assumptions on input or intermediary variables. +# +# The general approach is: +# * A constraint is a tuple of two sets of of symbolic expressions: +# the first of which are required to evaluate to zero, the second of which +# are required to evaluate to nonzero. +# - A constraint is said to be conflicting if any of its nonzero expressions +# is in the ideal with basis the zero expressions (in other words: when the +# zero expressions imply that one of the nonzero expressions are zero). +# * There is a list of laws that describe the intended behaviour, including +# laws for addition and doubling. Each law is called with the symbolic point +# coordinates as arguments, and returns: +# - A constraint describing the assumptions under which it is applicable, +# called "assumeLaw" +# - A constraint describing the requirements of the law, called "require" +# * Implementations are transliterated into functions that operate as well on +# algebraic input points, and are called once per combination of branches +# exectured. Each execution returns: +# - A constraint describing the assumptions this implementation requires +# (such as Z1=1), called "assumeFormula" +# - A constraint describing the assumptions this specific branch requires, +# but which is by construction guaranteed to cover the entire space by +# merging the results from all branches, called "assumeBranch" +# - The result of the computation +# * All combinations of laws with implementation branches are tried, and: +# - If the combination of assumeLaw, assumeFormula, and assumeBranch results +# in a conflict, it means this law does not apply to this branch, and it is +# skipped. +# - For others, we try to prove the require constraints hold, assuming the +# information in assumeLaw + assumeFormula + assumeBranch, and if this does +# not succeed, we fail. +# + To prove an expression is zero, we check whether it belongs to the +# ideal with the assumed zero expressions as basis. This test is exact. +# + To prove an expression is nonzero, we check whether each of its +# factors is contained in the set of nonzero assumptions' factors. +# This test is not exact, so various combinations of original and +# reduced expressions' factors are tried. +# - If we succeed, we print out the assumptions from assumeFormula that +# weren't implied by assumeLaw already. Those from assumeBranch are skipped, +# as we assume that all constraints in it are complementary with each other. +# +# Based on the sage verification scripts used in the Explicit-Formulas Database +# by Tanja Lange and others, see http://hyperelliptic.org/EFD + +class fastfrac: + """Fractions over rings.""" + + def __init__(self,R,top,bot=1): + """Construct a fractional, given a ring, a numerator, and denominator.""" + self.R = R + if parent(top) == ZZ or parent(top) == R: + self.top = R(top) + self.bot = R(bot) + elif top.__class__ == fastfrac: + self.top = top.top + self.bot = top.bot * bot + else: + self.top = R(numerator(top)) + self.bot = R(denominator(top)) * bot + + def iszero(self,I): + """Return whether this fraction is zero given an ideal.""" + return self.top in I and self.bot not in I + + def reduce(self,assumeZero): + zero = self.R.ideal(map(numerator, assumeZero)) + return fastfrac(self.R, zero.reduce(self.top)) / fastfrac(self.R, zero.reduce(self.bot)) + + def __add__(self,other): + """Add two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top + self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot + self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __sub__(self,other): + """Subtract two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top - self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot - self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __neg__(self): + """Return the negation of a fraction.""" + return fastfrac(self.R,-self.top,self.bot) + + def __mul__(self,other): + """Multiply two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.top,self.bot * other.bot) + return NotImplemented + + def __rmul__(self,other): + """Multiply something else with a fraction.""" + return self.__mul__(other) + + def __div__(self,other): + """Divide two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top,self.bot * other) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot,self.bot * other.top) + return NotImplemented + + def __pow__(self,other): + """Compute a power of a fraction.""" + if parent(other) == ZZ: + if other < 0: + # Negative powers require flipping top and bottom + return fastfrac(self.R,self.bot ^ (-other),self.top ^ (-other)) + else: + return fastfrac(self.R,self.top ^ other,self.bot ^ other) + return NotImplemented + + def __str__(self): + return "fastfrac((" + str(self.top) + ") / (" + str(self.bot) + "))" + def __repr__(self): + return "%s" % self + + def numerator(self): + return self.top + +class constraints: + """A set of constraints, consisting of zero and nonzero expressions. + + Constraints can either be used to express knowledge or a requirement. + + Both the fields zero and nonzero are maps from expressions to description + strings. The expressions that are the keys in zero are required to be zero, + and the expressions that are the keys in nonzero are required to be nonzero. + + Note that (a != 0) and (b != 0) is the same as (a*b != 0), so all keys in + nonzero could be multiplied into a single key. This is often much less + efficient to work with though, so we keep them separate inside the + constraints. This allows higher-level code to do fast checks on the individual + nonzero elements, or combine them if needed for stronger checks. + + We can't multiply the different zero elements, as it would suffice for one of + the factors to be zero, instead of all of them. Instead, the zero elements are + typically combined into an ideal first. + """ + + def __init__(self, **kwargs): + if 'zero' in kwargs: + self.zero = dict(kwargs['zero']) + else: + self.zero = dict() + if 'nonzero' in kwargs: + self.nonzero = dict(kwargs['nonzero']) + else: + self.nonzero = dict() + + def negate(self): + return constraints(zero=self.nonzero, nonzero=self.zero) + + def __add__(self, other): + zero = self.zero.copy() + zero.update(other.zero) + nonzero = self.nonzero.copy() + nonzero.update(other.nonzero) + return constraints(zero=zero, nonzero=nonzero) + + def __str__(self): + return "constraints(zero=%s,nonzero=%s)" % (self.zero, self.nonzero) + + def __repr__(self): + return "%s" % self + + +def conflicts(R, con): + """Check whether any of the passed non-zero assumptions is implied by the zero assumptions""" + zero = R.ideal(map(numerator, con.zero)) + if 1 in zero: + return True + # First a cheap check whether any of the individual nonzero terms conflict on + # their own. + for nonzero in con.nonzero: + if nonzero.iszero(zero): + return True + # It can be the case that entries in the nonzero set do not individually + # conflict with the zero set, but their combination does. For example, knowing + # that either x or y is zero is equivalent to having x*y in the zero set. + # Having x or y individually in the nonzero set is not a conflict, but both + # simultaneously is, so that is the right thing to check for. + if reduce(lambda a,b: a * b, con.nonzero, fastfrac(R, 1)).iszero(zero): + return True + return False + + +def get_nonzero_set(R, assume): + """Calculate a simple set of nonzero expressions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = set() + for nz in map(numerator, assume.nonzero): + for (f,n) in nz.factor(): + nonzero.add(f) + rnz = zero.reduce(nz) + for (f,n) in rnz.factor(): + nonzero.add(f) + return nonzero + + +def prove_nonzero(R, exprs, assume): + """Check whether an expression is provably nonzero, given assumptions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = get_nonzero_set(R, assume) + expl = set() + ok = True + for expr in exprs: + if numerator(expr) in zero: + return (False, [exprs[expr]]) + allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1) + for (f, n) in allexprs.factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for (f, n) in zero.reduce(numerator(allexprs)).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in numerator(expr).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in zero.reduce(numerator(expr)).factor(): + if f not in nonzero: + expl.add(exprs[expr]) + if expl: + return (False, list(expl)) + else: + return (True, None) + + +def prove_zero(R, exprs, assume): + """Check whether all of the passed expressions are provably zero, given assumptions""" + r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume) + if not r: + return (False, map(lambda x: "Possibly zero denominator: %s" % x, e)) + zero = R.ideal(map(numerator, assume.zero)) + nonzero = prod(x for x in assume.nonzero) + expl = [] + for expr in exprs: + if not expr.iszero(zero): + expl.append(exprs[expr]) + if not expl: + return (True, None) + return (False, expl) + + +def describe_extra(R, assume, assumeExtra): + """Describe what assumptions are added, given existing assumptions""" + zerox = assume.zero.copy() + zerox.update(assumeExtra.zero) + zero = R.ideal(map(numerator, assume.zero)) + zeroextra = R.ideal(map(numerator, zerox)) + nonzero = get_nonzero_set(R, assume) + ret = set() + # Iterate over the extra zero expressions + for base in assumeExtra.zero: + if base not in zero: + add = [] + for (f, n) in numerator(base).factor(): + if f not in nonzero: + add += ["%s" % f] + if add: + ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base]) + # Iterate over the extra nonzero expressions + for nz in assumeExtra.nonzero: + nzr = zeroextra.reduce(numerator(nz)) + if nzr not in zeroextra: + for (f,n) in nzr.factor(): + if zeroextra.reduce(f) not in nonzero: + ret.add("%s != 0" % zeroextra.reduce(f)) + return ", ".join(x for x in ret) + + +def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require): + """Check a set of zero and nonzero requirements, given a set of zero and nonzero assumptions""" + assume = assumeLaw + assumeAssert + assumeBranch + + if conflicts(R, assume): + # This formula does not apply + return None + + describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert) + + ok, msg = prove_zero(R, require.zero, assume) + if not ok: + return "FAIL, %s fails (assuming %s)" % (str(msg), describe) + + res, expl = prove_nonzero(R, require.nonzero, assume) + if not res: + return "FAIL, %s fails (assuming %s)" % (str(expl), describe) + + if describe != "": + return "OK (assuming %s)" % describe + else: + return "OK" + + +def concrete_verify(c): + for k in c.zero: + if k != 0: + return (False, c.zero[k]) + for k in c.nonzero: + if k == 0: + return (False, c.nonzero[k]) + return (True, None) diff --git a/sage/secp256k1.sage b/sage/secp256k1.sage new file mode 100644 index 000000000..a97e732f7 --- /dev/null +++ b/sage/secp256k1.sage @@ -0,0 +1,306 @@ +# Test libsecp256k1' group operation implementations using prover.sage + +import sys + +load("group_prover.sage") +load("weierstrass_prover.sage") + +def formula_secp256k1_gej_double_var(a): + """libsecp256k1's secp256k1_gej_double_var, used by various addition functions""" + rz = a.Z * a.Y + rz = rz * 2 + t1 = a.X^2 + t1 = t1 * 3 + t2 = t1^2 + t3 = a.Y^2 + t3 = t3 * 2 + t4 = t3^2 + t4 = t4 * 2 + t3 = t3 * a.X + rx = t3 + rx = rx * 4 + rx = -rx + rx = rx + t2 + t2 = -t2 + t3 = t3 * 6 + t3 = t3 + t2 + ry = t1 * t3 + t2 = -t4 + ry = ry + t2 + return jacobianpoint(rx, ry, rz) + +def formula_secp256k1_gej_add_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_var""" + if branch == 0: + return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z22 = b.Z^2 + z12 = a.Z^2 + u1 = a.X * z22 + u2 = b.X * z12 + s1 = a.Y * z22 + s1 = s1 * b.Z + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r) + if branch == 3: + return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h2 * h + h = h * b.Z + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge_var, which assume bz==1""" + if branch == 0: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z12 = a.Z^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if (branch == 2): + r = formula_secp256k1_gej_double_var(a) + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if (branch == 3): + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_zinv_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_zinv_var""" + bzinv = b.Z^(-1) + if branch == 0: + return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a) + if branch == 1: + bzinv2 = bzinv^2 + bzinv3 = bzinv2 * bzinv + rx = b.X * bzinv2 + ry = b.Y * bzinv3 + rz = 1 + return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz)) + azz = a.Z * bzinv + z12 = azz^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * azz + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if branch == 3: + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z + rz = rz * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge""" + zeroes = {} + nonzeroes = {} + a_infinity = False + if (branch & 4) != 0: + nonzeroes.update({a.Infinity : 'a_infinite'}) + a_infinity = True + else: + zeroes.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + rr = t^2 + m_alt = -u2 + tt = u1 * m_alt + rr = rr + tt + degenerate = (branch & 3) == 3 + if (branch & 1) != 0: + zeroes.update({m : 'm_zero'}) + else: + nonzeroes.update({m : 'm_nonzero'}) + if (branch & 2) != 0: + zeroes.update({rr : 'rr_zero'}) + else: + nonzeroes.update({rr : 'rr_nonzero'}) + rr_alt = s1 + rr_alt = rr_alt * 2 + m_alt = m_alt + u1 + if not degenerate: + rr_alt = rr + m_alt = m + n = m_alt^2 + q = n * t + n = n^2 + if degenerate: + n = m + t = rr_alt^2 + rz = a.Z * m_alt + infinity = False + if (branch & 8) != 0: + if not a_infinity: + infinity = True + zeroes.update({rz : 'r.z=0'}) + else: + nonzeroes.update({rz : 'r.z!=0'}) + rz = rz * 2 + q = -q + t = t + q + rx = t + t = t * 2 + t = t + q + t = t * rr_alt + t = t + n + ry = -t + rx = rx * 4 + ry = ry * 4 + if a_infinity: + rx = b.X + ry = b.Y + rz = 1 + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_old(branch, a, b): + """libsecp256k1's old secp256k1_gej_add_ge, which fails when ay+by=0 but ax!=bx""" + a_infinity = (branch & 1) != 0 + zero = {} + nonzero = {} + if a_infinity: + nonzero.update({a.Infinity : 'a_infinite'}) + else: + zero.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + z = a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + n = m^2 + q = n * t + n = n^2 + rr = t^2 + t = u1 * u2 + t = -t + rr = rr + t + t = rr^2 + rz = m * z + infinity = False + if (branch & 2) != 0: + if not a_infinity: + infinity = True + else: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(nonzero={z : 'conflict_a'}, zero={z : 'conflict_b'}), point_at_infinity()) + zero.update({rz : 'r.z=0'}) + else: + nonzero.update({rz : 'r.z!=0'}) + rz = rz * (0 if a_infinity else 2) + rx = t + q = -q + rx = rx + q + q = q * 3 + t = t * 2 + t = t + q + t = t * rr + t = t + n + ry = -t + rx = rx * (0 if a_infinity else 4) + ry = ry * (0 if a_infinity else 4) + t = b.X + t = t * (1 if a_infinity else 0) + rx = rx + t + t = b.Y + t = t * (1 if a_infinity else 0) + ry = ry + t + t = (1 if a_infinity else 0) + rz = rz + t + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz)) + +if __name__ == "__main__": + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old) + + if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive": + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43) diff --git a/sage/weierstrass_prover.sage b/sage/weierstrass_prover.sage new file mode 100644 index 000000000..03ef2ec90 --- /dev/null +++ b/sage/weierstrass_prover.sage @@ -0,0 +1,264 @@ +# Prover implementation for Weierstrass curves of the form +# y^2 = x^3 + A * x + B, specifically with a = 0 and b = 7, with group laws +# operating on affine and Jacobian coordinates, including the point at infinity +# represented by a 4th variable in coordinates. + +load("group_prover.sage") + + +class affinepoint: + def __init__(self, x, y, infinity=0): + self.x = x + self.y = y + self.infinity = infinity + def __str__(self): + return "affinepoint(x=%s,y=%s,inf=%s)" % (self.x, self.y, self.infinity) + + +class jacobianpoint: + def __init__(self, x, y, z, infinity=0): + self.X = x + self.Y = y + self.Z = z + self.Infinity = infinity + def __str__(self): + return "jacobianpoint(X=%s,Y=%s,Z=%s,inf=%s)" % (self.X, self.Y, self.Z, self.Infinity) + + +def point_at_infinity(): + return jacobianpoint(1, 1, 1, 1) + + +def negate(p): + if p.__class__ == affinepoint: + return affinepoint(p.x, -p.y) + if p.__class__ == jacobianpoint: + return jacobianpoint(p.X, -p.Y, p.Z) + assert(False) + + +def on_weierstrass_curve(A, B, p): + """Return a set of zero-expressions for an affine point to be on the curve""" + return constraints(zero={p.x^3 + A*p.x + B - p.y^2: 'on_curve'}) + + +def tangential_to_weierstrass_curve(A, B, p12, p3): + """Return a set of zero-expressions for ((x12,y12),(x3,y3)) to be a line that is tangential to the curve at (x12,y12)""" + return constraints(zero={ + (p12.y - p3.y) * (p12.y * 2) - (p12.x^2 * 3 + A) * (p12.x - p3.x): 'tangential_to_curve' + }) + + +def colinear(p1, p2, p3): + """Return a set of zero-expressions for ((x1,y1),(x2,y2),(x3,y3)) to be collinear""" + return constraints(zero={ + (p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x): 'colinear_1', + (p2.y - p3.y) * (p2.x - p1.x) - (p2.y - p1.y) * (p2.x - p3.x): 'colinear_2', + (p3.y - p1.y) * (p3.x - p2.x) - (p3.y - p2.y) * (p3.x - p1.x): 'colinear_3' + }) + + +def good_affine_point(p): + return constraints(nonzero={p.x : 'nonzero_x', p.y : 'nonzero_y'}) + + +def good_jacobian_point(p): + return constraints(nonzero={p.X : 'nonzero_X', p.Y : 'nonzero_Y', p.Z^6 : 'nonzero_Z'}) + + +def good_point(p): + return constraints(nonzero={p.Z^6 : 'nonzero_X'}) + + +def finite(p, *affine_fns): + con = good_point(p) + constraints(zero={p.Infinity : 'finite_point'}) + if p.Z != 0: + return con + reduce(lambda a, b: a + b, (f(affinepoint(p.X / p.Z^2, p.Y / p.Z^3)) for f in affine_fns), con) + else: + return con + +def infinite(p): + return constraints(nonzero={p.Infinity : 'infinite_point'}) + + +def law_jacobian_weierstrass_add(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian add, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(nonzero={pa.x - pb.x : 'different_x'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + colinear(pa, pb, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_double(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian doubling, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y - pb.y : 'equal_y'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + tangential_to_weierstrass_curve(A, B, pa, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_opposites(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y + pb.y : 'opposite_y'})) + require = infinite(pC) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_a(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pb) + + infinite(pA) + + finite(pB)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pb.x : 'c.x=b.x', pc.y - pb.y : 'c.y=b.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_b(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + infinite(pB) + + finite(pA)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pa.x : 'c.x=a.x', pc.y - pa.y : 'c.y=a.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_ab(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + infinite(pA) + + infinite(pB)) + require = infinite(pC) + return (assumeLaw, require) + + +laws_jacobian_weierstrass = { + 'add': law_jacobian_weierstrass_add, + 'double': law_jacobian_weierstrass_double, + 'add_opposite': law_jacobian_weierstrass_add_opposites, + 'add_infinite_a': law_jacobian_weierstrass_add_infinite_a, + 'add_infinite_b': law_jacobian_weierstrass_add_infinite_b, + 'add_infinite_ab': law_jacobian_weierstrass_add_infinite_ab +} + + +def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field""" + F = Integers(p) + print "Formula %s on Z%i:" % (name, p) + points = [] + for x in xrange(0, p): + for y in xrange(0, p): + point = affinepoint(F(x), F(y)) + r, e = concrete_verify(on_weierstrass_curve(A, B, point)) + if r: + points.append(point) + + for za in xrange(1, p): + for zb in xrange(1, p): + for pa in points: + for pb in points: + for ia in xrange(2): + for ib in xrange(2): + pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia) + pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib) + for branch in xrange(0, branches): + assumeAssert, assumeBranch, pC = formula(branch, pA, pB) + pC.X = F(pC.X) + pC.Y = F(pC.Y) + pC.Z = F(pC.Z) + pC.Infinity = F(pC.Infinity) + r, e = concrete_verify(assumeAssert + assumeBranch) + if r: + match = False + for key in laws_jacobian_weierstrass: + assumeLaw, require = laws_jacobian_weierstrass[key](A, B, pa, pb, pA, pB, pC) + r, e = concrete_verify(assumeLaw) + if r: + if match: + print " multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity) + else: + match = True + r, e = concrete_verify(require) + if not r: + print " failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e) + print + + +def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC): + assumeLaw, require = f(A, B, pa, pb, pA, pB, pC) + return check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require) + +def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve symbolically""" + R. = PolynomialRing(QQ,8,order='invlex') + lift = lambda x: fastfrac(R,x) + ax = lift(ax) + ay = lift(ay) + Az = lift(Az) + bx = lift(bx) + by = lift(by) + Bz = lift(Bz) + Ai = lift(Ai) + Bi = lift(Bi) + + pa = affinepoint(ax, ay, Ai) + pb = affinepoint(bx, by, Bi) + pA = jacobianpoint(ax * Az^2, ay * Az^3, Az, Ai) + pB = jacobianpoint(bx * Bz^2, by * Bz^3, Bz, Bi) + + res = {} + + for key in laws_jacobian_weierstrass: + res[key] = [] + + print ("Formula " + name + ":") + count = 0 + for branch in xrange(branches): + assumeFormula, assumeBranch, pC = formula(branch, pA, pB) + pC.X = lift(pC.X) + pC.Y = lift(pC.Y) + pC.Z = lift(pC.Z) + pC.Infinity = lift(pC.Infinity) + + for key in laws_jacobian_weierstrass: + res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch)) + + for key in res: + print " %s:" % key + val = res[key] + for x in val: + if x[0] is not None: + print " branch %i: %s" % (x[1], x[0]) + + print diff --git a/src/asm/field_10x26_arm.s b/src/asm/field_10x26_arm.s new file mode 100644 index 000000000..5df561f2f --- /dev/null +++ b/src/asm/field_10x26_arm.s @@ -0,0 +1,919 @@ +@ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: +/********************************************************************** + * Copyright (c) 2014 Wladimir J. van der Laan * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ +/* +ARM implementation of field_10x26 inner loops. + +Note: + +- To avoid unnecessary loads and make use of available registers, two + 'passes' have every time been interleaved, with the odd passes accumulating c' and d' + which will be added to c and d respectively in the the even passes + +*/ + + .syntax unified + .arch armv7-a + @ eabi attributes - see readelf -A + .eabi_attribute 8, 1 @ Tag_ARM_ISA_use = yes + .eabi_attribute 9, 0 @ Tag_Thumb_ISA_use = no + .eabi_attribute 10, 0 @ Tag_FP_arch = none + .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte + .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP + .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed + .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 + .text + + @ Field constants + .set field_R0, 0x3d10 + .set field_R1, 0x400 + .set field_not_M, 0xfc000000 @ ~M = ~0x3ffffff + + .align 2 + .global secp256k1_fe_mul_inner + .type secp256k1_fe_mul_inner, %function + @ Arguments: + @ r0 r Restrict: can overlap with a, not with b + @ r1 a + @ r2 b + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_mul_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r7,r8 scratch + r1 a (pointer) + r2 b (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + + /* A - interleaved with B */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #9*4] @ b[9] + ldr r0, [r1, #1*4] @ a[1] + umull r5, r6, r7, r8 @ d = a[0] * b[9] + ldr r14, [r2, #8*4] @ b[8] + umull r9, r10, r0, r8 @ d' = a[1] * b[9] + ldr r7, [r1, #2*4] @ a[2] + umlal r5, r6, r0, r14 @ d += a[1] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r14 @ d' += a[2] * b[8] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r8 @ d += a[2] * b[7] + ldr r14, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r8 @ d' += a[3] * b[7] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r14 @ d += a[3] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r14 @ d' += a[4] * b[6] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r8 @ d += a[4] * b[5] + ldr r14, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r8 @ d' += a[5] * b[5] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r14 @ d += a[5] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r14 @ d' += a[6] * b[4] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[3] + ldr r14, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r8 @ d' += a[7] * b[3] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[7] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r9, r10, r7, r14 @ d' += a[8] * b[2] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r8 @ d += a[8] * b[1] + ldr r14, [r2, #0*4] @ b[0] + umlal r9, r10, r0, r8 @ d' += a[9] * b[1] + ldr r7, [r1, #0*4] @ a[0] + umlal r5, r6, r0, r14 @ d += a[9] * b[0] + @ r7,r14 used in B + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 4*9] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + umull r3, r4, r7, r14 @ c = a[0] * b[0] + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C - interleaved with D */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #2*4] @ b[2] + ldr r14, [r2, #1*4] @ b[1] + umull r11, r12, r7, r8 @ c' = a[0] * b[2] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[1] * b[1] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[2] * b[0] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r14 @ d += a[2] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[3] * b[9] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r8 @ d += a[3] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[4] * b[8] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r14 @ d += a[4] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[5] * b[7] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r8 @ d += a[5] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r8 @ d' += a[6] * b[6] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r14 @ d' += a[7] * b[5] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r8 @ d' += a[8] * b[4] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r14 @ d' += a[9] * b[3] + umlal r5, r6, r0, r8 @ d += a[9] * b[2] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E - interleaved with F */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #4*4] @ b[4] + umull r11, r12, r7, r8 @ c' = a[0] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r3, r4, r7, r8 @ c += a[0] * b[3] + ldr r7, [r1, #1*4] @ a[1] + umlal r11, r12, r7, r8 @ c' += a[1] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r3, r4, r7, r8 @ c += a[1] * b[2] + ldr r7, [r1, #2*4] @ a[2] + umlal r11, r12, r7, r8 @ c' += a[2] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r3, r4, r7, r8 @ c += a[2] * b[1] + ldr r7, [r1, #3*4] @ a[3] + umlal r11, r12, r7, r8 @ c' += a[3] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r3, r4, r7, r8 @ c += a[3] * b[0] + ldr r7, [r1, #4*4] @ a[4] + umlal r11, r12, r7, r8 @ c' += a[4] * b[0] + ldr r8, [r2, #9*4] @ b[9] + umlal r5, r6, r7, r8 @ d += a[4] * b[9] + ldr r7, [r1, #5*4] @ a[5] + umull r9, r10, r7, r8 @ d' = a[5] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umlal r5, r6, r7, r8 @ d += a[5] * b[8] + ldr r7, [r1, #6*4] @ a[6] + umlal r9, r10, r7, r8 @ d' += a[6] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[7] + ldr r7, [r1, #7*4] @ a[7] + umlal r9, r10, r7, r8 @ d' += a[7] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r5, r6, r7, r8 @ d += a[7] * b[6] + ldr r7, [r1, #8*4] @ a[8] + umlal r9, r10, r7, r8 @ d' += a[8] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r5, r6, r7, r8 @ d += a[8] * b[5] + ldr r7, [r1, #9*4] @ a[9] + umlal r9, r10, r7, r8 @ d' += a[9] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r5, r6, r7, r8 @ d += a[9] * b[4] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G - interleaved with H */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #6*4] @ b[6] + ldr r14, [r2, #5*4] @ b[5] + umull r11, r12, r7, r8 @ c' = a[0] * b[6] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[1] * b[5] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[2] * b[4] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[3] * b[3] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[4] * b[2] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[5] * b[1] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[6] * b[0] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[7] * b[9] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[8] * b[8] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[9] * b[7] + umlal r5, r6, r0, r8 @ d += a[9] * b[6] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I - interleaved with J */ + ldr r8, [r2, #8*4] @ b[8] + ldr r7, [r1, #0*4] @ a[0] + ldr r14, [r2, #7*4] @ b[7] + umull r11, r12, r7, r8 @ c' = a[0] * b[8] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r11, r12, r0, r14 @ c' += a[1] * b[7] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r11, r12, r7, r8 @ c' += a[2] * b[6] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[3] * b[5] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[4] * b[4] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[5] * b[3] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[6] * b[2] + ldr r0, [r1, #7*4] @ a[7] + umlal r3, r4, r7, r14 @ c += a[6] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[7] * b[1] + ldr r7, [r1, #8*4] @ a[8] + umlal r3, r4, r0, r8 @ c += a[7] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[8] * b[0] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[9] * b[9] + umlal r5, r6, r0, r8 @ d += a[9] * b[8] + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_mul_inner, .-secp256k1_fe_mul_inner + + .align 2 + .global secp256k1_fe_sqr_inner + .type secp256k1_fe_sqr_inner, %function + @ Arguments: + @ r0 r Can overlap with a + @ r1 a + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_sqr_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r2,r7,r8 scratch + r1 a (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + /* A interleaved with B */ + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r7, [r1, #0*4] @ a[0] + mov r0, r0, asl #1 + ldr r14, [r1, #9*4] @ a[9] + umull r3, r4, r7, r7 @ c = a[0] * a[0] + ldr r8, [r1, #8*4] @ a[8] + mov r7, r7, asl #1 + umull r5, r6, r7, r14 @ d = a[0]*2 * a[9] + ldr r7, [r1, #2*4] @ a[2]*2 + umull r9, r10, r0, r14 @ d' = a[1]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[1]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #3*4] @ a[3]*2 + umlal r9, r10, r7, r8 @ d' += a[2]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[7] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umlal r9, r10, r0, r14 @ d' += a[3]*2 * a[7] + ldr r14, [r1, #5*4] @ a[5] + mov r7, r7, asl #1 + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[6] + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[6] + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[5] + umlal r9, r10, r14, r14 @ d' += a[5] * a[5] + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 9*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C interleaved with D */ + ldr r0, [r1, #0*4] @ a[0]*2 + ldr r14, [r1, #1*4] @ a[1] + mov r0, r0, asl #1 + ldr r8, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r14 @ c += a[0]*2 * a[1] + mov r7, r8, asl #1 @ a[2]*2 + umull r11, r12, r14, r14 @ c' = a[1] * a[1] + ldr r14, [r1, #9*4] @ a[9] + umlal r11, r12, r0, r8 @ c' += a[0]*2 * a[2] + ldr r0, [r1, #3*4] @ a[3]*2 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[9] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umull r9, r10, r0, r14 @ d' = a[3]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[7] + umlal r9, r10, r0, r14 @ d' += a[5]*2 * a[7] + umlal r5, r6, r0, r8 @ d += a[5]*2 * a[6] + umlal r9, r10, r8, r8 @ d' += a[6] * a[6] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E interleaved with F */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r14, [r1, #2*4] @ a[2] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + ldr r2, [r1, #4*4] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[3] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[4] + mov r2, r2, asl #1 @ a[4]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[3] + ldr r8, [r1, #9*4] @ a[9] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[2] + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r11, r12, r14, r14 @ c' += a[2] * a[2] + ldr r14, [r1, #8*4] @ a[8] + mov r0, r0, asl #1 + umlal r5, r6, r2, r8 @ d += a[4]*2 * a[9] + ldr r7, [r1, #6*4] @ a[6]*2 + umull r9, r10, r0, r8 @ d' = a[5]*2 * a[9] + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r14 @ d += a[5]*2 * a[8] + umlal r9, r10, r7, r14 @ d' += a[6]*2 * a[8] + umlal r5, r6, r7, r8 @ d += a[6]*2 * a[7] + umlal r9, r10, r8, r8 @ d' += a[7] * a[7] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G interleaved with H */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #5*4] @ a[5] + ldr r2, [r1, #6*4] @ a[6] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[5] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[6] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[5] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[4] + mov r0, r2, asl #1 @ a[6]*2 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[4] + ldr r14, [r1, #9*4] @ a[9] + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[3] + ldr r7, [r1, #7*4] @ a[7]*2 + umlal r11, r12, r8, r8 @ c' += a[3] * a[3] + mov r7, r7, asl #1 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[6]*2 * a[9] + umull r9, r10, r7, r14 @ d' = a[7]*2 * a[9] + umlal r5, r6, r7, r8 @ d += a[7]*2 * a[8] + umlal r9, r10, r8, r8 @ d' += a[8] * a[8] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I interleaved with J */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + ldr r2, [r1, #8*4] @ a[8] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[7] + ldr r14, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[8] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[7] + ldr r8, [r1, #5*4] @ a[5] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[6] + ldr r0, [r1, #3*4] @ a[3]*2 + mov r7, r7, asl #1 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[6] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[5] + mov r2, r2, asl #1 @ a[8]*2 + umlal r11, r12, r0, r8 @ c' += a[3]*2 * a[5] + umlal r3, r4, r0, r14 @ c += a[3]*2 * a[4] + umlal r11, r12, r14, r14 @ c' += a[4] * a[4] + ldr r8, [r1, #9*4] @ a[9] + umlal r5, r6, r2, r8 @ d += a[8]*2 * a[9] + @ r8 will be used in J + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + umlal r5, r6, r8, r8 @ d += a[9] * a[9] + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner + diff --git a/src/bench_ecdh.c b/src/bench_ecdh.c index 5a7c6376e..cde5e2dbb 100644 --- a/src/bench_ecdh.c +++ b/src/bench_ecdh.c @@ -28,7 +28,8 @@ static void bench_ecdh_setup(void* arg) { 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f }; - data->ctx = secp256k1_context_create(0); + /* create a context with no capabilities */ + data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); for (i = 0; i < 32; i++) { data->scalar[i] = i + 1; } diff --git a/src/bench_internal.c b/src/bench_internal.c index 7809f5f8c..0809f77bd 100644 --- a/src/bench_internal.c +++ b/src/bench_internal.c @@ -181,12 +181,12 @@ void bench_field_inverse_var(void* arg) { } } -void bench_field_sqrt_var(void* arg) { +void bench_field_sqrt(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 20000; i++) { - secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x); + secp256k1_fe_sqrt(&data->fe_x, &data->fe_x); secp256k1_fe_add(&data->fe_x, &data->fe_y); } } @@ -227,6 +227,15 @@ void bench_group_add_affine_var(void* arg) { } } +void bench_group_jacobi_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_gej_has_quad_y_var(&data->gej_x); + } +} + void bench_ecmult_wnaf(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; @@ -299,6 +308,21 @@ void bench_context_sign(void* arg) { } } +#ifndef USE_NUM_NONE +void bench_num_jacobi(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + secp256k1_num nx, norder; + + secp256k1_scalar_get_num(&nx, &data->scalar_x); + secp256k1_scalar_order_get_num(&norder); + secp256k1_scalar_get_num(&norder, &data->scalar_y); + + for (i = 0; i < 200000; i++) { + secp256k1_num_jacobi(&nx, &norder); + } +} +#endif int have_flag(int argc, char** argv, char *flag) { char** argm = argv + argc; @@ -333,12 +357,13 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); @@ -350,5 +375,8 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); +#ifndef USE_NUM_NONE + if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, 200000); +#endif return 0; } diff --git a/src/bench_verify.c b/src/bench_verify.c index 5718320cd..418defa0a 100644 --- a/src/bench_verify.c +++ b/src/bench_verify.c @@ -11,6 +11,12 @@ #include "util.h" #include "bench.h" +#ifdef ENABLE_OPENSSL_TESTS +#include +#include +#include +#endif + typedef struct { secp256k1_context *ctx; unsigned char msg[32]; @@ -19,6 +25,9 @@ typedef struct { size_t siglen; unsigned char pubkey[33]; size_t pubkeylen; +#ifdef ENABLE_OPENSSL_TESTS + EC_GROUP* ec_group; +#endif } benchmark_verify_t; static void benchmark_verify(void* arg) { @@ -40,6 +49,36 @@ static void benchmark_verify(void* arg) { } } +#ifdef ENABLE_OPENSSL_TESTS +static void benchmark_verify_openssl(void* arg) { + int i; + benchmark_verify_t* data = (benchmark_verify_t*)arg; + + for (i = 0; i < 20000; i++) { + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + { + EC_KEY *pkey = EC_KEY_new(); + const unsigned char *pubkey = &data->pubkey[0]; + int result; + + CHECK(pkey != NULL); + result = EC_KEY_set_group(pkey, data->ec_group); + CHECK(result); + result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; + CHECK(result); + result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); + CHECK(result); + EC_KEY_free(pkey); + } + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + } +} +#endif + int main(void) { int i; secp256k1_pubkey pubkey; @@ -62,6 +101,11 @@ int main(void) { CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); +#ifdef ENABLE_OPENSSL_TESTS + data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); + run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); + EC_GROUP_free(data.ec_group); +#endif secp256k1_context_destroy(data.ctx); return 0; diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index d110b4bb1..9a42e519b 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -203,7 +203,9 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { unsigned char c[32]; secp256k1_scalar sn, u1, u2; +#if !defined(EXHAUSTIVE_TEST_ORDER) secp256k1_fe xr; +#endif secp256k1_gej pubkeyj; secp256k1_gej pr; @@ -219,6 +221,21 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const if (secp256k1_gej_is_infinity(&pr)) { return 0; } + +#if defined(EXHAUSTIVE_TEST_ORDER) +{ + secp256k1_scalar computed_r; + int overflow = 0; + secp256k1_ge pr_ge; + secp256k1_ge_set_gej(&pr_ge, &pr); + secp256k1_fe_normalize(&pr_ge.x); + + secp256k1_fe_get_b32(c, &pr_ge.x); + secp256k1_scalar_set_b32(&computed_r, c, &overflow); + /* we fully expect overflow */ + return secp256k1_scalar_eq(sigr, &computed_r); +} +#else secp256k1_scalar_get_b32(c, sigr); secp256k1_fe_set_b32(&xr, c); @@ -252,6 +269,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const return 1; } return 0; +#endif } static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { diff --git a/src/ecmult_const_impl.h b/src/ecmult_const_impl.h index 90ac94770..0db314c48 100644 --- a/src/ecmult_const_impl.h +++ b/src/ecmult_const_impl.h @@ -58,25 +58,27 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { int global_sign; int skew = 0; int word = 0; + /* 1 2 3 */ int u_last; int u; -#ifdef USE_ENDOMORPHISM int flip; int bit; secp256k1_scalar neg_s; int not_neg_one; - /* If we are using the endomorphism, we cannot handle even numbers by negating - * them, since we are working with 128-bit numbers whose negations would be 256 - * bits, eliminating the performance advantage. Instead we use a technique from + /* Note that we cannot handle even numbers by negating them to be odd, as is + * done in other implementations, since if our scalars were specified to have + * width < 256 for performance reasons, their negations would have width 256 + * and we'd lose any performance benefit. Instead, we use a technique from * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) - * or 2 (for odd) to the number we are encoding, then compensating after the - * multiplication. */ - /* Negative 128-bit numbers will be negated, since otherwise they are 256-bit */ + * or 2 (for odd) to the number we are encoding, returning a skew value indicating + * this, and having the caller compensate after doing the multiplication. */ + + /* Negative numbers will be negated to keep their bit representation below the maximum width */ flip = secp256k1_scalar_is_high(&s); /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ - bit = flip ^ (s.d[0] & 1); + bit = flip ^ !secp256k1_scalar_is_even(&s); /* We check for negative one, since adding 2 to it will cause an overflow */ secp256k1_scalar_negate(&neg_s, &s); not_neg_one = !secp256k1_scalar_is_one(&neg_s); @@ -89,11 +91,6 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { global_sign = secp256k1_scalar_cond_negate(&s, flip); global_sign *= not_neg_one * 2 - 1; skew = 1 << bit; -#else - /* Otherwise, we just negate to force oddness */ - int is_even = secp256k1_scalar_is_even(&s); - global_sign = secp256k1_scalar_cond_negate(&s, is_even); -#endif /* 4 */ u_last = secp256k1_scalar_shr_int(&s, w); @@ -127,15 +124,13 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons secp256k1_ge tmpa; secp256k1_fe Z; + int skew_1; + int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; #ifdef USE_ENDOMORPHISM secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; - int skew_1; int skew_lam; secp256k1_scalar q_1, q_lam; -#else - int wnaf[1 + WNAF_SIZE(WINDOW_A - 1)]; #endif int i; @@ -145,18 +140,10 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons #ifdef USE_ENDOMORPHISM /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); - /* no need for zero correction when using endomorphism since even - * numbers have one added to them anyway */ skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); #else - int is_zero = secp256k1_scalar_is_zero(scalar); - /* the wNAF ladder cannot handle zero, so bump this to one .. we will - * correct the result after the fact */ - sc.d[0] += is_zero; - VERIFY_CHECK(!secp256k1_scalar_is_zero(&sc)); - - secp256k1_wnaf_const(wnaf, sc, WINDOW_A - 1); + skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); #endif /* Calculate odd multiples of a. @@ -179,21 +166,15 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons /* first loop iteration (separated out so we can directly set r, rather * than having it start at infinity, get doubled several times, then have * its new value added to it) */ -#ifdef USE_ENDOMORPHISM i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; VERIFY_CHECK(i != 0); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); secp256k1_gej_set_ge(r, &tmpa); - +#ifdef USE_ENDOMORPHISM i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; VERIFY_CHECK(i != 0); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); secp256k1_gej_add_ge(r, r, &tmpa); -#else - i = wnaf[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); - secp256k1_gej_set_ge(r, &tmpa); #endif /* remaining loop iterations */ for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { @@ -202,59 +183,57 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons for (j = 0; j < WINDOW_A - 1; ++j) { secp256k1_gej_double_nonzero(r, r, NULL); } -#ifdef USE_ENDOMORPHISM + n = wnaf_1[i]; ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); VERIFY_CHECK(n != 0); secp256k1_gej_add_ge(r, r, &tmpa); - +#ifdef USE_ENDOMORPHISM n = wnaf_lam[i]; ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); VERIFY_CHECK(n != 0); secp256k1_gej_add_ge(r, r, &tmpa); -#else - n = wnaf[i]; - VERIFY_CHECK(n != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge(r, r, &tmpa); #endif } secp256k1_fe_mul(&r->z, &r->z, &Z); -#ifdef USE_ENDOMORPHISM { /* Correct for wNAF skew */ secp256k1_ge correction = *a; secp256k1_ge_storage correction_1_stor; +#ifdef USE_ENDOMORPHISM secp256k1_ge_storage correction_lam_stor; +#endif secp256k1_ge_storage a2_stor; secp256k1_gej tmpj; secp256k1_gej_set_ge(&tmpj, &correction); secp256k1_gej_double_var(&tmpj, &tmpj, NULL); secp256k1_ge_set_gej(&correction, &tmpj); secp256k1_ge_to_storage(&correction_1_stor, a); +#ifdef USE_ENDOMORPHISM secp256k1_ge_to_storage(&correction_lam_stor, a); +#endif secp256k1_ge_to_storage(&a2_stor, &correction); /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); +#ifdef USE_ENDOMORPHISM secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); +#endif /* Apply the correction */ secp256k1_ge_from_storage(&correction, &correction_1_stor); secp256k1_ge_neg(&correction, &correction); secp256k1_gej_add_ge(r, r, &correction); +#ifdef USE_ENDOMORPHISM secp256k1_ge_from_storage(&correction, &correction_lam_stor); secp256k1_ge_neg(&correction, &correction); secp256k1_ge_mul_lambda(&correction, &correction); secp256k1_gej_add_ge(r, r, &correction); - } -#else - /* correct for zero */ - r->infinity |= is_zero; #endif + } } #endif diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index b63c4d866..35f254607 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -77,7 +77,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } - secp256k1_ge_set_all_gej_var(1024, prec, precj, cb); + secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index e6e5f4718..4e40104ad 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -7,13 +7,29 @@ #ifndef _SECP256K1_ECMULT_IMPL_H_ #define _SECP256K1_ECMULT_IMPL_H_ +#include + #include "group.h" #include "scalar.h" #include "ecmult.h" +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to lower these values for exhaustive tests because + * the tables cannot have infinities in them (this breaks the + * affine-isomorphism stuff which tracks z-ratios) */ +# if EXHAUSTIVE_TEST_ORDER > 128 +# define WINDOW_A 5 +# define WINDOW_G 8 +# elif EXHAUSTIVE_TEST_ORDER > 8 +# define WINDOW_A 4 +# define WINDOW_G 4 +# else +# define WINDOW_A 2 +# define WINDOW_G 2 +# endif +#else /* optimal for 128-bit and 256-bit exponents. */ #define WINDOW_A 5 - /** larger numbers may result in slightly better performance, at the cost of exponentially larger precomputed tables. */ #ifdef USE_ENDOMORPHISM @@ -23,6 +39,7 @@ /** One table for window size 16: 1.375 MiB. */ #define WINDOW_G 16 #endif +#endif /** The number of entries a table with precomputed multiples needs to have. */ #define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) @@ -101,7 +118,7 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge /* Compute the odd multiples in Jacobian form. */ secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); /* Convert them in batch to affine coordinates. */ - secp256k1_ge_set_table_gej_var(n, prea, prej, zr); + secp256k1_ge_set_table_gej_var(prea, prej, zr, n); /* Convert them to compact storage form. */ for (i = 0; i < n; i++) { secp256k1_ge_to_storage(&pre[i], &prea[i]); diff --git a/src/field.h b/src/field.h index 2d52af5e3..bbb1ee866 100644 --- a/src/field.h +++ b/src/field.h @@ -30,6 +30,8 @@ #error "Please select field implementation" #endif +#include "util.h" + /** Normalize a field element. */ static void secp256k1_fe_normalize(secp256k1_fe *r); @@ -50,6 +52,9 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); /** Set a field element equal to a small integer. Resulting field element is normalized. */ static void secp256k1_fe_set_int(secp256k1_fe *r, int a); +/** Sets a field element equal to zero, initializing all fields. */ +static void secp256k1_fe_clear(secp256k1_fe *a); + /** Verify whether a field element is zero. Requires the input to be normalized. */ static int secp256k1_fe_is_zero(const secp256k1_fe *a); @@ -57,6 +62,9 @@ static int secp256k1_fe_is_zero(const secp256k1_fe *a); static int secp256k1_fe_is_odd(const secp256k1_fe *a); /** Compare two field elements. Requires magnitude-1 inputs. */ +static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Same as secp256k1_fe_equal, but may be variable time. */ static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); /** Compare two field elements. Requires both inputs to be normalized */ @@ -92,7 +100,10 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); * The input's magnitude can be at most 8. The output magnitude is 1 (but not * guaranteed to be normalized). The result in r will always be a square * itself. */ -static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a); +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); + +/** Checks whether a field element is a quadratic residue. */ +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ @@ -104,7 +115,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a); +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); /** Convert a field element to the storage type. */ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index 212cc5396..7b8c07960 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -7,8 +7,6 @@ #ifndef _SECP256K1_FIELD_REPR_IMPL_H_ #define _SECP256K1_FIELD_REPR_IMPL_H_ -#include -#include #include "util.h" #include "num.h" #include "field.h" @@ -429,6 +427,14 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_f #endif } +#if defined(USE_EXTERNAL_ASM) + +/* External assembler implementation */ +void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); +void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); + +#else + #ifdef VERIFY #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) #else @@ -1037,7 +1043,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t VERIFY_BITS(r[2], 27); /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } - +#endif static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index b31e24ab8..7a99eb21e 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -11,7 +11,6 @@ #include "libsecp256k1-config.h" #endif -#include #include "util.h" #include "num.h" #include "field.h" diff --git a/src/field_5x52_int128_impl.h b/src/field_5x52_int128_impl.h index 9280bb5ea..0bf22bdd3 100644 --- a/src/field_5x52_int128_impl.h +++ b/src/field_5x52_int128_impl.h @@ -137,7 +137,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(r[2], 52); VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; @@ -259,7 +259,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; diff --git a/src/field_impl.h b/src/field_impl.h index 77f4aae2f..5127b279b 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -21,6 +21,13 @@ #error "Please select field implementation" #endif +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero(&na); +} + SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { secp256k1_fe na; secp256k1_fe_negate(&na, a, 1); @@ -28,7 +35,7 @@ SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const return secp256k1_fe_normalizes_to_zero_var(&na); } -static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a) { +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { /** Given that p is congruent to 3 mod 4, we can compute the square root of * a mod p as the (p+1)/4'th power of a. * @@ -123,7 +130,7 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a) { /* Check that a square root was actually calculated */ secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal_var(&t1, a); + return secp256k1_fe_equal(&t1, a); } static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { @@ -253,7 +260,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { #endif } -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a) { +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { secp256k1_fe u; size_t i; if (len < 1) { @@ -280,4 +287,29 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k r[0] = u; } +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { +#ifndef USE_NUM_NONE + unsigned char b[32]; + secp256k1_num n; + secp256k1_num m; + /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ + static const unsigned char prime[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F + }; + + secp256k1_fe c = *a; + secp256k1_fe_normalize_var(&c); + secp256k1_fe_get_b32(b, &c); + secp256k1_num_set_bin(&n, b, 32); + secp256k1_num_set_bin(&m, prime, 32); + return secp256k1_num_jacobi(&n, &m) >= 0; +#else + secp256k1_fe r; + return secp256k1_fe_sqrt(&r, a); +#endif +} + #endif diff --git a/src/group.h b/src/group.h index ebfe1ca70..4957b248f 100644 --- a/src/group.h +++ b/src/group.h @@ -47,7 +47,7 @@ static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const se * and a Y coordinate that is a quadratic residue modulo p. The return value * is true iff a coordinate with the given X coordinate exists. */ -static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x); +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness * for Y. Return value indicates whether the result is valid. */ @@ -65,12 +65,12 @@ static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb); +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); /** Set a batch of group elements equal to the inputs given in jacobian * coordinates (with known z-ratios). zr must contain the known z-ratios such * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ -static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr); +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); /** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to * the same global z "denominator". zr must contain the known z-ratios such @@ -94,6 +94,9 @@ static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); /** Check whether a group element is the point at infinity. */ static int secp256k1_gej_is_infinity(const secp256k1_gej *a); +/** Check whether a group element's y coordinate is a quadratic residue. */ +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); + /** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). * a may not be zero. Constant time. */ static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); diff --git a/src/group_impl.h b/src/group_impl.h index 42e2f6e6e..2e192b62f 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -7,12 +7,57 @@ #ifndef _SECP256K1_GROUP_IMPL_H_ #define _SECP256K1_GROUP_IMPL_H_ -#include - #include "num.h" #include "field.h" #include "group.h" +/* These points can be generated in sage as follows: + * + * 0. Setup a worksheet with the following parameters. + * b = 4 # whatever CURVE_B will be set to + * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + * C = EllipticCurve ([F (0), F (b)]) + * + * 1. Determine all the small orders available to you. (If there are + * no satisfactory ones, go back and change b.) + * print C.order().factor(limit=1000) + * + * 2. Choose an order as one of the prime factors listed in the above step. + * (You can also multiply some to get a composite order, though the + * tests will crash trying to invert scalars during signing.) We take a + * random point and scale it to drop its order to the desired value. + * There is some probability this won't work; just try again. + * order = 199 + * P = C.random_point() + * P = (int(P.order()) / int(order)) * P + * assert(P.order() == order) + * + * 3. Print the values. You'll need to use a vim macro or something to + * split the hex output into 4-byte chunks. + * print "%x %x" % P.xy() + */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 199 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, + 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, + 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, + 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED +); + +const int CURVE_B = 4; +# elif EXHAUSTIVE_TEST_ORDER == 13 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, + 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, + 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, + 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac +); +const int CURVE_B = 2; +# else +# error No known generator for the specified exhaustive test group order. +# endif +#else /** Generator for secp256k1, value 'g' defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ @@ -23,8 +68,11 @@ static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL ); +const int CURVE_B = 7; +#endif + static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { - secp256k1_fe zi2; + secp256k1_fe zi2; secp256k1_fe zi3; secp256k1_fe_sqr(&zi2, zi); secp256k1_fe_mul(&zi3, &zi2, zi); @@ -78,7 +126,7 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { r->y = a->y; } -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb) { +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { secp256k1_fe *az; secp256k1_fe *azi; size_t i; @@ -91,7 +139,7 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp } azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); - secp256k1_fe_inv_all_var(count, azi, az); + secp256k1_fe_inv_all_var(azi, az, count); free(az); count = 0; @@ -104,7 +152,7 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp free(azi); } -static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr) { +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { size_t i = len - 1; secp256k1_fe zi; @@ -147,9 +195,15 @@ static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp static void secp256k1_gej_set_infinity(secp256k1_gej *r) { r->infinity = 1; - secp256k1_fe_set_int(&r->x, 0); - secp256k1_fe_set_int(&r->y, 0); - secp256k1_fe_set_int(&r->z, 0); + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); +} + +static void secp256k1_ge_set_infinity(secp256k1_ge *r) { + r->infinity = 1; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); } static void secp256k1_gej_clear(secp256k1_gej *r) { @@ -165,19 +219,19 @@ static void secp256k1_ge_clear(secp256k1_ge *r) { secp256k1_fe_clear(&r->y); } -static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x) { +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { secp256k1_fe x2, x3, c; r->x = *x; secp256k1_fe_sqr(&x2, x); secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&c, &x3); - return secp256k1_fe_sqrt_var(&r->y, &c); + return secp256k1_fe_sqrt(&r->y, &c); } static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { - if (!secp256k1_ge_set_xquad_var(r, x)) { + if (!secp256k1_ge_set_xquad(r, x)) { return 0; } secp256k1_fe_normalize_var(&r->y); @@ -230,7 +284,7 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_sqr(&z2, &a->z); secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, 7); + secp256k1_fe_mul_int(&z6, CURVE_B); secp256k1_fe_add(&x3, &z6); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); @@ -244,18 +298,30 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { /* y^2 = x^3 + 7 */ secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&x3, &c); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */ + /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. + * + * Note that there is an implementation described at + * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * which trades a multiply for a square, but in practice this is actually slower, + * mainly because it requires more normalizations. + */ secp256k1_fe t1,t2,t3,t4; /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + * + * Having said this, if this function receives a point on a sextic twist, e.g. by + * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, + * since -6 does have a cube root mod p. For this point, this function will not set + * the infinity flag even though the point doubles to infinity, and the result + * point will be gibberish (z = 0 but infinity = 0). */ r->infinity = a->infinity; if (r->infinity) { @@ -623,4 +689,18 @@ static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { } #endif +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { + secp256k1_fe yz; + + if (a->infinity) { + return 0; + } + + /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as + * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z + is */ + secp256k1_fe_mul(&yz, &a->y, &a->z); + return secp256k1_fe_is_quad_var(&yz); +} + #endif diff --git a/src/hash.h b/src/hash.h index 0ff01e63f..fca98cab9 100644 --- a/src/hash.h +++ b/src/hash.h @@ -11,7 +11,7 @@ #include typedef struct { - uint32_t s[32]; + uint32_t s[8]; uint32_t buf[16]; /* In big endian */ size_t bytes; } secp256k1_sha256_t; diff --git a/src/hash_impl.h b/src/hash_impl.h index ae55df6d8..b47e65f83 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -269,15 +269,13 @@ static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 rng->retry = 0; } - +#undef BE32 #undef Round -#undef sigma0 #undef sigma1 -#undef Sigma0 +#undef sigma0 #undef Sigma1 -#undef Ch +#undef Sigma0 #undef Maj -#undef ReadBE32 -#undef WriteBE32 +#undef Ch #endif diff --git a/src/java/org/bitcoin/NativeSecp256k1.java b/src/java/org/bitcoin/NativeSecp256k1.java index 90a498eaa..1c67802fb 100644 --- a/src/java/org/bitcoin/NativeSecp256k1.java +++ b/src/java/org/bitcoin/NativeSecp256k1.java @@ -1,60 +1,446 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.bitcoin; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.math.BigInteger; import com.google.common.base.Preconditions; - +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import static org.bitcoin.NativeSecp256k1Util.*; /** - * This class holds native methods to handle ECDSA verification. - * You can find an example library that can be used for this at - * https://github.com/sipa/secp256k1 + *

This class holds native methods to handle ECDSA verification.

+ * + *

You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1

+ * + *

To build secp256k1 for use with bitcoinj, run + * `./configure --enable-jni --enable-experimental --enable-module-ecdh` + * and `make` then copy `.libs/libsecp256k1.so` to your system library path + * or point the JVM to the folder containing it with -Djava.library.path + *

*/ public class NativeSecp256k1 { - public static final boolean enabled; - static { - boolean isEnabled = true; - try { - System.loadLibrary("javasecp256k1"); - } catch (UnsatisfiedLinkError e) { - isEnabled = false; - } - enabled = isEnabled; - } - + + private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private static final Lock r = rwl.readLock(); + private static final Lock w = rwl.writeLock(); private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); /** * Verifies the given secp256k1 signature in native code. * Calling when enabled == false is undefined (probably library not loaded) - * + * * @param data The data which was signed, must be exactly 32 bytes * @param signature The signature * @param pub The public key which did the signing */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null) { - byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520); + if (byteBuff == null || byteBuff.capacity() < 520) { + byteBuff = ByteBuffer.allocateDirect(520); byteBuff.order(ByteOrder.nativeOrder()); nativeECDSABuffer.set(byteBuff); } byteBuff.rewind(); byteBuff.put(data); - byteBuff.putInt(signature.length); - byteBuff.putInt(pub.length); byteBuff.put(signature); byteBuff.put(pub); - return secp256k1_ecdsa_verify(byteBuff) == 1; + + byte[][] retByteArray; + + r.lock(); + try { + return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; + } finally { + r.unlock(); + } } /** - * @param byteBuff signature format is byte[32] data, - * native-endian int signatureLength, native-endian int pubkeyLength, - * byte[signatureLength] signature, byte[pubkeyLength] pub - * @returns 1 for valid signature, anything else for invalid + * libsecp256k1 Create an ECDSA signature. + * + * @param data Message hash, 32 bytes + * @param key Secret key, 32 bytes + * + * Return values + * @param sig byte array of signature */ - private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff); + public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ + Preconditions.checkArgument(data.length == 32 && sec.length <= 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(sec); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid + * + * @param seckey ECDSA Secret key, 32 bytes + */ + public static boolean secKeyVerify(byte[] seckey) { + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + r.lock(); + try { + return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; + } finally { + r.unlock(); + } + } + + + /** + * libsecp256k1 Compute Pubkey - computes public key from secret key + * + * @param seckey ECDSA Secret key, 32 bytes + * + * Return values + * @param pubkey ECDSA Public key, 33 or 65 bytes + */ + //TODO add a 'compressed' arg + public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + return retVal == 0 ? new byte[0]: pubArr; + } + + /** + * libsecp256k1 Cleanup - This destroys the secp256k1 context object + * This should be called at the end of the program for proper cleanup of the context. + */ + public static synchronized void cleanup() { + w.lock(); + try { + secp256k1_destroy_context(Secp256k1Context.getContext()); + } finally { + w.unlock(); + } + } + + public static long cloneContext() { + r.lock(); + try { + return secp256k1_ctx_clone(Secp256k1Context.getContext()); + } finally { r.unlock(); } + } + + /** + * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_add(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 create ECDH secret - constant time ECDH calculation + * + * @param seckey byte array of secret key used in exponentiaion + * @param pubkey byte array of public key used in exponentiaion + */ + public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] resArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + assertEquals(resArr.length, 32, "Got bad result length."); + assertEquals(retVal, 1, "Failed return value check."); + + return resArr; + } + + /** + * libsecp256k1 randomize - updates the context randomization + * + * @param seed 32-byte random seed + */ + public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ + Preconditions.checkArgument(seed.length == 32 || seed == null); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seed.length) { + byteBuff = ByteBuffer.allocateDirect(seed.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seed); + + w.lock(); + try { + return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; + } finally { + w.unlock(); + } + } + + private static native long secp256k1_ctx_clone(long context); + + private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen); + + private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen); + + private static native void secp256k1_destroy_context(long context); + + private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); + + private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); + + private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen); + + private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); + } diff --git a/src/java/org/bitcoin/NativeSecp256k1Test.java b/src/java/org/bitcoin/NativeSecp256k1Test.java new file mode 100644 index 000000000..c00d08899 --- /dev/null +++ b/src/java/org/bitcoin/NativeSecp256k1Test.java @@ -0,0 +1,226 @@ +package org.bitcoin; + +import com.google.common.io.BaseEncoding; +import java.util.Arrays; +import java.math.BigInteger; +import javax.xml.bind.DatatypeConverter; +import static org.bitcoin.NativeSecp256k1Util.*; + +/** + * This class holds test cases defined for testing this library. + */ +public class NativeSecp256k1Test { + + //TODO improve comments/add more tests + /** + * This tests verify() for a valid signature + */ + public static void testVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + assertEquals( result, true , "testVerifyPos"); + } + + /** + * This tests verify() for a non-valid signature + */ + public static void testVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testVerifyNeg"); + } + + /** + * This tests secret key verify() for a valid secretkey + */ + public static void testSecKeyVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, true , "testSecKeyVerifyPos"); + } + + /** + * This tests secret key verify() for a invalid secretkey + */ + public static void testSecKeyVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testSecKeyVerifyNeg"); + } + + /** + * This tests public key create() for a valid secretkey + */ + public static void testPubKeyCreatePos() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos"); + } + + /** + * This tests public key create() for a invalid secretkey + */ + public static void testPubKeyCreateNeg() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString, "" , "testPubKeyCreateNeg"); + } + + /** + * This tests sign() for a valid secretkey + */ + public static void testSignPos() throws AssertFailException{ + + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos"); + } + + /** + * This tests sign() for a invalid secretkey + */ + public static void testSignNeg() throws AssertFailException{ + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "" , "testSignNeg"); + } + + /** + * This tests private key tweak-add + */ + public static void testPrivKeyTweakAdd_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1"); + } + + /** + * This tests private key tweak-mul + */ + public static void testPrivKeyTweakMul_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1"); + } + + /** + * This tests private key tweak-add uncompressed + */ + public static void testPrivKeyTweakAdd_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2"); + } + + /** + * This tests private key tweak-mul uncompressed + */ + public static void testPrivKeyTweakMul_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2"); + } + + /** + * This tests seed randomization + */ + public static void testRandomize() throws AssertFailException { + byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random" + boolean result = NativeSecp256k1.randomize(seed); + assertEquals( result, true, "testRandomize"); + } + + public static void testCreateECDHSecret() throws AssertFailException{ + + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub); + String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret"); + } + + public static void main(String[] args) throws AssertFailException{ + + + System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n"); + + assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" ); + + //Test verify() success/fail + testVerifyPos(); + testVerifyNeg(); + + //Test secKeyVerify() success/fail + testSecKeyVerifyPos(); + testSecKeyVerifyNeg(); + + //Test computePubkey() success/fail + testPubKeyCreatePos(); + testPubKeyCreateNeg(); + + //Test sign() success/fail + testSignPos(); + testSignNeg(); + + //Test privKeyTweakAdd() 1 + testPrivKeyTweakAdd_1(); + + //Test privKeyTweakMul() 2 + testPrivKeyTweakMul_1(); + + //Test privKeyTweakAdd() 3 + testPrivKeyTweakAdd_2(); + + //Test privKeyTweakMul() 4 + testPrivKeyTweakMul_2(); + + //Test randomize() + testRandomize(); + + //Test ECDH + testCreateECDHSecret(); + + NativeSecp256k1.cleanup(); + + System.out.println(" All tests passed." ); + + } +} diff --git a/src/java/org/bitcoin/NativeSecp256k1Util.java b/src/java/org/bitcoin/NativeSecp256k1Util.java new file mode 100644 index 000000000..04732ba04 --- /dev/null +++ b/src/java/org/bitcoin/NativeSecp256k1Util.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +public class NativeSecp256k1Util{ + + public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + } + + public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ + if( !val.equals(val2) ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static class AssertFailException extends Exception { + public AssertFailException(String message) { + super( message ); + } + } +} diff --git a/src/java/org/bitcoin/Secp256k1Context.java b/src/java/org/bitcoin/Secp256k1Context.java new file mode 100644 index 000000000..216c986a8 --- /dev/null +++ b/src/java/org/bitcoin/Secp256k1Context.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +/** + * This class holds the context reference used in native methods + * to handle ECDSA operations. + */ +public class Secp256k1Context { + private static final boolean enabled; //true if the library is loaded + private static final long context; //ref to pointer to context obj + + static { //static initializer + boolean isEnabled = true; + long contextRef = -1; + try { + System.loadLibrary("secp256k1"); + contextRef = secp256k1_init_context(); + } catch (UnsatisfiedLinkError e) { + System.out.println("UnsatisfiedLinkError: " + e.toString()); + isEnabled = false; + } + enabled = isEnabled; + context = contextRef; + } + + public static boolean isEnabled() { + return enabled; + } + + public static long getContext() { + if(!enabled) return -1; //sanity check + return context; + } + + private static native long secp256k1_init_context(); +} diff --git a/src/java/org_bitcoin_NativeSecp256k1.c b/src/java/org_bitcoin_NativeSecp256k1.c index bb4cd7072..bcef7b32c 100644 --- a/src/java/org_bitcoin_NativeSecp256k1.c +++ b/src/java/org_bitcoin_NativeSecp256k1.c @@ -1,23 +1,377 @@ +#include +#include +#include #include "org_bitcoin_NativeSecp256k1.h" #include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" +#include "include/secp256k1_recovery.h" -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject) + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv* env, jclass classObject, jlong ctx_l) { - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - int sigLen = *((int*)(data + 32)); - int pubLen = *((int*)(data + 32 + 4)); + const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx); + + (void)classObject;(void)env; + + return ctx_clone_l; - return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen); } -static void __javasecp256k1_attach(void) __attribute__((constructor)); -static void __javasecp256k1_detach(void) __attribute__((destructor)); +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_context_randomize(ctx, seed); -static void __javasecp256k1_attach(void) { - secp256k1_start(SECP256K1_START_VERIFY); } -static void __javasecp256k1_detach(void) { - secp256k1_stop(); +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv* env, jclass classObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + secp256k1_context_destroy(ctx); + + (void)classObject;(void)env; +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* sigdata = { (unsigned char*) (data + 32) }; + const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) }; + + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pubkey; + + int ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen); + + if( ret ) { + ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if( ret ) { + ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey); + } + } + + (void)classObject; + + return ret; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + unsigned char* secKey = (unsigned char*) (data + 32); + + jobjectArray retArray; + jbyteArray sigArray, intsByteArray; + unsigned char intsarray[2]; + + secp256k1_ecdsa_signature sig[72]; + + int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL ); + + unsigned char outputSer[72]; + size_t outputLen = 72; + + if( ret ) { + int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + sigArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_ec_seckey_verify(ctx, secKey); +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + secp256k1_pubkey pubkey; + + jobjectArray retArray; + jbyteArray pubkeyArray, intsByteArray; + unsigned char intsarray[2]; + + int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey); + + unsigned char outputSer[65]; + size_t outputLen = 65; + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubkeyArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; + +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; +/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/ + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if( ret ) { + ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if ( ret ) { + ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1pubkey_1combine + (JNIEnv * env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint numkeys) +{ + (void)classObject;(void)env;(void)byteBufferObject;(void)ctx_l;(void)numkeys; + + return 0; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* pubdata = (const unsigned char*) (secdata + 32); + + jobjectArray retArray; + jbyteArray outArray, intsByteArray; + unsigned char intsarray[1]; + secp256k1_pubkey pubkey; + unsigned char nonce_res[32]; + size_t outputLen = 32; + + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if (ret) { + ret = secp256k1_ecdh( + ctx, + nonce_res, + &pubkey, + secdata + ); + } + + intsarray[0] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + outArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res); + (*env)->SetObjectArrayElement(env, retArray, 0, outArray); + + intsByteArray = (*env)->NewByteArray(env, 1); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; } diff --git a/src/java/org_bitcoin_NativeSecp256k1.h b/src/java/org_bitcoin_NativeSecp256k1.h index d7fb004fa..fe613c9e9 100644 --- a/src/java/org_bitcoin_NativeSecp256k1.h +++ b/src/java/org_bitcoin_NativeSecp256k1.h @@ -1,5 +1,6 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include +#include "include/secp256k1.h" /* Header for class org_bitcoin_NativeSecp256k1 */ #ifndef _Included_org_bitcoin_NativeSecp256k1 @@ -9,11 +10,108 @@ extern "C" { #endif /* * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_verify - * Signature: (Ljava/nio/ByteBuffer;)I + * Method: secp256k1_ctx_clone + * Signature: (J)J */ -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv *, jclass, jobject); +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_context_randomize + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_destroy_context + * Signature: (J)V + */ +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_verify + * Signature: (Ljava/nio/ByteBuffer;JII)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv *, jclass, jobject, jlong, jint, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_sign + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_seckey_verify + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_create + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_parse + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdh + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); + #ifdef __cplusplus } diff --git a/src/java/org_bitcoin_Secp256k1Context.c b/src/java/org_bitcoin_Secp256k1Context.c new file mode 100644 index 000000000..a52939e7e --- /dev/null +++ b/src/java/org_bitcoin_Secp256k1Context.c @@ -0,0 +1,15 @@ +#include +#include +#include "org_bitcoin_Secp256k1Context.h" +#include "include/secp256k1.h" + +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv* env, jclass classObject) +{ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + (void)classObject;(void)env; + + return (uintptr_t)ctx; +} + diff --git a/src/java/org_bitcoin_Secp256k1Context.h b/src/java/org_bitcoin_Secp256k1Context.h new file mode 100644 index 000000000..0d2bc84b7 --- /dev/null +++ b/src/java/org_bitcoin_Secp256k1Context.h @@ -0,0 +1,22 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +#include "include/secp256k1.h" +/* Header for class org_bitcoin_Secp256k1Context */ + +#ifndef _Included_org_bitcoin_Secp256k1Context +#define _Included_org_bitcoin_Secp256k1Context +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_bitcoin_Secp256k1Context + * Method: secp256k1_init_context + * Signature: ()J + */ +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/modules/ecdh/Makefile.am.include b/src/modules/ecdh/Makefile.am.include index 670b9c115..e3088b469 100644 --- a/src/modules/ecdh/Makefile.am.include +++ b/src/modules/ecdh/Makefile.am.include @@ -4,5 +4,5 @@ noinst_HEADERS += src/modules/ecdh/tests_impl.h if USE_BENCHMARK noinst_PROGRAMS += bench_ecdh bench_ecdh_SOURCES = src/bench_ecdh.c -bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) endif diff --git a/src/modules/recovery/Makefile.am.include b/src/modules/recovery/Makefile.am.include index 5de3ea33e..bf23c26e7 100644 --- a/src/modules/recovery/Makefile.am.include +++ b/src/modules/recovery/Makefile.am.include @@ -4,5 +4,5 @@ noinst_HEADERS += src/modules/recovery/tests_impl.h if USE_BENCHMARK noinst_PROGRAMS += bench_recover bench_recover_SOURCES = src/bench_recover.c -bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) endif diff --git a/src/modules/recovery/main_impl.h b/src/modules/recovery/main_impl.h old mode 100644 new mode 100755 index ec42f4bb6..86f2f0cb2 --- a/src/modules/recovery/main_impl.h +++ b/src/modules/recovery/main_impl.h @@ -138,16 +138,15 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecd secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { - unsigned char nonce32[32]; ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); if (!secp256k1_scalar_is_zero(&non) && !overflow) { if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { break; @@ -155,6 +154,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecd } count++; } + memset(nonce32, 0, 32); secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); diff --git a/src/modules/schnorr/Makefile.am.include b/src/modules/schnorr/Makefile.am.include deleted file mode 100644 index b3bfa7d5c..000000000 --- a/src/modules/schnorr/Makefile.am.include +++ /dev/null @@ -1,10 +0,0 @@ -include_HEADERS += include/secp256k1_schnorr.h -noinst_HEADERS += src/modules/schnorr/main_impl.h -noinst_HEADERS += src/modules/schnorr/schnorr.h -noinst_HEADERS += src/modules/schnorr/schnorr_impl.h -noinst_HEADERS += src/modules/schnorr/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_schnorr_verify -bench_schnorr_verify_SOURCES = src/bench_schnorr_verify.c -bench_schnorr_verify_LDADD = libsecp256k1.la $(SECP_LIBS) -endif diff --git a/src/modules/schnorr/main_impl.h b/src/modules/schnorr/main_impl.h deleted file mode 100644 index fa176a176..000000000 --- a/src/modules/schnorr/main_impl.h +++ /dev/null @@ -1,164 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_MAIN -#define SECP256K1_MODULE_SCHNORR_MAIN - -#include "include/secp256k1_schnorr.h" -#include "modules/schnorr/schnorr_impl.h" - -static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - secp256k1_sha256_t sha; - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, r32, 32); - secp256k1_sha256_write(&sha, msg32, 32); - secp256k1_sha256_finalize(&sha, h32); -} - -static const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; - -int secp256k1_schnorr_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar sec, non; - int ret = 0; - int overflow = 0; - unsigned int count = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, NULL, secp256k1_schnorr_msghash_sha256, msg32)) { - break; - } - } - count++; - } - if (!ret) { - memset(sig64, 0, 64); - } - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_schnorr_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { - secp256k1_ge q; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_pubkey_load(ctx, &q, pubkey); - return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *sig64, const unsigned char *msg32) { - secp256k1_ge q; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32)) { - secp256k1_pubkey_save(pubkey, &q); - return 1; - } else { - memset(pubkey, 0, sizeof(*pubkey)); - return 0; - } -} - -int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function noncefp, const void* noncedata) { - int count = 0; - int ret = 1; - secp256k1_gej Qj; - secp256k1_ge Q; - secp256k1_scalar sec; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(pubnonce != NULL); - ARG_CHECK(privnonce32 != NULL); - - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - do { - int overflow; - ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&sec, privnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - continue; - } - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sec); - secp256k1_ge_set_gej(&Q, &Qj); - - secp256k1_pubkey_save(pubnonce, &Q); - break; - } while(1); - - secp256k1_scalar_clear(&sec); - if (!ret) { - memset(pubnonce, 0, sizeof(*pubnonce)); - } - return ret; -} - -int secp256k1_schnorr_partial_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey *pubnonce_others, const unsigned char *secnonce32) { - int overflow = 0; - secp256k1_scalar sec, non; - secp256k1_ge pubnon; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(secnonce32 != NULL); - ARG_CHECK(pubnonce_others != NULL); - - secp256k1_scalar_set_b32(&sec, sec32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - return -1; - } - secp256k1_scalar_set_b32(&non, secnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&non)) { - return -1; - } - secp256k1_pubkey_load(ctx, &pubnon, pubnonce_others); - return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_partial_combine(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, size_t n) { - ARG_CHECK(sig64 != NULL); - ARG_CHECK(n >= 1); - ARG_CHECK(sig64sin != NULL); - return secp256k1_schnorr_sig_combine(sig64, n, sig64sin); -} - -#endif diff --git a/src/modules/schnorr/schnorr.h b/src/modules/schnorr/schnorr.h deleted file mode 100644 index de18147bd..000000000 --- a/src/modules/schnorr/schnorr.h +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_MODULE_SCHNORR_H_ -#define _SECP256K1_MODULE_SCHNORR_H_ - -#include "scalar.h" -#include "group.h" - -typedef void (*secp256k1_schnorr_msghash)(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32); - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins); - -#endif diff --git a/src/modules/schnorr/schnorr_impl.h b/src/modules/schnorr/schnorr_impl.h deleted file mode 100644 index e13ab6db7..000000000 --- a/src/modules/schnorr/schnorr_impl.h +++ /dev/null @@ -1,207 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_SCHNORR_IMPL_H_ -#define _SECP256K1_SCHNORR_IMPL_H_ - -#include - -#include "schnorr.h" -#include "num.h" -#include "field.h" -#include "group.h" -#include "ecmult.h" -#include "ecmult_gen.h" - -/** - * Custom Schnorr-based signature scheme. They support multiparty signing, public key - * recovery and batch validation. - * - * Rationale for verifying R's y coordinate: - * In order to support batch validation and public key recovery, the full R point must - * be known to verifiers, rather than just its x coordinate. In order to not risk - * being more strict in batch validation than normal validation, validators must be - * required to reject signatures with incorrect y coordinate. This is only possible - * by including a (relatively slow) field inverse, or a field square root. However, - * batch validation offers potentially much higher benefits than this cost. - * - * Rationale for having an implicit y coordinate oddness: - * If we commit to having the full R point known to verifiers, there are two mechanism. - * Either include its oddness in the signature, or give it an implicit fixed value. - * As the R y coordinate can be flipped by a simple negation of the nonce, we choose the - * latter, as it comes with nearly zero impact on signing or validation performance, and - * saves a byte in the signature. - * - * Signing: - * Inputs: 32-byte message m, 32-byte scalar key x (!=0), 32-byte scalar nonce k (!=0) - * - * Compute point R = k * G. Reject nonce if R's y coordinate is odd (or negate nonce). - * Compute 32-byte r, the serialization of R's x coordinate. - * Compute scalar h = Hash(r || m). Reject nonce if h == 0 or h >= order. - * Compute scalar s = k - h * x. - * The signature is (r, s). - * - * - * Verification: - * Inputs: 32-byte message m, public key point Q, signature: (32-byte r, scalar s) - * - * Signature is invalid if s >= order. - * Signature is invalid if r >= p. - * Compute scalar h = Hash(r || m). Signature is invalid if h == 0 or h >= order. - * Option 1 (faster for single verification): - * Compute point R = h * Q + s * G. Signature is invalid if R is infinity or R's y coordinate is odd. - * Signature is valid if the serialization of R's x coordinate equals r. - * Option 2 (allows batch validation and pubkey recovery): - * Decompress x coordinate r into point R, with odd y coordinate. Fail if R is not on the curve. - * Signature is valid if R + h * Q + s * G == 0. - */ - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Rj; - secp256k1_ge Ra; - unsigned char h32[32]; - secp256k1_scalar h, s; - int overflow; - secp256k1_scalar n; - - if (secp256k1_scalar_is_zero(key) || secp256k1_scalar_is_zero(nonce)) { - return 0; - } - n = *nonce; - - secp256k1_ecmult_gen(ctx, &Rj, &n); - if (pubnonce != NULL) { - secp256k1_gej_add_ge(&Rj, &Rj, pubnonce); - } - secp256k1_ge_set_gej(&Ra, &Rj); - secp256k1_fe_normalize(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - /* R's y coordinate is odd, which is not allowed (see rationale above). - Force it to be even by negating the nonce. Note that this even works - for multiparty signing, as the R point is known to all participants, - which can all decide to flip the sign in unison, resulting in the - overall R point to be negated too. */ - secp256k1_scalar_negate(&n, &n); - } - secp256k1_fe_normalize(&Ra.x); - secp256k1_fe_get_b32(sig64, &Ra.x); - hash(h32, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, h32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - secp256k1_scalar_clear(&n); - return 0; - } - secp256k1_scalar_mul(&s, &h, key); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_add(&s, &s, &n); - secp256k1_scalar_clear(&n); - secp256k1_scalar_get_b32(sig64 + 32, &s); - return 1; -} - -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - if (secp256k1_ge_is_infinity(pubkey)) { - return 0; - } - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - secp256k1_gej_set_ge(&Qj, pubkey); - secp256k1_ecmult(ctx, &Rj, &Qj, &h, &s); - if (secp256k1_gej_is_infinity(&Rj)) { - return 0; - } - secp256k1_ge_set_gej_var(&Ra, &Rj); - secp256k1_fe_normalize_var(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - return 0; - } - return secp256k1_fe_equal_var(&Rx, &Ra.x); -} - -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - if (!secp256k1_ge_set_xo_var(&Ra, &Rx, 0)) { - return 0; - } - secp256k1_gej_set_ge(&Rj, &Ra); - secp256k1_scalar_inverse_var(&h, &h); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_mul(&s, &s, &h); - secp256k1_ecmult(ctx, &Qj, &Rj, &h, &s); - if (secp256k1_gej_is_infinity(&Qj)) { - return 0; - } - secp256k1_ge_set_gej(pubkey, &Qj); - return 1; -} - -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins) { - secp256k1_scalar s = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - size_t i; - for (i = 0; i < n; i++) { - secp256k1_scalar si; - int overflow; - secp256k1_scalar_set_b32(&si, sig64ins[i] + 32, &overflow); - if (overflow) { - return -1; - } - if (i) { - if (memcmp(sig64ins[i - 1], sig64ins[i], 32) != 0) { - return -1; - } - } - secp256k1_scalar_add(&s, &s, &si); - } - if (secp256k1_scalar_is_zero(&s)) { - return 0; - } - memcpy(sig64, sig64ins[0], 32); - secp256k1_scalar_get_b32(sig64 + 32, &s); - secp256k1_scalar_clear(&s); - return 1; -} - -#endif diff --git a/src/modules/schnorr/tests_impl.h b/src/modules/schnorr/tests_impl.h deleted file mode 100644 index 5bd14a03e..000000000 --- a/src/modules/schnorr/tests_impl.h +++ /dev/null @@ -1,175 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_TESTS -#define SECP256K1_MODULE_SCHNORR_TESTS - -#include "include/secp256k1_schnorr.h" - -void test_schnorr_end_to_end(void) { - unsigned char privkey[32]; - unsigned char message[32]; - unsigned char schnorr_signature[64]; - secp256k1_pubkey pubkey, recpubkey; - - /* Generate a random key and message. */ - { - secp256k1_scalar key; - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(privkey, &key); - secp256k1_rand256_test(message); - } - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Schnorr sign. */ - CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1); - CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); - /* Destroy signature and verify again. */ - schnorr_signature[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 || - memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); -} - -/** Horribly broken hash function. Do not use for anything but tests. */ -void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - int i; - for (i = 0; i < 32; i++) { - h32[i] = r32[i] ^ msg32[i]; - } -} - -void test_schnorr_sign_verify(void) { - unsigned char msg32[32]; - unsigned char sig64[3][64]; - secp256k1_gej pubkeyj[3]; - secp256k1_ge pubkey[3]; - secp256k1_scalar nonce[3], key[3]; - int i = 0; - int k; - - secp256k1_rand256_test(msg32); - - for (k = 0; k < 3; k++) { - random_scalar_order_test(&key[k]); - - do { - random_scalar_order_test(&nonce[k]); - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) { - break; - } - } while(1); - - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]); - secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]); - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32)); - - for (i = 0; i < 4; i++) { - int pos = secp256k1_rand_bits(6); - int mod = 1 + secp256k1_rand_int(255); - sig64[k][pos] ^= mod; - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0); - sig64[k][pos] ^= mod; - } - } -} - -void test_schnorr_threshold(void) { - unsigned char msg[32]; - unsigned char sec[5][32]; - secp256k1_pubkey pub[5]; - unsigned char nonce[5][32]; - secp256k1_pubkey pubnonce[5]; - unsigned char sig[5][64]; - const unsigned char* sigs[5]; - unsigned char allsig[64]; - const secp256k1_pubkey* pubs[5]; - secp256k1_pubkey allpub; - int n, i; - int damage; - int ret = 0; - - damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; - secp256k1_rand256_test(msg); - n = 2 + secp256k1_rand_int(4); - for (i = 0; i < n; i++) { - do { - secp256k1_rand256_test(sec[i]); - } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); - CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); - CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); - pubs[i] = &pub[i]; - } - if (damage == 1) { - nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } else if (damage == 2) { - sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - for (i = 0; i < n; i++) { - secp256k1_pubkey allpubnonce; - const secp256k1_pubkey *pubnonces[4]; - int j; - for (j = 0; j < i; j++) { - pubnonces[j] = &pubnonce[j]; - } - for (j = i + 1; j < n; j++) { - pubnonces[j - 1] = &pubnonce[j]; - } - CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); - ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; - sigs[i] = sig[i]; - } - if (damage == 3) { - sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); - } - ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; - if ((ret & 1) == 0) { - ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; - } - if (damage == 4) { - allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - if ((ret & 7) == 0) { - ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; - } - CHECK((ret == 0) == (damage == 0)); -} - -void test_schnorr_recovery(void) { - unsigned char msg32[32]; - unsigned char sig64[64]; - secp256k1_ge Q; - - secp256k1_rand256_test(msg32); - secp256k1_rand256_test(sig64); - secp256k1_rand256_test(sig64 + 32); - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) { - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1); - } -} - -void run_schnorr_tests(void) { - int i; - for (i = 0; i < 32*count; i++) { - test_schnorr_end_to_end(); - } - for (i = 0; i < 32 * count; i++) { - test_schnorr_sign_verify(); - } - for (i = 0; i < 16 * count; i++) { - test_schnorr_recovery(); - } - for (i = 0; i < 10 * count; i++) { - test_schnorr_threshold(); - } -} - -#endif diff --git a/src/num.h b/src/num.h index ebfa71eb4..7bb9c5be8 100644 --- a/src/num.h +++ b/src/num.h @@ -32,6 +32,9 @@ static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsi /** Compute a modular inverse. The input must be less than the modulus. */ static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); +/** Compute the jacobi symbol (a|b). b must be positive and odd. */ +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); + /** Compare the absolute value of two numbers. */ static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); @@ -57,6 +60,9 @@ static void secp256k1_num_shift(secp256k1_num *r, int bits); /** Check whether a number is zero. */ static int secp256k1_num_is_zero(const secp256k1_num *a); +/** Check whether a number is one. */ +static int secp256k1_num_is_one(const secp256k1_num *a); + /** Check whether a number is strictly negative. */ static int secp256k1_num_is_neg(const secp256k1_num *a); diff --git a/src/num_gmp_impl.h b/src/num_gmp_impl.h index 7b6a89719..3a46495ee 100644 --- a/src/num_gmp_impl.h +++ b/src/num_gmp_impl.h @@ -144,6 +144,32 @@ static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, memset(v, 0, sizeof(v)); } +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { + int ret; + mpz_t ga, gb; + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); + + mpz_inits(ga, gb, NULL); + + mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); + mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); + if (a->neg) { + mpz_neg(ga, ga); + } + + ret = mpz_jacobi(ga, gb); + + mpz_clears(ga, gb, NULL); + + return ret; +} + +static int secp256k1_num_is_one(const secp256k1_num *a) { + return (a->limbs == 1 && a->data[0] == 1); +} + static int secp256k1_num_is_zero(const secp256k1_num *a) { return (a->limbs == 1 && a->data[0] == 0); } diff --git a/src/scalar.h b/src/scalar.h index b590ccd6d..27e9d8375 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -13,7 +13,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32.h" diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index aa2703dd2..56e7bd82a 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -282,8 +282,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq 56(%%rsi), %%r14\n" /* Initialize r8,r9,r10 */ "movq 0(%%rsi), %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += n0 * c0 */ "movq %8, %%rax\n" "mulq %%r11\n" @@ -291,7 +291,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* extract m0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += l1 */ "addq 8(%%rsi), %%r9\n" "adcq $0, %%r10\n" @@ -309,7 +309,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* extract m1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += l2 */ "addq 16(%%rsi), %%r10\n" "adcq $0, %%r8\n" @@ -332,7 +332,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r9\n" /* extract m2 */ "movq %%r10, %q2\n" - "movq $0, %%r10\n" + "xorq %%r10, %%r10\n" /* (r8,r9,r10) += l3 */ "addq 24(%%rsi), %%r8\n" "adcq $0, %%r9\n" @@ -355,7 +355,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r10\n" /* extract m3 */ "movq %%r8, %q3\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10,r8) += n3 * c1 */ "movq %9, %%rax\n" "mulq %%r14\n" @@ -387,8 +387,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq %q11, %%r13\n" /* Initialize (r8,r9,r10) */ "movq %q5, %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += m4 * c0 */ "movq %12, %%rax\n" "mulq %%r11\n" @@ -396,7 +396,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* extract p0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += m1 */ "addq %q6, %%r9\n" "adcq $0, %%r10\n" @@ -414,7 +414,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* extract p1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += m2 */ "addq %q7, %%r10\n" "adcq $0, %%r8\n" @@ -472,7 +472,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq %%rax, 0(%q6)\n" /* Move to (r8,r9) */ "movq %%rdx, %%r8\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p1 */ "addq %q2, %%r8\n" "adcq $0, %%r9\n" @@ -483,7 +483,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* Extract r1 */ "movq %%r8, 8(%q6)\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r8) += p4 */ "addq %%r10, %%r9\n" "adcq $0, %%r8\n" @@ -492,7 +492,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* Extract r2 */ "movq %%r9, 16(%q6)\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p3 */ "addq %q4, %%r8\n" "adcq $0, %%r9\n" diff --git a/src/scalar_impl.h b/src/scalar_impl.h index 88ea97de8..f5b237640 100644 --- a/src/scalar_impl.h +++ b/src/scalar_impl.h @@ -7,8 +7,6 @@ #ifndef _SECP256K1_SCALAR_IMPL_H_ #define _SECP256K1_SCALAR_IMPL_H_ -#include - #include "group.h" #include "scalar.h" @@ -16,7 +14,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low_impl.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64_impl.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32_impl.h" @@ -33,17 +33,37 @@ static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a /** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ static void secp256k1_scalar_order_get_num(secp256k1_num *r) { +#if defined(EXHAUSTIVE_TEST_ORDER) + static const unsigned char order[32] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER + }; +#else static const unsigned char order[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 }; +#endif secp256k1_num_set_bin(r, order, 32); } #endif static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { +#if defined(EXHAUSTIVE_TEST_ORDER) + int i; + *r = 0; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) + *r = i; + /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus + * have a composite group order; fix it in exhaustive_tests.c). */ + VERIFY_CHECK(*r != 0); +} +#else secp256k1_scalar *t; int i; /* First compute x ^ (2^N - 1) for some values of N. */ @@ -235,9 +255,9 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar } SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - /* d[0] is present and is the lowest word for all representations */ return !(a->d[0] & 1); } +#endif static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { #if defined(USE_SCALAR_INV_BUILTIN) @@ -261,6 +281,18 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_sc } #ifdef USE_ENDOMORPHISM +#if defined(EXHAUSTIVE_TEST_ORDER) +/** + * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the + * full case we don't bother making k1 and k2 be small, we just want them to be + * nontrivial to get full test coverage for the exhaustive tests. We therefore + * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. + */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; + *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; +} +#else /** * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, @@ -333,5 +365,6 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar secp256k1_scalar_add(r1, r1, a); } #endif +#endif #endif diff --git a/src/scalar_low.h b/src/scalar_low.h new file mode 100644 index 000000000..5574c44c7 --- /dev/null +++ b/src/scalar_low.h @@ -0,0 +1,15 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_ +#define _SECP256K1_SCALAR_REPR_ + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef uint32_t secp256k1_scalar; + +#endif diff --git a/src/scalar_low_impl.h b/src/scalar_low_impl.h new file mode 100644 index 000000000..4f94441f4 --- /dev/null +++ b/src/scalar_low_impl.h @@ -0,0 +1,114 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ +#define _SECP256K1_SCALAR_REPR_IMPL_H_ + +#include "scalar.h" + +#include + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(*a & 1); +} + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + if (offset < 32) + return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); + else + return 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + return secp256k1_scalar_get_bits(a, offset, count); +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; + return *r < *b; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + if (flag && bit < 32) + *r += (1 << bit); +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; + int i; + *r = 0; + for (i = 0; i < 32; i++) { + *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; + } + /* just deny overflow, it basically always happens */ + if (overflow) *overflow = 0; +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + memset(bin, 0, 32); + bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return *a == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + if (*a == 0) { + *r = 0; + } else { + *r = EXHAUSTIVE_TEST_ORDER - *a; + } +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return *a == 1; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + return *a > EXHAUSTIVE_TEST_ORDER / 2; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + if (flag) secp256k1_scalar_negate(r, r); + return flag ? -1 : 1; +} + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = *r & ((1 << n) - 1); + *r >>= n; + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { + *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r1 = *a; + *r2 = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return *a == *b; +} + +#endif diff --git a/src/secp256k1.c b/src/secp256k1.c old mode 100644 new mode 100755 index 62d192bae..fb8b882fa --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -4,8 +4,6 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#define SECP256K1_BUILD (1) - #include "include/secp256k1.h" #include "util.h" @@ -152,7 +150,6 @@ static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { secp256k1_ge Q; - (void)ctx; VERIFY_CHECK(ctx != NULL); ARG_CHECK(pubkey != NULL); memset(pubkey, 0, sizeof(*pubkey)); @@ -170,7 +167,6 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o size_t len; int ret = 0; - (void)ctx; VERIFY_CHECK(ctx != NULL); ARG_CHECK(outputlen != NULL); ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); @@ -216,7 +212,7 @@ static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(input != NULL); @@ -234,7 +230,7 @@ int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp25 int ret = 1; int overflow = 0; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(input64 != NULL); @@ -253,7 +249,7 @@ int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp25 int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(output != NULL); ARG_CHECK(outputlen != NULL); ARG_CHECK(sig != NULL); @@ -265,7 +261,7 @@ int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsign int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(output64 != NULL); ARG_CHECK(sig != NULL); @@ -363,16 +359,15 @@ int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { - unsigned char nonce32[32]; ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); if (!overflow && !secp256k1_scalar_is_zero(&non)) { if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { break; @@ -380,6 +375,7 @@ int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature } count++; } + memset(nonce32, 0, 32); secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); @@ -398,7 +394,6 @@ int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char int overflow; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - (void)ctx; secp256k1_scalar_set_b32(&sec, seckey, &overflow); ret = !overflow && !secp256k1_scalar_is_zero(&sec); @@ -437,7 +432,6 @@ int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char * VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); ARG_CHECK(tweak != NULL); - (void)ctx; secp256k1_scalar_set_b32(&term, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); @@ -485,7 +479,6 @@ int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char * VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); ARG_CHECK(tweak != NULL); - (void)ctx; secp256k1_scalar_set_b32(&factor, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); diff --git a/src/tests.c b/src/tests.c index 687a5f2fd..9ae7d3028 100644 --- a/src/tests.c +++ b/src/tests.c @@ -473,6 +473,8 @@ void test_num_negate(void) { } void test_num_add_sub(void) { + int i; + secp256k1_scalar s; secp256k1_num n1; secp256k1_num n2; secp256k1_num n1p2, n2p1, n1m2, n2m1; @@ -498,6 +500,110 @@ void test_num_add_sub(void) { CHECK(!secp256k1_num_eq(&n2p1, &n1)); secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ CHECK(secp256k1_num_eq(&n2p1, &n1)); + + /* check is_one */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&n1, &s); + CHECK(secp256k1_num_is_one(&n1)); + /* check that 2^n + 1 is never 1 */ + secp256k1_scalar_get_num(&n2, &s); + for (i = 0; i < 250; ++i) { + secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */ + secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */ + CHECK(!secp256k1_num_is_one(&n1p2)); + } +} + +void test_num_mod(void) { + int i; + secp256k1_scalar s; + secp256k1_num order, n; + + /* check that 0 mod anything is 0 */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_set_int(&s, 0); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that anything mod 1 is 0 */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that increasing the number past 2^256 does not break this */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&n, &s); + /* multiply by 2^8, which'll test this case with high probability */ + for (i = 0; i < 8; ++i) { + secp256k1_num_add(&n, &n, &n); + } + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); +} + +void test_num_jacobi(void) { + secp256k1_scalar sqr; + secp256k1_scalar small; + secp256k1_scalar five; /* five is not a quadratic residue */ + secp256k1_num order, n; + int i; + /* squares mod 5 are 1, 4 */ + const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 }; + + /* check some small values with 5 as the order */ + secp256k1_scalar_set_int(&five, 5); + secp256k1_scalar_get_num(&order, &five); + for (i = 0; i < 10; ++i) { + secp256k1_scalar_set_int(&small, i); + secp256k1_scalar_get_num(&n, &small); + CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]); + } + + /** test large values with 5 as group order */ + secp256k1_scalar_get_num(&order, &five); + /* we first need a scalar which is not a multiple of 5 */ + do { + secp256k1_num fiven; + random_scalar_order_test(&sqr); + secp256k1_scalar_get_num(&fiven, &five); + secp256k1_scalar_get_num(&n, &sqr); + secp256k1_num_mod(&n, &fiven); + } while (secp256k1_num_is_zero(&n)); + /* next force it to be a residue. 2 is a nonresidue mod 5 so we can + * just multiply by two, i.e. add the number to itself */ + if (secp256k1_num_jacobi(&n, &order) == -1) { + secp256k1_num_add(&n, &n, &n); + } + + /* test residue */ + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_num_add(&n, &n, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + + /** test with secp group order as order */ + secp256k1_scalar_order_get_num(&order); + random_scalar_order_test(&sqr); + secp256k1_scalar_sqr(&sqr, &sqr); + /* test residue */ + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_scalar_mul(&sqr, &sqr, &five); + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + /* test multiple of the order*/ + CHECK(secp256k1_num_jacobi(&order, &order) == 0); + + /* check one less than the order */ + secp256k1_scalar_set_int(&small, 1); + secp256k1_scalar_get_num(&n, &small); + secp256k1_num_sub(&n, &order, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */ } void run_num_smalltests(void) { @@ -505,6 +611,8 @@ void run_num_smalltests(void) { for (i = 0; i < 100*count; i++) { test_num_negate(); test_num_add_sub(); + test_num_mod(); + test_num_jacobi(); } } #endif @@ -689,6 +797,10 @@ void scalar_test(void) { secp256k1_scalar_inverse(&inv, &inv); /* Inverting one must result in one. */ CHECK(secp256k1_scalar_is_one(&inv)); +#ifndef USE_NUM_NONE + secp256k1_scalar_get_num(&invnum, &inv); + CHECK(secp256k1_num_is_one(&invnum)); +#endif } } @@ -855,7 +967,7 @@ void run_scalar_tests(void) { secp256k1_scalar zzv; #endif int overflow; - unsigned char chal[32][2][32] = { + unsigned char chal[33][2][32] = { {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, @@ -1111,9 +1223,17 @@ void run_scalar_tests(void) { {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}} + 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}}, + {{0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}, + {0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}} }; - unsigned char res[32][2][32] = { + unsigned char res[33][2][32] = { {{0x0c, 0x3b, 0x0a, 0xca, 0x8d, 0x1a, 0x2f, 0xb9, 0x8a, 0x7b, 0x53, 0x5a, 0x1f, 0xc5, 0x22, 0xa1, 0x07, 0x2a, 0x48, 0xea, 0x02, 0xeb, 0xb3, 0xd6, @@ -1369,10 +1489,18 @@ void run_scalar_tests(void) { {0xe4, 0xf1, 0x23, 0x84, 0xe1, 0xb5, 0x9d, 0xf2, 0xb8, 0x73, 0x8b, 0x45, 0x2b, 0x35, 0x46, 0x38, 0x10, 0x2b, 0x50, 0xf8, 0x8b, 0x35, 0xcd, 0x34, - 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}} + 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}}, + {{0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}, + {0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}} }; secp256k1_scalar_set_int(&one, 1); - for (i = 0; i < 32; i++) { + for (i = 0; i < 33; i++) { secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); CHECK(!overflow); secp256k1_scalar_set_b32(&y, chal[i][1], &overflow); @@ -1446,7 +1574,7 @@ void random_fe_non_zero(secp256k1_fe *nz) { void random_fe_non_square(secp256k1_fe *ns) { secp256k1_fe r; random_fe_non_zero(ns); - if (secp256k1_fe_sqrt_var(&r, ns)) { + if (secp256k1_fe_sqrt(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } @@ -1605,18 +1733,18 @@ void run_field_inv_all_var(void) { secp256k1_fe x[16], xi[16], xii[16]; int i; /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all_var(0, xi, x); + secp256k1_fe_inv_all_var(xi, x, 0); for (i = 0; i < count; i++) { size_t j; size_t len = secp256k1_rand_int(15) + 1; for (j = 0; j < len; j++) { random_fe_non_zero(&x[j]); } - secp256k1_fe_inv_all_var(len, xi, x); + secp256k1_fe_inv_all_var(xi, x, len); for (j = 0; j < len; j++) { CHECK(check_fe_inverse(&x[j], &xi[j])); } - secp256k1_fe_inv_all_var(len, xii, xi); + secp256k1_fe_inv_all_var(xii, xi, len); for (j = 0; j < len; j++) { CHECK(check_fe_equal(&x[j], &xii[j])); } @@ -1641,7 +1769,7 @@ void run_sqr(void) { void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { secp256k1_fe r1, r2; - int v = secp256k1_fe_sqrt_var(&r1, a); + int v = secp256k1_fe_sqrt(&r1, a); CHECK((v == 0) == (k == NULL)); if (k != NULL) { @@ -1802,7 +1930,7 @@ void test_ge(void) { zs[i] = gej[i].z; } } - secp256k1_fe_inv_all_var(4 * runs + 1, zinv, zs); + secp256k1_fe_inv_all_var(zinv, zs, 4 * runs + 1); free(zs); } @@ -1922,8 +2050,8 @@ void test_ge(void) { secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); } } - secp256k1_ge_set_table_gej_var(4 * runs + 1, ge_set_table, gej, zr); - secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej, &ctx->error_callback); + secp256k1_ge_set_table_gej_var(ge_set_table, gej, zr, 4 * runs + 1); + secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1, &ctx->error_callback); for (i = 0; i < 4 * runs + 1; i++) { secp256k1_fe s; random_fe_non_zero(&s); @@ -1951,8 +2079,8 @@ void test_add_neg_y_diff_x(void) { * of the sum to be wrong (since infinity has no xy coordinates). * HOWEVER, if the x-coordinates are different, infinity is the * wrong answer, and such degeneracies are exposed. This is the - * root of https://github.com/bitcoin/secp256k1/issues/257 which - * this test is a regression test for. + * root of https://github.com/bitcoin-core/secp256k1/issues/257 + * which this test is a regression test for. * * These points were generated in sage as * # secp256k1 params @@ -2051,15 +2179,16 @@ void run_ec_combine(void) { void test_group_decompress(const secp256k1_fe* x) { /* The input itself, normalized. */ secp256k1_fe fex = *x; - secp256k1_fe tmp; + secp256k1_fe fez; /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ secp256k1_ge ge_quad, ge_even, ge_odd; + secp256k1_gej gej_quad; /* Return values of the above calls. */ int res_quad, res_even, res_odd; secp256k1_fe_normalize_var(&fex); - res_quad = secp256k1_ge_set_xquad_var(&ge_quad, &fex); + res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex); res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); @@ -2085,13 +2214,29 @@ void test_group_decompress(const secp256k1_fe* x) { CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); /* Check that the Y coordinate result in ge_quad is a square. */ - CHECK(secp256k1_fe_sqrt_var(&tmp, &ge_quad.y)); - secp256k1_fe_sqr(&tmp, &tmp); - CHECK(secp256k1_fe_equal_var(&tmp, &ge_quad.y)); + CHECK(secp256k1_fe_is_quad_var(&ge_quad.y)); /* Check odd/even Y in ge_odd, ge_even. */ CHECK(secp256k1_fe_is_odd(&ge_odd.y)); CHECK(!secp256k1_fe_is_odd(&ge_even.y)); + + /* Check secp256k1_gej_has_quad_y_var. */ + secp256k1_gej_set_ge(&gej_quad, &ge_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); } } @@ -2383,9 +2528,7 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { secp256k1_scalar x, shift; int wnaf[256] = {0}; int i; -#ifdef USE_ENDOMORPHISM int skew; -#endif secp256k1_scalar num = *number; secp256k1_scalar_set_int(&x, 0); @@ -2395,10 +2538,8 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { for (i = 0; i < 16; ++i) { secp256k1_scalar_shr_int(&num, 8); } - skew = secp256k1_wnaf_const(wnaf, num, w); -#else - secp256k1_wnaf_const(wnaf, num, w); #endif + skew = secp256k1_wnaf_const(wnaf, num, w); for (i = WNAF_SIZE(w); i >= 0; --i) { secp256k1_scalar t; @@ -2417,10 +2558,8 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { } secp256k1_scalar_add(&x, &x, &t); } -#ifdef USE_ENDOMORPHISM - /* Skew num because when encoding 128-bit numbers as odd we use an offset */ + /* Skew num because when encoding numbers as odd we use an offset */ secp256k1_scalar_cadd_bit(&num, skew == 2, 1); -#endif CHECK(secp256k1_scalar_eq(&x, &num)); } @@ -3484,12 +3623,14 @@ void run_ecdsa_end_to_end(void) { int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { static const unsigned char zeroes[32] = {0}; +#ifdef ENABLE_OPENSSL_TESTS static const unsigned char max_scalar[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 }; +#endif int ret = 0; @@ -3607,13 +3748,13 @@ static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { static void damage_array(unsigned char *sig, size_t *len) { int pos; int action = secp256k1_rand_bits(3); - if (action < 1) { + if (action < 1 && *len > 3) { /* Delete a byte. */ pos = secp256k1_rand_int(*len); memmove(sig + pos, sig + pos + 1, *len - pos - 1); (*len)--; return; - } else if (action < 2) { + } else if (action < 2 && *len < 2048) { /* Insert a byte. */ pos = secp256k1_rand_int(1 + *len); memmove(sig + pos + 1, sig + pos, *len - pos); @@ -3785,6 +3926,7 @@ void run_ecdsa_der_parse(void) { int certainly_der = 0; int certainly_not_der = 0; random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der); + CHECK(buflen <= 2048); for (j = 0; j < 16; j++) { int ret = 0; if (j > 0) { diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c new file mode 100644 index 000000000..bda6ee475 --- /dev/null +++ b/src/tests_exhaustive.c @@ -0,0 +1,329 @@ +/*********************************************************************** + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include +#include + +#include + +#undef USE_ECMULT_STATIC_PRECOMPUTATION + +#ifndef EXHAUSTIVE_TEST_ORDER +/* see group_impl.h for allowable values */ +#define EXHAUSTIVE_TEST_ORDER 13 +#define EXHAUSTIVE_TEST_LAMBDA 9 /* cube root of 1 mod 13 */ +#endif + +#include "include/secp256k1.h" +#include "group.h" +#include "secp256k1.c" +#include "testrand_impl.h" + +/** stolen from tests.c */ +void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); + CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); +} + +void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { + secp256k1_fe z2s; + secp256k1_fe u1, u2, s1, s2; + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ + secp256k1_fe_sqr(&z2s, &b->z); + secp256k1_fe_mul(&u1, &a->x, &z2s); + u2 = b->x; secp256k1_fe_normalize_weak(&u2); + secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); + s2 = b->y; secp256k1_fe_normalize_weak(&s2); + CHECK(secp256k1_fe_equal_var(&u1, &u2)); + CHECK(secp256k1_fe_equal_var(&s1, &s2)); +} + +void random_fe(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_rand256(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} +/** END stolen from tests.c */ + +int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, + const unsigned char *key32, const unsigned char *algo16, + void *data, unsigned int attempt) { + secp256k1_scalar s; + int *idata = data; + (void)msg32; + (void)key32; + (void)algo16; + /* Some nonces cannot be used because they'd cause s and/or r to be zero. + * The signing function has retry logic here that just re-calls the nonce + * function with an increased `attempt`. So if attempt > 0 this means we + * need to change the nonce to avoid an infinite loop. */ + if (attempt > 0) { + (*idata)++; + } + secp256k1_scalar_set_int(&s, *idata); + secp256k1_scalar_get_b32(nonce32, &s); + return 1; +} + +#ifdef USE_ENDOMORPHISM +void test_exhaustive_endomorphism(const secp256k1_ge *group, int order) { + int i; + for (i = 0; i < order; i++) { + secp256k1_ge res; + secp256k1_ge_mul_lambda(&res, &group[i]); + ge_equals_ge(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res); + } +} +#endif + +void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j; + + /* Sanity-check (and check infinity functions) */ + CHECK(secp256k1_ge_is_infinity(&group[0])); + CHECK(secp256k1_gej_is_infinity(&groupj[0])); + for (i = 1; i < order; i++) { + CHECK(!secp256k1_ge_is_infinity(&group[i])); + CHECK(!secp256k1_gej_is_infinity(&groupj[i])); + } + + /* Check all addition formulae */ + for (j = 0; j < order; j++) { + secp256k1_fe fe_inv; + secp256k1_fe_inv(&fe_inv, &groupj[j].z); + for (i = 0; i < order; i++) { + secp256k1_ge zless_gej; + secp256k1_gej tmp; + /* add_var */ + secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_ge */ + if (j > 0) { + secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + /* add_ge_var */ + secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_zinv_var */ + zless_gej.infinity = groupj[j].infinity; + zless_gej.x = groupj[j].x; + zless_gej.y = groupj[j].y; + secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + } + + /* Check doubling */ + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + if (i > 0) { + secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + secp256k1_gej_double_var(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + + /* Check negation */ + for (i = 1; i < order; i++) { + secp256k1_ge tmp; + secp256k1_gej tmpj; + secp256k1_ge_neg(&tmp, &group[i]); + ge_equals_ge(&group[order - i], &tmp); + secp256k1_gej_neg(&tmpj, &groupj[i]); + ge_equals_gej(&group[order - i], &tmpj); + } +} + +void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j, r_log; + for (r_log = 1; r_log < order; r_log++) { + for (j = 0; j < order; j++) { + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + secp256k1_scalar na, ng; + secp256k1_scalar_set_int(&na, i); + secp256k1_scalar_set_int(&ng, j); + + secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng); + ge_equals_gej(&group[(i * r_log + j) % order], &tmp); + + if (i > 0) { + secp256k1_ecmult_const(&tmp, &group[i], &ng); + ge_equals_gej(&group[(i * j) % order], &tmp); + } + } + } + } +} + +void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k) { + secp256k1_fe x; + unsigned char x_bin[32]; + k %= EXHAUSTIVE_TEST_ORDER; + x = group[k].x; + secp256k1_fe_normalize(&x); + secp256k1_fe_get_b32(x_bin, &x); + secp256k1_scalar_set_b32(r, x_bin, NULL); +} + +void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int s, r, msg, key; + for (s = 1; s < order; s++) { + for (r = 1; r < order; r++) { + for (msg = 1; msg < order; msg++) { + for (key = 1; key < order; key++) { + secp256k1_ge nonconst_ge; + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pk; + secp256k1_scalar sk_s, msg_s, r_s, s_s; + secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; + int k, should_verify; + unsigned char msg32[32]; + + secp256k1_scalar_set_int(&s_s, s); + secp256k1_scalar_set_int(&r_s, r); + secp256k1_scalar_set_int(&msg_s, msg); + secp256k1_scalar_set_int(&sk_s, key); + + /* Verify by hand */ + /* Run through every k value that gives us this r and check that *one* works. + * Note there could be none, there could be multiple, ECDSA is weird. */ + should_verify = 0; + for (k = 0; k < order; k++) { + secp256k1_scalar check_x_s; + r_from_k(&check_x_s, group, k); + if (r_s == check_x_s) { + secp256k1_scalar_set_int(&s_times_k_s, k); + secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); + secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); + secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); + should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); + } + } + /* nb we have a "high s" rule */ + should_verify &= !secp256k1_scalar_is_high(&s_s); + + /* Verify by calling verify */ + secp256k1_ecdsa_signature_save(&sig, &r_s, &s_s); + memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); + secp256k1_pubkey_save(&pk, &nonconst_ge); + secp256k1_scalar_get_b32(msg32, &msg_s); + CHECK(should_verify == + secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); + } + } + } + } +} + +void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int i, j, k; + + /* Loop */ + for (i = 1; i < order; i++) { /* message */ + for (j = 1; j < order; j++) { /* key */ + for (k = 1; k < order; k++) { /* nonce */ + secp256k1_ecdsa_signature sig; + secp256k1_scalar sk, msg, r, s, expected_r; + unsigned char sk32[32], msg32[32]; + secp256k1_scalar_set_int(&msg, i); + secp256k1_scalar_set_int(&sk, j); + secp256k1_scalar_get_b32(sk32, &sk); + secp256k1_scalar_get_b32(msg32, &msg); + + secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); + /* Note that we compute expected_r *after* signing -- this is important + * because our nonce-computing function function might change k during + * signing. */ + r_from_k(&expected_r, group, k); + CHECK(r == expected_r); + CHECK((k * s) % order == (i + r * j) % order || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + } + } + } + + /* We would like to verify zero-knowledge here by counting how often every + * possible (s, r) tuple appears, but because the group order is larger + * than the field order, when coercing the x-values to scalar values, some + * appear more often than others, so we are actually not zero-knowledge. + * (This effect also appears in the real code, but the difference is on the + * order of 1/2^128th the field order, so the deviation is not useful to a + * computationally bounded attacker.) + */ +} + +int main(void) { + int i; + secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; + secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; + + /* Build context */ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + /* TODO set z = 1, then do num_tests runs with random z values */ + + /* Generate the entire group */ + secp256k1_gej_set_infinity(&groupj[0]); + secp256k1_ge_set_gej(&group[0], &groupj[0]); + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + /* Set a different random z-value for each Jacobian point */ + secp256k1_fe z; + random_fe(&z); + + secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); + secp256k1_ge_set_gej(&group[i], &groupj[i]); + secp256k1_gej_rescale(&groupj[i], &z); + + /* Verify against ecmult_gen */ + { + secp256k1_scalar scalar_i; + secp256k1_gej generatedj; + secp256k1_ge generated; + + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); + secp256k1_ge_set_gej(&generated, &generatedj); + + CHECK(group[i].infinity == 0); + CHECK(generated.infinity == 0); + CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); + CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); + } + } + + /* Run the tests */ +#ifdef USE_ENDOMORPHISM + test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); +#endif + test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); + + return 0; +} + From 0cc07f82f0d4043e93d8cea49356cd2bc5ffcb27 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 7 Dec 2016 15:20:40 +0100 Subject: [PATCH 1198/1223] [QA] add fundrawtransaction test on a locked wallet with empty keypool Github-Pull: #9295 Rebased-From: 1a6eacbf3b7e3d5941fec1154079bbc4678ce861 --- qa/rpc-tests/fundrawtransaction.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 8c45578fc..0dcca4cb5 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -484,6 +484,23 @@ class RawTransactionsTest(BitcoinTestFramework): self.is_network_split=False self.sync_all() + # drain the keypool + self.nodes[1].getnewaddress() + inputs = [] + outputs = {self.nodes[0].getnewaddress():1.1} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + # fund a transaction that requires a new key for the change output + # creating the key must be impossible because the wallet is locked + try: + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + raise AssertionError("Wallet unlocked without passphrase") + except JSONRPCException as e: + assert('Keypool ran out' in e.error['message']) + + #refill the keypool + self.nodes[1].walletpassphrase("test", 100) + self.nodes[1].walletlock() + try: self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) raise AssertionError("Wallet unlocked without passphrase") From 43bcfca48970b65d4eb215f20047bb99495f3727 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 6 Dec 2016 13:45:56 +0100 Subject: [PATCH 1199/1223] [Wallet] Bugfix: FRT: don't terminate when keypool is empty Github-Pull: #9295 Rebased-From: c24a4f5981d47d55aa9e4eb40294832a4d38fb80 --- src/wallet/wallet.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6ce8d19bf..5b35e49a0 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2290,7 +2290,11 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt CPubKey vchPubKey; bool ret; ret = reservekey.GetReservedKey(vchPubKey); - assert(ret); // should never fail, as we just unlocked + if (!ret) + { + strFailReason = _("Keypool ran out, please call keypoolrefill first"); + return false; + } scriptChange = GetScriptForDestination(vchPubKey.GetID()); } From a0f7ececfd096df398fc5e4aad07f1a43760afb4 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 12 Dec 2016 08:10:27 +0000 Subject: [PATCH 1200/1223] Update for OpenSSL 1.1 API Github-Pull: #9326 Rebased-From: bae1eef752dcecfd85fa482881e1dbe4d7e9f74c b05b1af10b9a5298bd90bea439f0fd6c636e0cfa --- src/qt/paymentrequestplus.cpp | 20 +++++++++++++++----- src/wallet/test/crypto_tests.cpp | 32 ++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 20e1f79ff..82be4d831 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -159,14 +159,24 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); - EVP_MD_CTX ctx; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context."); +#else + EVP_MD_CTX _ctx; + EVP_MD_CTX *ctx; + ctx = &_ctx; +#endif EVP_PKEY *pubkey = X509_get_pubkey(signing_cert); - EVP_MD_CTX_init(&ctx); - if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) || - !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { + EVP_MD_CTX_init(ctx); + if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || + !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || + !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid payment request."); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX_free(ctx); +#endif // OpenSSL API for getting human printable strings from certs is baroque. int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp index 05387f5f2..b235b9609 100644 --- a/src/wallet/test/crypto_tests.cpp +++ b/src/wallet/test/crypto_tests.cpp @@ -42,15 +42,19 @@ bool OldEncrypt(const CKeyingMaterial& vchPlaintext, std::vector int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; vchCiphertext = std::vector (nCLen); - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (!ctx) return false; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; - if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_init(ctx); + if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; + if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(ctx); + + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; @@ -66,15 +70,19 @@ bool OldDecrypt(const std::vector& vchCiphertext, CKeyingMaterial vchPlaintext = CKeyingMaterial(nPLen); - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (!ctx) return false; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_init(ctx); + if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; + if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(ctx); + + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; From 35174a0280845e9583a3af1fcf57ee1f98238539 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 6 Dec 2016 06:39:14 +0000 Subject: [PATCH 1201/1223] Make RelayWalletTransaction attempt to AcceptToMemoryPool. This resolves an issue where a wallet transaction which failed to relay previously because it couldn't make it into the mempool will not try again until restart, even though mempool conditions may have changed. Abandoned and known-conflicted transactions are skipped. Some concern was expressed that there may be users with many unknown conflicts would waste a lot of CPU time trying to add them to their memory pools over and over again. But I am doubtful these users exist in any number, if they do exist they have worse problems, and they can mitigate any performance issue this might have by abandoning the transactions in question. Github-Pull: #9290 Rebased-From: f692fce8a49e05e25f1c767aae1e50db419caebe --- src/wallet/wallet.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5b35e49a0..0403b3558 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1449,9 +1449,10 @@ void CWallet::ReacceptWalletTransactions() bool CWalletTx::RelayWalletTransaction() { assert(pwallet->GetBroadcastTransactions()); - if (!IsCoinBase()) + if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain() == 0) { - if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { + /* GetDepthInMainChain already catches known conflicts. */ + if (InMempool() || AcceptToMemoryPool(false, maxTxFee)) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; From f5d606e5ab0b20881cc0d58d63e6db065c59b411 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 8 Dec 2016 11:49:28 -0800 Subject: [PATCH 1202/1223] Return txid even if ATMP fails for new transaction Github-Pull: #9302 Rebased-From: b3a74100b86423c553ac327f3ea6fdbc2c50890a --- src/wallet/wallet.cpp | 21 +++++++++++---------- src/wallet/wallet.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0403b3558..7f6240262 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1442,7 +1442,8 @@ void CWallet::ReacceptWalletTransactions() CWalletTx& wtx = *(item.second); LOCK(mempool.cs); - wtx.AcceptToMemoryPool(false, maxTxFee); + CValidationState state; + wtx.AcceptToMemoryPool(false, maxTxFee, state); } } @@ -1451,8 +1452,9 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain() == 0) { + CValidationState state; /* GetDepthInMainChain already catches known conflicts. */ - if (InMempool() || AcceptToMemoryPool(false, maxTxFee)) { + if (InMempool() || AcceptToMemoryPool(false, maxTxFee, state)) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -2482,14 +2484,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (fBroadcastTransactions) { + CValidationState state; // Broadcast - if (!wtxNew.AcceptToMemoryPool(false, maxTxFee)) - { - // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); - return false; + if (!wtxNew.AcceptToMemoryPool(false, maxTxFee, state)) { + LogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", state.GetRejectReason()); + // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure. + } else { + wtxNew.RelayWalletTransaction(); } - wtxNew.RelayWalletTransaction(); } } return true; @@ -3595,8 +3597,7 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) +bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee, CValidationState& state) { - CValidationState state; return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0c95fdf4b..056dcc5da 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -213,7 +213,7 @@ public: bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ - bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee); + bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee, CValidationState& state); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } From 4ced31325699dc308571010ce004376d2915cd7e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 14 Dec 2016 17:00:06 -0500 Subject: [PATCH 1203/1223] Allow compactblock reconstruction when block is in flight --- src/main.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 191bcff4c..976e130f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5657,6 +5657,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlockHeaderAndShortTxIDs cmpctblock; vRecv >> cmpctblock; + // Keep a CBlock for "optimistic" compactblock reconstructions (see + // below) + CBlock block; + bool fBlockReconstructed = false; + LOCK(cs_main); if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) { @@ -5765,6 +5770,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, req.blockhash = pindex->GetBlockHash(); pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req); } + } else { + // This block is either already in flight from a different + // peer, or this peer has too many blocks outstanding to + // download from. + // Optimistically try to reconstruct anyway since we might be + // able to without any round trips. + PartiallyDownloadedBlock tempBlock(&mempool); + ReadStatus status = tempBlock.InitData(cmpctblock); + if (status != READ_STATUS_OK) { + // TODO: don't ignore failures + return true; + } + std::vector dummy; + status = tempBlock.FillBlock(block, dummy); + if (status == READ_STATUS_OK) { + fBlockReconstructed = true; + } } } else { if (fAlreadyInFlight) { @@ -5785,6 +5807,33 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + if (fBlockReconstructed) { + // If we got here, we were able to optimistically reconstruct a + // block that is in flight from some other peer. However, this + // cmpctblock may be invalid. In particular, while we've checked + // that the block merkle root commits to the transaction ids, we + // haven't yet checked that tx witnesses are properly committed to + // in the coinbase witness commitment. + // + // ProcessNewBlock will call MarkBlockAsReceived(), which will + // clear any in-flight compact block state that might be present + // from some other peer. We don't want a malleated compact block + // request to interfere with block relay, so we don't want to call + // ProcessNewBlock until we've already checked that the witness + // commitment is correct. + { + LOCK(cs_main); + CValidationState dummy; + if (!ContextualCheckBlock(block, dummy, pindex->pprev)) { + // TODO: could send reject message to peer? + return true; + } + } + CValidationState state; + ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false); + // TODO: could send reject message if block is invalid? + } + CheckBlockIndex(chainparams.GetConsensus()); } From 53b656f3558fe960d9328079ca18eb53418f2652 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Thu, 1 Dec 2016 12:59:10 -0500 Subject: [PATCH 1204/1223] [qa] Update compactblocks test for multi-peer reconstruction --- qa/rpc-tests/p2p-compactblocks.py | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index e0b72e684..156a559b1 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -757,6 +757,54 @@ class CompactBlocksTest(BitcoinTestFramework): msg.announce = True peer.send_and_ping(msg) + def test_compactblock_reconstruction_multiple_peers(self, node, stalling_peer, delivery_peer): + assert(len(self.utxos)) + + def announce_cmpct_block(node, peer): + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 5) + + cmpct_block = HeaderAndShortIDs() + cmpct_block.initialize_from_block(block) + msg = msg_cmpctblock(cmpct_block.to_p2p()) + peer.send_and_ping(msg) + with mininode_lock: + assert(peer.last_getblocktxn is not None) + return block, cmpct_block + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + mempool = node.getrawmempool() + for tx in block.vtx[1:]: + assert(tx.hash in mempool) + + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + # Now test that delivering an invalid compact block won't break relay + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit = [ CTxInWitness() ] + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)] + + cmpct_block.use_witness = True + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert(int(node.getbestblockhash(), 16) != block.sha256) + + msg = msg_blocktxn() + msg.block_transactions.blockhash = block.sha256 + msg.block_transactions.transactions = block.vtx[1:] + stalling_peer.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) def run_test(self): # Setup the p2p connections and start up the network thread. @@ -841,6 +889,10 @@ class CompactBlocksTest(BitcoinTestFramework): self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, False) self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, False) + print("\tTesting reconstructing compact blocks from all peers...") + self.test_compactblock_reconstruction_multiple_peers(self.nodes[1], self.segwit_node, self.old_node) + sync_blocks(self.nodes) + # Advance to segwit activation print ("\nAdvancing to segwit activation\n") self.activate_segwit(self.nodes[1]) From c365556185d89122a04344d2dc640cffc67f155c Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 5 Dec 2016 23:26:32 -0800 Subject: [PATCH 1205/1223] Complain when unknown rpcserialversion is specified Github-Pull: #9292 Rebased-From: 80d073c9bca4521d512ea14ff7919d4609647b6d --- src/init.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 8e40c4388..f2dbf5751 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -364,7 +364,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); - strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(>0) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); + strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); @@ -986,6 +986,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) return InitError("rpcserialversion must be non-negative."); + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) + return InitError("unknown rpcserialversion requested."); + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); From 49a612f347be150b03eb6ef8fa438d2b06e26993 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 11 Dec 2016 14:12:47 +0100 Subject: [PATCH 1206/1223] [qa] Don't set unknown rpcserialversion Github-Pull: #9322 Rebased-From: fa615d39b53a9309ef480c41ec073354c4371f40 --- qa/rpc-tests/segwit.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 4b4fdf8b1..31a48955e 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -85,7 +85,7 @@ class SegWitTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness", "-rpcserialversion=0"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=2"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1"])) self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) connect_nodes(self.nodes[1], 0) connect_nodes(self.nodes[2], 1) @@ -215,7 +215,6 @@ class SegWitTest(BitcoinTestFramework): assert_equal(len(segwit_tx_list), 5) print("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag") - # Note: node1 has version 2, which is simply >0 and will catch future upgrades in tests assert(self.nodes[2].getblock(block[0], False) != self.nodes[0].getblock(block[0], False)) assert(self.nodes[1].getblock(block[0], False) == self.nodes[2].getblock(block[0], False)) for i in range(len(segwit_tx_list)): From 2c5fc0dba32a6ede1d611554a04a996183aa8ee9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 19 Dec 2016 13:09:56 +0100 Subject: [PATCH 1207/1223] doc: Add initial pulls + authors list for 0.13.2 --- doc/release-notes.md | 107 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0830e0a12..acfb45ae2 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 0.13.x is now available from: +Bitcoin Core version 0.13.2 is now available from: - + This is a new minor version release, including ..., various bugfixes and performance improvements, as well as updated translations. @@ -60,7 +60,7 @@ can be abandoned with the previously existing abandontransaction RPC (or in the GUI via a context menu on the transaction). -0.13.x Change log +0.13.2 Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -68,13 +68,110 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -(to be filled in at release time) +### Consensus +- #9293 `e591c10` [0.13 Backport #9053] IBD using chainwork instead of height and not using header timestamp (gmaxwell) +- #9053 `5b93eee` IBD using chainwork instead of height and not using header timestamps (gmaxwell) + +### RPC and other APIs +- #8845 `1d048b9` Don't return the address of a P2SH of a P2SH (jnewbery) +- #9041 `87fbced` keypoololdest denote Unix epoch, not GMT (s-matthew-english) +- #9122 `f82c81b` fix getnettotals RPC description about timemillis (visvirial) +- #9042 `5bcb05d` [rpc] ParseHash: Fail when length is not 64 (MarcoFalke) +- #9194 `f26dab7` Add option to return non-segwit serialization via rpc (instagibbs) +- #9347 `b711390` [0.13.2] wallet/rpc backports (MarcoFalke) +- #9292 `c365556` Complain when unknown rpcserialversion is specified (sipa) +- #9322 `49a612f` [qa] Don't set unknown rpcserialversion (MarcoFalke) + +### Block and transaction handling +- #8357 `ce0d817` [mempool] Fix relaypriority calculation error (maiiz) +- #9267 `0a4aa87` [0.13 backport #9239] Disable fee estimates for a confirm target of 1 block (morcos) +- #9196 `0c09d9f` Send tip change notification from invalidateblock (ryanofsky) + +### P2P protocol and network code +- #8995 `9ef3875` Add missing cs_main lock to ::GETBLOCKTXN processing (TheBlueMatt) +- #9234 `94531b5` torcontrol: Explicitly request RSA1024 private key (laanwj) +- #8637 `2cad5db` Compact Block Tweaks (rebase of #8235) (sipa) +- #9058 `286e548` Fixes for p2p-compactblocks.py test timeouts on travis (#8842) (ryanofsky) +- #8865 `4c71fc4` Decouple peer-processing-logic from block-connection-logic (TheBlueMatt) +- #9117 `6fe3981` net: don't send feefilter messages before the version handshake is complete (theuni) +- #9188 `ca1fd75` Make orphan parent fetching ask for witnesses (gmaxwell) +- #9052 `3a3bcbf` Use RelevantServices instead of node_network in AttemptToEvict (gmaxwell) +- #9048 `9460771` [0.13 backport #9026] Fix handling of invalid compact blocks (sdaftuar) +- #9357 `03b6f62` [0.13 backport #9352] Attempt reconstruction from all compact block announcements (sdaftuar) +- #9189 `b96a8f7` Always add default_witness_commitment with GBT client support (sipa) +- #9253 `28d0f22` Fix calculation of number of bound sockets to use (TheBlueMatt) +- #9199 `da5a16b` Always drop the least preferred HB peer when adding a new one (gmaxwell) + +### Build system +- #9169 `d1b4da9` build: fix qt5.7 build under macOS (theuni) +- #9326 `a0f7ece` Update for OpenSSL 1.1 API (gmaxwell) +- #9224 `396c405` Prevent FD_SETSIZE error building on OpenBSD (ivdsangen) + +### GUI +- #8972 `6f86b53` Make warnings label selectable (jonasschnelli) (MarcoFalke) +- #9185 `6d70a73` Fix coincontrol sort issue (jonasschnelli) +- #9094 `5f3a12c` Use correct conversion function for boost::path datadir (laanwj) +- #8908 `4a974b2` Update bitcoin-qt.desktop (s-matthew-english) +- #9190 `dc46b10` Plug many memory leaks (laanwj) + +### Wallet +- #9290 `35174a0` Make RelayWalletTransaction attempt to AcceptToMemoryPool (gmaxwell) +- #9295 `43bcfca` Bugfix: Fundrawtransaction: don't terminate when keypool is empty (jonasschnelli) +- #9302 `f5d606e` Return txid even if ATMP fails for new transaction (sipa) + +### Tests and QA +- #9159 `eca9b46` Wait for specific block announcement in p2p-compactblocks (ryanofsky) +- #9186 `dccdc3a` Fix use-after-free in scheduler tests (laanwj) +- #9168 `3107280` Add assert_raises_message to check specific error message (mrbandrews) +- #9191 `29435db` 0.13.2 Backports (MarcoFalke) +- #9077 `1d4c884` Increase wallet-dump RPC timeout (ryanofsky) +- #9098 `ecd7db5` Handle zombies and cluttered tmpdirs (MarcoFalke) +- #8927 `387ec9d` Add script tests for FindAndDelete in pre-segwit and segwit scripts (jl2012) +- #9200 `eebc699` bench: Fix subtle counting issue when rescaling iteration count (laanwj) + +### Miscellaneous +- #8838 `094848b` Calculate size and weight of block correctly in CreateNewBlock() (jnewbery) +- #8920 `40169dc` Set minimum required Boost to 1.47.0 (fanquake) +- #9251 `a710a43` Improvement of documentation of command line parameter 'whitelist' (wodry) +- #8932 `106da69` Allow bitcoin-tx to create v2 transactions (btcdrak) +- #8929 `12428b4` add software-properties-common (sigwo) +- #9120 `08d1c90` bug: Missed one "return false" in recent refactoring in #9067 (UdjinM6) +- #9067 `f85ee01` Fix exit codes (UdjinM6) +- #9340 `fb987b3` [0.13] Update secp256k1 subtree (MarcoFalke) +- #9229 `b172377` Remove calls to getaddrinfo_a (TheBlueMatt) Credits ======= Thanks to everyone who directly contributed to this release: -(to be filled in at release time) +- Alex Morcos +- BtcDrak +- Cory Fields +- fanquake +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- Ivo van der Sangen +- jnewbery +- Johnson Lau +- Jonas Schnelli +- Luke Dashjr +- maiiz +- MarcoFalke +- Masahiko Hyuga +- Matt Corallo +- matthias +- mrbandrews +- Pavel Janík +- Pieter Wuille +- randy-waterhouse +- Russell Yanofsky +- S. Matthew English +- Steven +- Suhas Daftuar +- UdjinM6 +- Wladimir J. van der Laan +- wodry As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 7201dd7732fa69b498b1d647c66c2460af9bed7b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 19 Dec 2016 13:14:01 +0000 Subject: [PATCH 1208/1223] qt: Pre-rc1 translations update --- src/qt/bitcoinstrings.cpp | 8 +- src/qt/locale/bitcoin_ca.ts | 768 ++++++- src/qt/locale/bitcoin_ca_ES.ts | 774 ++++++- src/qt/locale/bitcoin_cs.ts | 1392 +++++++++++- src/qt/locale/bitcoin_de.ts | 398 +++- src/qt/locale/bitcoin_en.ts | 116 +- src/qt/locale/bitcoin_en_GB.ts | 112 +- src/qt/locale/bitcoin_es.ts | 1054 ++++++++- src/qt/locale/bitcoin_es_ES.ts | 3645 +++++++++++++++++++++++++++++++- src/qt/locale/bitcoin_et.ts | 886 +++++++- src/qt/locale/bitcoin_fa.ts | 322 ++- src/qt/locale/bitcoin_fr.ts | 1108 +++++++++- src/qt/locale/bitcoin_it_IT.ts | 10 +- src/qt/locale/bitcoin_ko_KR.ts | 28 + src/qt/locale/bitcoin_ku_IQ.ts | 72 + src/qt/locale/bitcoin_pl.ts | 262 ++- src/qt/locale/bitcoin_pt_BR.ts | 1236 ++++++++++- src/qt/locale/bitcoin_pt_PT.ts | 8 + src/qt/locale/bitcoin_sk.ts | 28 +- src/qt/locale/bitcoin_sv.ts | 219 +- src/qt/locale/bitcoin_ta.ts | 20 + src/qt/locale/bitcoin_vi_VN.ts | 262 ++- src/qt/locale/bitcoin_zh_CN.ts | 853 +++++++- 23 files changed, 13228 insertions(+), 353 deletions(-) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index b64ae5c70..7f90a51c5 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -145,6 +145,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Sets the serialization of raw transaction or block hex returned in non-" +"verbose mode, non-segwit(0) or segwit(1) (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Support filtering of blocks and transaction with bloom filters (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "The block database contains a block which appears to be from the future. " @@ -201,8 +204,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: We do not appear to fully agree with our peers! You may need to " "upgrade, or other nodes may need to upgrade."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Whitelist peers connecting from the given netmask or IP address. Can be " -"specified multiple times."), +"Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR " +"notated network (e.g. 1.2.3.0/24). Can be specified multiple times."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Whitelisted peers cannot be DoS banned and their transactions are always " "relayed, even if they are already in the mempool, useful e.g. for a gateway"), @@ -275,6 +278,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s' ( QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most unconnectable transactions in memory (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below megabytes (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Keypool ran out, please call keypoolrefill first"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 355cd4418..c4cb86d82 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -41,10 +41,78 @@ &Delete &Elimina -
+ + Choose the address to send coins to + Trieu l'adreça on enviar les monedes + + + Choose the address to receive coins with + Trieu l'adreça on rebre les monedes + + + C&hoose + &Tria + + + Sending addresses + Adreces d'enviament + + + Receiving addresses + Adreces de recepció + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. + + + &Copy Address + &Copia l'adreça + + + Copy &Label + Copia l'eti&queta + + + &Edit + &Edita + + + Export Address List + Exporta la llista d'adreces + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Exporting Failed + L'exportació ha fallat + + + There was an error trying to save the address list to %1. Please try again. + S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. + + AddressTableModel - + + Label + Etiqueta + + + Address + Adreça + + + (no label) + (sense etiqueta) + + AskPassphraseDialog @@ -63,7 +131,95 @@ Repeat new passphrase Repetiu la nova contrasenya - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>. + + + Encrypt wallet + Encripta el moneder + + + This operation needs your wallet passphrase to unlock the wallet. + Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. + + + Unlock wallet + Desbloqueja el moneder + + + This operation needs your wallet passphrase to decrypt the wallet. + Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. + + + Decrypt wallet + Desencripta el moneder + + + Change passphrase + Canvia la contrasenya + + + Enter the old passphrase and new passphrase to the wallet. + Introduïu la contrasenya antiga i la contrasenya nova al moneder. + + + Confirm wallet encryption + Confirma l'encriptació del moneder + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Esteu segur que voleu encriptar el vostre moneder? + + + Wallet encrypted + Moneder encriptat + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Ara es tancarà el %1 per finalitzar el procés d'encriptació. Recordeu que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. Per motius de seguretat, les còpies de seguretat anteriors del fitxer de moneder no encriptat esdevindran inusables tan aviat com començar a utilitzar el nou moneder encriptat. + + + Wallet encryption failed + L'encriptació del moneder ha fallat + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. + + + The supplied passphrases do not match. + Les contrasenyes introduïdes no coincideixen. + + + Wallet unlock failed + El desbloqueig del moneder ha fallat + + + The passphrase entered for the wallet decryption was incorrect. + La contrasenya introduïda per a desencriptar el moneder és incorrecta. + + + Wallet decryption failed + La desencriptació del moneder ha fallat + + + Wallet passphrase was successfully changed. + La contrasenya del moneder ha estat modificada correctament. + + + Warning: The Caps Lock key is on! + Avís: Les lletres majúscules estan activades! + + BanTableModel @@ -113,6 +269,14 @@ Quit application Surt de l'aplicació + + &About %1 + Qu&ant al %1 + + + Show information about %1 + Mosta informació sobre el %1 + About &Qt Quant a &Qt @@ -125,6 +289,10 @@ &Options... &Opcions... + + Modify configuration options for %1 + Modifica les opcions de configuració de %1 + &Encrypt Wallet... &Encripta el moneder... @@ -143,7 +311,7 @@ &Receiving addresses... - Adreces de &recepció + Adreces de &recepció... Open &URI... @@ -253,6 +421,14 @@ %n active connection(s) to Bitcoin network %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin + + Indexing blocks on disk... + S'estan indexant els blocs al disc... + + + Processing blocks on disk... + S'estan processant els blocs al disc... + No block source available... No hi ha cap font de bloc disponible... @@ -309,6 +485,14 @@ Up to date Al dia + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra el missatge d'ajuda del %1 per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin + + + %1 client + Client de %1 + Catching up... S'està posant al dia ... @@ -438,7 +622,143 @@ Priority Prioritat - + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Copy quantity + Copia la quantitat + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + highest + el més alt + + + higher + més alt + + + high + alt + + + medium-high + mig-alt + + + medium + mig + + + low-medium + baix-mig + + + low + baix + + + lower + més baix + + + lowest + el més baix + + + (%1 locked) + (%1 bloquejada) + + + none + cap + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Això comporta que cal una comissió d'almenys %1 per kB. + + + Can vary +/- 1 byte per input. + Pot variar +/- 1 byte per entrada. + + + Transactions with higher priority are more likely to get included into a block. + Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. + + + This label turns red if the priority is smaller than "medium". + Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Aquesta etiqueta es torna vermella si cap recipient rep un import inferior al llindar de polsim actual. + + + Can vary +/- %1 satoshi(s) per input. + Pot variar en +/- %1 satoshi(s) per entrada. + + + (no label) + (sense etiqueta) + + + change from %1 (%2) + canvia de %1 (%2) + + + (change) + (canvia) + + EditAddressDialog @@ -461,7 +781,39 @@ &Address &Adreça - + + New receiving address + Nova adreça de recepció + + + New sending address + Nova adreça d'enviament + + + Edit receiving address + Edita l'adreça de recepció + + + Edit sending address + Edita l'adreça d'enviament + + + The entered address "%1" is not a valid Bitcoin address. + L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. + + + The entered address "%1" is already in the address book. + L'adreça introduïda «%1» ja és present a la llibreta d'adreces. + + + Could not unlock wallet. + No s'ha pogut desbloquejar el moneder. + + + New key generation failed. + Ha fallat la generació d'una clau nova. + + FreespaceChecker @@ -495,6 +847,10 @@ (%1-bit) (%1-bit) + + About %1 + Quant al %1 + Command-line options Opcions de línia d'ordres @@ -531,12 +887,28 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - + + Reset all settings changed in the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + + Intro Welcome - Us donem la benviguda + Us donem la benvinguda + + + Welcome to %1. + Us donem la benvinguda a %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Com és la primera vegada que s'executa el programa, podeu triar on %1 emmagatzemarà les dades. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 baixarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim %2GB de dades s'emmagatzemaran en aquest directori, i augmentarà al llarg del temps. El moneder també s'emmagatzemarà en aquest directori. Use the default data directory @@ -581,7 +953,11 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + + Select payment request file to open + Seleccioneu el fitxer de sol·licitud de pagament per obrir + + OptionsDialog @@ -592,6 +968,14 @@ &Main &Principal + + Automatically start %1 after logging in to the system. + Inicieu %1 automàticament després d'entrar en el sistema. + + + &Start %1 on system login + &Inicia %1 en l'entrada al sistema + Size of &database cache Mida de la memòria cau de la base de &dades @@ -728,6 +1112,14 @@ &Window &Finestra + + &Hide the icon from the system tray. + Ama&ga la icona de la safata del sistema. + + + Hide tray icon + Amaga la icona de la safata + Show only a tray icon after minimizing the window. Mostra només la icona de la barra en minimitzar la finestra. @@ -748,6 +1140,10 @@ User Interface &language: &Llengua de la interfície d'usuari: + + The user interface language can be set here. This setting will take effect after restarting %1. + Aquí es pot definir la llengua de la interfície d'usuari. Aquest paràmetre tindrà efecte en reiniciar el %1. + &Unit to show amounts in: &Unitats per mostrar els imports en: @@ -874,7 +1270,27 @@ PaymentServer - + + Payment request error + Error de la sol·licitud de pagament + + + Cannot start bitcoin: click-to-pay handler + No es pot iniciar bitcoin: controlador click-to-pay + + + URI handling + Gestió d'URI + + + Network request error + Error en la sol·licitud de xarxa + + + Payment acknowledged + Pagament reconegut + + PeerTableModel @@ -931,7 +1347,23 @@ QRImageWidget - + + &Save Image... + De&sa la imatge... + + + &Copy Image + &Copia la imatge + + + Save QR Code + Desa el codi QR + + + PNG Image (*.png) + Imatge PNG (*.png) + + RPCConsole @@ -958,6 +1390,10 @@ Using BerkeleyDB version Utilitzant BerkeleyDB versió + + Datadir + Datadir + Startup time &Temps d'inici @@ -1273,7 +1709,15 @@ Remove Esborra - + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + ReceiveRequestDialog @@ -1292,10 +1736,66 @@ &Save Image... De&sa la imatge... + + Request payment to %1 + Sol·licita un pagament a %1 + + + Payment information + Informació de pagament + + + URI + URI + + + Address + Adreça + + + Amount + Import + + + Label + Etiqueta + + + Message + Missatge + RecentRequestsTableModel - + + Date + Data + + + Label + Etiqueta + + + Message + Missatge + + + (no label) + (sense etiqueta) + + + (no message) + (sense missatge) + + + (no amount requested) + (no s'ha sol·licitat import) + + + Requested + Sol·licitat + + SendCoinsDialog @@ -1446,7 +1946,79 @@ S&end E&nvia - + + Copy quantity + Copia la quantitat + + + Copy amount + Copia l'import + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + Total Amount %1 + Import total %1 + + + or + o + + + Confirm send coins + Confirma l'enviament de monedes + + + The recipient address is not valid. Please recheck. + L'adreça del destinatari no és vàlida. Torneu-la a comprovar. + + + The amount to pay must be larger than 0. + L'import a pagar ha de ser major que 0. + + + The amount exceeds your balance. + L'import supera el vostre balanç. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excedeix el vostre balanç quan s'afegeix la comissió a la transacció %1. + + + Duplicate address found: addresses should only be used once each. + S'ha trobat una adreça duplicada: les adreces només s'haurien d'utilitzar una vegada cada una. + + + Transaction creation failed! + La creació de la transacció ha fallat! + + + (no label) + (sense etiqueta) + + SendCoinsEntry @@ -1639,6 +2211,74 @@ TransactionDesc + + Status + Estat + + + Date + Data + + + Source + Font + + + Generated + Generada + + + From + De + + + unknown + desconegut + + + To + A + + + own address + adreça pròpia + + + Debit + Dèbit + + + Total debit + Dèbit total + + + Total credit + Crèdit total + + + Transaction fee + Comissió de transacció + + + Net amount + Import net + + + Message + Missatge + + + Comment + Comentari + + + Transaction ID + ID de la transacció + + + Amount + Import + TransactionDescDialog @@ -1649,9 +2289,109 @@ TransactionTableModel + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Offline + Fora de línia + + + Unconfirmed + Sense confirmar + + + Abandoned + Abandonada + + + Received with + Rebuda amb + + + Received from + Rebuda de + + + Sent to + Enviada a + + + Payment to yourself + Pagament a un mateix + + + Mined + Minada + + + (no label) + (sense etiqueta) + TransactionView + + Received with + Rebuda amb + + + Sent to + Enviada a + + + Mined + Minada + + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Address + Adreça + + + Exporting Failed + L'exportació ha fallat + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 976881531..410b6e616 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -41,10 +41,78 @@ &Delete &Elimina - + + Choose the address to send coins to + Trieu l'adreça on enviar les monedes + + + Choose the address to receive coins with + Trieu l'adreça on rebre les monedes + + + C&hoose + &Tria + + + Sending addresses + Adreces d'enviament + + + Receiving addresses + Adreces de recepció + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. + + + &Copy Address + &Copia l'adreça + + + Copy &Label + Copia l'eti&queta + + + &Edit + &Edita + + + Export Address List + Exporta la llista d'adreces + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Exporting Failed + L'exportació ha fallat + + + There was an error trying to save the address list to %1. Please try again. + S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. + + AddressTableModel - + + Label + Etiqueta + + + Address + Adreça + + + (no label) + (sense etiqueta) + + AskPassphraseDialog @@ -63,7 +131,95 @@ Repeat new passphrase Repetiu la nova contrasenya - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>. + + + Encrypt wallet + Encripta el moneder + + + This operation needs your wallet passphrase to unlock the wallet. + Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. + + + Unlock wallet + Desbloqueja el moneder + + + This operation needs your wallet passphrase to decrypt the wallet. + Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. + + + Decrypt wallet + Desencripta el moneder + + + Change passphrase + Canvia la contrasenya + + + Enter the old passphrase and new passphrase to the wallet. + Introduïu la contrasenya antiga i la contrasenya nova al moneder. + + + Confirm wallet encryption + Confirma l'encriptació del moneder + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Esteu segur que voleu encriptar el vostre moneder? + + + Wallet encrypted + Moneder encriptat + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Ara es tancarà el %1 per finalitzar el procés d'encriptació. Recordeu que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. Per motius de seguretat, les còpies de seguretat anteriors del fitxer de moneder no encriptat esdevindran inusables tan aviat com començar a utilitzar el nou moneder encriptat. + + + Wallet encryption failed + L'encriptació del moneder ha fallat + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. + + + The supplied passphrases do not match. + Les contrasenyes introduïdes no coincideixen. + + + Wallet unlock failed + El desbloqueig del moneder ha fallat + + + The passphrase entered for the wallet decryption was incorrect. + La contrasenya introduïda per a desencriptar el moneder és incorrecta. + + + Wallet decryption failed + La desencriptació del moneder ha fallat + + + Wallet passphrase was successfully changed. + La contrasenya del moneder ha estat modificada correctament. + + + Warning: The Caps Lock key is on! + Avís: Les lletres majúscules estan activades! + + BanTableModel @@ -113,6 +269,14 @@ Quit application Surt de l'aplicació + + &About %1 + Qu&ant al %1 + + + Show information about %1 + Mosta informació sobre el %1 + About &Qt Quant a &Qt @@ -125,6 +289,10 @@ &Options... &Opcions... + + Modify configuration options for %1 + Modifica les opcions de configuració de %1 + &Encrypt Wallet... &Encripta el moneder... @@ -143,7 +311,7 @@ &Receiving addresses... - Adreces de &recepció + Adreces de &recepció... Open &URI... @@ -253,6 +421,14 @@ %n active connection(s) to Bitcoin network %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin + + Indexing blocks on disk... + S'estan indexant els blocs al disc... + + + Processing blocks on disk... + S'estan processant els blocs al disc... + No block source available... No hi ha cap font de bloc disponible... @@ -309,6 +485,14 @@ Up to date Al dia + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra el missatge d'ajuda del %1 per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin + + + %1 client + Client de %1 + Catching up... S'està posant al dia ... @@ -438,7 +622,143 @@ Priority Prioritat - + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Copy quantity + Copia la quantitat + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + highest + el més alt + + + higher + més alt + + + high + alt + + + medium-high + mig-alt + + + medium + mig + + + low-medium + baix-mig + + + low + baix + + + lower + més baix + + + lowest + el més baix + + + (%1 locked) + (%1 bloquejada) + + + none + cap + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Això comporta que cal una comissió d'almenys %1 per kB. + + + Can vary +/- 1 byte per input. + Pot variar +/- 1 byte per entrada. + + + Transactions with higher priority are more likely to get included into a block. + Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. + + + This label turns red if the priority is smaller than "medium". + Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Aquesta etiqueta es torna vermella si cap recipient rep un import inferior al llindar de polsim actual. + + + Can vary +/- %1 satoshi(s) per input. + Pot variar en +/- %1 satoshi(s) per entrada. + + + (no label) + (sense etiqueta) + + + change from %1 (%2) + canvia de %1 (%2) + + + (change) + (canvia) + + EditAddressDialog @@ -461,7 +781,39 @@ &Address &Adreça - + + New receiving address + Nova adreça de recepció + + + New sending address + Nova adreça d'enviament + + + Edit receiving address + Edita l'adreça de recepció + + + Edit sending address + Edita l'adreça d'enviament + + + The entered address "%1" is not a valid Bitcoin address. + L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. + + + The entered address "%1" is already in the address book. + L'adreça introduïda «%1» ja és present a la llibreta d'adreces. + + + Could not unlock wallet. + No s'ha pogut desbloquejar el moneder. + + + New key generation failed. + Ha fallat la generació d'una clau nova. + + FreespaceChecker @@ -495,6 +847,10 @@ (%1-bit) (%1-bit) + + About %1 + Quant al %1 + Command-line options Opcions de línia d'ordres @@ -531,12 +887,28 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - + + Reset all settings changed in the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + + Intro Welcome - Us donem la benviguda + Us donem la benvinguda + + + Welcome to %1. + Us donem la benvinguda a %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Com és la primera vegada que s'executa el programa, podeu triar on %1 emmagatzemarà les dades. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 baixarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim %2GB de dades s'emmagatzemaran en aquest directori, i augmentarà al llarg del temps. El moneder també s'emmagatzemarà en aquest directori. Use the default data directory @@ -581,7 +953,11 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + + Select payment request file to open + Seleccioneu el fitxer de sol·licitud de pagament per obrir + + OptionsDialog @@ -592,6 +968,14 @@ &Main &Principal + + Automatically start %1 after logging in to the system. + Inicieu %1 automàticament després d'entrar en el sistema. + + + &Start %1 on system login + &Inicia %1 en l'entrada al sistema + Size of &database cache Mida de la memòria cau de la base de &dades @@ -728,6 +1112,14 @@ &Window &Finestra + + &Hide the icon from the system tray. + Ama&ga la icona de la safata del sistema. + + + Hide tray icon + Amaga la icona de la safata + Show only a tray icon after minimizing the window. Mostra només la icona de la barra en minimitzar la finestra. @@ -748,6 +1140,10 @@ User Interface &language: &Llengua de la interfície d'usuari: + + The user interface language can be set here. This setting will take effect after restarting %1. + Aquí es pot definir la llengua de la interfície d'usuari. Aquest paràmetre tindrà efecte en reiniciar el %1. + &Unit to show amounts in: &Unitats per mostrar els imports en: @@ -874,7 +1270,27 @@ PaymentServer - + + Payment request error + Error de la sol·licitud de pagament + + + Cannot start bitcoin: click-to-pay handler + No es pot iniciar bitcoin: controlador click-to-pay + + + URI handling + Gestió d'URI + + + Network request error + Error en la sol·licitud de xarxa + + + Payment acknowledged + Pagament reconegut + + PeerTableModel @@ -931,7 +1347,23 @@ QRImageWidget - + + &Save Image... + De&sa la imatge... + + + &Copy Image + &Copia la imatge + + + Save QR Code + Desa el codi QR + + + PNG Image (*.png) + Imatge PNG (*.png) + + RPCConsole @@ -958,6 +1390,10 @@ Using BerkeleyDB version Utilitzant BerkeleyDB versió + + Datadir + Datadir + Startup time &Temps d'inici @@ -1273,7 +1709,15 @@ Remove Esborra - + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + ReceiveRequestDialog @@ -1292,10 +1736,66 @@ &Save Image... De&sa la imatge... + + Request payment to %1 + Sol·licita un pagament a %1 + + + Payment information + Informació de pagament + + + URI + URI + + + Address + Adreça + + + Amount + Import + + + Label + Etiqueta + + + Message + Missatge + RecentRequestsTableModel - + + Date + Data + + + Label + Etiqueta + + + Message + Missatge + + + (no label) + (sense etiqueta) + + + (no message) + (sense missatge) + + + (no amount requested) + (no s'ha sol·licitat import) + + + Requested + Sol·licitat + + SendCoinsDialog @@ -1446,7 +1946,79 @@ S&end E&nvia - + + Copy quantity + Copia la quantitat + + + Copy amount + Copia l'import + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + Total Amount %1 + Import total %1 + + + or + o + + + Confirm send coins + Confirma l'enviament de monedes + + + The recipient address is not valid. Please recheck. + L'adreça del destinatari no és vàlida. Torneu-la a comprovar. + + + The amount to pay must be larger than 0. + L'import a pagar ha de ser major que 0. + + + The amount exceeds your balance. + L'import supera el vostre balanç. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excedeix el vostre balanç quan s'afegeix la comissió a la transacció %1. + + + Duplicate address found: addresses should only be used once each. + S'ha trobat una adreça duplicada: les adreces només s'haurien d'utilitzar una vegada cada una. + + + Transaction creation failed! + La creació de la transacció ha fallat! + + + (no label) + (sense etiqueta) + + SendCoinsEntry @@ -1639,6 +2211,74 @@ TransactionDesc + + Status + Estat + + + Date + Data + + + Source + Font + + + Generated + Generada + + + From + De + + + unknown + desconegut + + + To + A + + + own address + adreça pròpia + + + Debit + Dèbit + + + Total debit + Dèbit total + + + Total credit + Crèdit total + + + Transaction fee + Comissió de transacció + + + Net amount + Import net + + + Message + Missatge + + + Comment + Comentari + + + Transaction ID + ID de la transacció + + + Amount + Import + TransactionDescDialog @@ -1649,9 +2289,109 @@ TransactionTableModel + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Offline + Fora de línia + + + Unconfirmed + Sense confirmar + + + Abandoned + Abandonada + + + Received with + Rebuda amb + + + Received from + Rebuda de + + + Sent to + Enviada a + + + Payment to yourself + Pagament a un mateix + + + Mined + Minada + + + (no label) + (sense etiqueta) + TransactionView + + Received with + Rebuda amb + + + Sent to + Enviada a + + + Mined + Minada + + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Address + Adreça + + + Exporting Failed + L'exportació ha fallat + UnitDisplayStatusBarControl @@ -1737,7 +2477,11 @@ Bitcoin Core - Nucli de Bitcoin + Bitcoin Core + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee és molt elevat. Aquesta és la comissió de transacció que podeu pagar quan les estimacions de comissions no estan disponibles. Bind to given address and always listen on it. Use [host]:port notation for IPv6 diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 449e67dd3..02e959d01 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -15,7 +15,7 @@ Copy the currently selected address to the system clipboard - Zkopíruj aktuálně vybranou adresu do systémové schránky + Zkopíruj tuto adresu do systémové schránky &Copy @@ -27,7 +27,7 @@ Delete the currently selected address from the list - Smaž zvolenou adresu ze seznamu + Smaž tuto adresu ze seznamu Export the data in the current tab to a file @@ -41,10 +41,78 @@ &Delete S&maž - + + Choose the address to send coins to + Zvol adresu, na kterou pošleš mince + + + Choose the address to receive coins with + Zvol adres na příjem mincí + + + C&hoose + &Zvol + + + Sending addresses + Odesílací adresy + + + Receiving addresses + Přijímací adresy + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Tohle jsou tvé Bitcoinové adresy pro posílání plateb. Před odesláním mincí si vždy zkontroluj částku a cílovou adresu. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Nezapomeň si pro každou transakci vždy vygenerovat novou adresu. + + + &Copy Address + &Kopíruj adresu + + + Copy &Label + Kopíruj &označení + + + &Edit + &Uprav + + + Export Address List + Export seznamu adres + + + Comma separated file (*.csv) + Formát CSV (*.csv) + + + Exporting Failed + Exportování selhalo + + + There was an error trying to save the address list to %1. Please try again. + Při ukládání seznamu adres do %1 se přihodila nějaká chyba. Zkus to prosím znovu. + + AddressTableModel - + + Label + Označení + + + Address + Adresa + + + (no label) + (bez označení) + + AskPassphraseDialog @@ -63,10 +131,106 @@ Repeat new passphrase Totéž heslo ještě jednou - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Zadej nové heslo k peněžence.<br/>Použij <b>alespoň deset náhodných znaků</b> nebo <b>alespoň osm slov</b>. + + + Encrypt wallet + Zašifruj peněženku + + + This operation needs your wallet passphrase to unlock the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla odemknout. + + + Unlock wallet + Odemkni peněženku + + + This operation needs your wallet passphrase to decrypt the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla dešifrovat. + + + Decrypt wallet + Dešifruj peněženku + + + Change passphrase + Změň heslo + + + Enter the old passphrase and new passphrase to the wallet. + Zadej staré a nové heslo k peněžence. + + + Confirm wallet encryption + Potvrď zašifrování peněženky + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Upozornění: Pokud si zašifruješ peněženku a ztratíš či zapomeneš heslo, <b>PŘIJDEŠ O VŠECHNY BITCOINY</b>! + + + Are you sure you wish to encrypt your wallet? + Jsi si jistý, že chceš peněženku zašifrovat? + + + Wallet encrypted + Peněženka je zašifrována + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky nemůže zabránit krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + DŮLEŽITÉ: Všechny předchozí zálohy peněženky by měly být nahrazeny nově vygenerovanou, zašifrovanou peněženkou. Z bezpečnostních důvodů budou předchozí zálohy nešifrované peněženky nepoužitelné, jakmile začneš používat novou zašifrovanou peněženku. + + + Wallet encryption failed + Zašifrování peněženky selhalo + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Zašifrování peněženky selhalo kvůli vnitřní chybě. Tvá peněženka tedy nebyla zašifrována. + + + The supplied passphrases do not match. + Zadaná hesla nejsou shodná. + + + Wallet unlock failed + Nepodařilo se odemknout peněženku + + + The passphrase entered for the wallet decryption was incorrect. + Nezadal jsi správné heslo pro dešifrování peněženky. + + + Wallet decryption failed + Nepodařilo se dešifrovat peněženku + + + Wallet passphrase was successfully changed. + Heslo k peněžence bylo v pořádku změněno. + + + Warning: The Caps Lock key is on! + Upozornění: Caps Lock je zapnutý! + + BanTableModel - + + IP/Netmask + IP/Maska + + + Banned Until + Blokován do + + BitcoinGUI @@ -105,6 +269,14 @@ Quit application Ukonči aplikaci + + &About %1 + O &%1 + + + Show information about %1 + Zobraz informace o %1 + About &Qt O &Qt @@ -117,6 +289,10 @@ &Options... &Možnosti... + + Modify configuration options for %1 + Uprav nastavení %1 + &Encrypt Wallet... Zaši&fruj peněženku... @@ -245,6 +421,14 @@ %n active connection(s) to Bitcoin network %n aktivní spojení do Bitcoinové sítě%n aktivní spojení do Bitcoinové sítě%n aktivních spojení do Bitcoinové sítě + + Indexing blocks on disk... + Vytvářím index bloků na disku... + + + Processing blocks on disk... + Zpracovávám bloky na disku... + No block source available... Není dostupný žádný zdroj bloků... @@ -283,7 +467,7 @@ Transactions after this will not yet be visible. - Novější transakce zatím nejsou vidět. + Následné transakce ještě nebudou vidět. Error @@ -301,6 +485,14 @@ Up to date Aktuální + + Show the %1 help message to get a list with possible Bitcoin command-line options + Seznam argumentů Bitcoinu pro příkazovou řádku získáš v nápovědě %1 + + + %1 client + %1 klient + Catching up... Stahuji... @@ -430,7 +622,87 @@ Priority Priorita - + + Copy address + Kopíruj adresu + + + Copy label + Kopíruj její označení + + + Copy amount + Kopíruj částku + + + Copy transaction ID + Kopíruj ID transakce + + + Lock unspent + Zamkni neutracené + + + Unlock unspent + Odemkni k utracení + + + Copy quantity + Kopíruj počet + + + Copy fee + Kopíruj poplatek + + + Copy after fee + Kopíruj čistou částku + + + Copy bytes + Kopíruj bajty + + + Copy dust + Kopíruj prach + + + Copy change + Kopíruj drobné + + + (%1 locked) + (%1 zamčeno) + + + yes + ano + + + no + ne + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Popisek zčervená, pokud má některý příjemce obdržet částku menší, než je aktuální práh pro prach. + + + Can vary +/- %1 satoshi(s) per input. + Může se lišit o +/– %1 satoshi na každý vstup. + + + (no label) + (bez označení) + + + change from %1 (%2) + drobné z %1 (%2) + + + (change) + (drobné) + + EditAddressDialog @@ -453,7 +725,39 @@ &Address &Adresa - + + New receiving address + Nová přijímací adresa + + + New sending address + Nová odesílací adresa + + + Edit receiving address + Uprav přijímací adresu + + + Edit sending address + Uprav odesílací adresu + + + The entered address "%1" is not a valid Bitcoin address. + Zadaná adresa „%1“ není platná Bitcoinová adresa. + + + The entered address "%1" is already in the address book. + Zadaná adresa „%1“ už v adresáři je. + + + Could not unlock wallet. + Nemohu odemknout peněženku. + + + New key generation failed. + Nepodařilo se mi vygenerovat nový klíč. + + FreespaceChecker @@ -487,6 +791,10 @@ (%1-bit) (%1-bit) + + About %1 + O %1 + Command-line options Argumenty příkazové řádky @@ -523,13 +831,29 @@ Show splash screen on startup (default: %u) Zobrazit startovací obrazovku (výchozí: %u) - + + Reset all settings changed in the GUI + Vrátit všechny volby měněné v GUI na výchozí hodnoty + + Intro Welcome Vítej + + Welcome to %1. + Vítej v %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Tohle je poprvé, co spouštíš %1, takže si můžeš zvolit, kam bude ukládat svá data. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 bude stahovat kopii řetězce bloků. Proto bude potřeba do tohoto adresáře uložit nejméně %2 GB dat – toto číslo bude navíc v průběhu času růst. Tvá peněženka bude rovněž uložena v tomto adresáři. + Use the default data directory Použij výchozí adresář pro data @@ -573,7 +897,11 @@ Select payment request file Vyber soubor platebního požadavku - + + Select payment request file to open + Vyber soubor platebního požadavku k načtení + + OptionsDialog @@ -584,6 +912,14 @@ &Main &Hlavní + + Automatically start %1 after logging in to the system. + Automaticky spustí %1 po přihlášení do systému. + + + &Start %1 on system login + S&pustit %1 po přihlášení do systému + Size of &database cache Velikost &databázové cache @@ -622,7 +958,7 @@ Active command-line options that override above options: - Aktivní argumenty z příkazové řádky, které mají přednost před nastavením výše: + Aktivní argumenty z příkazové řádky, které přetloukly tato nastavení: Reset all client options to default. @@ -690,7 +1026,7 @@ Used for reaching peers via: - Použije se k připojování k protějškům přes: + Použije se k připojování k protějskům přes: Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. @@ -720,6 +1056,14 @@ &Window O&kno + + &Hide the icon from the system tray. + Skryje ikonu, která se zobrazuje v panelu. + + + Hide tray icon + Skrýt &ikonu z panelu + Show only a tray icon after minimizing the window. Po minimalizaci okna zobrazí pouze ikonu v panelu. @@ -740,6 +1084,10 @@ User Interface &language: &Jazyk uživatelského rozhraní: + + The user interface language can be set here. This setting will take effect after restarting %1. + Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování %1. + &Unit to show amounts in: Je&dnotka pro částky: @@ -754,7 +1102,7 @@ &OK - &Použít + &Budiž &Cancel @@ -782,7 +1130,7 @@ This change would require a client restart. - Tato změna vyžaduje restart aplikace. + Tahle změna bude chtít restartovat klienta. The supplied proxy address is invalid. @@ -829,7 +1177,7 @@ Balances - Stav účtů + Stavy účtů Total: @@ -866,7 +1214,95 @@ PaymentServer - + + Payment request error + Chyba platebního požadavku + + + Cannot start bitcoin: click-to-pay handler + Nemůžu spustit bitcoin: obsluha click-to-pay + + + URI handling + Zpracování URI + + + Payment request fetch URL is invalid: %1 + Zdrojová URL platebního požadavku není platná: %1 + + + Invalid payment address %1 + Neplatná platební adresa %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + Nepodařilo se analyzovat URI! Důvodem může být neplatná Bitcoinová adresa nebo poškozené parametry URI. + + + Payment request file handling + Zpracování souboru platebního požadavku + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku. + + + Payment request rejected + Platební požadavek byl odmítnut + + + Payment request network doesn't match client network. + Síť platebního požadavku neodpovídá síti klienta. + + + Payment request expired. + Platební požadavek vypršel. + + + Payment request is not initialized. + Platební požadavek není zahájený. + + + Unverified payment requests to custom payment scripts are unsupported. + Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované. + + + Invalid payment request. + Neplatný platební požadavek. + + + Requested payment amount of %1 is too small (considered dust). + Požadovaná platební částka %1 je příliš malá (je považována za prach). + + + Refund from %1 + Vrácení peněz od %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů). + + + Error communicating with %1: %2 + Chyba při komunikaci s %1: %2 + + + Payment request cannot be parsed! + Platební požadavek je nečitelný! + + + Bad response from server %1 + Chybná odpověď ze serveru %1 + + + Network request error + Chyba síťového požadavku + + + Payment acknowledged + Platba potvrzena + + PeerTableModel @@ -923,12 +1359,28 @@ QRImageWidget - + + &Save Image... + &Ulož obrázek... + + + &Copy Image + &Kopíruj obrázek + + + Save QR Code + Ulož QR kód + + + PNG Image (*.png) + PNG obrázek (*.png) + + RPCConsole N/A - N/A + nedostupná informace Client version @@ -950,6 +1402,10 @@ Using BerkeleyDB version Používaná verze BerkeleyDB + + Datadir + Adresář s daty + Startup time Čas spuštění @@ -974,9 +1430,17 @@ Current number of blocks Aktuální počet bloků + + Memory Pool + Transakční zásobník + + + Current number of transactions + Aktuální množství transakcí + Memory usage - Využití paměti + Obsazenost paměti Received @@ -990,10 +1454,18 @@ &Peers &Protějšky + + Banned peers + Protějšky pod klatbou (blokované) + Select a peer to view detailed information. Vyber protějšek a uvidíš jeho detailní informace. + + Whitelisted + Vždy vítán + Direction Směr @@ -1002,10 +1474,34 @@ Version Verze + + Starting Block + Počáteční blok + + + Synced Headers + Aktuálně hlaviček + + + Synced Blocks + Aktuálně bloků + User Agent Typ klienta + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Otevři soubor s ladicími záznamy %1 z aktuálního datového adresáře. U velkých žurnálů to může pár vteřin zabrat. + + + Decrease font size + Zmenšit písmo + + + Increase font size + Zvětšit písmo + Services Služby @@ -1030,6 +1526,14 @@ Ping Time Odezva + + The duration of a currently outstanding ping. + Jak dlouho už čekám na pong. + + + Ping Wait + Doba čekání na odezvu + Time Offset Časový posun @@ -1102,6 +1606,10 @@ &Unban Node &Zbavit uzel klatby + + Welcome to the %1 RPC console. + Vítej v RPC konzoli %1. + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. V historii se pohybuješ šipkami nahoru a dolů a pomocí <b>Ctrl-L</b> čistíš obrazovku. @@ -1229,7 +1737,19 @@ Remove Smazat - + + Copy label + Kopíruj její označení + + + Copy message + Kopíruj zprávu + + + Copy amount + Kopíruj částku + + ReceiveRequestDialog @@ -1248,10 +1768,74 @@ &Save Image... &Ulož obrázek... - + + Request payment to %1 + Platební požadavek: %1 + + + Payment information + Informace o platbě + + + URI + URI + + + Address + Adresa + + + Amount + Částka + + + Label + Označení + + + Message + Zpráva + + + Resulting URI too long, try to reduce the text for label / message. + Výsledná URI je příliš dlouhá, zkus zkrátit text označení/zprávy. + + + Error encoding URI into QR Code. + Chyba při kódování URI do QR kódu. + + RecentRequestsTableModel - + + Date + Datum + + + Label + Označení + + + Message + Zpráva + + + (no label) + (bez označení) + + + (no message) + (bez zprávy) + + + (no amount requested) + (bez požadované částky) + + + Requested + Požádáno + + SendCoinsDialog @@ -1402,7 +1986,111 @@ S&end Pošl&i - + + Copy quantity + Kopíruj počet + + + Copy amount + Kopíruj částku + + + Copy fee + Kopíruj poplatek + + + Copy after fee + Kopíruj čistou částku + + + Copy bytes + Kopíruj bajty + + + Copy dust + Kopíruj prach + + + Copy change + Kopíruj drobné + + + %1 to %2 + %1 pro %2 + + + Are you sure you want to send? + Jsi si jistý, že to chceš poslat? + + + added as transaction fee + přidán jako transakční poplatek + + + Total Amount %1 + Celková částka %1 + + + or + nebo + + + Confirm send coins + Potvrď odeslání mincí + + + The recipient address is not valid. Please recheck. + Adresa příjemce je neplatná – překontroluj ji prosím. + + + The amount to pay must be larger than 0. + Odesílaná částka musí být větší než 0. + + + The amount exceeds your balance. + Částka překračuje stav účtu. + + + The total exceeds your balance when the %1 transaction fee is included. + Celková částka při připočítání poplatku %1 překročí stav účtu. + + + Duplicate address found: addresses should only be used once each. + Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou. + + + Transaction creation failed! + Vytvoření transakce selhalo! + + + A fee higher than %1 is considered an absurdly high fee. + Poplatek vyšší než %1 je považován za absurdně vysoký. + + + Payment request expired. + Platební požadavek vypršel. + + + Pay only the required fee of %1 + Zaplatit pouze vyžadovaný poplatek %1 + + + Estimated to begin confirmation within %n block(s). + Potvrzování by podle odhadu mělo začít během %n bloku.Potvrzování by podle odhadu mělo začít během %n bloků.Potvrzování by podle odhadu mělo začít během %n bloků. + + + Warning: Invalid Bitcoin address + Upozornění: Neplatná Bitcoinová adresa + + + Warning: Unknown change address + Upozornění: Neznámá adresa pro drobné + + + (no label) + (bez označení) + + SendCoinsEntry @@ -1481,12 +2169,24 @@ Memo: Poznámka: - + + Enter a label for this address to add it to your address book + Zadej označení této adresy; obojí se ti pak uloží do adresáře + + SendConfirmationDialog - + + Yes + Ano + + ShutdownWindow + + %1 is shutting down... + %1 se ukončuje... + Do not shut down the computer until this window disappears. Nevypínej počítač, dokud toto okno nezmizí. @@ -1578,7 +2278,59 @@ Reset all verify message fields Vymaž všechna pole formuláře pro ověření zrávy - + + Click "Sign Message" to generate signature + Kliknutím na „Podepiš zprávu“ vygeneruješ podpis + + + The entered address is invalid. + Zadaná adresa je neplatná. + + + Please check the address and try again. + Zkontroluj ji prosím a zkus to pak znovu. + + + The entered address does not refer to a key. + Zadaná adresa nepasuje ke klíči. + + + Wallet unlock was cancelled. + Odemčení peněženky bylo zrušeno. + + + Private key for the entered address is not available. + Soukromý klíč pro zadanou adresu není dostupný. + + + Message signing failed. + Nepodařilo se podepsat zprávu. + + + Message signed. + Zpráva podepsána. + + + The signature could not be decoded. + Podpis nejde dekódovat. + + + Please check the signature and try again. + Zkontroluj ho prosím a zkus to pak znovu. + + + The signature did not match the message digest. + Podpis se neshoduje s hašem zprávy. + + + Message verification failed. + Nepodařilo se ověřit zprávu. + + + Message verified. + Zpráva ověřena. + + SplashScreen @@ -1595,20 +2347,456 @@ TransactionDesc - + + Open for %n more block(s) + Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků + + + Open until %1 + Otřevřeno dokud %1 + + + conflicted with a transaction with %1 confirmations + koliduje s transakcí o %1 konfirmacích + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/nepotvrzeno, %1 + + + in memory pool + v transakčním zásobníku + + + not in memory pool + není ani v transakčním zásobníku + + + abandoned + zanechaná + + + %1/unconfirmed + %1/nepotvrzeno + + + %1 confirmations + %1 potvrzení + + + Status + Stav + + + , has not been successfully broadcast yet + , ještě nebylo rozesláno + + + , broadcast through %n node(s) + , rozesláno přes %n uzel, rozesláno přes %n uzly, rozesláno přes %n uzlů + + + Date + Datum + + + Source + Zdroj + + + Generated + Vygenerováno + + + From + Od + + + unknown + neznámo + + + To + Pro + + + own address + vlastní adresa + + + watch-only + sledovaná + + + label + označení + + + Credit + Příjem + + + matures in %n more block(s) + dozraje po %n blokudozraje po %n blocíchdozraje po %n blocích + + + not accepted + neakceptováno + + + Debit + Výdaj + + + Total debit + Celkové výdaje + + + Total credit + Celkové příjmy + + + Transaction fee + Transakční poplatek + + + Net amount + Čistá částka + + + Message + Zpráva + + + Comment + Komentář + + + Transaction ID + ID transakce + + + Output index + Pořadí výstupu + + + Merchant + Obchodník + + + 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. + Vygenerované mince musí čekat %1 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na „neakceptovaný“ a nepůjde utratit. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. + + + Debug information + Ladicí informace + + + Transaction + Transakce + + + Inputs + Vstupy + + + Amount + Částka + + + true + true + + + false + false + + TransactionDescDialog This pane shows a detailed description of the transaction Toto okno zobrazuje detailní popis transakce - + + Details for %1 + Podrobnosti o %1 + + TransactionTableModel - + + Date + Datum + + + Type + Typ + + + Label + Označení + + + Open for %n more block(s) + Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků + + + Open until %1 + Otřevřeno dokud %1 + + + Offline + Offline + + + Unconfirmed + Nepotvrzeno + + + Abandoned + Zanechaná + + + Confirming (%1 of %2 recommended confirmations) + Potvrzuje se (%1 z %2 doporučených potvrzení) + + + Confirmed (%1 confirmations) + Potvrzeno (%1 potvrzení) + + + Conflicted + V kolizi + + + Immature (%1 confirmations, will be available after %2) + Nedozráno (%1 potvrzení, dozraje při %2 potvrzeních) + + + This block was not received by any other nodes and will probably not be accepted! + Tento blok nedostal žádný jiný uzel a pravděpodobně nebude akceptován! + + + Generated but not accepted + Vygenerováno, ale neakceptováno + + + Received with + Přijato do + + + Received from + Přijato od + + + Sent to + Posláno na + + + Payment to yourself + Platba sama sobě + + + Mined + Vytěženo + + + watch-only + sledovací + + + (n/a) + (n/a) + + + (no label) + (bez označení) + + + Transaction status. Hover over this field to show number of confirmations. + Stav transakce. Najetím myši na toto políčko si zobrazíš počet potvrzení. + + + Date and time that the transaction was received. + Datum a čas přijetí transakce. + + + Type of transaction. + Druh transakce. + + + Whether or not a watch-only address is involved in this transaction. + Zda tato transakce zahrnuje i některou sledovanou adresu. + + + User-defined intent/purpose of the transaction. + Uživatelsky určený účel transakce. + + + Amount removed from or added to balance. + Částka odečtená z nebo přičtená k účtu. + + TransactionView - + + All + Vše + + + Today + Dnes + + + This week + Tento týden + + + This month + Tento měsíc + + + Last month + Minulý měsíc + + + This year + Letos + + + Range... + Rozsah... + + + Received with + Přijato + + + Sent to + Posláno + + + To yourself + Sám sobě + + + Mined + Vytěženo + + + Other + Ostatní + + + Enter address or label to search + Zadej adresu nebo označení pro její vyhledání + + + Min amount + Minimální částka + + + Abandon transaction + Zapomenout transakci + + + Copy address + Kopíruj adresu + + + Copy label + Kopíruj její označení + + + Copy amount + Kopíruj částku + + + Copy transaction ID + Kopíruj ID transakce + + + Copy raw transaction + Kopíruj surovou transakci + + + Copy full transaction details + Kopíruj kompletní podrobnosti o transakci + + + Edit label + Uprav označení + + + Show transaction details + Zobraz detaily transakce + + + Export Transaction History + Exportuj transakční historii + + + Comma separated file (*.csv) + Formát CSV (*.csv) + + + Confirmed + Potvrzeno + + + Watch-only + Sledovaná + + + Date + Datum + + + Type + Typ + + + Label + Označení + + + Address + Adresa + + + ID + ID + + + Exporting Failed + Exportování selhalo + + + There was an error trying to save the transaction history to %1. + Při ukládání transakční historie do %1 se přihodila nějaká chyba. + + + Exporting Successful + Úspěšně vyexportováno + + + The transaction history was successfully saved to %1. + Transakční historie byla v pořádku uložena do %1. + + + Range: + Rozsah: + + + to + + + UnitDisplayStatusBarControl @@ -1618,13 +2806,53 @@ WalletFrame - + + No wallet has been loaded. + Žádná peněženka se nenačetla. + + WalletModel - + + Send Coins + Pošli mince + + WalletView - + + &Export + &Export + + + Export the data in the current tab to a file + Exportuj data z tohoto panelu do souboru + + + Backup Wallet + Záloha peněženky + + + Wallet Data (*.dat) + Data peněženky (*.dat) + + + Backup Failed + Zálohování selhalo + + + There was an error trying to save the wallet data to %1. + Při ukládání peněženky do %1 se přihodila nějaká chyba. + + + Backup Successful + Úspěšně zazálohováno + + + The wallet data was successfully saved to %1. + Data z peněženky byla v pořádku uložena do %1. + + bitcoin-core @@ -1711,6 +2939,10 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port + + Cannot obtain a lock on data directory %s. %s is probably already running. + Nedaří se mi získat zámek na datový adresář %s. %s pravděpodobně už jednou běží. + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Smazat všechny transakce peněženky a při startu obnovit pouze relevantní části řetězce bloků pomocí -rescan @@ -1723,6 +2955,18 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID) + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Horní hranice pro celkový poplatek (v %s) za jednu transakci z peněženky nebo jednu surovou transakci; příliš nízká hodnota může zmařit velké transakce (výchozí: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, %s nebude fungovat správně. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Prosíme, zapoj se nebo přispěj, pokud ti %s přijde užitečný. Více informací o programu je na %s. + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d) @@ -1751,6 +2995,14 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Vždy vítat protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. + + You need to rebuild the database using -reindex-chainstate to change -txindex + Je třeba přestavět databázi použitím -reindex-chainstate, aby bylo možné změnit -txindex + + + %s corrupt, salvage failed + %s je poškozen, jeho záchrana se nezdařila + -maxmempool must be at least %d MB -maxmempool musí být alespoň %d MB @@ -1763,10 +3015,18 @@ Append comment to the user agent string Připojit komentář k typu klienta + + Attempt to recover private keys from a corrupt wallet on startup + Pokusit se při startu zachránit soukromé klíče z poškozeného souboru s klíči + Block creation options: Možnosti vytváření bloku: + + Cannot resolve -%s address: '%s' + Nemohu přeložit -%s adresu: '%s' + Connect only to the specified node(s) Připojit se pouze k zadanému uzlu (příp. zadaným uzlům) @@ -1775,6 +3035,10 @@ Connection options: Možnosti připojení: + + Copyright (C) %i-%i + Copyright (C) %i–%i + Corrupted block database detected Bylo zjištěno poškození databáze bloků @@ -1791,6 +3055,10 @@ Do you want to rebuild the block database now? Chceš přestavět databázi bloků hned teď? + + Enable transaction replacement in the memory pool (default: %u) + Povolit výměnu transakcí v transakčním zásobníku (výchozí: %u) + Error initializing block database Chyba při zakládání databáze bloků @@ -1799,6 +3067,18 @@ Error initializing wallet database environment %s! Chyba při vytváření databázového prostředí %s pro peněženku! + + Error loading %s + Chyba při načítání %s + + + Error loading %s: Wallet corrupted + Chyba při načítání %s: peněženka je poškozená + + + Error loading %s: Wallet requires newer version of %s + Chyba při načítání %s: peněženka vyžaduje novější verzi %s + Error loading block database Chyba při načítání databáze bloků @@ -1823,10 +3103,18 @@ Incorrect or no genesis block found. Wrong datadir for network? Nemám žádný nebo jen špatný genesis blok. Není špatně nastavený datadir? + + Initialization sanity check failed. %s is shutting down. + Selhala úvodní zevrubná prověrka. %s se ukončuje. + Invalid -onion address: '%s' Neplatná -onion adresa: '%s' + + Invalid amount for -%s=<amount>: '%s' + Neplatná částka pro -%s=<částka>: '%s' + Invalid amount for -fallbackfee=<amount>: '%s' Neplatná částka pro -fallbackfee=<částka>: '%s' @@ -1835,6 +3123,10 @@ Keep the transaction memory pool below <n> megabytes (default: %u) Udržovat zasobník transakcí menší než <n> megabajtů (výchozí: %u) + + Loading banlist... + Načítám seznam klateb... + Location of the auth cookie (default: data dir) Místo pro autentizační cookie (výchozí: adresář pro data) @@ -1847,6 +3139,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion) + + Print this help message and exit + Vypsat tuto nápovědu a skončit + Print version and exit Vypsat verzi a skončit @@ -1859,6 +3155,10 @@ Prune mode is incompatible with -txindex. Prořezávací režim není kompatibilní s -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Při startu znovu vytvořit index řetězce bloků z aktuálních blk*.dat souborů + Set database cache size in megabytes (%d to %d, default: %d) Nastavit velikost databázové vyrovnávací paměti v megabajtech (%d až %d, výchozí: %d) @@ -1871,6 +3171,10 @@ Specify wallet file (within data directory) Udej název souboru s peněženkou (v rámci datového adresáře) + + Unable to bind to %s on this computer. %s is probably already running. + Nedaří se mi připojit na %s na tomhle počítači. %s už pravděpodobně jednou běží. + Unsupported argument -benchmark ignored, use -debug=bench. Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench. @@ -1903,6 +3207,14 @@ Wallet %s resides outside data directory %s Peněženka %s se nachází mimo datový adresář %s + + Wallet debugging/testing options: + Možnosti ladění/testování peněženky: + + + Wallet needed to be rewritten: restart %s to complete + Soubor s peněženkou potřeboval přepsat: restartuj %s, aby se operace dokončila + Wallet options: Možnosti peněženky: @@ -1939,6 +3251,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Poplatky (v %s/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání, těžení a vytváření transakcí (výchozí: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Vynutit přeposílání transakcí od vždy vítaných protějšků (tj. těch na bílé listině), i když porušují místní zásady pro přeposílání (výchozí: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u) @@ -2107,6 +3423,10 @@ Warning Upozornění + + Warning: unknown new rules activated (versionbit %i) + Upozornění: aktivována neznámá nová pravidla (verzový bit %i) + Whether to operate in a blocks only mode (default: %u) Zda fungovat v čistě blokovém režimu (výchozí: %u) @@ -2199,6 +3519,10 @@ Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times Uživatelské jméno a zahašované heslo pro JSON-RPC spojení. Pole <userpw> má formát: <UŽIVATELSKÉ_JMÉNO>:<SŮL>$<HAŠ>. Pomocný pythonní skript je přiložen v share/rpcuser. Tuto volbu lze použít i vícekrát + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Upozornění: soubor s peněženkou je poškozený, data jsou však zachráněna! Původní soubor %s je uložený jako %s v %s. Pokud nejsou stav tvého účtu nebo transakce v pořádku, zřejmě bys měl obnovit zálohu. + (default: %s) (výchozí: %s) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 0e99b8df0..939dfe6c0 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -183,7 +183,43 @@ %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. %1 wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Bitte beachten Sie, dass die Wallet-Verschlüsselung nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadprogramme schützt, die Ihren Computer befällt. - + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + WICHTIG: Alle vorherigen Wallet-Sicherungen sollten durch die neu erzeugte, verschlüsselte Wallet ersetzt werden. Aus Sicherheitsgründen werden vorherige Sicherungen der unverschlüsselten Wallet nutzlos, sobald Sie die neue, verschlüsselte Wallet verwenden. + + + Wallet encryption failed + Wallet-Verschlüsselung fehlgeschlagen + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Die Wallet-Verschlüsselung ist aufgrund eines internen Fehlers fehlgeschlagen. Ihre Wallet wurde nicht verschlüsselt. + + + The supplied passphrases do not match. + Die eingegebenen Passphrasen stimmen nicht überein. + + + Wallet unlock failed + Wallet-Entsperrung fehlgeschlagen + + + The passphrase entered for the wallet decryption was incorrect. + Die eingegebene Passphrase zur Wallet-Entschlüsselung war nicht korrekt. + + + Wallet decryption failed + Wallet-Entschlüsselung fehlgeschlagen + + + Wallet passphrase was successfully changed. + Die Wallet-Passphrase wurde erfolgreich geändert. + + + Warning: The Caps Lock key is on! + Warnung: Die Feststelltaste ist aktiviert! + + BanTableModel @@ -602,6 +638,18 @@ Copy transaction ID Transaktionskennung kopieren + + Lock unspent + Nicht ausgegebenen Betrag sperren + + + Unlock unspent + Nicht ausgegebenen Betrag entsperren + + + Copy quantity + Anzahl kopieren + Copy fee Gebühr kopieren @@ -618,6 +666,10 @@ Copy priority Priorität kopieren + + Copy dust + "Staub" kopieren + Copy change Wechselgeld kopieren @@ -674,10 +726,42 @@ no nein + + This label turns red if the transaction size is greater than 1000 bytes. + Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist. + + + This means a fee of at least %1 per kB is required. + Das bedeutet, dass eine Gebühr von mindestens %1 pro kB erforderlich ist. + + + Can vary +/- 1 byte per input. + Kann um +/- 1 Byte pro Eingabe variieren. + + + Transactions with higher priority are more likely to get included into a block. + Transaktionen mit höherer Priorität haben eine größere Chance in einen Block aufgenommen zu werden. + + + This label turns red if the priority is smaller than "medium". + Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist. + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als die derzeitige "Staubgrenze" erhält. + + + Can vary +/- %1 satoshi(s) per input. + Kann pro Eingabe um +/- %1 Satoshi(s) abweichen. + (no label) (keine Bezeichnung) + + change from %1 (%2) + Wechselgeld von %1 (%2) + (change) (Wechselgeld) @@ -705,7 +789,39 @@ &Address &Adresse - + + New receiving address + Neue Empfangsadresse + + + New sending address + Neue Zahlungsadresse + + + Edit receiving address + Empfangsadresse bearbeiten + + + Edit sending address + Zahlungsadresse bearbeiten + + + The entered address "%1" is not a valid Bitcoin address. + Die eingegebene Adresse "%1" ist keine gültige Bitcoin-Adresse. + + + The entered address "%1" is already in the address book. + Die eingegebene Adresse "%1" befindet sich bereits im Adressbuch. + + + Could not unlock wallet. + Wallet konnte nicht entsperrt werden. + + + New key generation failed. + Erzeugung eines neuen Schlüssels fehlgeschlagen. + + FreespaceChecker @@ -845,7 +961,11 @@ Select payment request file Zahlungsanforderungsdatei auswählen - + + Select payment request file to open + Zu öffnende Zahlungsanforderungsdatei auswählen + + OptionsDialog @@ -1158,7 +1278,95 @@ PaymentServer - + + Payment request error + fehlerhafte Zahlungsanforderung + + + Cannot start bitcoin: click-to-pay handler + "bitcoin: Klicken-zum-Bezahlen"-Handler konnte nicht gestartet werden + + + URI handling + URI-Verarbeitung + + + Payment request fetch URL is invalid: %1 + Abruf-URL der Zahlungsanforderung ist ungültig: %1 + + + Invalid payment address %1 + Ungültige Zahlungsadresse %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kann nicht analysiert werden! Dies kann durch eine ungültige Bitcoin-Adresse oder fehlerhafte URI-Parameter verursacht werden. + + + Payment request file handling + Zahlungsanforderungsdatei-Verarbeitung + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Zahlungsanforderungsdatei kann nicht gelesen werden! Dies kann durch eine ungültige Zahlungsanforderungsdatei verursacht werden. + + + Payment request rejected + Zahlungsanforderung abgelehnt + + + Payment request network doesn't match client network. + Netzwerk der Zahlungsanforderung stimmt nicht mit dem Client-Netzwerk überein. + + + Payment request expired. + Zahlungsanforderung abgelaufen. + + + Payment request is not initialized. + Zahlungsanforderung ist nicht initialisiert. + + + Unverified payment requests to custom payment scripts are unsupported. + Unverifizierte Zahlungsanforderungen an benutzerdefinierte Zahlungsskripte werden nicht unterstützt. + + + Invalid payment request. + Ungültige Zahlungsanforderung. + + + Requested payment amount of %1 is too small (considered dust). + Angeforderter Zahlungsbetrag in Höhe von %1 ist zu niedrig und wurde als "Staub" eingestuft. + + + Refund from %1 + Rücküberweisung von %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte). + + + Error communicating with %1: %2 + Kommunikationsfehler mit %1: %2 + + + Payment request cannot be parsed! + Zahlungsanforderung kann nicht verarbeitet werden! + + + Bad response from server %1 + Fehlerhafte Antwort vom Server: %1 + + + Network request error + fehlerhafte Netzwerkanfrage + + + Payment acknowledged + Zahlung bestätigt + + PeerTableModel @@ -1215,7 +1423,23 @@ QRImageWidget - + + &Save Image... + Grafik &speichern... + + + &Copy Image + Grafik &kopieren + + + Save QR Code + QR-Code speichern + + + PNG Image (*.png) + PNG-Grafik (*.png) + + RPCConsole @@ -1581,6 +1805,10 @@ Copy label Bezeichnung kopieren + + Copy message + Nachricht kopieren + Copy amount Betrag kopieren @@ -1604,26 +1832,74 @@ &Save Image... Grafik &speichern... + + Request payment to %1 + Zahlung anfordern an %1 + + + Payment information + Zahlungsinformationen + + + URI + URI + Address Adresse - Label - Bezeichnung + Amount + Betrag - - - RecentRequestsTableModel Label Bezeichnung + + Message + Nachricht + + + Resulting URI too long, try to reduce the text for label / message. + Resultierende URI ist zu lang, bitte den Text für Bezeichnung/Nachricht kürzen. + + + Error encoding URI into QR Code. + Beim Enkodieren der URI in den QR-Code ist ein Fehler aufgetreten. + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Bezeichnung + + + Message + Nachricht + (no label) (keine Bezeichnung) - + + (no message) + (keine Nachricht) + + + (no amount requested) + (kein Betrag angefordert) + + + Requested + Angefordert + + SendCoinsDialog @@ -1774,6 +2050,10 @@ S&end &Überweisen + + Copy quantity + Anzahl kopieren + Copy amount Betrag kopieren @@ -1794,10 +2074,86 @@ Copy priority Priorität kopieren + + Copy dust + "Staub" kopieren + Copy change Wechselgeld kopieren + + %1 to %2 + %1 an %2 + + + Are you sure you want to send? + Wollen Sie die Überweisung ausführen? + + + added as transaction fee + als Transaktionsgebühr hinzugefügt + + + Total Amount %1 + Gesamtbetrag %1 + + + or + oder + + + Confirm send coins + Überweisung bestätigen + + + The recipient address is not valid. Please recheck. + Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen. + + + The amount to pay must be larger than 0. + Der zu zahlende Betrag muss größer als 0 sein. + + + The amount exceeds your balance. + Der angegebene Betrag übersteigt Ihren Kontostand. + + + The total exceeds your balance when the %1 transaction fee is included. + Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand. + + + Duplicate address found: addresses should only be used once each. + Doppelte Adresse entdeckt: Adressen dürfen jeweils nur einmal vorkommen. + + + Transaction creation failed! + Transaktionserstellung fehlgeschlagen! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist. + + + A fee higher than %1 is considered an absurdly high fee. + Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen. + + + Payment request expired. + Zahlungsanforderung abgelaufen. + + + Pay only the required fee of %1 + Nur die notwendige Gebühr in Höhe von %1 zahlen + + + Estimated to begin confirmation within %n block(s). + Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken.Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken. + + + Warning: Invalid Bitcoin address + Warnung: Ungültige Bitcoin-Adresse + (no label) (keine Bezeichnung) @@ -1999,6 +2355,18 @@ TransactionDesc + + Date + Datum + + + Message + Nachricht + + + Amount + Betrag + TransactionDescDialog @@ -2009,6 +2377,10 @@ TransactionTableModel + + Date + Datum + Label Bezeichnung @@ -2040,6 +2412,10 @@ Comma separated file (*.csv) Kommagetrennte-Datei (*.csv) + + Date + Datum + Label Bezeichnung diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 7631a666c..69fe10232 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -304,12 +304,12 @@ Sign &message... - + Synchronizing with network... Synchronizing with network... - + &Overview &Overview @@ -404,12 +404,12 @@ - + Reindexing blocks on disk... Reindexing blocks on disk... - + Send coins to a Bitcoin address Send coins to a Bitcoin address @@ -439,12 +439,12 @@ &Verify message... - + Bitcoin Bitcoin - + Wallet Wallet @@ -529,7 +529,7 @@ - + %n active connection(s) to Bitcoin network %n active connection to Bitcoin network @@ -633,12 +633,12 @@ Up to date - + Show the %1 help message to get a list with possible Bitcoin command-line options - + %1 client @@ -796,7 +796,7 @@ - + Copy address @@ -862,7 +862,7 @@ - + highest @@ -1540,7 +1540,7 @@ Form - + 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. 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. @@ -1783,7 +1783,7 @@ - + %1 d @@ -1975,8 +1975,8 @@ - - + + Select a peer to view detailed information. @@ -2107,7 +2107,7 @@ - + In: @@ -2127,7 +2127,7 @@ Clear console - + &Disconnect Node @@ -2165,7 +2165,7 @@ - + Welcome to the %1 RPC console. @@ -2180,7 +2180,7 @@ Type <b>help</b> for an overview of available commands. - + %1 B @@ -2333,7 +2333,7 @@ - + Copy label @@ -3779,7 +3779,7 @@ bitcoin-core - + Options: Options: @@ -3789,22 +3789,22 @@ Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -3829,7 +3829,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -3839,7 +3839,7 @@ - + Pruning blockstore... @@ -3854,12 +3854,12 @@ - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -3949,7 +3949,7 @@ - + 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 @@ -3979,12 +3979,7 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. - - - - + You need to rebuild the database using -reindex-chainstate to change -txindex @@ -4173,6 +4168,11 @@ Keep the transaction memory pool below <n> megabytes (default: %u) + + + Keypool ran out, please call keypoolrefill first + + Loading banlist... @@ -4319,7 +4319,7 @@ - + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times @@ -4394,7 +4394,12 @@ - + + Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d) + + + + The transaction amount is too small to send after the fee has been deducted @@ -4409,7 +4414,12 @@ - + + Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times. + + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -4469,7 +4479,7 @@ - + Need to specify a port with -whitebind: '%s' @@ -4604,22 +4614,22 @@ Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect - + Loading addresses... Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -4664,7 +4674,7 @@ - + Support filtering of blocks and transaction with bloom filters (default: %u) @@ -4734,7 +4744,7 @@ Invalid -proxy address: '%s' - + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) @@ -4819,27 +4829,27 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds - + Loading block index... Loading block index... - + Add a node to connect to and attempt to keep the connection open Add a node to connect to and attempt to keep the connection open - + Loading wallet... Loading wallet... - + Cannot downgrade wallet Cannot downgrade wallet @@ -4849,12 +4859,12 @@ Cannot write default address - + Rescanning... Rescanning... - + Done loading Done loading diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index f308f6d4d..4dbd5ee9c 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -41,10 +41,66 @@ &Delete &Delete + + Choose the address to send coins to + Choose the address to send coins to + + + Choose the address to receive coins with + Choose the address to receive coins with + + + C&hoose + C&hoose + + + Sending addresses + Sending addresses + + + Receiving addresses + Receiving addresses + + + &Copy Address + &Copy Address + + + Copy &Label + Copy &Label + + + &Edit + &Edit + + + Export Address List + Export Address List + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Exporting Failed + AddressTableModel - + + Label + Label + + + Address + Address + + + (no label) + (no label) + + AskPassphraseDialog @@ -63,6 +119,10 @@ Repeat new passphrase Repeat new passphrase + + Encrypt wallet + Encrypt wallet + BanTableModel @@ -466,6 +526,10 @@ Priority Priority + + (no label) + (no label) + EditAddressDialog @@ -1380,9 +1444,25 @@ &Save Image... &Save Image... + + Address + Address + + + Label + Label + RecentRequestsTableModel + + Label + Label + + + (no label) + (no label) + SendCoinsDialog @@ -1534,7 +1614,11 @@ S&end S&end - + + (no label) + (no label) + + SendCoinsEntry @@ -1741,9 +1825,33 @@ TransactionTableModel + + Label + Label + + + (no label) + (no label) + TransactionView + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Label + Label + + + Address + Address + + + Exporting Failed + Exporting Failed + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index a0b188e5b..1fbbf74b7 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -49,6 +49,10 @@ Choose the address to receive coins with Seleccione la dirección de la que recibir monedas + + C&hoose + E&scoger + Sending addresses Enviando direcciones @@ -195,7 +199,27 @@ The supplied passphrases do not match. La frase clave introducida no coincide. - + + Wallet unlock failed + Fracasó el desbloqueo del monedero + + + The passphrase entered for the wallet decryption was incorrect. + La frase clave introducida para la encriptación del monedero es incorrecta. + + + Wallet decryption failed + Fracasó la encriptación del monedero + + + Wallet passphrase was successfully changed. + La frase clave del monedero se ha cambiado con éxito. + + + Warning: The Caps Lock key is on! + Alerta: ¡La clave de bloqueo Caps está activa! + + BanTableModel @@ -598,11 +622,151 @@ Priority Prioridad + + Copy address + Copiar ubicación + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Lock unspent + Bloquear lo no gastado + + + Unlock unspent + Desbloquear lo no gastado + + + Copy quantity + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + highest + el más alto + + + higher + más alto + + + high + alto + + + medium-high + media altura + + + medium + medio + + + low-medium + medio bajo + + + low + bajo + + + lower + más bajo + + + lowest + el más bajo + + + (%1 locked) + (%1 bloqueado) + + + none + ninguno + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Esta etiqueta se vuelve roja sí el tamaño de transacción es mayor de 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Esto significa que se requiere una couta de al menos %1 por kB. + + + Can vary +/- 1 byte per input. + Puede variar +/- 1 byte por entrada. + + + Transactions with higher priority are more likely to get included into a block. + Las transacciones con mayor prioridad son más probablemente incluídas en un bloque. + + + This label turns red if the priority is smaller than "medium". + Esta etiqueta se vuelve roja si la priodidad es inferior a "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Esta etiqueta se vuelve roja si algún destinatario recibe una cantidad inferior a la actual puerta polvorienta. + + + Can vary +/- %1 satoshi(s) per input. + Puede variar +/- %1 satoshi(s) por entrada. + (no label) (sin etiqueta) - + + change from %1 (%2) + cambia desde %1 (%2) + + + (change) + (cambio) + + EditAddressDialog @@ -625,7 +789,39 @@ &Address &Dirección - + + New receiving address + Nueva dirección de recivimiento + + + New sending address + Nueva dirección de envío + + + Edit receiving address + Editar dirección de recivimiento + + + Edit sending address + Editar dirección de envío + + + The entered address "%1" is not a valid Bitcoin address. + La dirección introducida "%1" no es una dirección Bitcoin válida. + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" está ya en la agenda. + + + Could not unlock wallet. + Podría no desbloquear el monedero. + + + New key generation failed. + Falló la generación de la nueva clave. + + FreespaceChecker @@ -761,7 +957,11 @@ Select payment request file Seleccionar archivo de sulicitud de pago - + + Select payment request file to open + Seleccionar el archivo de solicitud de pago para abrir + + OptionsDialog @@ -1074,7 +1274,95 @@ PaymentServer - + + Payment request error + Fallo en la solicitud de pago + + + Cannot start bitcoin: click-to-pay handler + No se puede iniciar bitcoin: encargado click-para-pagar + + + URI handling + Manejo de URI + + + Payment request fetch URL is invalid: %1 + La búsqueda de solicitud de pago URL es válida: %1 + + + Invalid payment address %1 + Dirección de pago inválida %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI no puede ser analizado! Esto puede ser causado por una dirección Bitcoin inválida o parametros URI mal formados. + + + Payment request file handling + Manejo del archivo de solicitud de pago + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + ¡El archivo de solicitud de pago no puede ser leído! Esto puede ser causado por un archivo de solicitud de pago inválido. + + + Payment request rejected + Solicitud de pago rechazada + + + Payment request network doesn't match client network. + La red de solicitud de pago no cimbina la red cliente. + + + Payment request expired. + Solicitud de pago caducada. + + + Payment request is not initialized. + La solicitud de pago no se ha iniciado. + + + Unverified payment requests to custom payment scripts are unsupported. + Solicitudes de pago sin verificar a scripts de pago habitual no se soportan. + + + Invalid payment request. + Solicitud de pago inválida. + + + Requested payment amount of %1 is too small (considered dust). + Cantidad de pago solicitada de %1 es demasiado pequeña (considerado polvo). + + + Refund from %1 + Reembolsar desde %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Solicitud de pago de %1 es demasiado grande (%2 bytes, permitidos %3 bytes). + + + Error communicating with %1: %2 + Fallo al comunicar con %1: %2 + + + Payment request cannot be parsed! + ¡La solicitud de pago no puede ser analizada! + + + Bad response from server %1 + Mala respuesta desde el servidor %1 + + + Network request error + Fallo de solicitud de red + + + Payment acknowledged + Pago declarado + + PeerTableModel @@ -1131,7 +1419,23 @@ QRImageWidget - + + &Save Image... + &Guardar imagen... + + + &Copy Image + &Copiar imagen + + + Save QR Code + Guardar código QR + + + PNG Image (*.png) + Imagen PNG (*.png) + + RPCConsole @@ -1493,7 +1797,19 @@ Remove Eliminar - + + Copy label + Copiar capa + + + Copy message + Copiar imagen + + + Copy amount + Copiar cantidad + + ReceiveRequestDialog @@ -1512,26 +1828,74 @@ &Save Image... Guardar Imagen... + + Request payment to %1 + Solicitar pago a %1 + + + Payment information + Información de pago + + + URI + URI + Address Dirección - Label - Etiqueta + Amount + Cantidad - - - RecentRequestsTableModel Label Etiqueta + + Message + Mensaje + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante demasiado grande, trate de reducir el texto de etiqueta / mensaje. + + + Error encoding URI into QR Code. + Fallo al codificar URI en código QR. + + + + RecentRequestsTableModel + + Date + Fecha + + + Label + Etiqueta + + + Message + Mensaje + (no label) (sin etiqueta) - + + (no message) + (no hay mensaje) + + + (no amount requested) + (no hay solicitud de cantidad) + + + Requested + Solicitado + + SendCoinsDialog @@ -1682,6 +2046,114 @@ S&end &Enviar + + Copy quantity + Copiar cantidad + + + Copy amount + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + ¿Seguro que quiere enviar? + + + added as transaction fee + añadido como transacción de cuota + + + Total Amount %1 + Cantidad total %1 + + + or + o + + + Confirm send coins + Confirmar enviar monedas + + + The recipient address is not valid. Please recheck. + La dirección de destinatario no es válida. Por favor revísela. + + + The amount to pay must be larger than 0. + La cantidad a pagar debe de ser mayor que 0. + + + The amount exceeds your balance. + La cantidad excede su saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excede su saldo cuando la cuota de transacción de %1 es incluida. + + + Duplicate address found: addresses should only be used once each. + Dirección duplicada encontrada: la dirección sólo debería ser utilizada una vez por cada uso. + + + Transaction creation failed! + ¡Falló la creación de transacción! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + ¡La transacción fue rechazada! Esto podría pasar si algunas de las monedas de su monedero fueron ya gastadas, así como si ha utilizado una copia del wallet.dat y las monedas fueron gastadas en la copia pero no marcadas como gastadas aquí. + + + A fee higher than %1 is considered an absurdly high fee. + Una couta mayor que %1 se considera una cuota irracionalmente alta. + + + Payment request expired. + Solicitud de pago caducada. + + + Pay only the required fee of %1 + Pagar únicamente la cuota solicitada de %1 + + + Estimated to begin confirmation within %n block(s). + Se estima que sea confirmado dentro del %n bloque(s).Se estima que sea confirmado dentro del %n bloque(s). + + + Warning: Invalid Bitcoin address + Alerta: dirección Bitcoin inválida + + + Warning: Unknown change address + Alerta: dirección cambiada desconocida + (no label) (sin etiqueta) @@ -1765,10 +2237,18 @@ Memo: Memo: - + + Enter a label for this address to add it to your address book + Introduzca una etiqueta para esta dirección para añadirla a su agenda + + SendConfirmationDialog - + + Yes + + + ShutdownWindow @@ -1866,7 +2346,59 @@ Reset all verify message fields Vaciar todos los campos de la verificación de mensaje - + + Click "Sign Message" to generate signature + Click en "Fírmar mensaje" para generar una firma + + + The entered address is invalid. + La dirección introducida no es válida. + + + Please check the address and try again. + Por favor revise la dirección e inténtelo de nuevo. + + + The entered address does not refer to a key. + La dirección introducida no remite a una clave. + + + Wallet unlock was cancelled. + El desbloqueo del monedero fue cancelado. + + + Private key for the entered address is not available. + La clave privada de la dirección introducida no está disponible. + + + Message signing failed. + Falló la firma del mensaje. + + + Message signed. + Mensaje firmado. + + + The signature could not be decoded. + La firma no pudo descodificarse. + + + Please check the signature and try again. + Por favor compruebe la firma y pruebe de nuevo. + + + The signature did not match the message digest. + La firma no se combinó con el mensaje. + + + Message verification failed. + Falló la verificación del mensaje. + + + Message verified. + Mensaje verificado. + + SplashScreen @@ -1883,31 +2415,419 @@ TransactionDesc - + + Open for %n more block(s) + Abrir para %n más bloque(s)Abrir para %n más bloque(s) + + + Open until %1 + Abierto hasta %1 + + + conflicted with a transaction with %1 confirmations + Hay un conflicto con la traducción de las confirmaciones %1 + + + %1/offline + %1/sin conexión + + + 0/unconfirmed, %1 + 0/no confirmado, %1 + + + in memory pool + en el equipo de memoria + + + not in memory pool + no en el equipo de memoria + + + abandoned + abandonado + + + %1/unconfirmed + %1/no confirmado + + + %1 confirmations + confirmaciones %1 + + + Status + Estado + + + , has not been successfully broadcast yet + , no ha sido emitido con éxito aún + + + , broadcast through %n node(s) + , emisión a través de %n nodo(s), emisión a través de %n nodo(s) + + + Date + Fecha + + + Source + Fuente + + + Generated + Generado + + + From + Desde + + + unknown + desconocido + + + To + Para + + + own address + dirección propia + + + watch-only + de observación + + + label + etiqueta + + + Credit + Credito + + + matures in %n more block(s) + disponible en %n bloque(s) másdisponible en %n bloque(s) más + + + not accepted + no aceptada + + + Debit + Enviado + + + Total debit + Total enviado + + + Total credit + Total recibido + + + Transaction fee + Comisión de transacción + + + Net amount + Cantidad neta + + + Message + Mensaje + + + Comment + Comentario + + + Transaction ID + Identificador de transacción (ID) + + + Output index + Indice de salida + + + Merchant + Vendedor + + + 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. + Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo. + + + Debug information + Información de depuración + + + Transaction + Transacción + + + Inputs + entradas + + + Amount + Cantidad + + + true + verdadero + + + false + falso + + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + Details for %1 + Detalles para %1 + + TransactionTableModel + + Date + Fecha + + + Type + Tipo + Label Etiqueta + + Open for %n more block(s) + Abrir para %n bloque(s) másAbrir para %n bloque(s) más + + + Open until %1 + Abierto hasta %1 + + + Offline + Sin conexion + + + Unconfirmed + Sin confirmar + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmaciones recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + Conflicted + En conflicto + + + Immature (%1 confirmations, will be available after %2) + No disponible (%1 confirmaciones. Estarán disponibles al cabo de %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! + + + Generated but not accepted + Generado pero no aceptado + + + Received with + Recibido con + + + Received from + Recibidos de + + + Sent to + Enviado a + + + Payment to yourself + Pago proprio + + + Mined + Minado + + + watch-only + de observación + + + (n/a) + (nd) + (no label) (sin etiqueta) - + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. + + + Date and time that the transaction was received. + Fecha y hora en que se recibió la transacción. + + + Type of transaction. + Tipo de transacción. + + + Whether or not a watch-only address is involved in this transaction. + Si una dirección watch-only está involucrada en esta transacción o no. + + + User-defined intent/purpose of the transaction. + Descripción de la transacción definido por el usuario. + + + Amount removed from or added to balance. + Cantidad retirada o añadida al saldo. + + TransactionView + + All + Todo + + + Today + Hoy + + + This week + Esta semana + + + This month + Este mes + + + Last month + Mes pasado + + + This year + Este año + + + Range... + Rango... + + + Received with + Recibido con + + + Sent to + Enviado a + + + To yourself + A usted mismo + + + Mined + Minado + + + Other + Otra + + + Enter address or label to search + Introduzca una dirección o etiqueta que buscar + + + Min amount + Cantidad mínima + + + Abandon transaction + Transacción abandonada + + + Copy address + Copiar ubicación + + + Copy label + Copiar capa + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Copy raw transaction + Copiar transacción raw + + + Copy full transaction details + Copiar todos los detalles de la transacción + + + Edit label + Editar etiqueta + + + Show transaction details + Mostrar detalles de la transacción + + + Export Transaction History + Exportar historial de transacciones + Comma separated file (*.csv) Archivo separado de coma (*.csv) + + Confirmed + Confirmado + + + Watch-only + De observación + + + Date + Fecha + + + Type + Tipo + Label Etiqueta @@ -1916,11 +2836,35 @@ Address Dirección + + ID + ID + Exporting Failed Falló la exportación - + + There was an error trying to save the transaction history to %1. + Ha habido un error al intentar guardar la transacción con %1. + + + Exporting Successful + Exportación finalizada + + + The transaction history was successfully saved to %1. + La transacción ha sido guardada en %1. + + + Range: + Rango: + + + to + para + + UnitDisplayStatusBarControl @@ -1930,13 +2874,53 @@ WalletFrame - + + No wallet has been loaded. + No se ha cargado ningún monedero + + WalletModel - + + Send Coins + Enviar + + WalletView - + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar a un archivo los datos de esta pestaña + + + Backup Wallet + Copia de seguridad del monedero + + + Wallet Data (*.dat) + Datos de monedero (*.dat) + + + Backup Failed + La copia de seguridad ha fallado + + + There was an error trying to save the wallet data to %1. + Ha habido un error al intentar guardar los datos del monedero en %1. + + + Backup Successful + Se ha completado con éxito la copia de respaldo + + + The wallet data was successfully saved to %1. + Los datos del monedero se han guardado con éxito en %1. + + bitcoin-core @@ -2318,6 +3302,10 @@ Specify wallet file (within data directory) Especificar archivo de monedero (dentro del directorio de datos) + + Starting network threads... + Iniciando funciones de red... + The source code is available from %s. El código fuente esta disponible desde %s. @@ -2402,6 +3390,10 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Las comisiones (en %s/kB) mas pequeñas que esto se consideran como cero comisión para la retransmisión, minería y creación de la transacción (predeterminado: %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u) @@ -2556,7 +3548,7 @@ Transaction too large - Transacción demasiado grande + Transacción demasiado grande, intenta dividirla en varias. Unable to bind to %s on this computer (bind returned error %s) @@ -2564,7 +3556,7 @@ Upgrade wallet to latest format on startup - Actualizar el monedero al último formato + Actualizar el monedero al último formato al inicio Username for JSON-RPC connections @@ -2610,15 +3602,15 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = mantener los meta datos de transacción, por ejemplo: propietario e información de pago, 2 = omitir los metadatos) -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -maxtxfee tiene un ajuste muy elevado! Las comisiones así de grandes podrían ser pagadas en una única transaccion. + -maxtxfee tiene un ajuste muy elevado! Comisiones muy grandes podrían ser pagadas en una única transaccion. -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - -paytxfee tiene un ajuste muy elevado! Esta es la comisión de transacción que pagaras si envías una transaccion. + -paytxfee tiene un valor muy elevado! La comisión de transacción que pagaras si envías una transaccion es alta. Do not keep transactions in the mempool longer than <n> hours (default: %u) @@ -2646,7 +3638,7 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. - Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles. + Error: argumento -socks encontrado. El ajuste de la versión SOCKS ya no es posible, sólo proxies SOCKS5 son compatibles. Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. @@ -2746,7 +3738,7 @@ Spend unconfirmed change when sending transactions (default: %u) - Gastar cambio no confirmado al enviar transacciones (predeterminado: %u) + Usar cambio aún no confirmado al enviar transacciones (predeterminado: %u) Threshold for disconnecting misbehaving peers (default: %u) @@ -2774,7 +3766,7 @@ Cannot downgrade wallet - No se puede rebajar el monedero + No se puede cambiar a una versión mas antigua el monedero Cannot write default address diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index 40b6bb7df..8725cff58 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -3,11 +3,11 @@ AddressBookPage Right-click to edit address or label - Haz clic derecho para editar la dirección o la etiqueta + Haz clic derecho para editar la dirección o etiqueta Create a new address - Crea una nueva direccióon + Crear una nueva dirección &New @@ -15,7 +15,7 @@ Copy the currently selected address to the system clipboard - Copia la direccón seleccionada al portapapeles del sistema + Copiar la dirección seleccionada al portapapeles del sistema &Copy @@ -27,11 +27,11 @@ Delete the currently selected address from the list - Elimina la dirección seleccionada de la lista + Eliminar la dirección seleccionada de la lista Export the data in the current tab to a file - Exporta los datos de la pestaña actual a un archivo + Exportar los datos en la ficha actual a un archivo &Export @@ -41,19 +41,87 @@ &Delete &Eliminar - + + Choose the address to send coins to + Seleccione la dirección a la que enviar monedas + + + Choose the address to receive coins with + Seleccione la dirección de la que recibir monedas + + + C&hoose + E&scoger + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son sus direcciones Bitcoin para enviar pagos. Verifique siempre la cantidad y la dirección de recibimiento antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son sus direcciones Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recibimiento para cada transacción + + + &Copy Address + &Copiar Dirección + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the address list to %1. Please try again. + Había un error intentando guardar la lista de direcciones en %1. Por favor inténtelo de nuevo. + + AddressTableModel - + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + + AskPassphraseDialog Passphrase Dialog - Dialogo de Contraseña + Diálogo de contraseña Enter passphrase - Introduzca la contraseña + Introducir contraseña New passphrase @@ -61,12 +129,108 @@ Repeat new passphrase - Repite la nueva contraseña + Repita la nueva contraseña - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduzca la nueva frase clave del monedero. <br/>Por favor utilice una frase clave de <b>diez o más carácteres aleatorios</b>, o <b>ocho o más palabras</b>. + + + Encrypt wallet + Monedero encriptado + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita su frase clave de monedero para desbloquear el monedero. + + + Unlock wallet + Desbloquear monedero + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita su frase clave de cartera para desencriptar el monedero. + + + Decrypt wallet + Desencriptar monedero + + + Change passphrase + Cambiar frase clave + + + Enter the old passphrase and new passphrase to the wallet. + Introduzca la vieja frase clave y la nueva flase clave para el monedero. + + + Confirm wallet encryption + Confirmar encriptación del monedero + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advertencia: Si encripta su monedero y pierde su frase clave <b>PERDERÁ TODOS SUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + ¿Seguro que desea encriptar su monedero? + + + Wallet encrypted + Monedero encriptado + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 se cerrará ahora para terminar el proceso de encriptación. Recuerde que encriptar su monedero no puede proteger completamente su monedero de ser robado por malware que infecte su ordenador. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Cualquier copia de seguridad anterior que haya hecho en su archivo de monedero debería ser reemplazada con el archivo de monedero encriptado generado recientemente. Por razones de seguridad, las copias de seguridad anteriores del archivo de monedero desencriptado serán inútiles en cuanto empiece a utilizar el nuevo monedero encriptado. + + + Wallet encryption failed + Fracasó la encriptación de monedero + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falló la encriptación del monedero debido a un error interno. Su monedero no fue encriptado. + + + The supplied passphrases do not match. + La frase clave introducida no coincide. + + + Wallet unlock failed + Fracasó el desbloqueo del monedero + + + The passphrase entered for the wallet decryption was incorrect. + La frase clave introducida para la encriptación del monedero es incorrecta. + + + Wallet decryption failed + Fracasó la encriptación del monedero + + + Wallet passphrase was successfully changed. + La frase clave del monedero se ha cambiado con éxito. + + + Warning: The Caps Lock key is on! + Alerta: ¡La clave de bloqueo Caps está activa! + + BanTableModel - + + IP/Netmask + IP/Máscara + + + Banned Until + Bloqueado Hasta + + BitcoinGUI @@ -75,7 +239,7 @@ Synchronizing with network... - Sincronizando con la red... + Sincronizando con la red… &Overview @@ -87,7 +251,7 @@ Show general overview of wallet - Mostrar vista general de la cartera + Mostrar vista general del monedero &Transactions @@ -95,7 +259,7 @@ Browse transaction history - Navegar historial de transacciones + Examinar el historial de transacciones E&xit @@ -105,37 +269,49 @@ Quit application Salir de la aplicación + + &About %1 + &Acerca de %1 + + + Show information about %1 + Mostrar información acerca de %1 + About &Qt Acerca de &Qt Show information about Qt - Muestra información acerca de Qt + Mostrar información acerca de Qt &Options... &Opciones... + + Modify configuration options for %1 + Modificar las opciones de configuración para %1 + &Encrypt Wallet... - &Encriptar Cartera... + &Cifrar monedero… &Backup Wallet... - &Hacer copia de seguridad de la cartera... + &Guardar copia del monedero... &Change Passphrase... - &Cambiar contraseña... + &Cambiar la contraseña… &Sending addresses... - &Enviando direcciones... + Direcciones de &envío... &Receiving addresses... - &Recibiendo direcciones.. + Direcciones de &recepción... Open &URI... @@ -143,123 +319,3470 @@ Reindexing blocks on disk... - Reindexando bloques en el disco... + Reindexando bloques en disco... Send coins to a Bitcoin address - Envia monedas a una dirección Bitcoin + Enviar bitcoins a una dirección Bitcoin Backup wallet to another location - Crea una copia de seguridad de tu cartera en otra ubicación + Copia de seguridad del monedero en otra ubicación - + + Change the passphrase used for wallet encryption + Cambiar la contraseña utilizada para el cifrado del monedero + + + &Debug window + &Ventana de depuración + + + Open debugging and diagnostic console + Abrir la consola de depuración y diagnóstico + + + &Verify message... + &Verificar mensaje... + + + Bitcoin + Bitcoin + + + Wallet + Monedero + + + &Send + &Enviar + + + &Receive + &Recibir + + + &Show / Hide + &Mostrar / Ocultar + + + Show or hide the main Window + Mostrar u ocultar la ventana principal + + + Encrypt the private keys that belong to your wallet + Cifrar las claves privadas de su monedero + + + Sign messages with your Bitcoin addresses to prove you own them + Firmar mensajes con sus direcciones Bitcoin para demostrar la propiedad + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verificar mensajes comprobando que están firmados con direcciones Bitcoin concretas + + + &File + &Archivo + + + &Settings + &Configuración + + + &Help + &Ayuda + + + Tabs toolbar + Barra de pestañas + + + Request payments (generates QR codes and bitcoin: URIs) + Solicitar pagos (generando códigos QR e identificadores URI "bitcoin:") + + + Show the list of used sending addresses and labels + Mostrar la lista de direcciones de envío y etiquetas + + + Show the list of used receiving addresses and labels + Muestra la lista de direcciones de recepción y etiquetas + + + Open a bitcoin: URI or payment request + Abrir un identificador URI "bitcoin:" o una petición de pago + + + &Command-line options + &Opciones de consola de comandos + + + %n active connection(s) to Bitcoin network + %n conexión activa hacia la red Bitcoin%n conexiones activas hacia la red Bitcoin + + + Indexing blocks on disk... + Indexando bloques en disco... + + + Processing blocks on disk... + Procesando bloques en disco... + + + No block source available... + Ninguna fuente de bloques disponible ... + + + Processed %n block(s) of transaction history. + %n bloque procesado del historial de transacciones.%n bloques procesados del historial de transacciones. + + + %n hour(s) + %n hora%n horas + + + %n day(s) + %n día%n días + + + %n week(s) + %n semana%n semanas + + + %1 and %2 + %1 y %2 + + + %n year(s) + %n año%n años + + + %1 behind + %1 atrás + + + Last received block was generated %1 ago. + El último bloque recibido fue generado hace %1. + + + Transactions after this will not yet be visible. + Las transacciones posteriores aún no están visibles. + + + Error + Error + + + Warning + Aviso + + + Information + Información + + + Up to date + Actualizado + + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostrar el mensaje de ayuda %1 para obtener una lista de los posibles comandos de linea de comandos de Bitcoin + + + %1 client + %1 cliente + + + Catching up... + Actualizando... + + + Date: %1 + + Fecha: %1 + + + + Amount: %1 + + Amount: %1 + + + + Type: %1 + + Tipo: %1 + + + + Label: %1 + + Etiqueta: %1 + + + + Address: %1 + + Dirección: %1 + + + + Sent transaction + Transacción enviada + + + Incoming transaction + Transacción entrante + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + El monedero está <b>cifrado</b> y actualmente <b>desbloqueado</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + El monedero está <b>cifrado</b> y actualmente <b>bloqueado</b> + + CoinControlDialog - + + Coin Selection + Selección de la moneda + + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Cuantía: + + + Priority: + Prioridad: + + + Fee: + Tasa: + + + Dust: + Polvo: + + + After Fee: + Después de aplicar la comisión: + + + Change: + Cambio: + + + (un)select all + (des)marcar todos + + + Tree mode + Modo árbol + + + List mode + Modo lista + + + Amount + Cantidad + + + Received with label + Recibido con etiqueta + + + Received with address + Recibido con dirección + + + Date + Fecha + + + Confirmations + Confirmaciones + + + Confirmed + Confirmado + + + Priority + Prioridad + + + Copy address + Copiar ubicación + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Lock unspent + Bloquear lo no gastado + + + Unlock unspent + Desbloquear lo no gastado + + + Copy quantity + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + highest + el más alto + + + higher + más alto + + + high + alto + + + medium-high + media altura + + + medium + medio + + + low-medium + medio bajo + + + low + bajo + + + lower + más bajo + + + lowest + el más bajo + + + (%1 locked) + (%1 bloqueado) + + + none + ninguno + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Esta etiqueta se vuelve roja sí el tamaño de transacción es mayor de 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Esto significa que se requiere una couta de al menos %1 por kB. + + + Can vary +/- 1 byte per input. + Puede variar +/- 1 byte por entrada. + + + Transactions with higher priority are more likely to get included into a block. + Las transacciones con mayor prioridad son más probablemente incluídas en un bloque. + + + This label turns red if the priority is smaller than "medium". + Esta etiqueta se vuelve roja si la priodidad es inferior a "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Esta etiqueta se vuelve roja si algún destinatario recibe una cantidad inferior a la actual puerta polvorienta. + + + Can vary +/- %1 satoshi(s) per input. + Puede variar +/- %1 satoshi(s) por entrada. + + + (no label) + (sin etiqueta) + + + change from %1 (%2) + cambia desde %1 (%2) + + + (change) + (cambio) + + EditAddressDialog + + Edit Address + Editar Dirección + &Label - Etiqueta + &Etiqueta + + + The label associated with this address list entry + La etiqueta asociada con esta entrada de la lista de direcciones + + + The address associated with this address list entry. This can only be modified for sending addresses. + La dirección asociada con esta entrada de la lista de direcciones. Solo puede ser modificada para direcciones de envío. &Address - Dirección + &Dirección - + + New receiving address + Nueva dirección de recivimiento + + + New sending address + Nueva dirección de envío + + + Edit receiving address + Editar dirección de recivimiento + + + Edit sending address + Editar dirección de envío + + + The entered address "%1" is not a valid Bitcoin address. + La dirección introducida "%1" no es una dirección Bitcoin válida. + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" está ya en la agenda. + + + Could not unlock wallet. + Podría no desbloquear el monedero. + + + New key generation failed. + Falló la generación de la nueva clave. + + FreespaceChecker - + + A new data directory will be created. + Se creará un nuevo directorio de datos. + + + name + nombre + + + Directory already exists. Add %1 if you intend to create a new directory here. + El directorio ya existe. Añada %1 si pretende crear aquí un directorio nuevo. + + + Path already exists, and is not a directory. + La ruta ya existe y no es un directorio. + + + Cannot create data directory here. + No se puede crear un directorio de datos aquí. + + HelpMessageDialog - + + version + versión + + + (%1-bit) + (%1-bit) + + + About %1 + Acerda de %1 + + + Command-line options + Opciones de la línea de órdenes + + + Usage: + Uso: + + + command-line options + opciones de la consola de comandos + + + UI Options: + Opciones de interfaz de usuario: + + + Choose data directory on startup (default: %u) + Elegir directorio de datos al iniciar (predeterminado: %u) + + + Set language, for example "de_DE" (default: system locale) + Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) + + + Start minimized + Arrancar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) + + + Reset all settings changed in the GUI + Reiniciar todos los ajustes modificados en el GUI + + Intro - + + Welcome + Bienvenido + + + Welcome to %1. + Bienvenido a %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Al ser la primera vez que se ejecuta el programa, puede elegir donde %1 almacenara sus datos + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 va a descargar y almacenar una copia de la cadena de bloques de Bitcoin. Al menos %2GB de datos seran almacenados en este directorio, que ira creciendo con el tiempo. El monedero se guardara tambien en ese directorio. + + + Use the default data directory + Utilizar el directorio de datos predeterminado + + + Use a custom data directory: + Utilizar un directorio de datos personalizado: + + + Error: Specified data directory "%1" cannot be created. + Error: no ha podido crearse el directorio de datos especificado "%1". + + + Error + Error + + + %n GB of free space available + %n GB de espacio libre%n GB de espacio disponible + + + (of %n GB needed) + (de %n GB necesitados)(de %n GB requeridos) + + OpenURIDialog - + + Open URI + Abrir URI... + + + Open payment request from URI or file + Abrir solicitud de pago a partir de un identificador URI o de un archivo + + + URI: + URI: + + + Select payment request file + Seleccionar archivo de sulicitud de pago + + + Select payment request file to open + Seleccionar el archivo de solicitud de pago para abrir + + OptionsDialog - + + Options + Opciones + + + &Main + &Principal + + + Automatically start %1 after logging in to the system. + Iniciar automaticamente %1 al encender el sistema. + + + &Start %1 on system login + &Iniciar %1 al iniciar el sistema + + + Size of &database cache + Tamaño de cache de la &base de datos + + + MB + MB + + + Number of script &verification threads + Número de hilos de &verificación de scripts + + + Accept connections from outside + Aceptar conexiones desde el exterior + + + Allow incoming connections + Aceptar conexiones entrantes + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1) + + + 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. + Minimizar en lugar de salir de la aplicación cuando la ventana está cerrada. Cuando se activa esta opción, la aplicación sólo se cerrará después de seleccionar Salir en el menú. + + + 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 |. + Identificadores URL de terceros (por ejemplo, un explorador de bloques) que aparecen en la pestaña de transacciones como elementos del menú contextual. El %s en la URL es reemplazado por el valor hash de la transacción. Se pueden separar URL múltiples por una barra vertical |. + + + Third party transaction URLs + Identificadores URL de transacciones de terceros + + + Active command-line options that override above options: + Opciones activas de consola de comandos que tienen preferencia sobre las opciones anteriores: + + + Reset all client options to default. + Restablecer todas las opciones predeterminadas del cliente. + + + &Reset Options + &Restablecer opciones + + + &Network + &Red + + + (0 = auto, <0 = leave that many cores free) + (0 = automático, <0 = dejar libres ese número de núcleos) + + + W&allet + &Monedero + + + Expert + Experto + + + Enable coin &control features + Habilitar funcionalidad de &coin control + + + 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. + Si desactiva el gasto del cambio no confirmado, no se podrá usar el cambio de una transacción hasta que se alcance al menos una confirmación. Esto afecta también a cómo se calcula su saldo. + + + &Spend unconfirmed change + &Gastar cambio no confirmado + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Abrir automáticamente el puerto del cliente Bitcoin en el router. Esta opción solo funciona si el router admite UPnP y está activado. + + + Map port using &UPnP + Mapear el puerto mediante &UPnP + + + Connect to the Bitcoin network through a SOCKS5 proxy. + Conectarse a la red Bitcoin a través de un proxy SOCKS5. + + + &Connect through SOCKS5 proxy (default proxy): + &Conectarse a través de proxy SOCKS5 (proxy predeterminado): + + + Proxy &IP: + Dirección &IP del proxy: + + + &Port: + &Puerto: + + + Port of the proxy (e.g. 9050) + Puerto del servidor proxy (ej. 9050) + + + Used for reaching peers via: + Usado para alcanzar compañeros via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Muestra si el proxy SOCKS5 predeterminado es utilizado para llegar a los pares a traves de este tipo de red. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Conectar a la red Bitcoin mediante un proxy SOCKS5 por separado para los servicios ocultos de Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima: + + + &Window + &Ventana + + + &Hide the icon from the system tray. + &Ocultar el icono de la barra de tareas + + + Hide tray icon + Ocultar barra de tareas + + + Show only a tray icon after minimizing the window. + Minimizar la ventana a la bandeja de iconos del sistema. + + + &Minimize to the tray instead of the taskbar + &Minimizar a la bandeja en vez de a la barra de tareas + + + M&inimize on close + M&inimizar al cerrar + + + &Display + &Interfaz + + + User Interface &language: + I&dioma de la interfaz de usuario + + + The user interface language can be set here. This setting will take effect after restarting %1. + El idioma de la interfaz de usuario puede establecerse aquí. Esta configuración tendrá efecto tras reiniciar %1. + + + &Unit to show amounts in: + Mostrar las cantidades en la &unidad: + + + Choose the default subdivision unit to show in the interface and when sending coins. + Elegir la subdivisión predeterminada para mostrar cantidades en la interfaz y cuando se envían bitcoins. + + + Whether to show coin control features or not. + Mostrar o no funcionalidad de Coin Control + + + &OK + &Aceptar + + + &Cancel + &Cancelar + + + default + predeterminado + + + none + ninguna + + + Confirm options reset + Confirme el restablecimiento de las opciones + + + Client restart required to activate changes. + Se necesita reiniciar el cliente para activar los cambios. + + + Client will be shut down. Do you want to proceed? + El cliente se cerrará. ¿Desea continuar? + + + This change would require a client restart. + Este cambio exige el reinicio del cliente. + + + The supplied proxy address is invalid. + La dirección proxy indicada es inválida. + + OverviewPage - + + Form + Formulario + + + 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. + La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado. + + + Watch-only: + De observación: + + + Available: + Disponible: + + + Your current spendable balance + Su saldo disponible actual + + + Pending: + Pendiente: + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total de transacciones pendientes de confirmar y que aún no contribuye al saldo disponible + + + Immature: + No madurado: + + + Mined balance that has not yet matured + Saldo recién minado que aún no ha madurado. + + + Balances + Saldos + + + Total: + Total: + + + Your current total balance + Su saldo actual total + + + Your current balance in watch-only addresses + Su saldo actual en direcciones watch-only + + + Spendable: + Gastable: + + + Recent transactions + Transacciones recientes + + + Unconfirmed transactions to watch-only addresses + Transacciones sin confirmar en direcciones watch-only + + + Mined balance in watch-only addresses that has not yet matured + Saldo minado en direcciones watch-only que aún no ha madurado + + + Current total balance in watch-only addresses + Saldo total en las direcciones watch-only + + PaymentServer - + + Payment request error + Fallo en la solicitud de pago + + + Cannot start bitcoin: click-to-pay handler + No se puede iniciar bitcoin: encargado click-para-pagar + + + URI handling + Manejo de URI + + + Payment request fetch URL is invalid: %1 + La búsqueda de solicitud de pago URL es válida: %1 + + + Invalid payment address %1 + Dirección de pago inválida %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI no puede ser analizado! Esto puede ser causado por una dirección Bitcoin inválida o parametros URI mal formados. + + + Payment request file handling + Manejo del archivo de solicitud de pago + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + ¡El archivo de solicitud de pago no puede ser leído! Esto puede ser causado por un archivo de solicitud de pago inválido. + + + Payment request rejected + Solicitud de pago rechazada + + + Payment request network doesn't match client network. + La red de solicitud de pago no cimbina la red cliente. + + + Payment request expired. + Solicitud de pago caducada. + + + Payment request is not initialized. + La solicitud de pago no se ha iniciado. + + + Unverified payment requests to custom payment scripts are unsupported. + Solicitudes de pago sin verificar a scripts de pago habitual no se soportan. + + + Invalid payment request. + Solicitud de pago inválida. + + + Requested payment amount of %1 is too small (considered dust). + Cantidad de pago solicitada de %1 es demasiado pequeña (considerado polvo). + + + Refund from %1 + Reembolsar desde %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Solicitud de pago de %1 es demasiado grande (%2 bytes, permitidos %3 bytes). + + + Error communicating with %1: %2 + Fallo al comunicar con %1: %2 + + + Payment request cannot be parsed! + ¡La solicitud de pago no puede ser analizada! + + + Bad response from server %1 + Mala respuesta desde el servidor %1 + + + Network request error + Fallo de solicitud de red + + + Payment acknowledged + Pago declarado + + PeerTableModel - + + User Agent + User Agent + + + Node/Service + Nodo/Servicio + + + Ping Time + Ping + + QObject - + + Amount + Cantidad + + + Enter a Bitcoin address (e.g. %1) + Introducir una dirección Bitcoin (p. ej. %1) + + + %1 d + %1 d + + + %1 h + %1 h + + + %1 m + %1 m + + + %1 s + %1 s + + + None + Ninguno + + + N/A + N/D + + + %1 ms + %1 ms + + QRImageWidget - + + &Save Image... + &Guardar imagen... + + + &Copy Image + &Copiar imagen + + + Save QR Code + Guardar código QR + + + PNG Image (*.png) + Imagen PNG (*.png) + + RPCConsole - + + N/A + N/D + + + Client version + Versión del cliente + + + &Information + &Información + + + Debug window + Ventana de depuración + + + General + General + + + Using BerkeleyDB version + Utilizando la versión de BerkeleyDB + + + Datadir + Datadir + + + Startup time + Hora de inicio + + + Network + Red + + + Name + Nombre + + + Number of connections + Número de conexiones + + + Block chain + Cadena de bloques + + + Current number of blocks + Número actual de bloques + + + Memory Pool + Piscina de Memoria + + + Current number of transactions + Número actual de transacciones + + + Memory usage + Uso de memoria + + + Received + Recibido + + + Sent + Enviado + + + &Peers + &Pares + + + Banned peers + Peers Bloqueados + + + Select a peer to view detailed information. + Seleccionar un par para ver su información detallada. + + + Whitelisted + En la lista blanca + + + Direction + Dirección + + + Version + Versión + + + Starting Block + Importando bloques... + + + Synced Headers + Sincronizar Cabeceras + + + Synced Blocks + Bloques Sincronizados + + + User Agent + User Agent + + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Abrir el archivo de depuración %1 desde el directorio de datos actual. Puede tardar unos segundos para ficheros de gran tamaño. + + + Decrease font size + Disminuir tamaño de letra + + + Increase font size + Aumentar tamaño de letra + + + Services + Servicios + + + Ban Score + Puntuación de bloqueo + + + Connection Time + Duración de la conexión + + + Last Send + Ultimo envío + + + Last Receive + Ultima recepción + + + Ping Time + Ping + + + The duration of a currently outstanding ping. + La duración de un ping actualmente en proceso. + + + Ping Wait + Espera de Ping + + + Time Offset + Desplazamiento de tiempo + + + Last block time + Hora del último bloque + + + &Open + &Abrir + + + &Console + &Consola + + + &Network Traffic + &Tráfico de Red + + + &Clear + &Vaciar + + + Totals + Total: + + + In: + Entrante: + + + Out: + Saliente: + + + Debug log file + Archivo de registro de depuración + + + Clear console + Borrar consola + + + &Disconnect Node + Nodo &Desconectado + + + Ban Node for + Prohibir Nodo para + + + 1 &hour + 1 &hora + + + 1 &day + 1 &día + + + 1 &week + 1 &semana + + + 1 &year + 1 &año + + + &Unban Node + &Desbanear Nodo + + + Welcome to the %1 RPC console. + Bienvenido a la consola RPC %1. + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Use las flechas arriba y abajo para navegar por el historial y <b>Control+L</b> para vaciar la pantalla. + + + Type <b>help</b> for an overview of available commands. + Escriba <b>help</b> para ver un resumen de los comandos disponibles. + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + (node id: %1) + (nodo: %1) + + + via %1 + via %1 + + + never + nunca + + + Inbound + Entrante + + + Outbound + Saliente + + + Yes + + + + No + No + + + Unknown + Desconocido + + ReceiveCoinsDialog - + + &Amount: + Cantidad + + + &Label: + &Etiqueta: + + + &Message: + Mensaje: + + + Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. + Reutilizar una de las direcciones previamente usadas para recibir. Reutilizar direcciones tiene problemas de seguridad y privacidad. No lo uses a menos que antes regeneres una solicitud de pago. + + + R&euse an existing receiving address (not recommended) + R&eutilizar una dirección existente para recibir (no recomendado) + + + 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. + Un mensaje opcional para adjuntar a la solicitud de pago, que se muestra cuando se abre la solicitud. Nota: El mensaje no se enviará con el pago por la red Bitcoin. + + + An optional label to associate with the new receiving address. + Etiqueta opcional para asociar con la nueva dirección de recepción. + + + Use this form to request payments. All fields are <b>optional</b>. + Utilice este formulario para solicitar pagos. Todos los campos son <b>opcionales</b>. + + + An optional amount to request. Leave this empty or zero to not request a specific amount. + Para solicitar una cantidad opcional. Deje este vacío o cero para no solicitar una cantidad específica. + + + Clear all fields of the form. + Vaciar todos los campos del formulario. + + + Clear + Vaciar + + + Requested payments history + Historial de pagos solicitados + + + &Request payment + &Solicitar pago + + + Show the selected request (does the same as double clicking an entry) + Muestra la petición seleccionada (También doble clic) + + + Show + Mostrar + + + Remove the selected entries from the list + Borrar de la lista las direcciónes actualmente seleccionadas + + + Remove + Eliminar + + + Copy label + Copiar capa + + + Copy message + Copiar imagen + + + Copy amount + Copiar cantidad + + ReceiveRequestDialog - Copy &Address - &Copiar Direccón + QR Code + Código QR - + + Copy &URI + Copiar &URI + + + Copy &Address + Copiar &Dirección + + + &Save Image... + Guardar Imagen... + + + Request payment to %1 + Solicitar pago a %1 + + + Payment information + Información de pago + + + URI + URI + + + Address + Dirección + + + Amount + Cantidad + + + Label + Etiqueta + + + Message + Mensaje + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante demasiado grande, trate de reducir el texto de etiqueta / mensaje. + + + Error encoding URI into QR Code. + Fallo al codificar URI en código QR. + + RecentRequestsTableModel - + + Date + Fecha + + + Label + Etiqueta + + + Message + Mensaje + + + (no label) + (sin etiqueta) + + + (no message) + (no hay mensaje) + + + (no amount requested) + (no hay solicitud de cantidad) + + + Requested + Solicitado + + SendCoinsDialog - + + Send Coins + Enviar bitcoins + + + Coin Control Features + Características de Coin Control + + + Inputs... + Entradas... + + + automatically selected + Seleccionado automáticamente + + + Insufficient funds! + Fondos insuficientes! + + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Cuantía: + + + Priority: + Prioridad: + + + Fee: + Tasa: + + + After Fee: + Después de tasas: + + + Change: + Cambio: + + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + Si se marca esta opción pero la dirección de cambio está vacía o es inválida, el cambio se enviará a una nueva dirección recién generada. + + + Custom change address + Dirección propia + + + Transaction Fee: + Comisión de Transacción: + + + Choose... + Elija... + + + collapse fee-settings + Colapsar ajustes de cuota + + + per kilobyte + por kilobyte + + + If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. + Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a sólo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "el mínimo total" pagaría 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte + + + Hide + Ocultar + + + total at least + total por lo menos + + + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + Pagando solamente la cuota mínima es correcto, siempre y cuando haya menos volumen de transacciones que el espacio en los bloques. Pero tenga en cuenta que esto puede terminar en una transacción nunca confirmada, una vez que haya más demanda para transacciones Bitcoin que la red pueda procesar. + + + (read the tooltip) + (leer la sugerencia) + + + Recommended: + Recomendado: + + + Custom: + Personalizado: + + + (Smart fee not initialized yet. This usually takes a few blocks...) + (Tarifa inteligente no inicializado aún. Esto generalmente lleva a pocos bloques...) + + + Confirmation time: + Tiempo de confirmación: + + + normal + normal + + + fast + rápido + + + Send to multiple recipients at once + Enviar a múltiples destinatarios de una vez + + + Add &Recipient + Añadir &destinatario + + + Clear all fields of the form. + Vaciar todos los campos del formulario + + + Dust: + Polvo: + + + Clear &All + Vaciar &todo + + + Balance: + Saldo: + + + Confirm the send action + Confirmar el envío + + + S&end + &Enviar + + + Copy quantity + Copiar cantidad + + + Copy amount + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + ¿Seguro que quiere enviar? + + + added as transaction fee + añadido como transacción de cuota + + + Total Amount %1 + Cantidad total %1 + + + or + o + + + Confirm send coins + Confirmar enviar monedas + + + The recipient address is not valid. Please recheck. + La dirección de destinatario no es válida. Por favor revísela. + + + The amount to pay must be larger than 0. + La cantidad a pagar debe de ser mayor que 0. + + + The amount exceeds your balance. + La cantidad excede su saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excede su saldo cuando la cuota de transacción de %1 es incluida. + + + Duplicate address found: addresses should only be used once each. + Dirección duplicada encontrada: la dirección sólo debería ser utilizada una vez por cada uso. + + + Transaction creation failed! + ¡Falló la creación de transacción! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + ¡La transacción fue rechazada! Esto podría pasar si algunas de las monedas de su monedero fueron ya gastadas, así como si ha utilizado una copia del wallet.dat y las monedas fueron gastadas en la copia pero no marcadas como gastadas aquí. + + + A fee higher than %1 is considered an absurdly high fee. + Una couta mayor que %1 se considera una cuota irracionalmente alta. + + + Payment request expired. + Solicitud de pago caducada. + + + Pay only the required fee of %1 + Pagar únicamente la cuota solicitada de %1 + + + Estimated to begin confirmation within %n block(s). + Se estima que sea confirmado dentro del %n bloque(s).Se estima que sea confirmado dentro del %n bloque(s). + + + Warning: Invalid Bitcoin address + Alerta: dirección Bitcoin inválida + + + Warning: Unknown change address + Alerta: dirección cambiada desconocida + + + (no label) + (sin etiqueta) + + SendCoinsEntry - + + A&mount: + Ca&ntidad: + + + Pay &To: + &Pagar a: + + + &Label: + &Etiqueta: + + + Choose previously used address + Escoger direcciones previamente usadas + + + This is a normal payment. + Esto es un pago ordinario. + + + The Bitcoin address to send the payment to + Dirección Bitcoin a la que enviar el pago + + + Alt+A + Alt+A + + + Paste address from clipboard + Pegar dirección desde portapapeles + + + Alt+P + Alt+P + + + Remove this entry + Eliminar esta transacción + + + 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. + La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el + + + S&ubtract fee from amount + Restar comisiones a la cantidad + + + Message: + Mensaje: + + + This is an unauthenticated payment request. + Esta es una petición de pago no autentificada. + + + This is an authenticated payment request. + Esta es una petición de pago autentificada. + + + Enter a label for this address to add it to the list of used addresses + Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas + + + 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. + Un mensaje que se adjuntó a la bitcoin: URL que será almacenada con la transacción para su referencia. Nota: Este mensaje no se envía a través de la red Bitcoin. + + + Pay To: + Paga a: + + + Memo: + Memo: + + + Enter a label for this address to add it to your address book + Introduzca una etiqueta para esta dirección para añadirla a su agenda + + SendConfirmationDialog - + + Yes + + + ShutdownWindow - + + %1 is shutting down... + %1 se esta cerrando... + + + Do not shut down the computer until this window disappears. + No apague el equipo hasta que desaparezca esta ventana. + + SignVerifyMessageDialog - + + Signatures - Sign / Verify a Message + Firmas - Firmar / verificar un mensaje + + + &Sign Message + &Firmar mensaje + + + 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. + Puede firmar los mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa de manera vaga o aleatoria, pues los ataques de phishing pueden tratar de engañarle firmando su identidad a través de ellos. Sólo firme declaraciones totalmente detalladas con las que usted esté de acuerdo. + + + The Bitcoin address to sign the message with + Dirección Bitcoin con la que firmar el mensaje + + + Choose previously used address + Escoger dirección previamente usada + + + Alt+A + Alt+A + + + Paste address from clipboard + Pegar dirección desde portapapeles + + + Alt+P + Alt+P + + + Enter the message you want to sign here + Introduzca el mensaje que desea firmar aquí + + + Signature + Firma + + + Copy the current signature to the system clipboard + Copiar la firma actual al portapapeles del sistema + + + Sign the message to prove you own this Bitcoin address + Firmar el mensaje para demostrar que se posee esta dirección Bitcoin + + + Sign &Message + Firmar &mensaje + + + Reset all sign message fields + Vaciar todos los campos de la firma de mensaje + + + Clear &All + Vaciar &todo + + + &Verify Message + &Verificar mensaje + + + 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! + Introduzca la dirección para la firma, el mensaje (asegurándose de copiar tal cual los saltos de línea, espacios, tabulaciones, etc.) y la firma a continuación para verificar el mensaje. Tenga cuidado de no asumir más información de lo que dice el propio mensaje firmado para evitar fraudes basados en ataques de tipo man-in-the-middle. + + + The Bitcoin address the message was signed with + La dirección Bitcoin con la que se firmó el mensaje + + + Verify the message to ensure it was signed with the specified Bitcoin address + Verificar el mensaje para comprobar que fue firmado con la dirección Bitcoin indicada + + + Verify &Message + Verificar &mensaje + + + Reset all verify message fields + Vaciar todos los campos de la verificación de mensaje + + + Click "Sign Message" to generate signature + Click en "Fírmar mensaje" para generar una firma + + + The entered address is invalid. + La dirección introducida no es válida. + + + Please check the address and try again. + Por favor revise la dirección e inténtelo de nuevo. + + + The entered address does not refer to a key. + La dirección introducida no remite a una clave. + + + Wallet unlock was cancelled. + El desbloqueo del monedero fue cancelado. + + + Private key for the entered address is not available. + La clave privada de la dirección introducida no está disponible. + + + Message signing failed. + Falló la firma del mensaje. + + + Message signed. + Mensaje firmado. + + + The signature could not be decoded. + La firma no pudo descodificarse. + + + Please check the signature and try again. + Por favor compruebe la firma y pruebe de nuevo. + + + The signature did not match the message digest. + La firma no se combinó con el mensaje. + + + Message verification failed. + Falló la verificación del mensaje. + + + Message verified. + Mensaje verificado. + + SplashScreen - + + [testnet] + [testnet] + + TrafficGraphWidget - + + KB/s + KB/s + + TransactionDesc - + + Open for %n more block(s) + Abrir para %n más bloque(s)Abrir para %n más bloque(s) + + + Open until %1 + Abierto hasta %1 + + + conflicted with a transaction with %1 confirmations + Hay un conflicto con la traducción de las confirmaciones %1 + + + %1/offline + %1/sin conexión + + + 0/unconfirmed, %1 + 0/no confirmado, %1 + + + in memory pool + en el equipo de memoria + + + not in memory pool + no en el equipo de memoria + + + abandoned + abandonado + + + %1/unconfirmed + %1/no confirmado + + + %1 confirmations + confirmaciones %1 + + + Status + Estado + + + , has not been successfully broadcast yet + , no ha sido emitido con éxito aún + + + , broadcast through %n node(s) + , emisión a través de %n nodo(s), emisión a través de %n nodo(s) + + + Date + Fecha + + + Source + Fuente + + + Generated + Generado + + + From + Desde + + + unknown + desconocido + + + To + Para + + + own address + dirección propia + + + watch-only + de observación + + + label + etiqueta + + + Credit + Credito + + + matures in %n more block(s) + disponible en %n bloque(s) másdisponible en %n bloque(s) más + + + not accepted + no aceptada + + + Debit + Enviado + + + Total debit + Total enviado + + + Total credit + Total recibido + + + Transaction fee + Comisión de transacción + + + Net amount + Cantidad neta + + + Message + Mensaje + + + Comment + Comentario + + + Transaction ID + Identificador de transacción (ID) + + + Output index + Indice de salida + + + Merchant + Vendedor + + + 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. + Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo. + + + Debug information + Información de depuración + + + Transaction + Transacción + + + Inputs + entradas + + + Amount + Cantidad + + + true + verdadero + + + false + falso + + TransactionDescDialog - + + This pane shows a detailed description of the transaction + Esta ventana muestra información detallada sobre la transacción + + + Details for %1 + Detalles para %1 + + TransactionTableModel - + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Open for %n more block(s) + Abrir para %n bloque(s) másAbrir para %n bloque(s) más + + + Open until %1 + Abierto hasta %1 + + + Offline + Sin conexion + + + Unconfirmed + Sin confirmar + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmaciones recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + Conflicted + En conflicto + + + Immature (%1 confirmations, will be available after %2) + No disponible (%1 confirmaciones. Estarán disponibles al cabo de %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! + + + Generated but not accepted + Generado pero no aceptado + + + Received with + Recibido con + + + Received from + Recibidos de + + + Sent to + Enviado a + + + Payment to yourself + Pago proprio + + + Mined + Minado + + + watch-only + de observación + + + (n/a) + (nd) + + + (no label) + (sin etiqueta) + + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. + + + Date and time that the transaction was received. + Fecha y hora en que se recibió la transacción. + + + Type of transaction. + Tipo de transacción. + + + Whether or not a watch-only address is involved in this transaction. + Si una dirección watch-only está involucrada en esta transacción o no. + + + User-defined intent/purpose of the transaction. + Descripción de la transacción definido por el usuario. + + + Amount removed from or added to balance. + Cantidad retirada o añadida al saldo. + + TransactionView - + + All + Todo + + + Today + Hoy + + + This week + Esta semana + + + This month + Este mes + + + Last month + Mes pasado + + + This year + Este año + + + Range... + Rango... + + + Received with + Recibido con + + + Sent to + Enviado a + + + To yourself + A usted mismo + + + Mined + Minado + + + Other + Otra + + + Enter address or label to search + Introduzca una dirección o etiqueta que buscar + + + Min amount + Cantidad mínima + + + Abandon transaction + Transacción abandonada + + + Copy address + Copiar ubicación + + + Copy label + Copiar capa + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Copy raw transaction + Copiar transacción raw + + + Copy full transaction details + Copiar todos los detalles de la transacción + + + Edit label + Editar etiqueta + + + Show transaction details + Mostrar detalles de la transacción + + + Export Transaction History + Exportar historial de transacciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Confirmed + Confirmado + + + Watch-only + De observación + + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Address + Dirección + + + ID + ID + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the transaction history to %1. + Ha habido un error al intentar guardar la transacción con %1. + + + Exporting Successful + Exportación finalizada + + + The transaction history was successfully saved to %1. + La transacción ha sido guardada en %1. + + + Range: + Rango: + + + to + para + + UnitDisplayStatusBarControl - + + Unit to show amounts in. Click to select another unit. + Unidad en la que se muestran las cantidades. Haga clic para seleccionar otra unidad. + + WalletFrame - + + No wallet has been loaded. + No se ha cargado ningún monedero + + WalletModel - + + Send Coins + Enviar + + WalletView - + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar a un archivo los datos de esta pestaña + + + Backup Wallet + Copia de seguridad del monedero + + + Wallet Data (*.dat) + Datos de monedero (*.dat) + + + Backup Failed + La copia de seguridad ha fallado + + + There was an error trying to save the wallet data to %1. + Ha habido un error al intentar guardar los datos del monedero en %1. + + + Backup Successful + Se ha completado con éxito la copia de respaldo + + + The wallet data was successfully saved to %1. + Los datos del monedero se han guardado con éxito en %1. + + bitcoin-core - + + Options: + Opciones: + + + + Specify data directory + Especificar directorio para los datos + + + Connect to a node to retrieve peer addresses, and disconnect + Conectar a un nodo para obtener direcciones de pares y desconectar + + + Specify your own public address + Especifique su propia dirección pública + + + Accept command line and JSON-RPC commands + Aceptar comandos consola y JSON-RPC + + + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si <category> no es proporcionado o si <category> =1, muestra toda la información de depuración. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + La Poda se ha configurado por debajo del minimo de %d MiB. Por favor utiliza un valor mas alto. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Poda: la ultima sincronizacion de la cartera sobrepasa los datos podados. Necesitas reindexar con -reindex (o descargar la cadena de bloques de nuevo en el caso de un nodo podado) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduce los requisitos de almacenaje podando (eliminando) los bloques viejos. Este modo es incompatible con -txindex y -rescan. Advertencia: Revertir este ajuste requiere volver a descargar la cadena de bloques al completo. (predeterminado: 0 = deshabilitar la poda de bloques, >%u = objetivo de tamaño en MiB para usar para los archivos de bloques) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Nos es posible re-escanear en modo podado.Necesitas utilizar -reindex el cual descargara la cadena de bloques al completo de nuevo. + + + Error: A fatal internal error occurred, see debug.log for details + Un error interno fatal ocurrió, ver debug.log para detalles + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comisión (en %s/KB) para agregar a las transacciones que envíe (por defecto: %s) + + + Pruning blockstore... + Poda blockstore ... + + + Run in the background as a daemon and accept commands + Ejecutar en segundo plano como daemon y aceptar comandos + + + + Unable to start HTTP server. See debug log for details. + No se ha podido comenzar el servidor HTTP. Ver debug log para detalles. + + + Accept connections from outside (default: 1 if no -proxy or -connect) + Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) + + + Bitcoin Core + Bitcoin Core + + + The %s developers + Los %s desarrolladores + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee tiene un ajuste muy alto! Esta es la comisión de transacción que pagarás cuando las estimaciones de comisiones no estén disponibles. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Una comision (en %s/kB) que sera usada cuando las estimacion de comision no disponga de suficientes datos (predeterminado: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Aceptar transacciones retransmitidas recibidas desde nodos en la lista blanca incluso cuando no estés retransmitiendo transacciones (predeterminado: %d) + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6 + + + Cannot obtain a lock on data directory %s. %s is probably already running. + No se puede bloquear el directorio %s. %s ya se está ejecutando. + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>. + + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Bytes equivalentes por sigop en transacciones para retrasmisión y minado (predeterminado: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Error cargando %s: No puede habilitar HD en un monedero existente que no es HD + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error leyendo %s!. Todas las claves se han leido correctamente, pero los datos de transacciones o la libreta de direcciones pueden faltar o ser incorrectos. + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) + + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Ajuste máximo permitido del tiempo offset medio de pares. La perspectiva local de tiempo se verá influenciada por los pares anteriores y posteriores a esta cantidad. (Por defecto: %u segundos) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Máximas comisiones totales (en %s) para utilizar en una sola transacción de la cartera; establecer esto demasiado bajo puede abortar grandes transacciones (predeterminado: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Por favor, compruebe si la fecha y hora en su computadora son correctas! Si su reloj esta mal, %s no trabajara correctamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Contribuya si encuentra %s de utilidad. Visite %s para mas información acerca del programa. + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, <0 = dejar libres ese número de núcleos; predeterminado: %d) + + + 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 + La base de datos de bloques contiene un bloque que parece ser del futuro. Esto puede ser porque la fecha y hora de tu ordenador están mal ajustados. Reconstruye la base de datos de bloques solo si estas seguro de que la fecha y hora de tu ordenador estan ajustados correctamente. + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería. + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + No es posible reconstruir la base de datos a un estado anterior. Debe descargar de nuevo la cadena de bloques. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes. + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla. + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces. + + + You need to rebuild the database using -reindex-chainstate to change -txindex + Necesita reconstruir la base de datos usando -reindex-chainstate para cambiar -txindex + + + %s corrupt, salvage failed + %s corrupto. Fracasó la recuperacion + + + -maxmempool must be at least %d MB + -maxmempool debe ser por lo menos de %d MB + + + <category> can be: + <category> puede ser: + + + Append comment to the user agent string + Adjunta un comentario a la linea de agente de usuario + + + Attempt to recover private keys from a corrupt wallet on startup + Intento de recuperar claves privadas de un monedero corrupto en arranque + + + Block creation options: + Opciones de creación de bloques: + + + Cannot resolve -%s address: '%s' + No se puede resolver -%s direccion: '%s' + + + Change index out of range + Cambio de indice fuera de rango + + + Connect only to the specified node(s) + Conectar sólo a los nodos (o nodo) especificados + + + Connection options: + Opciones de conexión: + + + Copyright (C) %i-%i + Copyright (C) %i-%i + + + Corrupted block database detected + Corrupción de base de datos de bloques detectada. + + + Debugging/Testing options: + Opciones de depuración/pruebas: + + + Do not load the wallet and disable wallet RPC calls + No cargar el monedero y desactivar las llamadas RPC del monedero + + + Do you want to rebuild the block database now? + ¿Quieres reconstruir la base de datos de bloques ahora? + + + Enable publish hash block in <address> + Activar publicar bloque .hash en <.Address> + + + Enable publish hash transaction in <address> + Activar publicar transacción .hash en <.Address> + + + Enable publish raw block in <address> + Habilita la publicacion de bloques en bruto en <direccion> + + + Enable publish raw transaction in <address> + Habilitar publicar transacción en rama en <dirección> + + + Enable transaction replacement in the memory pool (default: %u) + Habilita el reemplazamiento de transacciones en la piscina de memoria (predeterminado: %u) + + + Error initializing block database + Error al inicializar la base de datos de bloques + + + Error initializing wallet database environment %s! + Error al inicializar el entorno de la base de datos del monedero %s + + + Error loading %s + Error cargando %s + + + Error loading %s: Wallet corrupted + Error cargando %s: Monedero dañado + + + Error loading %s: Wallet requires newer version of %s + Error cargando %s: Monedero requiere un versión mas reciente de %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Error cargando %s: No puede deshabilitar HD en un monedero existente que ya es HD + + + Error loading block database + Error cargando base de datos de bloques + + + Error opening block database + Error al abrir base de datos de bloques. + + + Error: Disk space is low! + Error: ¡Espacio en disco bajo! + + + Failed to listen on any port. Use -listen=0 if you want this. + Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto. + + + Importing... + Importando... + + + Incorrect or no genesis block found. Wrong datadir for network? + Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red? + + + Initialization sanity check failed. %s is shutting down. + La inicialización de la verificación de validez falló. Se está apagando %s. + + + Invalid -onion address: '%s' + Dirección -onion inválida: '%s' + + + Invalid amount for -%s=<amount>: '%s' + Cantidad no valida para -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Cantidad inválida para -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Mantener la memoria de transacciones por debajo de <n> megabytes (predeterminado: %u) + + + Loading banlist... + Cargando banlist... + + + Location of the auth cookie (default: data dir) + Ubicación de la cookie de autenticación (default: data dir) + + + Not enough file descriptors available. + No hay suficientes descriptores de archivo disponibles. + + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion) + + + Print this help message and exit + Imprimir este mensaje de ayuda y salir + + + Print version and exit + Imprimir versión y salir + + + Prune cannot be configured with a negative value. + Pode no se puede configurar con un valor negativo. + + + Prune mode is incompatible with -txindex. + El modo recorte es incompatible con -txindex. + + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruir el estado de la cadena e indice de bloques a partir de los ficheros blk*.dat en disco + + + Rebuild chain state from the currently indexed blocks + Reconstruir el estado de la cadena a partir de los bloques indexados + + + Rewinding blocks... + Verificando bloques... + + + Set database cache size in megabytes (%d to %d, default: %d) + Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) + + + Set maximum BIP141 block weight (default: %d) + Establecer peso máximo bloque BIP141 (predeterminado: %d) + + + Set maximum block size in bytes (default: %d) + Establecer tamaño máximo de bloque en bytes (predeterminado: %d) + + + Specify wallet file (within data directory) + Especificar archivo de monedero (dentro del directorio de datos) + + + Starting network threads... + Iniciando funciones de red... + + + The source code is available from %s. + El código fuente esta disponible desde %s. + + + Unable to bind to %s on this computer. %s is probably already running. + No se ha podido conectar con %s en este equipo. %s es posible que este todavia en ejecución. + + + Unsupported argument -benchmark ignored, use -debug=bench. + El argumento -benchmark no es soportado y ha sido ignorado, utiliza -debug=bench + + + Unsupported argument -debugnet ignored, use -debug=net. + Parámetros no compatibles -debugnet ignorados , use -debug = red. + + + Unsupported argument -tor found, use -onion. + Parámetros no compatibles -tor encontrados, use -onion . + + + Use UPnP to map the listening port (default: %u) + Usar UPnP para asignar el puerto de escucha (predeterminado:: %u) + + + User Agent comment (%s) contains unsafe characters. + El comentario del Agente de Usuario (%s) contiene caracteres inseguros. + + + Verifying blocks... + Verificando bloques... + + + Verifying wallet... + Verificando monedero... + + + Wallet %s resides outside data directory %s + El monedero %s se encuentra fuera del directorio de datos %s + + + Wallet debugging/testing options: + Opciones de depuración/pruebas de monedero: + + + Wallet needed to be rewritten: restart %s to complete + Es necesario reescribir el monedero: reiniciar %s para completar + + + Wallet options: + Opciones de monedero: + + + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + Permitir conexiones JSON-RPC de origen especificado. Válido para son una sola IP (por ejemplo 1.2.3.4), una red/máscara de red (por ejemplo 1.2.3.4/255.255.255.0) o una red/CIDR (e.g. 1.2.3.4/24). Esta opción se puede especificar varias veces + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + Ligar a las direcciones especificadas y poner en lista blanca a los equipos conectados a ellas. Usar la notación para IPv6 [host]:puerto. + + + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + Ligar a las direcciones especificadas para escuchar por conexiones JSON-RPC. Usar la notación para IPv6 [host]:puerto. Esta opción se puede especificar múltiples veces (por defecto: ligar a todas las interfaces) + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy) + + + Error: Listening for incoming connections failed (listen returned error %s) + Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s) + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Las comisiones (en %s/kB) mas pequeñas que esto se consideran como cero comisión para la retransmisión, minería y creación de la transacción (predeterminado: %s) + + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Cantidad no válida para -maxtxfee=<amount>: '%s' (debe ser por lo menos la cuota de comisión mínima de %s para prevenir transacciones atascadas) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u) + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d) + + + The transaction amount is too small to send after the fee has been deducted + Monto de transacción muy pequeña luego de la deducción por comisión + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit <https://www.openssl.org/>, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard. + + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usar tras BIP32 la generación de llave determinística jerárquica (HD) . Solo tiene efecto durante el primer inicio/generación del monedero + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway. + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques + + + (default: %u) + (por defecto: %u) + + + Accept public REST requests (default: %u) + Aceptar solicitudes públicas en FERIADOS (por defecto: %u) + + + Automatically create Tor hidden service (default: %d) + Automáticamente crea el servicio Tor oculto (por defecto: %d) + + + Connect through SOCKS5 proxy + Conectar usando SOCKS5 proxy + + + Error reading from database, shutting down. + Error al leer la base de datos, cerrando. + + + Imports blocks from external blk000??.dat file on startup + Importa los bloques desde un archivo externo blk000?.dat + + + Information + Información + + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Cantidad inválida para -paytxfee=<amount>: '%s' (debe ser por lo menos %s) + + + Invalid netmask specified in -whitelist: '%s' + Máscara de red inválida especificada en -whitelist: '%s' + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Mantener como máximo <n> transacciones no conectables en memoria (por defecto: %u) + + + Need to specify a port with -whitebind: '%s' + Necesita especificar un puerto con -whitebind: '%s' + + + Node relay options: + Opciones de nodos de retransmisión: + + + RPC server options: + Opciones de servidor RPC: + + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduciendo -maxconnections de %d a %d, debido a limitaciones del sistema. + + + Rescan the block chain for missing wallet transactions on startup + Rescanea la cadena de bloques para transacciones perdidas de la cartera + + + Send trace/debug info to console instead of debug.log file + Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log + + + Send transactions as zero-fee transactions if possible (default: %u) + Mandar transacciones como comisión-cero si es posible (por defecto: %u) + + + Show all debugging options (usage: --help -help-debug) + Muestra todas las opciones de depuración (uso: --help -help-debug) + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug) + + + Signing transaction failed + Transacción falló + + + The transaction amount is too small to pay the fee + Cantidad de la transacción demasiado pequeña para pagar la comisión + + + This is experimental software. + Este software es experimental. + + + Tor control port password (default: empty) + Contraseña del puerto de control de Tor (predeterminado: vacio) + + + Tor control port to use if onion listening enabled (default: %s) + Puerto de control de Tor a utilizar si la escucha de onion esta activada (predeterminado: %s) + + + Transaction amount too small + Cantidad de la transacción demasiado pequeña + + + Transaction amounts must be positive + Las cantidades en las transacciones deben ser positivas + + + Transaction too large for fee policy + Operación demasiado grande para la política de tasas + + + Transaction too large + Transacción demasiado grande, intenta dividirla en varias. + + + Unable to bind to %s on this computer (bind returned error %s) + No es posible conectar con %s en este sistema (bind ha dado el error %s) + + + Upgrade wallet to latest format on startup + Actualizar el monedero al último formato al inicio + + + Username for JSON-RPC connections + Nombre de usuario para las conexiones JSON-RPC + + + + Warning + Aviso + + + Warning: unknown new rules activated (versionbit %i) + Advertencia: nuevas reglas desconocidas activadas (versionbit %i) + + + Whether to operate in a blocks only mode (default: %u) + Si se debe o no operar en un modo de solo bloques (predeterminado: %u) + + + Zapping all transactions from wallet... + Eliminando todas las transacciones del monedero... + + + ZeroMQ notification options: + Opciones de notificación ZeroQM: + + + Password for JSON-RPC connections + Contraseña para las conexiones JSON-RPC + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque) + + + Allow DNS lookups for -addnode, -seednode and -connect + Permitir búsquedas DNS para -addnode, -seednode y -connect + + + Loading addresses... + Cargando direcciones... + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = mantener los meta datos de transacción, por ejemplo: propietario e información de pago, 2 = omitir los metadatos) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee tiene un ajuste muy elevado! Comisiones muy grandes podrían ser pagadas en una única transaccion. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee tiene un valor muy elevado! La comisión de transacción que pagaras si envías una transaccion es alta. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + No mantener transacciones en la memoria mas de <n> horas (predeterminado: %u) + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Las comisiones (en %s/kB) menores que esto son consideradas de cero comision para la creacion de transacciones (predeterminado: %s) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: %u) + + + Output debugging information (default: %u, supplying <category> is optional) + Mostrar depuración (por defecto: %u, proporcionar <category> es opcional) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Error: argumento -socks encontrado. El ajuste de la versión SOCKS ya no es posible, sólo proxies SOCKS5 son compatibles. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + El argumento no soportado -whitelistalwaysrelay ha sido ignorado, utiliza -whitelistrelay y/o -whitelistforcerelay. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nombre de usuario y hash de la contraseña para las conexiones JSON-RPC. El campo <userpw> tiene el formato: <USERNAME>:<SALT>$<HASH>. Se incluye un script python convencional en share/rpcuser. Esta opción puede ser especificada multiples veces + + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advertencia: Se están minando versiones de bloques desconocidas! Es posible que normas desconocidas estén activas + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Aviso: fichero de monedero corrupto, datos recuperados! Original %s guardado como %s en %s; si su balance de transacciones es incorrecto, debe restaurar desde una copia de seguridad. + + + (default: %s) + (predeterminado: %s) + + + Always query for peer addresses via DNS lookup (default: %u) + Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u) + + + How many blocks to check at startup (default: %u, 0 = all) + Cuántos bloques comprobar al iniciar (predeterminado: %u, 0 = todos) + + + Include IP addresses in debug output (default: %u) + Incluir direcciones IP en la salida de depuración (por defecto: %u) + + + Invalid -proxy address: '%s' + Dirección -proxy inválida: '%s' + + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Escuchar conexiones JSON-RPC en <puerto> (predeterminado: %u o testnet: %u) + + + Listen for connections on <port> (default: %u or testnet: %u) + Escuchar conexiones en <puerto> (predeterminado: %u o testnet: %u) + + + Maintain at most <n> connections to peers (default: %u) + Mantener como máximo <n> conexiones a pares (predeterminado: %u) + + + Make the wallet broadcast transactions + Realiza las operaciones de difusión del monedero + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Búfer de recepción máximo por conexión, <n>*1000 bytes (por defecto: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Búfer de recepción máximo por conexión, , <n>*1000 bytes (por defecto: %u) + + + Prepend debug output with timestamp (default: %u) + Anteponer marca temporal a la información de depuración (por defecto: %u) + + + Relay and mine data carrier transactions (default: %u) + Retransmitir y minar transacciones de transporte de datos (por defecto: %u) + + + Relay non-P2SH multisig (default: %u) + Relay non-P2SH multisig (default: %u) + + + Set key pool size to <n> (default: %u) + Ajustar el número de claves en reserva <n> (predeterminado: %u) + + + Set the number of threads to service RPC calls (default: %d) + Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d) + + + Specify configuration file (default: %s) + Especificar archivo de configuración (por defecto: %s) + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Especificar tiempo de espera de la conexión (mínimo: 1, por defecto: %d) + + + Specify pid file (default: %s) + Especificar archivo pid (predeterminado: %s) + + + Spend unconfirmed change when sending transactions (default: %u) + Usar cambio aún no confirmado al enviar transacciones (predeterminado: %u) + + + Threshold for disconnecting misbehaving peers (default: %u) + Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u) + + + Unknown network specified in -onlynet: '%s' + La red especificada en -onlynet '%s' es desconocida + + + Insufficient funds + Fondos insuficientes + + + Loading block index... + Cargando el índice de bloques... + + + Add a node to connect to and attempt to keep the connection open + Añadir un nodo al que conectarse y tratar de mantener la conexión abierta + + + Loading wallet... + Cargando monedero... + + + Cannot downgrade wallet + No se puede cambiar a una versión mas antigua el monedero + + + Cannot write default address + No se puede escribir la dirección predeterminada + + + Rescanning... + Reexplorando... + + + Done loading + Se terminó de cargar + + + Error + Error + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 5d2423eef..e65d4e6e4 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -41,10 +41,78 @@ &Delete &Kustuta - + + Choose the address to send coins to + Vali aadress millele mündid saata + + + Choose the address to receive coins with + Vali aadress müntide vastuvõtmiseks + + + C&hoose + V&ali + + + Sending addresses + Saatvad aadressid + + + Receiving addresses + Vastuvõtvad aadressid + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Need on sinu Bitcoin aadressid maksete saatmiseks. Ennem müntide saatmist kontrolli alati summat ja makse saaja aadressi. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Need on sinu Bitcoin aadressid sisenevate maksete vastu võtmiseks. Soovitav on iga tehingu tarbeks kasutada uut aadressi. + + + &Copy Address + &Kopeeri Aadress + + + Copy &Label + Kopeeri &Silt + + + &Edit + &Muuda + + + Export Address List + Ekspordi Aadresside Nimekiri + + + Comma separated file (*.csv) + Komadega eraldatud väärtuste fail (*.csv) + + + Exporting Failed + Eksport ebaõnnestus. + + + There was an error trying to save the address list to %1. Please try again. + Tõrge aadressi nimekirja salvestamisel %1. Palun proovi uuesti. + + AddressTableModel - + + Label + Märge + + + Address + Aadress + + + (no label) + (märge puudub) + + AskPassphraseDialog @@ -63,7 +131,87 @@ Repeat new passphrase Korda salafraasi - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Sisesta uus salafraas rahakotti.<br/>Kasuta salafraasi millles on<b>kümme või rohkem juhuslikku sümbolit<b>,või<b>kaheksa või rohkem sõna<b/>. + + + Encrypt wallet + Krüpteeri rahakott + + + This operation needs your wallet passphrase to unlock the wallet. + Antud operatsioon vajab rahakoti lahtilukustamiseks salafraasi. + + + Unlock wallet + Ava rahakoti lukk + + + This operation needs your wallet passphrase to decrypt the wallet. + Antud operatsioon vajab rahakoti dekrüpteerimiseks salafraasi. + + + Decrypt wallet + Dekrüpteeri rahakott + + + Change passphrase + Vaheta salafraasi + + + Enter the old passphrase and new passphrase to the wallet. + Sisesta vana salafraas ja uus salafraas rahakotti. + + + Confirm wallet encryption + Kinnita rahakoti krüpteerimine. + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Hoiatus:Kui sa krüpteerid oma rahakoti ja kaotad salafraasi, siis sa<b>KAOTAD OMA BITCOINID</b>! + + + Are you sure you wish to encrypt your wallet? + Kas oled kindel, et soovid rahakoti krüpteerida? + + + Wallet encrypted + Rahakott krüpteeritud + + + Wallet encryption failed + Rahakoti krüpteerimine ebaõnnestus + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Rahakoti krüpteerimine ebaõnnestus sisemise tõrke tõttu. Sinu rahakott ei ole krüpteeritud. + + + The supplied passphrases do not match. + Sisestatud salafraasid ei kattu. + + + Wallet unlock failed + Rahakoti lahtilukustamine ebaõnnestus + + + The passphrase entered for the wallet decryption was incorrect. + Rahakoti dekrüpteerimiseks sisestatud salafraas ei ole õige. + + + Wallet decryption failed + Rahakoti dekrüpteerimine ebaõnnestus + + + Wallet passphrase was successfully changed. + Rahakoti salafraas on edukalt vahetatud. + + + Warning: The Caps Lock key is on! + Hoiatus:Klaviatuuri suurtähelukk on peal. + + BanTableModel @@ -101,6 +249,10 @@ Quit application Väljumine + + &About %1 + &Teave %1 + About &Qt Teave &Qt kohta @@ -147,7 +299,7 @@ &Debug window - &Debugimise aken + &Silumise aken Open debugging and diagnostic console @@ -171,7 +323,7 @@ &Receive - &Saama + &Võta vastu &Show / Hide @@ -209,10 +361,38 @@ Tabs toolbar Vahelehe tööriistariba + + Request payments (generates QR codes and bitcoin: URIs) + Loo maksepäring (genereerib QR koodid ja bitcoini: URId) + + + Open a bitcoin: URI or payment request + Ava bitcoini: URI või maksepäring + &Command-line options Käsurea valikud + + %n active connection(s) to Bitcoin network + %n aktiivne ühendus Bitcoini võrku%n aktiivset ühendust Bitcoini võrku + + + Indexing blocks on disk... + Kõvakettal olevate plokkide indekseerimine... + + + Processing blocks on disk... + Kõvakettal olevate plokkide töötlemine... + + + No block source available... + Plokkide allikas pole saadaval... + + + Processed %n block(s) of transaction history. + Töödeldud %n plokk transaktsioonide ajaloost.Töödeldud %n plokki transaktsioonide ajaloost. + %n hour(s) %n tund%n tundi @@ -261,9 +441,13 @@ Up to date Ajakohane + + %1 client + %1 klient + Catching up... - Jõuan... + Jõuan järgi... Date: %1 @@ -318,27 +502,183 @@ Quantity: Kogus: + + Bytes: + Baiti: + Amount: Summa: + + Priority: + Prioriteet + Fee: Tasu: + + Dust: + Puru: + + + After Fee: + Peale tehingutasu: + + + Change: + Vahetusraha: + + + Tree mode + Puu režiim + + + List mode + Loetelu režiim + Amount Kogus + + Received with label + Vastuvõetud märgisega + + + Received with address + Vastuvõetud aadressiga + Date Kuupäev + + Confirmations + Kinnitused + Confirmed Kinnitatud - + + Priority + Prioriteet + + + Copy address + Kopeeri aadress + + + Copy label + Kopeeri märgis + + + Copy amount + Kopeeri summa + + + Copy transaction ID + Kopeeri tehingu ID + + + Copy quantity + Kopeeri kogus + + + Copy fee + Kopeeri tehingutasu + + + Copy bytes + Kopeeri baidid + + + Copy priority + Kopeeri prioriteet + + + Copy dust + Kopeeri puru + + + Copy change + Kopeeri vahetusraha + + + highest + kõrgeim + + + higher + kõrgem + + + high + kõrge + + + medium-high + keskmiselt kõrge + + + medium + keskmine + + + low-medium + keskmiselt madal + + + low + madal + + + lower + madalam + + + lowest + madalaim + + + (%1 locked) + (%1 lukustatud) + + + none + puudub + + + yes + jah + + + no + ei + + + This label turns red if the transaction size is greater than 1000 bytes. + Märgis muutub punaseks kui transaktsiooni suurus ületab 1000 baiti. + + + This means a fee of at least %1 per kB is required. + See tähendab, et vajalik tehingutasu on vähemalt %1 kB kohta + + + This label turns red if the priority is smaller than "medium". + See märgis muutud punaseks kui prioriteet on madalam kui "keskmine". + + + (no label) + (märgis puudub) + + + (change) + (vahetusraha) + + EditAddressDialog @@ -353,7 +693,39 @@ &Address &Aadress - + + New receiving address + Uus vastu võttev aadress + + + New sending address + Uus saatev aadress + + + Edit receiving address + Muuda vastuvõtvat aadressi + + + Edit sending address + Muuda saatvat aadressi + + + The entered address "%1" is not a valid Bitcoin address. + Sisestatud aadress "%1" ei ole korrektne Bitcoin aadress. + + + The entered address "%1" is already in the address book. + Sisestatud aadress "%1" on juba aadressi raamatus. + + + Could not unlock wallet. + Rahakoti lahtilukustamine ebaõnnestus. + + + New key generation failed. + Uue võtme genereerimine ebaõnnestus. + + FreespaceChecker @@ -379,6 +751,14 @@ command-line options käsurea valikud + + UI Options: + Kasutajaliidese Suvandid: + + + Show splash screen on startup (default: %u) + Käivitamisel kuva laadimisekraani (vaikimisi %u) + Intro @@ -401,7 +781,15 @@ URI: URI: - + + Select payment request file + Vali maksepäringu fail + + + Select payment request file to open + Vali maksepäringu fail mida avada + + OptionsDialog @@ -500,6 +888,10 @@ default vaikeväärtus + + none + puudub + Confirm options reset Kinnita valikute algseadistamine @@ -519,6 +911,10 @@ 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. Kuvatav info ei pruugi olla ajakohane. Ühenduse loomisel süngitakse sinu rahakott automaatselt Bitconi võrgustikuga, kuid see toiming on hetkel lõpetamata. + + Pending: + Ootel: + Immature: Ebaküps: @@ -527,6 +923,10 @@ Mined balance that has not yet matured Mitte aegunud mine'itud jääk + + Total: + Kokku: + Recent transactions Hiljutised tehingud @@ -534,6 +934,22 @@ PaymentServer + + Payment request error + Maksepäringu tõrge + + + Payment request rejected + Maksepäring tagasi lükatud + + + Payment request expired. + Maksepäring aegunud. + + + Unverified payment requests to custom payment scripts are unsupported. + Kinnitamata maksepäringud kohandatud makse scriptidele ei ole toetatud. + PeerTableModel @@ -551,6 +967,10 @@ QRImageWidget + + Save QR Code + Salvesta QR Kood + RPCConsole @@ -574,6 +994,10 @@ General Üldine + + Using BerkeleyDB version + Kasutab BerkeleyDB versiooni + Startup time Käivitamise hetk @@ -598,6 +1022,10 @@ Current number of blocks Plokkide hetkearv + + Memory usage + Mälu kasutus + Received Vastuvõetud @@ -614,6 +1042,14 @@ Version Versioon + + Synced Headers + Sünkroniseeritud Päised + + + Synced Blocks + Sünkroniseeritud Plokid + Services Teenused @@ -632,7 +1068,7 @@ Debug log file - Debugimise logifail + Silumise logifail Clear console @@ -662,7 +1098,27 @@ %1 GB %1 GB - + + Inbound + Sisenev + + + Outbound + Väljuv + + + Yes + Jah + + + No + Ei + + + Unknown + Teadmata + + ReceiveCoinsDialog @@ -677,6 +1133,10 @@ &Message: &Sõnum: + + Clear all fields of the form. + Puhasta kõik vormi väljad. + Show Näita @@ -685,16 +1145,76 @@ Remove Eemalda - + + Copy label + Kopeeri märgis + + + Copy message + Kopeeri sõnum + + + Copy amount + Kopeeri summa + + ReceiveRequestDialog + + QR Code + QR Kood + Copy &Address &Kopeeri Aadress + + Payment information + Makse Informatsioon + + + Address + Aadress + + + Amount + Summa + + + Label + Silt + + + Message + Sõnum + + + Resulting URI too long, try to reduce the text for label / message. + URI liiga pikk, proovi vähendada märke / sõnumi pikkust. + RecentRequestsTableModel + + Date + Kuupäev + + + Label + Silt + + + Message + Sõnum + + + (no label) + (märge puudub) + + + (no message) + (sõnum puudub) + SendCoinsDialog @@ -702,6 +1222,14 @@ Send Coins Müntide saatmine + + Inputs... + Sisendid... + + + automatically selected + automaatselt valitud + Insufficient funds! Liiga suur summa @@ -710,14 +1238,30 @@ Quantity: Kogus: + + Bytes: + Baiti: + Amount: Summa: + + Priority: + Prioriteet + Fee: Tasu: + + After Fee: + Peale tehingutasu: + + + Change: + Vahetusraha: + Transaction Fee: Tehingu tasu: @@ -726,6 +1270,10 @@ Choose... Vali... + + per kilobyte + kilobaidi kohta + Hide Peida @@ -734,6 +1282,10 @@ Recommended: Soovitatud: + + Confirmation time: + Kinnitamise aeg: + normal normaalne @@ -750,6 +1302,14 @@ Add &Recipient Lisa &Saaja + + Clear all fields of the form. + Puhasta kõik vormi väljad. + + + Dust: + Puru: + Clear &All Puhasta &Kõik @@ -766,7 +1326,63 @@ S&end S&aada - + + Copy quantity + Kopeeri kogus + + + Copy amount + Kopeeri summa + + + Copy fee + Kopeeri tehingutasu + + + Copy bytes + Kopeeri baidid + + + Copy priority + Kopeeri prioriteet + + + Copy dust + Kopeeri puru + + + Copy change + Kopeeri vahetusraha + + + Are you sure you want to send? + Oled kindel, et soovid saata? + + + added as transaction fee + lisatud kui tehingutasu + + + or + või + + + The recipient address is not valid. Please recheck. + Saaja aadress ei ole korrektne. Palun kontrolli üle. + + + Payment request expired. + Maksepäring aegunud. + + + Warning: Invalid Bitcoin address + Hoiatus: Ebakorrektne Bitcoin aadress + + + (no label) + (märgis puudub) + + SendCoinsEntry @@ -781,6 +1397,10 @@ &Label: &Märgis + + Choose previously used address + Vali eelnevalt kasutatud aadress + Alt+A Alt+A @@ -793,6 +1413,10 @@ Alt+P Alt+P + + S&ubtract fee from amount + L&ahuta tehingutasu summast + Message: Sõnum: @@ -804,10 +1428,22 @@ SendConfirmationDialog - + + Yes + Jah + + ShutdownWindow - + + %1 is shutting down... + %1 lülitub välja... + + + Do not shut down the computer until this window disappears. + Ära lülita arvutit välja ennem kui see aken on kadunud. + + SignVerifyMessageDialog @@ -818,6 +1454,14 @@ &Sign Message &Allkirjastamise teade + + The Bitcoin address to sign the message with + Bitcoin aadress millega sõnum allkirjastada + + + Choose previously used address + Vali eelnevalt kasutatud aadress + Alt+A Alt+A @@ -862,6 +1506,10 @@ &Verify Message &Kinnita Sõnum + + The Bitcoin address the message was signed with + Bitcoin aadress millega sõnum on allkirjastatud + Verify the message to ensure it was signed with the specified Bitcoin address Kinnita sõnum tõestamaks selle allkirjastatust määratud Bitcoini aadressiga. @@ -874,7 +1522,55 @@ Reset all verify message fields Tühjenda kõik sõnumi kinnitamise väljad - + + Click "Sign Message" to generate signature + Allkirja loomiseks vajuta "Allkirjasta Sõnum" + + + The entered address is invalid. + Sisestatud aadress ei ole korrektne + + + Please check the address and try again. + Palun kontrolli aadressi ja proovi uuesti. + + + Wallet unlock was cancelled. + Rahakoti lahtilukustamine on katkestatud. + + + Private key for the entered address is not available. + Sisestatud aadressi privaatvõti pole saadaval. + + + Message signing failed. + Sõnumi allkirjastamine ebaõnnestus. + + + Message signed. + Sõnum allkirjastatud + + + The signature could not be decoded. + Allkirja polnud võimalik dekodeerida. + + + Please check the signature and try again. + Palun kontrolli allkirja ja proovi uuesti. + + + The signature did not match the message digest. + Allkiri ei vastanud sõnumi krüptoräsile. + + + Message verification failed. + Sõnumi verifitseerimine ebaõnnestus. + + + Message verified. + Sõnum verifitseeritud. + + SplashScreen @@ -891,7 +1587,67 @@ TransactionDesc - + + %1/unconfirmed + %1/kinnitamata + + + %1 confirmations + %1 kinnitust + + + Status + Olek + + + Date + Kuupäev + + + Generated + Genereeritud + + + label + märgis + + + not accepted + pole vastu võetud + + + Transaction fee + Tehingutasu + + + Message + Sõnum + + + Comment + Kommentaar + + + Merchant + Kaupleja + + + Inputs + Sisendid + + + Amount + Summa + + + true + tõene + + + false + väär + + TransactionDescDialog @@ -901,9 +1657,105 @@ TransactionTableModel + + Date + Kuupäev + + + Type + Tüüp + + + Label + Silt + + + Unconfirmed + Kinnitamata + + + (no label) + (silt puudub) + TransactionView + + All + Kõik + + + Today + Täna + + + This week + Käesolev nädal + + + This month + Käesolev kuu + + + Last month + Eelmine kuu + + + This year + Käesolev aasta + + + Range... + Vahemik... + + + Min amount + Minimaalne summa + + + Copy address + Kopeeri aadress + + + Copy label + Kopeeri märgis + + + Copy amount + Kopeeri summa + + + Copy transaction ID + Kopeeri tehingu ID + + + Comma separated file (*.csv) + Komadega eraldatud väärtuste fail (*.csv) + + + Date + Kuupäev + + + Type + Tüüp + + + Label + Silt + + + Address + Aadress + + + ID + ID + + + Exporting Failed + Eksport ebaõnnestus. + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index a02c2dd9a..5a31ff591 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -41,10 +41,50 @@ &Delete &حذف + + Choose the address to send coins to + آدرس مورد نظر برای ارسال کوین ها را انتخاب کنید + + + Choose the address to receive coins with + آدرس موردنظر برای دریافت کوین ها را انتخاب کنید. + + + C&hoose + انتخاب + + + Sending addresses + آدرس های فرستنده + + + Receiving addresses + آدرس های گیرنده + + + Copy &Label + کپی و برچسب‌&گذاری + + + &Edit + &ویرایش + AddressTableModel - + + Label + برچسب + + + Address + آدرس + + + (no label) + (بدون برچسب) + + AskPassphraseDialog @@ -63,7 +103,55 @@ Repeat new passphrase تکرار گذرواژهٔ جدید - + + Encrypt wallet + رمزنگاری کیف پول + + + Unlock wallet + باز کردن قفل کیف پول + + + Decrypt wallet + رمزگشایی کیف پول + + + Confirm wallet encryption + تأیید رمزنگاری کیف پول + + + Are you sure you wish to encrypt your wallet? + آیا مطمئن هستید که می‌خواهید کیف پول خود را رمزنگاری کنید؟ + + + Wallet encrypted + کیف پول رمزنگاری شد + + + Wallet encryption failed + رمزنگاری کیف پول با شکست مواجه شد + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + رمزنگاری کیف پول بنا به یک خطای داخلی با شکست مواجه شد. کیف پول شما رمزنگاری نشد. + + + Wallet unlock failed + بازگشایی قفل کیف‌پول با شکست مواجه شد + + + Wallet decryption failed + رمزگشایی کیف پول با شکست مواجه شد + + + Wallet passphrase was successfully changed. + گذرواژهٔ کیف پول با موفقیت عوض شد. + + + Warning: The Caps Lock key is on! + هشدار: کلید Caps Lock روشن است! + + BanTableModel @@ -133,6 +221,10 @@ &Options... &تنظیمات... + + Modify configuration options for %1 + تغییر تنظیمات %1 + &Encrypt Wallet... &رمزنگاری کیف پول... @@ -237,6 +329,10 @@ Tabs toolbar نوارابزار برگه‌ها + + Request payments (generates QR codes and bitcoin: URIs) + درخواست پرداخت ( تولید کد کیوار و ادرس بیت کوین) + Show the list of used sending addresses and labels نمایش لیست آدرس های ارسال و لیبل ها @@ -257,10 +353,18 @@ %n active connection(s) to Bitcoin network %n ارتباط فعال با شبکهٔ بیت‌کوین + + Processing blocks on disk... + پردازش بلوک‌ها روی دیسک... + No block source available... منبعی برای دریافت بلاک در دسترس نیست... + + Processed %n block(s) of transaction history. + پردازش %n بلاک از تاریخچه ی تراکنش ها + %n hour(s) %n ساعت @@ -434,7 +538,99 @@ Priority اولویت - + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + + + Copy transaction ID + کپی شناسهٔ تراکنش + + + Lock unspent + قفل کردن خرج نشده ها + + + Unlock unspent + بازکردن قفل خرج نشده ها + + + Copy quantity + کپی تعداد + + + highest + بیشترین + + + higher + بیشتر + + + high + زیاد + + + medium-high + متوسط رو به بالا + + + medium + متوسط + + + low-medium + متوسط متمایل به کم + + + low + کم + + + lower + کمتر + + + lowest + کمترین + + + (%1 locked) + (%1 قفل شده) + + + none + هیچکدام + + + yes + بله + + + no + خیر + + + This label turns red if the transaction size is greater than 1000 bytes. + اگر حجم تراکنش از 1000 بایت بیشتر شود برچسب قرمز می شود. + + + Can vary +/- 1 byte per input. + ممکن است +/- 1 بایت در ورودی تفاوت داشته باشد. + + + (no label) + (بدون برچسب) + + + (change) + (تغییر) + + EditAddressDialog @@ -449,6 +645,34 @@ &Address &نشانی + + New receiving address + نشانی گیرنده جدید + + + New sending address + نشانی فرستنده جدید + + + Edit receiving address + ویرایش آدرس گیرنده + + + Edit sending address + ویرایش آدرس قرستنده + + + The entered address "%1" is not a valid Bitcoin address. + نشانی وارد شده "%1" یک نشانی معتبر بیت‌کوین نیست. + + + The entered address "%1" is already in the address book. + نشانی وارد شده «%1» در حال حاضر در دفترچه وجود دارد. + + + Could not unlock wallet. + نمی‌توان کیف پول را رمزگشایی کرد. + FreespaceChecker @@ -499,6 +723,18 @@ UI Options: گزینه‌های رابط کاربری: + + Set language, for example "de_DE" (default: system locale) + زبان را تنظیم کنید؛ برای مثال «de_DE» (پیشفرض: زبان سیستم) + + + Start minimized + شروع برنامه به صورت کوچک‌شده + + + Set SSL root certificates for payment request (default: -system-) + تنظیم گواهی ریشه SSl برای درخواست پرداخت (پیشفرض: -system-) + Show splash screen on startup (default: %u) نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیش‌فرض: %u) @@ -537,6 +773,14 @@ Open URI بازکردن آدرس + + Open payment request from URI or file + بازکردن درخواست پرداخت از آدرس یا فایل + + + URI: + آدرس اینترنتی: + Select payment request file انتخاب فایل درخواست پرداخت @@ -552,6 +796,10 @@ &Main &عمومی + + Automatically start %1 after logging in to the system. + اجرای خودکار %1 بعد زمان ورود به سیستم. + MB مگابایت @@ -981,7 +1229,15 @@ Remove حذف کردن - + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + + ReceiveRequestDialog @@ -996,9 +1252,25 @@ &Save Image... &ذخیره عکس... + + Address + آدرس + + + Label + برچسب + RecentRequestsTableModel + + Label + برچسب + + + (no label) + (بدون برچسب) + SendCoinsDialog @@ -1114,7 +1386,19 @@ S&end &ارسال - + + Copy quantity + کپی تعداد + + + Copy amount + کپی مقدار + + + (no label) + (بدون برچسب) + + SendCoinsEntry @@ -1285,9 +1569,37 @@ TransactionTableModel + + Label + برچسب + + + (no label) + (بدون برچسب) + TransactionView + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + + + Copy transaction ID + کپی شناسهٔ تراکنش + + + Label + برچسب + + + Address + آدرس + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 4d33a58bf..30a9fa3c0 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -91,7 +91,7 @@ Exporting Failed - L'exportation a échoué + Échec d'exportation There was an error trying to save the address list to %1. Please try again. @@ -133,7 +133,7 @@ Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Saisissez une nouvelle phrase de passe pour le portefeuille.<br/>Veuillez utiliser une phrase composée de <b>dix caractères aléatoires ou plus</b>, ou bien de <b>huit mots ou plus</b>. + Saisissez la nouvelle phrase de passe du porte-monnaie.<br/>Veuillez utiliser une phrase de passe composée de <b>dix caractères aléatoires ou plus</b>, ou de <b>huit mots ou plus</b>. Encrypt wallet @@ -159,7 +159,67 @@ Change passphrase Changer la phrase de passe - + + Enter the old passphrase and new passphrase to the wallet. + Saisir l'ancienne puis la nouvelle phrase de passe du porte-monnaie. + + + Confirm wallet encryption + Confirmer le chiffrement du porte-monnaie + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avertissement : si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! + + + Are you sure you wish to encrypt your wallet? + Voulez-vous vraiment chiffrer votre porte-monnaie ? + + + Wallet encrypted + Le porte-monnaie est chiffré + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 va maintenant se fermer pour terminer le processus de chiffrement. Souvenez-vous que le chiffrement de votre porte-monnaie ne peut pas protéger entièrement vos bitcoins contre le vol par des logiciels malveillants qui infecteraient votre ordinateur. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT : toutes les sauvegardes précédentes du fichier de votre porte-monnaie devraient être remplacées par le fichier du porte-monnaie chiffré nouvellement généré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de porte-monnaie non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau porte-monnaie chiffré. + + + Wallet encryption failed + Échec de chiffrement du porte-monnaie + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré. + + + The supplied passphrases do not match. + Les phrases de passe saisies ne correspondent pas. + + + Wallet unlock failed + Échec de déverrouillage du porte-monnaie + + + The passphrase entered for the wallet decryption was incorrect. + La phrase de passe saisie pour déchiffrer le porte-monnaie était erronée. + + + Wallet decryption failed + Échec de déchiffrement du porte-monnaie + + + Wallet passphrase was successfully changed. + La phrase de passe du porte-monnaie a été modifiée avec succès. + + + Warning: The Caps Lock key is on! + Avertissement : la touche Verr. Maj. est activée ! + + BanTableModel @@ -175,7 +235,7 @@ BitcoinGUI Sign &message... - &Signer le message... + Signer un &message... Synchronizing with network... @@ -199,7 +259,7 @@ Browse transaction history - Parcourir l'historique des transactions + Parcourir l'historique transactionnel E&xit @@ -303,15 +363,15 @@ &Show / Hide - &Afficher / Masquer + &Afficher / cacher Show or hide the main Window - Afficher ou masquer la fenêtre principale + Afficher ou cacher la fenêtre principale Encrypt the private keys that belong to your wallet - Chiffrer les clefs privées de votre porte-monnaie + Chiffrer les clés privées qui appartiennent à votre porte-monnaie Sign messages with your Bitcoin addresses to prove you own them @@ -351,7 +411,7 @@ Open a bitcoin: URI or payment request - Ouvrir un URI bitcoin: ou une demande de paiement + Ouvrir une URI bitcoin: ou une demande de paiement &Command-line options @@ -399,7 +459,7 @@ %1 behind - en retard d'%1 + en retard de %1 Last received block was generated %1 ago. @@ -562,11 +622,151 @@ Priority Priorité + + Copy address + Copier l’adresse + + + Copy label + Copier l’étiquette + + + Copy amount + Copier le montant + + + Copy transaction ID + Copier l'ID de la transaction + + + Lock unspent + Verrouiller les transactions non dépensées + + + Unlock unspent + Déverrouiller les transactions non dépensées + + + Copy quantity + Copier la quantité + + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy dust + Copier la poussière + + + Copy change + Copier la monnaie + + + highest + la plus élevée + + + higher + plus élevée + + + high + élevée + + + medium-high + moyenne-élevée + + + medium + moyenne + + + low-medium + faible-moyenne + + + low + faible + + + lower + plus faible + + + lowest + la plus faible + + + (%1 locked) + (%1 verrouillée) + + + none + aucune + + + yes + oui + + + no + non + + + This label turns red if the transaction size is greater than 1000 bytes. + Cette étiquette devient rouge si la taille de la transaction dépasse 1 000 octets. + + + This means a fee of at least %1 per kB is required. + Cela signifie que des frais d'au moins %1 sont exigés par Ko. + + + Can vary +/- 1 byte per input. + Peut varier +/- 1 octet par entrée. + + + Transactions with higher priority are more likely to get included into a block. + Les transactions à priorité élevée on plus de chance d'être incluses dans un bloc. + + + This label turns red if the priority is smaller than "medium". + Cette étiquette devient rouge si la priorité est plus basse que « moyenne ». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Cette étiquette devient rouge si un destinataire reçoit un montant inférieur au seuil actuel de poussière. + + + Can vary +/- %1 satoshi(s) per input. + Peut varier +/- %1 satoshi(s) par entrée. + (no label) (aucune étiquette) - + + change from %1 (%2) + monnaie de %1 (%2) + + + (change) + (monnaie) + + EditAddressDialog @@ -589,7 +789,39 @@ &Address &Adresse - + + New receiving address + Nouvelle adresse de réception + + + New sending address + Nouvelle adresse d’envoi + + + Edit receiving address + Modifier l’adresse de réception + + + Edit sending address + Modifier l’adresse d'envoi + + + The entered address "%1" is not a valid Bitcoin address. + L'adresse saisie « %1 » n'est pas une adresse Bitcoin valide. + + + The entered address "%1" is already in the address book. + L’adresse saisie « %1 » est déjà présente dans le carnet d'adresses. + + + Could not unlock wallet. + Impossible de déverrouiller le porte-monnaie. + + + New key generation failed. + Échec de génération de la nouvelle clé. + + FreespaceChecker @@ -729,7 +961,11 @@ Select payment request file Choisir le fichier de demande de paiement - + + Select payment request file to open + Choisir le fichier de demande de paiement à ouvrir + + OptionsDialog @@ -1042,7 +1278,95 @@ PaymentServer - + + Payment request error + Erreur de demande de paiement + + + Cannot start bitcoin: click-to-pay handler + Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin: + + + URI handling + Gestion des URI + + + Payment request fetch URL is invalid: %1 + L'URL de récupération de la demande de paiement est invalide : %1 + + + Invalid payment address %1 + Adresse de paiement invalide %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + L'URI ne peut pas être analysée ! Cela peut être causé par une adresse Bitcoin invalide ou par des paramètres d'URI mal formés. + + + Payment request file handling + Gestion des fichiers de demande de paiement + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Le fichier de demande de paiement ne peut pas être lu ! Cela peut être causé par un fichier de demande de paiement invalide. + + + Payment request rejected + Demande de paiement rejetée + + + Payment request network doesn't match client network. + Le réseau de la demande de paiement ne correspond pas au réseau du client. + + + Payment request expired. + La demande de paiement a expiré + + + Payment request is not initialized. + La demande de paiement n'est pas initialisée. + + + Unverified payment requests to custom payment scripts are unsupported. + Les demandes de paiements non vérifiées vers des scripts de paiement personnalisés ne sont pas prises en charge. + + + Invalid payment request. + Demande de paiement invalide. + + + Requested payment amount of %1 is too small (considered dust). + Le paiement demandé d'un montant de %1 est trop faible (considéré comme de la poussière). + + + Refund from %1 + Remboursement de %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + La demande de paiement %1 est trop grande (%2 octets, %3 octets permis). + + + Error communicating with %1: %2 + Erreur de communication avec %1 : %2 + + + Payment request cannot be parsed! + La demande de paiement ne peut pas être analysée ! + + + Bad response from server %1 + Mauvaise réponse du serveur %1 + + + Network request error + Erreur de demande réseau + + + Payment acknowledged + Le paiement a été confirmé + + PeerTableModel @@ -1099,7 +1423,23 @@ QRImageWidget - + + &Save Image... + &Enregistrer l'image... + + + &Copy Image + &Copier l'image + + + Save QR Code + Enregistrer le code QR + + + PNG Image (*.png) + Image PNG (*.png) + + RPCConsole @@ -1216,7 +1556,7 @@ Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. - Ouvrir le journal de débogage de %1 depuis le répertoire de données actuel. Ceci peut prendre quelques secondes pour les journaux de grande taille. + Ouvrir le fichier journal de débogage de %1 à partir du répertoire de données actuel. Cela peut prendre quelques secondes pour les fichiers journaux de grande taille. Decrease font size @@ -1461,7 +1801,19 @@ Remove Retirer - + + Copy label + Copier l’étiquette + + + Copy message + Copier le message + + + Copy amount + Copier le montant + + ReceiveRequestDialog @@ -1480,26 +1832,74 @@ &Save Image... &Enregistrer l'image... + + Request payment to %1 + Demande de paiement à %1 + + + Payment information + Informations de paiement + + + URI + URI + Address Adresse - Label - Étiquette + Amount + Montant - - - RecentRequestsTableModel Label Étiquette + + Message + Message + + + Resulting URI too long, try to reduce the text for label / message. + L'URI résultante est trop longue. Essayez de réduire le texte de l'étiquette ou du message. + + + Error encoding URI into QR Code. + Erreur d'encodage de l'URI en code QR. + + + + RecentRequestsTableModel + + Date + Date + + + Label + Étiquette + + + Message + Message + (no label) (aucune étiquette) - + + (no message) + (aucun message) + + + (no amount requested) + (aucun montant demandé) + + + Requested + Demandée + + SendCoinsDialog @@ -1650,6 +2050,110 @@ S&end E&nvoyer + + Copy quantity + Copier la quantité + + + Copy amount + Copier le montant + + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy dust + Copier la poussière + + + Copy change + Copier la monnaie + + + %1 to %2 + %1 à %2 + + + Are you sure you want to send? + Voulez-vous vraiment envoyer ? + + + added as transaction fee + ajoutés comme frais de transaction + + + Total Amount %1 + Montant total %1 + + + or + ou + + + Confirm send coins + Confirmer l’envoi de pièces + + + The recipient address is not valid. Please recheck. + L'adresse du destinataire est invalide. Veuillez la revérifier. + + + The amount to pay must be larger than 0. + Le montant à payer doit être supérieur à 0. + + + The amount exceeds your balance. + Le montant dépasse votre solde. + + + The total exceeds your balance when the %1 transaction fee is included. + Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus. + + + Duplicate address found: addresses should only be used once each. + Adresse identique trouvée : chaque adresse ne devrait être utilisée qu'une fois. + + + Transaction creation failed! + Échec de création de la transaction ! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + La transaction a été rejetée ! Cela peut arriver si certaines pièces de votre porte-monnaie étaient déjà dépensées, par exemple si vous avez utilisé une copie de wallet.dat et que des pièces ont été dépensées dans la copie sans être marquées comme telles ici. + + + A fee higher than %1 is considered an absurdly high fee. + Des frais supérieurs à %1 sont considérés comme ridiculement élevés. + + + Payment request expired. + La demande de paiement a expiré + + + Pay only the required fee of %1 + Payer seulement les frais exigés de %1 + + + Warning: Invalid Bitcoin address + Avertissement : adresse Bitcoin invalide + + + Warning: Unknown change address + Avertissement : adresse de monnaie rendue inconnue + (no label) (aucune étiquette) @@ -1733,10 +2237,18 @@ Memo: Mémo : - + + Enter a label for this address to add it to your address book + Saisir une étiquette pour cette adresse afin de l’ajouter à votre carnet d’adresses + + SendConfirmationDialog - + + Yes + Oui + + ShutdownWindow @@ -1760,7 +2272,7 @@ 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. - Vous pouvez signer des messages/accords avec vos adresses pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Faites attention de ne rien signer de vague ou au hasard, car des attaques d'hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l'usurper. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous êtes d'accord. + Vous pouvez signer des messages ou des accords avec vos adresses pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Faites attention de ne rien signer de vague ou au hasard, car des attaques d'hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l'usurper. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous êtes d'accord. The Bitcoin address to sign the message with @@ -1834,7 +2346,59 @@ Reset all verify message fields Réinitialiser tous les champs de vérification de message - + + Click "Sign Message" to generate signature + Cliquez sur « Signer le message » pour générer la signature + + + The entered address is invalid. + L'adresse saisie est invalide. + + + Please check the address and try again. + Veuillez vérifier l'adresse et ressayer. + + + The entered address does not refer to a key. + L'adresse saisie ne fait pas référence à une clé. + + + Wallet unlock was cancelled. + Le déverrouillage du porte-monnaie a été annulé. + + + Private key for the entered address is not available. + La clé privée n'est pas disponible pour l'adresse saisie. + + + Message signing failed. + Échec de signature du message. + + + Message signed. + Le message a été signé. + + + The signature could not be decoded. + La signature n'a pu être décodée. + + + Please check the signature and try again. + Veuillez vérifier la signature et ressayer. + + + The signature did not match the message digest. + La signature ne correspond pas au condensé du message. + + + Message verification failed. + Échec de vérification du message. + + + Message verified. + Le message a été vérifié. + + SplashScreen @@ -1851,31 +2415,419 @@ TransactionDesc - + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + + + Open until %1 + Ouvert jusqu'à %1 + + + conflicted with a transaction with %1 confirmations + est en conflit avec une transaction ayant %1 confirmations + + + %1/offline + %1/hors ligne + + + 0/unconfirmed, %1 + 0/non confirmées, %1 + + + in memory pool + dans la réserve de mémoire + + + not in memory pool + pas dans la réserve de mémoire + + + abandoned + abandonnée + + + %1/unconfirmed + %1/non confirmée + + + %1 confirmations + %1 confirmations + + + Status + État + + + , has not been successfully broadcast yet + , n’a pas encore été diffusée avec succès + + + , broadcast through %n node(s) + , diffusée à travers %n nœud, diffusée à travers %n nœuds + + + Date + Date + + + Source + Source + + + Generated + Générée + + + From + De + + + unknown + inconnue + + + To + À + + + own address + votre adresse + + + watch-only + juste-regarder + + + label + étiquette + + + Credit + Crédit + + + matures in %n more block(s) + arrive à maturité dans %n bloc de plusarrive à maturité dans %n blocs de plus + + + not accepted + refusée + + + Debit + Débit + + + Total debit + Débit total + + + Total credit + Crédit total + + + Transaction fee + Frais de transaction + + + Net amount + Montant net + + + Message + Message + + + Comment + Commentaire + + + Transaction ID + ID de la transaction + + + Output index + Index de sorties + + + Merchant + Marchand + + + 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. + Les pièces générées doivent mûrir pendant %1 blocs avant de pouvoir être dépensées. Lorsque ce bloc a été généré, il a été diffusé sur le réseau pour être ajouté à la chaîne de blocs. Si son intégration à la chaîne échoue, son état sera modifié en « refusée » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du vôtre. + + + Debug information + Informations de débogage + + + Transaction + Transaction + + + Inputs + Entrées + + + Amount + Montant + + + true + vrai + + + false + faux + + TransactionDescDialog This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - + + Details for %1 + Détails de %1 + + TransactionTableModel + + Date + Date + + + Type + Type + Label Étiquette + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + + + Open until %1 + Ouvert jusqu'à %1 + + + Offline + Hors ligne + + + Unconfirmed + Non confirmée + + + Abandoned + Abandonnée + + + Confirming (%1 of %2 recommended confirmations) + Confirmation (%1 sur %2 confirmations recommandées) + + + Confirmed (%1 confirmations) + Confirmée (%1 confirmations) + + + Conflicted + En conflit + + + Immature (%1 confirmations, will be available after %2) + Immature (%1 confirmations, sera disponible après %2) + + + This block was not received by any other nodes and will probably not be accepted! + Ce bloc n’a été reçu par aucun autre nœud et ne sera probablement pas accepté ! + + + Generated but not accepted + Générée mais refusée + + + Received with + Reçue avec + + + Received from + Reçue de + + + Sent to + Envoyée à + + + Payment to yourself + Paiement à vous-même + + + Mined + Miné + + + watch-only + juste-regarder + + + (n/a) + (n.d) + (no label) (aucune étiquette) - + + Transaction status. Hover over this field to show number of confirmations. + État de la transaction. Survoler ce champ avec la souris pour afficher le nombre de confirmations. + + + Date and time that the transaction was received. + Date et heure de réception de la transaction. + + + Type of transaction. + Type de transaction. + + + Whether or not a watch-only address is involved in this transaction. + Une adresse juste-regarder est-elle ou non impliquée dans cette transaction. + + + User-defined intent/purpose of the transaction. + Intention/but de la transaction défini par l'utilisateur. + + + Amount removed from or added to balance. + Le montant a été ajouté ou soustrait du solde. + + TransactionView + + All + Toutes + + + Today + Aujourd’hui + + + This week + Cette semaine + + + This month + Ce mois + + + Last month + Le mois dernier + + + This year + Cette année + + + Range... + Plage… + + + Received with + Reçue avec + + + Sent to + Envoyée à + + + To yourself + À vous-même + + + Mined + Miné + + + Other + Autres + + + Enter address or label to search + Saisir une adresse ou une étiquette à rechercher + + + Min amount + Montant min. + + + Abandon transaction + Abandonner la transaction + + + Copy address + Copier l’adresse + + + Copy label + Copier l’étiquette + + + Copy amount + Copier le montant + + + Copy transaction ID + Copier l'ID de la transaction + + + Copy raw transaction + Copier la transaction brute + + + Copy full transaction details + Copier tous les détails de la transaction + + + Edit label + Modifier l’étiquette + + + Show transaction details + Afficher les détails de la transaction + + + Export Transaction History + Exporter l'historique transactionnel + Comma separated file (*.csv) Valeurs séparées par des virgules (*.csv) + + Confirmed + Confirmée + + + Watch-only + Juste-regarder + + + Date + Date + + + Type + Type + Label Étiquette @@ -1885,10 +2837,34 @@ Adresse - Exporting Failed - L'exportation a échoué + ID + ID - + + Exporting Failed + Échec d'exportation + + + There was an error trying to save the transaction history to %1. + Une erreur est survenue lors de l'enregistrement de l'historique transactionnel vers %1. + + + Exporting Successful + L'exportation est réussie + + + The transaction history was successfully saved to %1. + L'historique transactionnel a été enregistré avec succès vers %1. + + + Range: + Plage : + + + to + à + + UnitDisplayStatusBarControl @@ -1898,13 +2874,53 @@ WalletFrame - + + No wallet has been loaded. + Aucun porte-monnaie n'a été chargé. + + WalletModel - + + Send Coins + Envoyer des pièces + + WalletView - + + &Export + &Exporter + + + Export the data in the current tab to a file + Exporter les données de l'onglet actuel vers un fichier + + + Backup Wallet + Sauvegarder le porte-monnaie + + + Wallet Data (*.dat) + Données du porte-monnaie (*.dat) + + + Backup Failed + Échec de la sauvegarde + + + There was an error trying to save the wallet data to %1. + Une erreur est survenue lors de l'enregistrement des données du porte-monnaie vers %1. + + + Backup Successful + La sauvegarde est réussie + + + The wallet data was successfully saved to %1. + Les données du porte-monnaie ont été enregistrées avec succès vers %1 + + bitcoin-core @@ -2077,7 +3093,7 @@ Attempt to recover private keys from a corrupt wallet on startup - Tenter de récupérer les clefs privées d'un porte-monnaie corrompu lors du démarrage + Tenter de récupérer les clés privées d'un porte-monnaie corrompu lors du démarrage Block creation options: @@ -2259,6 +3275,10 @@ Specify wallet file (within data directory) Spécifiez le fichier de porte-monnaie (dans le répertoire de données) + + Starting network threads... + Démarrage des processus réseau... + The source code is available from %s. Le code source est disponible sur %s. @@ -2285,7 +3305,7 @@ Verifying blocks... - Vérification des blocs... + Vérification des blocs... Verifying wallet... @@ -2357,7 +3377,7 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) - Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d) + Définir la taille maximale en octets des transactions à priorité élevée et frais modiques (par défaut : %d) The transaction amount is too small to send after the fee has been deducted @@ -2369,7 +3389,7 @@ Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start - Utiliser une génération de clef hiérarchique déterministe (HD) après BIP32. N'a d'effet que lors de la création/premier lancement du porte-monnaie + Utiliser une génération de clé hiérarchique déterministe (HD) après BIP32. N'a d'effet que lors de la création ou du lancement intitial du porte-monnaie Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway @@ -2401,7 +3421,7 @@ Imports blocks from external blk000??.dat file on startup - Importe des blocs depuis un fichier blk000??.dat externe lors du démarrage + Importe des blocs à partir d'un fichier blk000??.dat externe lors du démarrage Information @@ -2545,11 +3565,11 @@ -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés en une seule transaction. + La valeur -maxtxfee est très élevée ! Des frais aussi élevés pourraient être payés en une seule transaction. -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. + La valeur -paytxfee est très élevée ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. Do not keep transactions in the mempool longer than <n> hours (default: %u) @@ -2669,7 +3689,7 @@ Set key pool size to <n> (default: %u) - Définir la taille de la réserve de clefs à <n> (par défaut : %u) + Définir la taille de la réserve de clés à <n> (par défaut : %u) Set the number of threads to service RPC calls (default: %d) diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts index 10216a71f..c36ae2e48 100644 --- a/src/qt/locale/bitcoin_it_IT.ts +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -59,9 +59,17 @@ Repeat new passphrase Ripeti nuova passphrase - + + Warning: The Caps Lock key is on! + Attenzione: Il tasto blocco delle maiuscole è attivo! + + BanTableModel + + IP/Netmask + IP/Netmask + Banned Until bannato fino diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 3fc93b7e2..399322d45 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -41,9 +41,21 @@ &Delete 삭제(&D) + + C&hoose + 선택 (&H) + + + &Edit + 편집 (&E) + AddressTableModel + + Address + 주소 + AskPassphraseDialog @@ -466,6 +478,10 @@ Priority 우선순위 + + Copy address + 주소 복사 + EditAddressDialog @@ -1380,6 +1396,10 @@ &Save Image... 이미지 저장(&S)... + + Address + 주소 + RecentRequestsTableModel @@ -1744,6 +1764,14 @@ TransactionView + + Copy address + 주소 복사 + + + Address + 주소 + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_ku_IQ.ts b/src/qt/locale/bitcoin_ku_IQ.ts index 9e52770aa..80fa68289 100644 --- a/src/qt/locale/bitcoin_ku_IQ.ts +++ b/src/qt/locale/bitcoin_ku_IQ.ts @@ -28,6 +28,10 @@ AddressTableModel + + Address + ناوونیشان + AskPassphraseDialog @@ -92,6 +96,22 @@ Priority لەپێشی + + high + بەرز + + + low + نزم + + + yes + بەڵێ + + + no + نەخێر + EditAddressDialog @@ -160,14 +180,30 @@ &Information &زانیاری + + General + گشتی + + + Network + تۆڕ + Name ناو + + Sent + نێدرا + Version وەشان + + Services + خزمەتگوزاریەکان + &Open &کردنەوە @@ -180,6 +216,34 @@ Totals گشتییەکان + + In: + لە ناو + + + Out: + لەدەرەوە + + + 1 &hour + 1&سات + + + 1 &day + 1&ڕۆژ + + + 1 &week + 1&هەفتە + + + 1 &year + 1&ساڵ + + + never + هەرگیز + Yes بەڵێ @@ -214,6 +278,10 @@ ReceiveRequestDialog + + Address + ناوونیشان + RecentRequestsTableModel @@ -270,6 +338,10 @@ TransactionView + + Address + ناوونیشان + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 57c336c85..deb6c37c7 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -41,9 +41,57 @@ &Delete &Usuń + + Sending addresses + Adresy wysyłania + + + Receiving addresses + Adresy odbioru + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Tutaj znajdują się adresy Bitcoin na które wysyłasz płatności. Zawsze sprawdzaj ilość i adres odbiorcy przed wysyłką monet. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + To są twoje adresy Bitcoin do odbierania płatności. Zaleca się używanie nowych adresów odbiorczych dla każdej transakcji. + + + &Copy Address + &Kopiuj adres + + + Copy &Label + Kopiuj &Etykietę + + + &Edit + &Edytuj + + + Export Address List + Eksportuj listę adresów + + + Comma separated file (*.csv) + Plik *.CSV (dane rozdzielane przecinkami) + + + Exporting Failed + Eksportowanie nie powiodło się + AddressTableModel + + Label + Etykieta + + + Address + Adres + AskPassphraseDialog @@ -63,6 +111,50 @@ Repeat new passphrase Powtórz nowe hasło + + Encrypt wallet + Zaszyfruj portfel + + + Unlock wallet + Odblokuj portfel + + + Decrypt wallet + Odszyfruj portfel + + + Change passphrase + Zmień hasło + + + Enter the old passphrase and new passphrase to the wallet. + Podaj stare i nowe hasło do portfela. + + + Confirm wallet encryption + Potwierdź szyfrowanie portfela + + + Wallet encrypted + Portfel zaszyfrowany + + + Wallet encryption failed + Szyfrowanie portfela nie powiodło się + + + Wallet unlock failed + Odblokowanie portfela nie powiodło się + + + The passphrase entered for the wallet decryption was incorrect. + Wprowadzone hasło do odszyfrowania portfela jest niepoprawne. + + + Wallet decryption failed + Odszyfrowanie portfela nie powiodło się + BanTableModel @@ -466,6 +558,86 @@ Priority Priorytet + + Copy address + Kopiuj adres + + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + + + Copy transaction ID + Skopiuj ID transakcji + + + Lock unspent + Zablokuj niewydane + + + Unlock unspent + Odblokuj niewydane + + + Copy quantity + Skopiuj ilość + + + Copy fee + Skopiuj prowizję + + + Copy after fee + Skopiuj ilość po opłacie + + + highest + najwyższy + + + higher + wyższy + + + high + wysoki + + + medium-high + średnio wysoki + + + medium + średni + + + low-medium + średnio niski + + + low + niski + + + lower + niższy + + + lowest + najniższy + + + yes + tak + + + no + nie + EditAddressDialog @@ -1361,7 +1533,15 @@ Remove Usuń - + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + + ReceiveRequestDialog @@ -1380,9 +1560,21 @@ &Save Image... &Zapisz obraz... + + Address + Adres + + + Label + Etykieta + RecentRequestsTableModel + + Label + Etykieta + SendCoinsDialog @@ -1534,6 +1726,22 @@ S&end Wy&syłka + + Copy quantity + Skopiuj ilość + + + Copy amount + Kopiuj kwotę + + + Copy fee + Skopiuj prowizję + + + Copy after fee + Skopiuj ilość po opłacie + SendCoinsEntry @@ -1742,9 +1950,45 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw TransactionTableModel + + Label + Etykieta + TransactionView + + Copy address + Kopiuj adres + + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + + + Copy transaction ID + Skopiuj ID transakcji + + + Comma separated file (*.csv) + Plik *.CSV (dane rozdzielane przecinkami) + + + Label + Etykieta + + + Address + Adres + + + Exporting Failed + Eksportowanie nie powiodło się + UnitDisplayStatusBarControl @@ -1796,6 +2040,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) Prune: ostatnia synchronizacja portfela jest za danymi. Muszisz -reindexować (pobrać cały ciąg bloków ponownie w przypadku przyciętego węzła) + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Zredukuj wymaganą ilość miejsca na dysku poprzez usuwanie starych bloków. Ten tryb jest niekompatybilny z -txindex oraz -rescan. Ostrzeżenie: Wycofanie tego ustawienia wymaga ponownego pobrania całego łańcucha bloków. (domyślnie: 0 = wyłącz usuwanie bloków, >%u = docelowy rozmiar w MiB jaki wykorzystać na pliki z blokami) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Ponowne skanowanie nie jest możliwe w trybie przycinania. Będzie trzeba użyć -reindex, co pobierze ponownie cały łańcuch bloków. + Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log @@ -1832,6 +2084,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee ma ustawioną bardzo dużą wartość! Jest to prowizja za transakcje, którą możesz zapłacić gdy oszacowanie opłaty jest niemożliwe. + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Stawka prowizji (w %s/kB), która będzie użyta, gdy oszacowane dane o prowizjach nie będą wystarczające (domyślnie: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6 diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 2dbd28dc6..aeaf99f50 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -41,10 +41,78 @@ &Delete &Excluir - + + Choose the address to send coins to + Escoha o endereço para enviar moedas + + + Choose the address to receive coins with + Escolha o enereço para receber moedas + + + C&hoose + Escol&ha + + + Sending addresses + Endereços de envio + + + Receiving addresses + Endereços de recebimento + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estes são os seus endereços para enviar pagamentos. Sempre cheque a quantia e o endereço do destinatário antes de enviar moedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estes são os seus endereços para receber pagamentos. É recomendado usar um novo para cada transação. + + + &Copy Address + &Copiar endereço + + + Copy &Label + Copiar rótu&lo + + + &Edit + &Editar + + + Export Address List + Exportar lista de endereços + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Falha na exportação + + + There was an error trying to save the address list to %1. Please try again. + Erro ao salvar a lista de endereço para %1. Tente novamente. + + AddressTableModel - + + Label + Rótuo + + + Address + Endereço + + + (no label) + (sem rótuo) + + AskPassphraseDialog @@ -63,7 +131,91 @@ Repeat new passphrase Repita a nova frase de segurança - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Insira a nova senha para a carteira.<br/>Favor usar uma senha com <b>dez ou mais caracteres aleatórios</b>, ou <b>oito ou mais palavras</b>. + + + Encrypt wallet + Criptografar carteira + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operação precisa da sua senha para desbloquear a carteira. + + + Unlock wallet + Desbloquear carteira + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operação precisa da sua senha para descriptografar a carteira + + + Decrypt wallet + Descriptografar carteira + + + Change passphrase + Alterar senha + + + Enter the old passphrase and new passphrase to the wallet. + Insira a senha antiga e a nova para a carteira. + + + Confirm wallet encryption + Confirmar criptografia da carteira + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Aviso: Se você criptografar sua carteira e perder sua senha, você vai <b>PERDER TODOS OS SEUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Tem certeza que deseja criptografar a carteira? + + + Wallet encrypted + Carteira criptografada + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Qualquer backup prévio que você tenha feito da sua carteira deve ser substituído pelo novo e encriptado arquivo gerado. Por razões de segurança, qualquer backup do arquivo não criptografado se tornará inútil assim que você começar a usar uma nova carteira criptografada. + + + Wallet encryption failed + Falha ao criptografar carteira + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falha na criptografia devido a um erro inerno. Sua carteira não foi criptografada. + + + The supplied passphrases do not match. + As senhas não conferem. + + + Wallet unlock failed + Falha ao desbloquear carteira + + + The passphrase entered for the wallet decryption was incorrect. + A senha inserida para descriptografar a carteira está incorreta. + + + Wallet decryption failed + Falha ao descriptografar a carteira + + + Wallet passphrase was successfully changed. + A senha da carteira foi alterada com êxito. + + + Warning: The Caps Lock key is on! + Aviso: Tecla Caps Lock ativa! + + BanTableModel @@ -179,7 +331,7 @@ &Debug window - Janela de &Depuração + Janela de &depuração Open debugging and diagnostic console @@ -466,7 +618,151 @@ Priority Prioridade - + + Copy address + Copiar endereço + + + Copy label + Copiar rótulo + + + Copy amount + Copiar quantia + + + Copy transaction ID + Copiar ID da transação + + + Lock unspent + Boquear saída + + + Unlock unspent + Desboquear saída + + + Copy quantity + Copiar quantia + + + Copy fee + Copiar taxa + + + Copy after fee + Copiar pós taxa + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridade + + + Copy dust + Copiar poeira + + + Copy change + Copiar troco + + + highest + mega alta + + + higher + super alta + + + high + alta + + + medium-high + média alta + + + medium + média + + + low-medium + média baixa + + + low + baixa + + + lower + super baixa + + + lowest + mega baixa + + + (%1 locked) + (%1 bloqueada) + + + none + nenhum + + + yes + sim + + + no + não + + + This label turns red if the transaction size is greater than 1000 bytes. + Este texto fica vermeho se o tamanho da transação for maior que 1 KiB. + + + This means a fee of at least %1 per kB is required. + Isso quer dizer que uma taxa de pelo menos %1 per KiB será necessária. + + + Can vary +/- 1 byte per input. + Pode variar +/- 1 byte por entrada + + + Transactions with higher priority are more likely to get included into a block. + Transações de alta prioridade são mais propensas a serem incluídas em um bloco. + + + This label turns red if the priority is smaller than "medium". + Este texto fica vermelho se a prioridade é menor que "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Este texto fica vermelho se qualquer destinatário receber uma quantidade menor que que o dust. + + + Can vary +/- %1 satoshi(s) per input. + Pode variar +/- %1 satoshi(s) por entrada + + + (no label) + (sem rótuo) + + + change from %1 (%2) + troco de %1 (%2) + + + (change) + (troco) + + EditAddressDialog @@ -489,7 +785,39 @@ &Address &Endereço - + + New receiving address + Novo endereço de recebimento + + + New sending address + Novo endereço de envio + + + Edit receiving address + Editar endereço de recebimento + + + Edit sending address + Editar endereço de envio + + + The entered address "%1" is not a valid Bitcoin address. + O endereço digitado "%1" não é um endereço válido. + + + The entered address "%1" is already in the address book. + O endereço digitado "%1" já se encontra no catálogo de endereços. + + + Could not unlock wallet. + Não foi possível desbloquear a carteira + + + New key generation failed. + Falha ao gerar chave + + FreespaceChecker @@ -629,7 +957,11 @@ Select payment request file Selecione o arquivo de cobrança - + + Select payment request file to open + Selecione o arquivo de cobrança para ser aberto + + OptionsDialog @@ -942,7 +1274,95 @@ PaymentServer - + + Payment request error + Erro no pedido de pagamento + + + Cannot start bitcoin: click-to-pay handler + Não foi possível iniciar bitcoin: manipulador click-to-pay + + + URI handling + Manipulação de URI + + + Payment request fetch URL is invalid: %1 + URL de cobrança é inválida: %1 + + + Invalid payment address %1 + Endereço de pagamento %1 inválido + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI não pode ser analisado! Isto pode ser causado por um endereço inválido ou parâmetros URI informados incorretamente. + + + Payment request file handling + Manipulação de arquivo de cobrança + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Arquivo de pedido de pagamento não pode ser lido! Isto pode ser causado por uma requisição de pagamento inválida. + + + Payment request rejected + Pedido de pagamento rejeitado + + + Payment request network doesn't match client network. + Rede do pedido de pagamento não corresponde rede do cliente. + + + Payment request expired. + Pedido de pagamento expirado + + + Payment request is not initialized. + Pedido de pagamento não inicializado + + + Unverified payment requests to custom payment scripts are unsupported. + Pedidos de pagamento não verificados para scripts de pagamento personalizados não são suportados. + + + Invalid payment request. + Pedido de pagamento inválido + + + Requested payment amount of %1 is too small (considered dust). + Valor do pagamento solicitado de %1 é muito pequeno (Considerado poeira). + + + Refund from %1 + Reembolso de %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes). + + + Error communicating with %1: %2 + Erro na comunicação com %1: %2 + + + Payment request cannot be parsed! + Pedido de pagamento não pode ser analisado! + + + Bad response from server %1 + Erro na resposta do servidor: %1 + + + Network request error + Erro de solicitação de rede + + + Payment acknowledged + Pagamento reconhecido + + PeerTableModel @@ -999,7 +1419,23 @@ QRImageWidget - + + &Save Image... + &Savar imagem + + + &Copy Image + &Copiar imagem + + + Save QR Code + Salvar código QR + + + PNG Image (*.png) + Imagem PNG (*.png) + + RPCConsole @@ -1196,7 +1632,7 @@ Debug log file - Arquivo de log de Depuração + Arquivo de log de depuração Clear console @@ -1361,7 +1797,19 @@ Remove Remover - + + Copy label + Copiar rótulo + + + Copy message + Copiar mensagem + + + Copy amount + Copiar quantia + + ReceiveRequestDialog @@ -1380,10 +1828,74 @@ &Save Image... &Salvar Imagem... - + + Request payment to %1 + Pedido de pagamento para %1 + + + Payment information + Informação do pagamento + + + URI + URI + + + Address + Endereço + + + Amount + Quantia + + + Label + Rótuo + + + Message + Mensagem + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante muito longa. Tente reduzir o texto do rótulo ou da mensagem. + + + Error encoding URI into QR Code. + Erro ao codigicar o URI em código QR + + RecentRequestsTableModel - + + Date + Data + + + Label + Rótuo + + + Message + Mensagem + + + (no label) + (sem rótuo) + + + (no message) + (sem mensagem) + + + (no amount requested) + (nenhuma quantia solicitada) + + + Requested + Solicitado + + SendCoinsDialog @@ -1534,7 +2046,119 @@ S&end Enviar - + + Copy quantity + Copiar quantia + + + Copy amount + Copiar quantia + + + Copy fee + Copiar taxa + + + Copy after fee + Copiar pós taxa + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridade + + + Copy dust + Copiar poeira + + + Copy change + Copiar troco + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + Tem certeza que deseja enviar? + + + added as transaction fee + adicionado como taxa da transação + + + Total Amount %1 + Quantia tota %1 + + + or + ou + + + Confirm send coins + Confirme o envio de moedas + + + The recipient address is not valid. Please recheck. + Endereço de envio inváido. Favor checar. + + + The amount to pay must be larger than 0. + A quantia à pagar deve ser maior que 0 + + + The amount exceeds your balance. + A quantia excede o seu saldo + + + The total exceeds your balance when the %1 transaction fee is included. + O total excede o seu saldo quando a taxa da transação %1 é incluída + + + Duplicate address found: addresses should only be used once each. + Endereço duplicado encontrado: Endereços devem ser usados somente uma vez cada. + + + Transaction creation failed! + Falha na criação da transação + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + A transação foi rejeitada! Isso pode acontecer se algumas moedas na sua carteira já foram gastas em outro local, por exemplo se você tiver uma cópia da carteira e as moedas tiverem sido gastas na cópia mas não marcados como gastas aqui ainda. + + + A fee higher than %1 is considered an absurdly high fee. + Uma taxa maior que %1 é considerada uma taxa absurdamente alta. + + + Payment request expired. + Pedido de pagamento expirado + + + Pay only the required fee of %1 + Pagar somente a taxa requerida de %1 + + + Estimated to begin confirmation within %n block(s). + Estimado a começar confirmação em %n bloco(s).Estimado começar confirmação em %n bloco(s). + + + Warning: Invalid Bitcoin address + Aviso: Endereço inválido + + + Warning: Unknown change address + Aviso: Endereço de troco inválido + + + (no label) + (sem rótuo) + + SendCoinsEntry @@ -1613,10 +2237,18 @@ Memo: Memorizar: - + + Enter a label for this address to add it to your address book + Digite um rótulo para este endereço para adicioná-lo ao catálogo de endereços + + SendConfirmationDialog - + + Yes + Sim + + ShutdownWindow @@ -1710,7 +2342,59 @@ Reset all verify message fields Limpar todos os campos de assinatura da mensagem - + + Click "Sign Message" to generate signature + Clique em "Assinar mensagem" para gerar a assinatura + + + The entered address is invalid. + O endereço digitado é inválido + + + Please check the address and try again. + Favor checar o endereço e tente novamente + + + The entered address does not refer to a key. + O endereço fornecido não se refere a uma chave. + + + Wallet unlock was cancelled. + O desbloqueio da carteira foi cancelado + + + Private key for the entered address is not available. + A chave privada do endereço inserido não está disponível + + + Message signing failed. + Falha ao assinar mensagem + + + Message signed. + Mensagem assinada + + + The signature could not be decoded. + A assinatura não pode ser descodificada + + + Please check the signature and try again. + Favor checar a assinatura e tente novamente + + + The signature did not match the message digest. + A assinatura não corresponde a mensagem + + + Message verification failed. + Falha na verificação da mensagem + + + Message verified. + Mensagem verificada + + SplashScreen @@ -1727,20 +2411,456 @@ TransactionDesc - + + Open for %n more block(s) + Aberto para mais %n bloco(s)Aberto para mais %n bloco(s) + + + Open until %1 + Aberto até %1 + + + conflicted with a transaction with %1 confirmations + conflitado com uma transação com %1 confirmações + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/não confirmado, %1 + + + in memory pool + na memória + + + not in memory pool + não na memóra + + + abandoned + abandonado + + + %1/unconfirmed + %1/não confirmado + + + %1 confirmations + %1 confirmações + + + Status + Status + + + , has not been successfully broadcast yet + , ainda não foi propagada na rede com êxito. + + + , broadcast through %n node(s) + , propagada por %n nó(s), propagada por %n nó(s) + + + Date + Data + + + Source + Fonte + + + Generated + Gerado + + + From + De + + + unknown + desconhecido + + + To + Para + + + own address + próprio endereço + + + watch-only + monitorado + + + label + rótulo + + + Credit + Crédito + + + matures in %n more block(s) + amadurece em mais %n bloco(s)amadurece em mais %n bloco(s) + + + not accepted + não aceito + + + Debit + Débito + + + Total debit + Débito total + + + Total credit + Crédito total + + + Transaction fee + Taxa da transação + + + Net amount + Valor líquido + + + Message + Mensagem + + + Comment + Comentário + + + Transaction ID + ID da transação + + + Output index + Index da saída + + + Merchant + Mercador + + + 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. + Moedas recém minerados precisam aguardar %1 blocos antes de serem gastos. Quando o bloco foi gerado, ele foi disseminado pela rede para ser adicionado à blockchain. Se ele falhar em ser inserido na cadeia, seu estado será modificado para "não aceito" e ele não poderá ser gasto. Isso pode acontecer eventualmente quando blocos são gerados quase que simultaneamente. + + + Debug information + Depurar informação + + + Transaction + Transação + + + Inputs + Entradas + + + Amount + Quantia + + + true + verdadeiro + + + false + falso + + TransactionDescDialog This pane shows a detailed description of the transaction Este painel mostra uma descrição detalhada da transação - + + Details for %1 + Detalhes para %1 + + TransactionTableModel - + + Date + Data + + + Type + Tipo + + + Label + Rótuo + + + Open for %n more block(s) + Aberto por mais %n bloco(s)Aberto por mais %n bloco(s) + + + Open until %1 + Aberto até %1 + + + Offline + Offline + + + Unconfirmed + Não confirmado + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmações recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmações) + + + Conflicted + Conflitado + + + Immature (%1 confirmations, will be available after %2) + Recém-criado (%1 confirmações, disponível somente após %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloco não foi recebido por nenhum outro participante da rede e provavelmente não será aceito! + + + Generated but not accepted + Gerado mas não aceito + + + Received with + Recebido em + + + Received from + Recebido de + + + Sent to + Enviado para + + + Payment to yourself + Pagamento para você mesmo + + + Mined + Minerado + + + watch-only + monitorado + + + (n/a) + (n/a) + + + (no label) + (sem rótuo) + + + Transaction status. Hover over this field to show number of confirmations. + Status da transação. Passe o mouse sobre este campo para mostrar o número de confirmações. + + + Date and time that the transaction was received. + Data e hora em que a transação foi recebida. + + + Type of transaction. + Tipo de transação + + + Whether or not a watch-only address is involved in this transaction. + Mostrar ou não endereços monitorados na lista de transações. + + + User-defined intent/purpose of the transaction. + Intenção/Propósito definido pelo usuário para a transação + + + Amount removed from or added to balance. + Quantidade debitada ou creditada ao saldo. + + TransactionView - + + All + Todos + + + Today + Hoje + + + This week + Essa semana + + + This month + Esse mês + + + Last month + Último mês + + + This year + Este ano + + + Range... + Intervalo... + + + Received with + Recebido em + + + Sent to + Enviado para + + + To yourself + Para você mesmo + + + Mined + Minerado + + + Other + Outro + + + Enter address or label to search + Procure um endereço ou rótulo + + + Min amount + Quantia mínima + + + Abandon transaction + Transação abandonada + + + Copy address + Copiar endereço + + + Copy label + Copiar rótulo + + + Copy amount + Copiar quantia + + + Copy transaction ID + Copiar ID da transação + + + Copy raw transaction + Copiar o raw da transação + + + Copy full transaction details + Copiar dados completos da transação + + + Edit label + Editar rótulo + + + Show transaction details + Mostrar detalhes da transação + + + Export Transaction History + Exportar histórico de transações + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Confirmed + Confirmado + + + Watch-only + Monitorado + + + Date + Data + + + Type + Tipo + + + Label + Rótuo + + + Address + Endereço + + + ID + ID + + + Exporting Failed + Falha na exportação + + + There was an error trying to save the transaction history to %1. + Ocorreu um erro ao tentar salvar o histórico de transações em %1. + + + Exporting Successful + Exportação feita com êxito + + + The transaction history was successfully saved to %1. + O histórico de transação foi gravado com êxito em %1. + + + Range: + Intervalo: + + + to + para + + UnitDisplayStatusBarControl @@ -1750,13 +2870,53 @@ WalletFrame - + + No wallet has been loaded. + Nenhuma carteira carregada + + WalletModel - + + Send Coins + Enviar moedas + + WalletView - + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar os dados da guia atual para um arquivo + + + Backup Wallet + Backup da carteira + + + Wallet Data (*.dat) + Dados da carteira (*.dat) + + + Backup Failed + Falha no backup + + + There was an error trying to save the wallet data to %1. + Ocorreu um erro ao tentar salvar os dados da carteira em %1. + + + Backup Successful + Êxito no backup + + + The wallet data was successfully saved to %1. + Os dados da carteira foram salvos com êxito em %1. + + bitcoin-core @@ -1793,7 +2953,7 @@ Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) - Reduza os requerimentos de armazenamento de dados (cortando) deletando blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilita o corte de blocos, >%u = tamanho alvo em MiB para o uso de blocos cortados) + Reduza o armazenamento de dados apagando os blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilitado, >%u = tamanho em MiB para o uso de blocos cortados) Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. @@ -1855,6 +3015,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distribuido sob a licença MIT software license. Veja os termos em <http://www.opensource.org/licenses/mit-license.php>. + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Número mínimo de bytes por assinatura em transações que transmitimos e mineramos (default: %u) + Error loading %s: You can't enable HD on a already existing non-HD wallet Erro ao carregar %s. Não é permitido habilitar HD em carteiras não-HD pre existentes. @@ -2099,6 +3263,14 @@ Prune mode is incompatible with -txindex. O modo prune é incompatível com -txindex. + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruir índice de cadeia de bloco a partir dos arquivos blk*.dat no disco + + + Rebuild chain state from the currently indexed blocks + Reconstruir estado a partir dos blocos indexados + Rewinding blocks... Reanalizando blocos... @@ -2119,6 +3291,10 @@ Specify wallet file (within data directory) Especifique o arquivo da carteira (dentro do diretório de dados) + + Starting network threads... + Iniciando análise da rede... + The source code is available from %s. O código fonte está disponível pelo %s @@ -2199,13 +3375,17 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) Comissões (em %s/kB) menores serão consideradas como zero para relaying, mineração e criação de transação (padrão %s) + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Se paytxfee não estiver definida, incluir comissão suficiente para que as transações comecem a ter confirmações em média dentro de N blocos (padrão %u) Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - Valor inválido para -maxtxfee = <valor>: '%s'( precisa ser pelo menos a comissão mínima de %s para prevenir travamento de transações) + Valor inválido para -maxtxfee=<valor>: '%s' (precisa ser pelo menos a taxa mínima de %s para prevenir que a transação nunca seja confirmada) Maximum size of data in data carrier transactions we relay and mine (default: %u) @@ -2231,6 +3411,10 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit <https://www.openssl.org> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usar carteira HD. Somente tem efeito na criação de uma nova carteira + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway Peers permitidos não podem ser banidos do DoS e suas transações sempre são transmitidas, até mesmo se eles já estão no pool de memória, útil, por exemplo, para um gateway diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index cbecf9058..e4c5bef16 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -41,6 +41,14 @@ &Delete &Eliminar + + Choose the address to send coins to + Escolhe qual o endereço para o qual enviar moedas + + + Choose the address to receive coins with + Escolhe qual o endereço para receber moedas + AddressTableModel diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index ee0568ed5..7e46f251d 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -44,7 +44,11 @@ AddressTableModel - + + (no label) + (bez popisu) + + AskPassphraseDialog @@ -466,6 +470,10 @@ Priority Priorita + + (no label) + (bez popisu) + EditAddressDialog @@ -1384,6 +1392,10 @@ RecentRequestsTableModel + + (no label) + (bez popisu) + SendCoinsDialog @@ -1535,7 +1547,15 @@ S&end &Odoslať - + + or + alebo + + + (no label) + (bez popisu) + + SendCoinsEntry @@ -1734,6 +1754,10 @@ TransactionTableModel + + (no label) + (bez popisu) + TransactionView diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 5b122f76c..7e30b263a 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -73,10 +73,47 @@ &Copy Address &Kopiera adress - + + Copy &Label + Kopiera &etikett + + + &Edit + &Redigera + + + Export Address List + Exportera adresslista + + + Comma separated file (*.csv) + Kommaseparerad fil (*.csv) + + + Exporting Failed + Export misslyckades + + + There was an error trying to save the address list to %1. Please try again. + Det inträffade ett fel när adresslistan skulle sparas till %1. +Var vänlig och försök igen. + + AddressTableModel - + + Label + Etikett + + + Address + Adress + + + (no label) + (Ingen etikett) + + AskPassphraseDialog @@ -95,7 +132,95 @@ Repeat new passphrase Upprepa nytt lösenord - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Ange plånbokens nya lösenord. <br/> Använd ett lösenord på <b>tio eller fler slumpmässiga tecken,</b> eller <b>åtta eller fler ord.</b>. + + + Encrypt wallet + Kryptera plånbok + + + This operation needs your wallet passphrase to unlock the wallet. + Denna operation behöver din plånboks lösenord för att låsa upp plånboken. + + + Unlock wallet + Lås upp plånbok + + + This operation needs your wallet passphrase to decrypt the wallet. + Denna operation behöver din plånboks lösenord för att dekryptera plånboken. + + + Decrypt wallet + Dekryptera plånbok + + + Change passphrase + Ändra lösenord + + + Enter the old passphrase and new passphrase to the wallet. + Ge det gamla lösenordet och det nya lösenordet för plånboken. + + + Confirm wallet encryption + Bekräfta kryptering av plånbok + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + VARNING: Om du krypterar din plånbok och glömmer ditt lösenord, kommer du att <b>FÖRLORA ALLA DINA BITCOIN</b>! + + + Are you sure you wish to encrypt your wallet? + Är du säker på att du vill kryptera din plånbok? + + + Wallet encrypted + Plånbok krypterad + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 kommer nu att stänga ner för att färdigställa krypteringen. Tänk på att en krypterad plånbok inte skyddar mot stöld om din dator är infekterad med en keylogger. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + VIKTIGT: Alla tidigare säkerhetskopior du har gjort av plånboksfilen ska ersättas med den nya genererade, krypterade plånboksfilen. Av säkerhetsskäl kommer tidigare säkerhetskopior av den okrypterade plånboksfilen blir oanvändbara när du börjar använda en ny, krypterad plånbok. + + + Wallet encryption failed + Kryptering av plånbok misslyckades + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Kryptering av plånbok misslyckades på grund av ett internt fel. Din plånbok blev inte krypterad. + + + The supplied passphrases do not match. + De angivna lösenorden överensstämmer inte. + + + Wallet unlock failed + Misslyckades låsa upp plånboken + + + The passphrase entered for the wallet decryption was incorrect. + Lösenordet för dekryptering av plånboken var felaktig. + + + Wallet decryption failed + Dekryptering av plånbok misslyckades + + + Wallet passphrase was successfully changed. + Plånbokens lösenord har ändrats. + + + Warning: The Caps Lock key is on! + Varning: Caps Lock är påslaget! + + BanTableModel @@ -498,6 +623,22 @@ Priority Prioritet + + Copy address + Kopiera adress + + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + + + (no label) + (Ingen etikett) + EditAddressDialog @@ -1393,7 +1534,15 @@ Remove Ta bort - + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + + ReceiveRequestDialog @@ -1412,9 +1561,25 @@ &Save Image... &Spara Bild... + + Address + Adress + + + Label + Etikett + RecentRequestsTableModel + + Label + Etikett + + + (no label) + (Ingen etikett) + SendCoinsDialog @@ -1566,7 +1731,15 @@ S&end &Skicka - + + Copy amount + Kopiera belopp + + + (no label) + (Ingen etikett) + + SendCoinsEntry @@ -1773,9 +1946,45 @@ TransactionTableModel + + Label + Etikett + + + (no label) + (Ingen etikett) + TransactionView + + Copy address + Kopiera adress + + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + + + Comma separated file (*.csv) + Kommaseparerad fil (*.csv) + + + Label + Etikett + + + Address + Adress + + + Exporting Failed + Export misslyckades + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index 699ded2c6..1ce2c4df8 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -25,9 +25,21 @@ &Delete &அழி + + Sending addresses + முகவரிகள் அனுப்பப்படுகின்றன + + + Receiving addresses + முகவரிகள் பெறப்படுகின்றன + AddressTableModel + + Address + முகவரி + AskPassphraseDialog @@ -558,6 +570,10 @@ &Save Image... &படத்தை சேமி... + + Address + முகவரி + RecentRequestsTableModel @@ -678,6 +694,10 @@ TransactionView + + Address + முகவரி + UnitDisplayStatusBarControl diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index 5774f5b9b..fdfc92117 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -619,6 +619,10 @@ QRImageWidget + + &Save Image... + $Lưu hình ảnh... + RPCConsole @@ -646,6 +650,58 @@ User Agent User Agent + + 1 &hour + 1&giờ + + + 1 &day + 1&ngày + + + 1 &week + 1&tuần + + + 1 &year + 1&năm + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Sử dụng phím lên và xuống để di chuyển lịch sử, và <b>Ctrl-L</b> để xóa màn hình + + + Type <b>help</b> for an overview of available commands. + Gõ <b>help</b> để xem nhưng câu lệnh có sẵn + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + never + không bao giờ + + + Yes + Đồng ý + + + No + Không + ReceiveCoinsDialog @@ -653,19 +709,119 @@ &Amount: Lượng: + + &Label: + &Nhãn + + + &Message: + &Tin nhắn: + + + Use this form to request payments. All fields are <b>optional</b>. + Sử dụng form này để yêu cầu thanh toán. Tất cả các trường <b>không bắt buộc<b> + + + Clear all fields of the form. + Xóa tất cả các trường trong biểu mẫu + + + Clear + Xóa + + + Requested payments history + Lịch sử yêu cầu thanh toán + + + &Request payment + &Yêu cầu thanh toán + + + Show + Hiển thị + + + Remove the selected entries from the list + Xóa khỏi danh sách + + + Remove + Xóa + + + Copy message + Copy tin nhắn + ReceiveRequestDialog + + QR Code + QR Code + + + Copy &URI + Copy &URI + Copy &Address &Copy Địa Chỉ - + + &Save Image... + $Lưu hình ảnh... + + + Request payment to %1 + Yêu cầu thanh toán cho %1 + + + Payment information + Thông tin thanh toán + + + URI + URI + + + Message + Tin nhắn + + + Error encoding URI into QR Code. + Lỗi khi encode từ URI thành QR Code + + RecentRequestsTableModel + + Message + Tin nhắn + + + (no message) + (không tin nhắn) + SendCoinsDialog + + Send Coins + Gửi Coins + + + Coin Control Features + Tính năng Control Coin + + + Inputs... + Nhập... + + + automatically selected + Tự động chọn + Insufficient funds! Không đủ tiền @@ -698,6 +854,86 @@ Change: Thay đổi: + + Transaction Fee: + Phí giao dịch + + + Choose... + Chọn... + + + collapse fee-settings + Thu gọn fee-settings + + + per kilobyte + trên KB + + + Hide + Ẩn + + + total at least + Tổng cộng ít nhất + + + (read the tooltip) + (Đọc hướng dẫn) + + + Confirmation time: + Thời gian xác nhận + + + normal + Bình thường + + + fast + Nhanh + + + Send to multiple recipients at once + Gửi đến nhiều người nhận trong một lần + + + Add &Recipient + Thêm &Người nhận + + + Clear all fields of the form. + Xóa tất cả các trường trong biểu mẫu + + + Clear &All + Xóa &Tất cả + + + Balance: + Tài khoản + + + Confirm the send action + Xác nhận sự gửi + + + %1 to %2 + %1 đến %2 + + + Total Amount %1 + Tổng cộng %1 + + + or + hoặc + + + Confirm send coins + Xác nhận gửi coins + SendCoinsEntry @@ -705,15 +941,27 @@ A&mount: Lượng: + + &Label: + &Nhãn + SendConfirmationDialog - + + Yes + Đồng ý + + ShutdownWindow SignVerifyMessageDialog + + Clear &All + Xóa &Tất cả + SplashScreen @@ -723,6 +971,10 @@ TransactionDesc + + Message + Tin nhắn + TransactionDescDialog @@ -741,7 +993,11 @@ WalletModel - + + Send Coins + Gửi Coins + + WalletView diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index b8d3cadc2..98142b7b0 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -41,10 +41,78 @@ &Delete 删除(&D) - + + Choose the address to send coins to + 选择要付钱过去的地址 + + + Choose the address to receive coins with + 选择要收钱进来的地址 + + + C&hoose + 选择 + + + Sending addresses + 付款地址 + + + Receiving addresses + 收款地址 + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + 这些是你要付款过去的比特币地址。在付钱之前,务必要检查金额和收款地址是否正确。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + 这些是你用来收款的比特币地址。建议在每次交易时,都使用一个新的收款地址。 + + + &Copy Address + 复制地址 + + + Copy &Label + 复制标签 + + + &Edit + 编辑 + + + Export Address List + 导出地址列表 + + + Comma separated file (*.csv) + 逗号分隔文件 (*.csv) + + + Exporting Failed + 导出失败 + + + There was an error trying to save the address list to %1. Please try again. + 存储地址列表到 %1 时发生错误。请再试一次。 + + AddressTableModel - + + Label + 标签 + + + Address + 地址 + + + (no label) + (无标签) + + AskPassphraseDialog @@ -63,7 +131,95 @@ Repeat new passphrase 重复新密码 - + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 输入钱包的新密码。<br/>密码请用<b>10 个以上的随机字符</b>,或是<b>8 个以上的字词</b>。 + + + Encrypt wallet + 加密钱包 + + + This operation needs your wallet passphrase to unlock the wallet. + 这个操作需要你的钱包密码来解锁钱包。 + + + Unlock wallet + 解锁钱包 + + + This operation needs your wallet passphrase to decrypt the wallet. + 这个操作需要你的钱包密码来把钱包解密。 + + + Decrypt wallet + 解密钱包 + + + Change passphrase + 修改密码 + + + Enter the old passphrase and new passphrase to the wallet. + 请输入钱包的旧密码和新密码。 + + + Confirm wallet encryption + 确认钱包加密 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: 如果把钱包加密后又忘记密码,你就会从此<b>失去其中所有的比特币了</b>! + + + Are you sure you wish to encrypt your wallet? + 你确定要把钱包加密吗? + + + Wallet encrypted + 钱包已加密 + + + %1 will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + %1 现在要关闭,以完成加密过程。请注意,加密钱包不能完全防止入侵你的电脑的恶意程序偷取钱币。 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 重要: 请改用新产生的有加密的钱包文件,来取代旧钱包文件的备份。为了安全性,当你开始使用新的有加密的钱包后,旧钱包文件的备份就不能再使用了。 + + + Wallet encryption failed + 钱包加密失败 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 因为内部错误导致钱包加密失败。你的钱包还是没加密。 + + + The supplied passphrases do not match. + 提供的密码不yi'zhi。 + + + Wallet unlock failed + 钱包解锁失败 + + + The passphrase entered for the wallet decryption was incorrect. + 输入用来解密钱包的密码不正确。 + + + Wallet decryption failed + 钱包解密失败 + + + Wallet passphrase was successfully changed. + 钱包密码修改成功。 + + + Warning: The Caps Lock key is on! + 警告: 大写字母锁定已开启! + + BanTableModel @@ -115,7 +271,7 @@ &About %1 - &关于 %1 + 关于 %1 Show information about %1 @@ -243,7 +399,7 @@ Request payments (generates QR codes and bitcoin: URIs) - 请求支付(生成二维码和 bitcoin: URI) + 请求支付 (生成二维码和 bitcoin: URI) Show the list of used sending addresses and labels @@ -255,7 +411,7 @@ Open a bitcoin: URI or payment request - 打开一个比特币:URI 或支付请求 + 打开一个 bitcoin: URI 或支付请求 &Command-line options @@ -388,7 +544,7 @@ CoinControlDialog Coin Selection - 币源选择(Coin Selection) + 选择钱币 Quantity: @@ -462,7 +618,151 @@ Priority 优先级 - + + Copy address + 复制地址 + + + Copy label + 复制标签 + + + Copy amount + 复制金额 + + + Copy transaction ID + 复制交易识别码 + + + Lock unspent + 锁定未花费 + + + Unlock unspent + 解锁未花费 + + + Copy quantity + 复制数目 + + + Copy fee + 复制手续费 + + + Copy after fee + 复制计费后金额 + + + Copy bytes + 复制字节数 + + + Copy priority + 复制优先度 + + + Copy dust + 复制零散金额 + + + Copy change + 复制找零金额 + + + highest + 最高 + + + higher + 很高 + + + high + + + + medium-high + 中高 + + + medium + 中等 + + + low-medium + 中低 + + + low + + + + lower + 很低 + + + lowest + 最低 + + + (%1 locked) + (锁定 %1 枚) + + + none + + + + yes + + + + no + + + + This label turns red if the transaction size is greater than 1000 bytes. + 当交易大小大于 1000 字节时,文字会变红色。 + + + This means a fee of at least %1 per kB is required. + 表示每一千字节(kB)需要至少 %1 的手续费。 + + + Can vary +/- 1 byte per input. + 每组输入可能会误差多或少 1 个字节。 + + + Transactions with higher priority are more likely to get included into a block. + 优先度较高的交易比较有可能被接受放进区块中。 + + + This label turns red if the priority is smaller than "medium". + 当优先度低于“中等”时,文字会变红色。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 当任何一个收款金额小于目前的零散金额上限时,文字会变红色。 + + + Can vary +/- %1 satoshi(s) per input. + 每组输入可能有 +/- %1 个 satoshi 的误差。 + + + (no label) + (无标签) + + + change from %1 (%2) + 找零前是 %1 (%2) + + + (change) + (找零) + + EditAddressDialog @@ -485,7 +785,39 @@ &Address 地址(&A) - + + New receiving address + 新建收款地址 + + + New sending address + 新建付款地址 + + + Edit receiving address + 编辑收款地址 + + + Edit sending address + 编辑付款地址 + + + The entered address "%1" is not a valid Bitcoin address. + 输入的地址 %1 并不是有效的比特币地址。 + + + The entered address "%1" is already in the address book. + 输入的地址 %1 已经存在地址簿。 + + + Could not unlock wallet. + 无法将钱包解锁。 + + + New key generation failed. + 产生新的密钥失败了。 + + FreespaceChecker @@ -579,6 +911,10 @@ As this is the first time the program is launched, you can choose where %1 will store its data. 由于这是第一次启动此程序,您可以选择%1的数据所存储的位置 + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 会下载并存储一份比特币区块链的副本。至少有 %2GB 的数据会存储到这个目录中,并且还会持续增长。另外钱包资料也会储存在这个目录。 + Use the default data directory 使用默认的数据目录 @@ -622,7 +958,11 @@ Select payment request file 选择付款请求文件 - + + Select payment request file to open + 选择要打开的付款请求文件 + + OptionsDialog @@ -633,6 +973,14 @@ &Main 主要(&M) + + Automatically start %1 after logging in to the system. + 在登入系统后自动启动 %1 + + + &Start %1 on system login + 系统登入时启动 %1 + Size of &database cache 数据库缓存大小(&D) @@ -759,7 +1107,7 @@ Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. - 在Tor匿名网络下通过不同的SOCKS5代理连接比特币网络 + 在 Tor 匿名网络下通过不同的 SOCKS5 代理连接比特币网络 Use separate SOCKS5 proxy to reach peers via Tor hidden services: @@ -769,6 +1117,14 @@ &Window 窗口(&W) + + &Hide the icon from the system tray. + 不在通知区显示图标 + + + Hide tray icon + 不显示通知区图标 + Show only a tray icon after minimizing the window. 最小化窗口后仅显示托盘图标 @@ -789,6 +1145,10 @@ User Interface &language: 用户界面语言(&L): + + The user interface language can be set here. This setting will take effect after restarting %1. + 可以在这里设定用户界面的语言。这个设定在重启 %1 后才会生效。 + &Unit to show amounts in: 比特币金额单位(&U): @@ -846,7 +1206,7 @@ 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. - 现在显示的消息可能是过期的. 在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。 + 现在显示的消息可能是过期的。在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。 Watch-only: @@ -915,7 +1275,56 @@ PaymentServer - + + Payment request error + 要求付款时发生错误 + + + Cannot start bitcoin: click-to-pay handler + 无法启动 bitcoin 协议的“ +一键支付”处理器 + + + URI handling + URI 处理 + + + Payment request fetch URL is invalid: %1 + 取得付款请求的 URL 无效: %1 + + + Invalid payment address %1 + 无效的付款地址 %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + 无法解析 URI 地址!可能是因为比特币地址无效,或是 URI 参数格式错误。 + + + Payment request file handling + 处理付款请求文件 + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 无法读取付款请求文件!可能是文件无效造成的。 + + + Payment request rejected + 付款请求已被拒绝 + + + Payment request network doesn't match client network. + 付款请求的网络类型跟客户端不符。 + + + Payment request expired. + 付款请求已过期。 + + + Payment acknowledged + 付款已确认 + + PeerTableModel @@ -972,7 +1381,23 @@ QRImageWidget - + + &Save Image... + 保存图片(&S)... + + + &Copy Image + 复制图片 + + + Save QR Code + 保存二维码 + + + PNG Image (*.png) + PNG 图像(*.png) + + RPCConsole @@ -999,6 +1424,10 @@ Using BerkeleyDB version 使用的 BerkeleyDB 版本 + + Datadir + 数据目录 + Startup time 启动时间 @@ -1083,6 +1512,14 @@ User Agent 用户代理 + + Decrease font size + 缩小文字 + + + Increase font size + 放大文字 + Services 服务 @@ -1107,6 +1544,10 @@ Ping Time Ping 时间 + + The duration of a currently outstanding ping. + 目前这一次 ping 已经过去的时间。 + Ping Wait Ping等待 @@ -1141,7 +1582,7 @@ In: - 输入: + 输入: Out: @@ -1183,6 +1624,10 @@ &Unban Node (&U)允许节点连接 + + Welcome to the %1 RPC console. + 欢迎使用 %1 的 RPC 控制台。 + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 使用上下方向键浏览历史, <b>Ctrl-L</b>清除屏幕。 @@ -1310,7 +1755,19 @@ Remove 移除 - + + Copy label + 复制标签 + + + Copy message + 复制消息 + + + Copy amount + 复制金额 + + ReceiveRequestDialog @@ -1329,9 +1786,53 @@ &Save Image... 保存图片(&S)... - + + URI + URI + + + Address + 地址 + + + Amount + 金额 + + + Label + 标签 + + + Message + 消息 + + + Error encoding URI into QR Code. + 把 URI 编码成二维码时发生错误。 + + RecentRequestsTableModel + + Date + 日期 + + + Label + 标签 + + + Message + 消息 + + + (no label) + (无标签) + + + (no message) + (无消息) + SendCoinsDialog @@ -1483,7 +1984,59 @@ S&end 发送(&E) - + + Copy quantity + 复制数目 + + + Copy amount + 复制金额 + + + Copy fee + 复制手续费 + + + Copy after fee + 复制计费后金额 + + + Copy bytes + 复制字节数 + + + Copy priority + 复制优先度 + + + Copy dust + 复制零散金额 + + + Copy change + 复制找零金额 + + + Total Amount %1 + 总金额 %1 + + + or + + + + Payment request expired. + 付款请求已过期。 + + + Warning: Invalid Bitcoin address + 警告: 比特币地址无效 + + + (no label) + (无标签) + + SendCoinsEntry @@ -1565,9 +2118,17 @@ SendConfirmationDialog - + + Yes + + + ShutdownWindow + + %1 is shutting down... + 正在关闭 %1 ... + Do not shut down the computer until this window disappears. 在此窗口消失前不要关闭计算机。 @@ -1676,7 +2237,43 @@ TransactionDesc - + + Date + 日期 + + + Message + 消息 + + + Merchant + 商家 + + + Debug information + 调试信息 + + + Transaction + 交易 + + + Inputs + 输入 + + + Amount + 金额 + + + true + + + + false + + + TransactionDescDialog @@ -1686,10 +2283,130 @@ TransactionTableModel + + Date + 日期 + + + Type + 种类 + + + Label + 标签 + + + Received with + 收款 + + + Sent to + 付款 + + + Mined + 挖矿所得 + + + (no label) + (无标签) + TransactionView - + + All + 全部 + + + Today + 今天 + + + This week + 这星期 + + + This month + 这个月 + + + Last month + 上个月 + + + This year + 今年 + + + Range... + 指定范围... + + + Received with + 收款 + + + Sent to + 付款 + + + To yourself + 给自己 + + + Mined + 挖矿所得 + + + Other + 其它 + + + Copy address + 复制地址 + + + Copy label + 复制标签 + + + Copy amount + 复制金额 + + + Copy transaction ID + 复制交易识别码 + + + Comma separated file (*.csv) + 逗号分隔文件 (*.csv) + + + Date + 日期 + + + Type + 种类 + + + Label + 标签 + + + Address + 地址 + + + Exporting Failed + 导出失败 + + + to + + + UnitDisplayStatusBarControl @@ -1705,6 +2422,18 @@ WalletView + + Backup Wallet + 备份钱包 + + + Backup Failed + 备份失败 + + + Backup Successful + 备份成功 + bitcoin-core @@ -1779,7 +2508,11 @@ Bitcoin Core - 比特币核心 + Bitcoin Core + + + The %s developers + %s 开发人员 -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. @@ -1861,6 +2594,10 @@ Connection options: 连接选项: + + Copyright (C) %i-%i + 版权所有 (C) %i-%i + Corrupted block database detected 检测发现数据块数据库损坏。请使用 -reindex参数重启客户端。 @@ -1905,6 +2642,10 @@ Error initializing wallet database environment %s! Error initializing wallet database environment %s! + + Error loading %s + 载入 %s 时发生错误 + Error loading block database 导入数据块数据库出错 @@ -1977,6 +2718,14 @@ Specify wallet file (within data directory) 指定钱包文件(数据目录内) + + Starting network threads... + 正在启动网络线程... + + + The source code is available from %s. + 源代码可以在 %s 获得。 + Unsupported argument -benchmark ignored, use -debug=bench. 忽略不支持的选项 -benchmark,使用 -debug=bench @@ -1999,11 +2748,11 @@ Verifying blocks... - 正在验证数据库的完整性... + 正在验证区块... Verifying wallet... - 正在检测钱包的完整性... + 正在验证钱包... Wallet %s resides outside data directory %s @@ -2105,6 +2854,10 @@ Error reading from database, shutting down. 读取数据库出错,关闭中。 + + Imports blocks from external blk000??.dat file on startup + 启动时从其他来源的 blk000??.dat 文件导入区块 + Information 信息 @@ -2133,6 +2886,10 @@ RPC server options: RPC 服务器选项: + + Reducing -maxconnections from %d to %d, because of system limitations. + 因为系统的限制,将 -maxconnections 参数从 %d 降到了 %d + Rescan the block chain for missing wallet transactions on startup 重新扫描区块链以查找遗漏的钱包交易 @@ -2165,6 +2922,14 @@ This is experimental software. 这是实验性的软件。 + + Tor control port password (default: empty) + Tor 控制端口密码 (默认值: 空白) + + + Tor control port to use if onion listening enabled (default: %s) + 开启监听 onion 连接时的 Tor 控制端口号 (默认值: %s) + Transaction amount too small 交易量太小 @@ -2197,13 +2962,17 @@ Warning 警告 + + Warning: unknown new rules activated (versionbit %i) + 警告: 不明的交易规则被启用了(versionbit %i) + Whether to operate in a blocks only mode (default: %u) 是否用块方进行 (%u) Zapping all transactions from wallet... - Zapping all transactions from wallet... + 正在消除錢包中的所有交易... ZeroMQ notification options: @@ -2230,6 +2999,22 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + 参数 -maxtxfee 设定了很高的金额!这是你一次交易就有可能付出的最高手续费。 + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + 参数 -paytxfee 设定了很高的金额!这是你交易付款时所要付的手续费。 + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + 不要让交易留在内存池中超过 <n> 个小时 (默认值: %u) + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + 当产生交易时,如果每千字节 (kB) 的手续费比这个值 (单位是 %s) 低,就视为没支付手续费 (默认值: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) 数据块验证 严密级别 -checkblocks (0-4, 默认: %u) @@ -2246,10 +3031,22 @@ Output debugging information (default: %u, supplying <category> is optional) 输出调试信息 (默认: %u, 提供 <category> 是可选项) + + Support filtering of blocks and transaction with bloom filters (default: %u) + 支持用 Bloom 过滤器来过滤区块和交易(默认值: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + 网络版本字符串的总长度 (%i) 超过最大长度 (%i) 了。请减少 uacomment 参数的数目或长度。 + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) 尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d) + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + 找到不再支持的 -socks 参数。现在只支持 SOCKS5 协议的代理服务器,因此不可以指定 SOCKS 协议版本。 + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. 一个不被支持的参数 -whitelistalwaysrelay 被忽略了。请使用 -whitelistrelay 或者 -whitelistforcerelay. @@ -2258,6 +3055,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC 连接要使用的用户名和散列密码。<userpw> 的格式是:<用户名>:<盐>$<散列值>。在 share/rpcuser 目录下有一个示范的 python 脚本。这个选项可以被多次指定。 + Warning: Unknown block versions being mined! It's possible unknown rules are in effect 警告: 未知的区块版本被挖掘!未知规则可能已生效 @@ -2356,7 +3157,7 @@ Loading block index... - 正在加载数据块索引... + 正在加载区块索引... Add a node to connect to and attempt to keep the connection open From bdd6d4c97df2052fe160f12ac507ec5946f91a07 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Fri, 2 Dec 2016 15:29:20 -0500 Subject: [PATCH 1209/1223] SelectCoinsMinConf: Prefer coins with fewer ancestors --- src/txmempool.cpp | 7 +++ src/txmempool.h | 3 ++ src/wallet/test/wallet_tests.cpp | 74 ++++++++++++++++---------------- src/wallet/wallet.cpp | 19 ++++++-- src/wallet/wallet.h | 4 +- 5 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 59afb2cf5..a7056554a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1134,3 +1134,10 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe if (maxFeeRateRemoved > CFeeRate(0)) LogPrint("mempool", "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString()); } + +bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const { + LOCK(cs); + if (exists(txid) && std::max(mapTx.find(txid)->GetCountWithAncestors(), mapTx.find(txid)->GetCountWithDescendants()) >= chainLimit) + return false; + return true; +} diff --git a/src/txmempool.h b/src/txmempool.h index afb328b5a..8129a0537 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -595,6 +595,9 @@ public: /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ int Expire(int64_t time); + /** Returns false if the transaction is in the mempool and not within the chain limit specified. */ + bool TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const; + unsigned long size() { LOCK(cs); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index c6c505898..38637b2d5 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -78,24 +78,24 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); // with an empty wallet we can't even pay one cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); add_coin(1*CENT, 4); // add a new 1 cent coin // with a new 1 cent coin, we still can't find a mature 1 cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // but we can find a new 1 cent - BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); add_coin(2*CENT); // add a mature 2 cent coin // we can't make 3 cents of mature coins - BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // we can make 3 cents of new coins - BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); add_coin(5*CENT); // add a mature 5 cent coin, @@ -105,33 +105,33 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 // we can't make 38 cents only if we disallow new coins: - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // we can't even make 37 cents if we don't allow new coins even if they're from us - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, 0, vCoins, setCoinsRet, nValueRet)); // but we can make 37 cents if we accept new coins from ourself - BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); // and we can make 38 cents if we accept all new coins - BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); // try making 34 cents from 1,2,5,10,20 - we can't do it exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 - BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. - BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK(nValueRet == 8 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) - BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -145,30 +145,30 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total // check that we have 71 and not 72 - BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins // now try making 11 cents. we should get 5+6 - BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -177,11 +177,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin( 2*COIN); add_coin( 3*COIN); add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -196,14 +196,14 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // but if we add a bigger coin, small change is avoided add_coin(1111*MIN_CHANGE); // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // if we add more small coins: @@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 7 / 10); // and try again to make 1.0 * MIN_CHANGE - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) for (int i = 0; i < 20; i++) add_coin(50000 * COIN); - BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 6 / 10); add_coin(MIN_CHANGE * 7 / 10); add_coin(1111 * MIN_CHANGE); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 6 / 10); add_coin(MIN_CHANGE * 8 / 10); add_coin(1111 * MIN_CHANGE); - BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 @@ -254,12 +254,12 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 100); // trying to make 100.01 from these three coins - BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change - BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // Create 676 inputs (= MAX_STANDARD_TX_SIZE / 148 bytes per input) for (uint16_t j = 0; j < 676; j++) add_coin(amt); - BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); if (amt - 2000 < MIN_CHANGE) { // needs more than one input: uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); @@ -291,8 +291,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); int fails = 0; @@ -300,8 +300,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } @@ -321,8 +321,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) add_coin(1000 * COIN); add_coin(3 * COIN); - BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7f6240262..1a33744ce 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1921,7 +1921,7 @@ static void ApproximateBestSubset(vector vCoins, +bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, vector vCoins, set >& setCoinsRet, CAmount& nValueRet) const { setCoinsRet.clear(); @@ -1946,6 +1946,9 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs)) continue; + if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors)) + continue; + int i = output.i; CAmount n = pcoin->vout[i].nValue; @@ -2071,10 +2074,17 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& ++it; } + size_t nMaxChainLength = std::min(GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)); + bool fRejectLongChains = GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); + bool res = nTargetValue <= nValueFromPresetInputs || - SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) || - SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) || - (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet)); + SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, 0, vCoins, setCoinsRet, nValueRet) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, 2, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::min((size_t)4, nMaxChainLength/3), vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength/2, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::numeric_limits::max(), vCoins, setCoinsRet, nValueRet)); // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end()); @@ -3263,6 +3273,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); } return strUsage; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 056dcc5da..10f6ea8fe 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -51,6 +51,8 @@ static const CAmount MIN_CHANGE = CENT; static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; //! Default for -sendfreetransactions static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; +//! Default for -walletrejectlongchains +static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! Largest (in bytes) free transaction we're willing to create @@ -668,7 +670,7 @@ public: * completion the coin set and corresponding actual target value is * assembled */ - bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; + bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; From f00066ac513774ba7fcad9e2054b209ffb2c23e8 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Fri, 2 Dec 2016 15:45:43 -0500 Subject: [PATCH 1210/1223] CreateTransaction: Don't return success with too-many-ancestor txn --- src/wallet/wallet.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1a33744ce..7bcb9aaf1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2452,6 +2452,21 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt } } + if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { + // Lastly, ensure this tx will pass the mempool's chain limits + LockPoints lp; + CTxMemPoolEntry entry(txNew, 0, 0, 0, 0, false, 0, false, 0, lp); + CTxMemPool::setEntries setAncestors; + size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; + size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; + std::string errString; + if (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { + strFailReason = _("Transaction has too long of a mempool chain"); + return false; + } + } return true; } From 4bf2bec18e5f3c613a0bf5c5fa78f6ec14dcc4f5 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Fri, 2 Dec 2016 12:20:29 -0500 Subject: [PATCH 1211/1223] Test for fix of txn chaining in wallet --- qa/rpc-tests/wallet.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 3c0dc0f4e..992fb8a2d 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -330,10 +330,12 @@ class WalletTest (BitcoinTestFramework): # disabled until issue is fixed: https://github.com/bitcoin/bitcoin/issues/7463 # '-salvagewallet', ] + chainlimit = 6 for m in maintenance: print("check " + m) stop_nodes(self.nodes) - self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) + # set lower ancestor limit for later + self.nodes = start_nodes(3, self.options.tmpdir, [[m, "-limitancestorcount="+str(chainlimit)]] * 3) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: # reindex will leave rpc warm up "early"; Wait for it to finish time.sleep(0.1) @@ -346,5 +348,26 @@ class WalletTest (BitcoinTestFramework): assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1]) assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) + # ==Check that wallet prefers to use coins that don't exceed mempool limits ===== + + # Get all non-zero utxos together + chain_addrs = [self.nodes[0].getnewaddress(), self.nodes[0].getnewaddress()] + singletxid = self.nodes[0].sendtoaddress(chain_addrs[0], self.nodes[0].getbalance(), "", "", True) + self.nodes[0].generate(1) + node0_balance = self.nodes[0].getbalance() + # Split into two chains + rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')}) + signedtx = self.nodes[0].signrawtransaction(rawtx) + singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) + txids = [singletxid, singletxid] + self.nodes[0].generate(1) + + # Make a long chain of unconfirmed payments without hitting mempool limit + txid_list = [] + for i in range(chainlimit*2): + txid_list.append(self.nodes[0].sendtoaddress(chain_addrs[0], Decimal('0.0001'))) + assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2) + assert_equal(len(txid_list), chainlimit*2) + if __name__ == '__main__': WalletTest().main() From e1ff0dbe19c3e7df21206d22bb12c686cd130b4c Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Mon, 19 Dec 2016 09:35:23 -0500 Subject: [PATCH 1212/1223] reduce number of lookups in TransactionWithinChainLimit --- src/txmempool.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a7056554a..63a26da32 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1137,7 +1137,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const { LOCK(cs); - if (exists(txid) && std::max(mapTx.find(txid)->GetCountWithAncestors(), mapTx.find(txid)->GetCountWithDescendants()) >= chainLimit) - return false; - return true; + auto it = mapTx.find(txid); + return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit && + it->GetCountWithDescendants() < chainLimit); } From 8e707e868d6020de0d352279eed4fcd0138f3695 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 20 Dec 2016 13:34:57 +0100 Subject: [PATCH 1213/1223] doc: Add #9382 to release notes --- doc/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index acfb45ae2..9d35d8e5f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -118,6 +118,7 @@ git merge commit are mentioned. - #9290 `35174a0` Make RelayWalletTransaction attempt to AcceptToMemoryPool (gmaxwell) - #9295 `43bcfca` Bugfix: Fundrawtransaction: don't terminate when keypool is empty (jonasschnelli) - #9302 `f5d606e` Return txid even if ATMP fails for new transaction (sipa) +- #9262 `fe39f26` Prefer coins that have fewer ancestors, sanity check txn before ATMP (instagibbs) ### Tests and QA - #9159 `eca9b46` Wait for specific block announcement in p2p-compactblocks (ryanofsky) From 20817ce92cc23951d2750076204c66218776f899 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 20 Dec 2016 22:11:45 +0100 Subject: [PATCH 1214/1223] Bump version to 0.13.2 --- configure.ac | 2 +- doc/Doxyfile | 2 +- doc/README.md | 2 +- doc/README_windows.txt | 2 +- src/clientversion.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index e76a3c722..d4e775aef 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 13) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2016) diff --git a/doc/Doxyfile b/doc/Doxyfile index a5f0aa6c7..c2af687ec 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = "Bitcoin Core" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.13.1 +PROJECT_NUMBER = 0.13.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index 25a280155..be2ab7283 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.1 +Bitcoin Core 0.13.2 ===================== Setup diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 1127ea766..0623049da 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.13.1 +Bitcoin Core 0.13.2 ===================== Intro diff --git a/src/clientversion.h b/src/clientversion.h index 74d0a94bf..eb0ee5973 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,7 +16,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 13 -#define CLIENT_VERSION_REVISION 1 +#define CLIENT_VERSION_REVISION 2 #define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build From 7a26a34112663b1d4a8de4ce94e5e1b7c97d0869 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 20 Dec 2016 22:17:19 +0100 Subject: [PATCH 1215/1223] Bump nMinimumChainWork --- src/chainparams.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 69514617b..7544e71a0 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -98,7 +98,7 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90"); + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003418b3ccbe5e93bcb39b43"); /** * The message start string is designed to be unlikely to occur in normal data. @@ -198,7 +198,7 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000198b4def2baa9338d6"); + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000001b3fcc3e766e365e4b"); pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; From 3882c053333ea3deeafdccd38a4bfd40114d776c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 20 Dec 2016 22:48:25 +0100 Subject: [PATCH 1216/1223] [qt] Bump BLOCK_CHAIN_SIZE --- src/qt/intro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 1a241ae0f..83b2107d2 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -23,7 +23,7 @@ static const uint64_t GB_BYTES = 1000000000LL; /* Minimum free space (in GB) needed for data directory */ -static const uint64_t BLOCK_CHAIN_SIZE = 80; +static const uint64_t BLOCK_CHAIN_SIZE = 100; /* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ static const uint64_t CHAIN_STATE_SIZE = 2; /* Total required space (in GB) depending on user choice (prune, not prune) */ From da233db8e09a472cedf21dbc60946a757f52d1af Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 20 Dec 2016 22:43:56 +0100 Subject: [PATCH 1217/1223] Bump man pages --- contrib/debian/manpages/bitcoin-cli.1 | 95 ++++- contrib/debian/manpages/bitcoin-qt.1 | 502 +++++++++++++++++++++++++- contrib/debian/manpages/bitcoin-tx.1 | 107 ++++++ contrib/debian/manpages/bitcoind.1 | 496 +++++++++++++++++++++++-- 4 files changed, 1154 insertions(+), 46 deletions(-) create mode 100644 contrib/debian/manpages/bitcoin-tx.1 diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 index 16c338dd3..dbd4745d1 100644 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -1,21 +1,84 @@ -.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-CLI "1" "December 2016" "bitcoin-cli v0.13.2.0" "User Commands" .SH NAME -bitcoin-cli \- a remote procedure call client for Bitcoin Core. -.SH SYNOPSIS -bitcoin-cli [options] [params] \- Send command to Bitcoin Core. -.TP -bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands. +bitcoin-cli \- manual page for bitcoin-cli v0.13.2.0 .SH DESCRIPTION -This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core. - -.SH OPTIONS +Bitcoin Core RPC client version v0.13.2.0 +.SS "Usage:" .TP -\fB\-?\fR -Show possible options. +bitcoin\-cli [options] [params] +Send command to Bitcoin Core +.TP +bitcoin\-cli [options] help +List commands +.TP +bitcoin\-cli [options] help +Get help for a command +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing +tools and app development. +.HP +\fB\-rpcconnect=\fR +.IP +Send commands to node running on (default: 127.0.0.1) +.HP +\fB\-rpcport=\fR +.IP +Connect to JSON\-RPC on (default: 8332 or testnet: 18332) +.HP +\fB\-rpcwait\fR +.IP +Wait for RPC server to start +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcclienttimeout=\fR +.IP +Timeout during HTTP requests (default: 900) +.HP +\fB\-stdin\fR +.IP +Read extra arguments from standard input, one per line until EOF/Ctrl\-D +(recommended for sensitive information such as passphrases) +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers -.SH "SEE ALSO" -\fBbitcoind\fP, \fBbitcoin.conf\fP -.SH AUTHOR -This manual page was written by Ciemon Dunville . Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . -The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP. +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index 685a28208..e14e1480a 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -1,13 +1,501 @@ -.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-QT "1" "December 2016" "bitcoin-qt v0.13.2.0" "User Commands" .SH NAME -bitcoin-qt \- peer-to-peer network based digital currency +bitcoin-qt \- manual page for bitcoin-qt v0.13.2.0 .SH DESCRIPTION -.SS "Usage:" +Bitcoin Core version v0.13.2.0 (64\-bit) +Usage: .IP bitcoin\-qt [command\-line options] .SH OPTIONS -.TP +.HP \-? -List options. -.SH "SEE ALSO" -bitcoind(1) +.IP +Print this help message and exit +.HP +\fB\-version\fR +.IP +Print version and exit +.HP +\fB\-alertnotify=\fR +.IP +Execute command when a relevant alert is received or we see a really +long fork (%s in cmd is replaced by message) +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-checkblocks=\fR +.IP +How many blocks to check at startup (default: 6, 0 = all) +.HP +\fB\-checklevel=\fR +.IP +How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Set database cache size in megabytes (4 to 16384, default: 300) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external blk000??.dat file on startup +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +72) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = +leave that many cores free, default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by pruning (deleting) old blocks. This mode +is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting +this setting requires re\-downloading the entire blockchain. +(default: 0 = disable pruning blocks, >550 = target size in MiB +to use for block files) +.HP +\fB\-reindex\-chainstate\fR +.IP +Rebuild chain state from the currently indexed blocks +.HP +\fB\-reindex\fR +.IP +Rebuild chain state and block index from the blk*.dat files on disk +.HP +\fB\-sysperms\fR +.IP +Create new files with system default permissions, instead of umask 077 +(only effective with disabled wallet functionality) +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +Add a node to connect to and attempt to keep the connection open +.HP +\fB\-banscore=\fR +.IP +Threshold for disconnecting misbehaving peers (default: 100) +.HP +\fB\-bantime=\fR +.IP +Number of seconds to keep misbehaving peers from reconnecting (default: +86400) +.HP +\fB\-bind=\fR +.IP +Bind to given address and always listen on it. Use [host]:port notation +for IPv6 +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node(s) +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor hidden service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most connections to peers (default: 125) +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection send buffer, *1000 bytes (default: 1000) +.HP +\fB\-maxtimeadjustment\fR +.IP +Maximum allowed median peer time offset adjustment. Local perspective of +time may be influenced by peers forward or backward by this +amount. (default: 4200 seconds) +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor hidden services +(default: \fB\-proxy\fR) +.HP +\fB\-onlynet=\fR +.IP +Only connect to nodes in network (ipv4, ipv6 or onion) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay non\-P2SH multisig (default: 1) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +1) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333 or testnet: 18333) +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect +.HP +\fB\-timeout=\fR +.IP +Specify connection timeout in milliseconds (minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control port to use if onion listening enabled (default: +127.0.0.1:9051) +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-whitebind=\fR +.IP +Bind to given address and whitelist peers connecting to it. Use +[host]:port notation for IPv6 +.HP +\fB\-whitelist=\fR +.IP +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple +times. Whitelisted peers cannot be DoS banned and their +transactions are always relayed, even if they are already in the +mempool, useful e.g. for a gateway +.HP +\fB\-whitelistrelay\fR +.IP +Accept relayed transactions received from whitelisted peers even when +not relaying transactions (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Force relay of transactions from whitelisted peers even if they violate +local relay policy (default: 1) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target (in MiB per 24h), +0 = no limit (default: 0) +.PP +Wallet options: +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 100) +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kB) that will be used when fee estimation has +insufficient data (default: 0.0002) +.HP +\fB\-mintxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee (in BTC/kB) to add to transactions you send (default: 0.00) +.HP +\fB\-rescan\fR +.IP +Rescan the block chain for missing wallet transactions on startup +.HP +\fB\-salvagewallet\fR +.IP +Attempt to recover private keys from a corrupt wallet on startup +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 2) +.HP +\fB\-usehd\fR +.IP +Use hierarchical deterministic key generation (HD) after BIP32. Only has +effect during wallet creation/first start (default: 1) +.HP +\fB\-upgradewallet\fR +.IP +Upgrade wallet to latest format on startup +.HP +\fB\-wallet=\fR +.IP +Specify wallet file (within data directory) (default: wallet.dat) +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes (%s in cmd is replaced +by TxID) +.HP +\fB\-zapwallettxes=\fR +.IP +Delete all wallet transactions and only recover those parts of the +blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. +account owner and payment request information, 2 = drop tx meta +data) +.PP +Debugging/Testing options: +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.HP +\fB\-debug=\fR +.IP +Output debugging information (default: 0, supplying is +optional). If is not supplied or if = 1, +output all debugging information. can be: addrman, +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq, qt. +.HP +\fB\-help\-debug\fR +.IP +Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for relaying, +mining and transaction creation (default: 0.00001) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction or raw +transaction; setting this too low may abort large transactions +(default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console instead of debug.log file +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Maximum size of data in data carrier transactions we relay and mine +(default: 83) +.HP +\fB\-mempoolreplacement\fR +.IP +Enable transaction replacement in the memory pool (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 3000000) +.HP +\fB\-blockmaxsize=\fR +.IP +Set maximum block size in bytes (default: 750000) +.HP +\fB\-blockprioritysize=\fR +.IP +Set maximum size of high\-priority/low\-fee transactions in bytes +(default: 0) +.PP +RPC server options: +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcbind=\fR +.IP +Bind to given address to listen for JSON\-RPC connections. Use +[host]:port notation for IPv6. This option can be specified +multiple times (default: bind to all interfaces) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie (default: data dir) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcauth=\fR +.IP +Username and hashed password for JSON\-RPC connections. The field + comes in the format: :$. A +canonical python script is included in share/rpcuser. This option +can be specified multiple times +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332 or testnet: +18332) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid for are a +single IP (e.g. 1.2.3.4), a network/netmask (e.g. +1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This +option can be specified multiple times +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 4) +.PP +UI Options: +.HP +\fB\-choosedatadir\fR +.IP +Choose data directory on startup (default: 0) +.HP +\fB\-lang=\fR +.IP +Set language, for example "de_DE" (default: system locale) +.HP +\fB\-min\fR +.IP +Start minimized +.HP +\fB\-rootcertificates=\fR +.IP +Set SSL root certificates for payment request (default: \fB\-system\-\fR) +.HP +\fB\-splash\fR +.IP +Show splash screen on startup (default: 1) +.HP +\fB\-resetguisettings\fR +.IP +Reset all settings changed in the GUI +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers + +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-tx.1 b/contrib/debian/manpages/bitcoin-tx.1 new file mode 100644 index 000000000..0cbb4ad58 --- /dev/null +++ b/contrib/debian/manpages/bitcoin-tx.1 @@ -0,0 +1,107 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-TX "1" "December 2016" "bitcoin-tx v0.13.2.0" "User Commands" +.SH NAME +bitcoin-tx \- manual page for bitcoin-tx v0.13.2.0 +.SH DESCRIPTION +Bitcoin Core bitcoin\-tx utility version v0.13.2.0 +.SS "Usage:" +.TP +bitcoin\-tx [options] [commands] +Update hex\-encoded bitcoin transaction +.TP +bitcoin\-tx [options] \fB\-create\fR [commands] +Create hex\-encoded bitcoin transaction +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-create\fR +.IP +Create new, empty TX. +.HP +\fB\-json\fR +.IP +Select JSON output +.HP +\fB\-txid\fR +.IP +Output only the hex\-encoded transaction id of the resultant transaction. +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing +tools and app development. +.PP +Commands: +.IP +delin=N +.IP +Delete input N from TX +.IP +delout=N +.IP +Delete output N from TX +.IP +in=TXID:VOUT(:SEQUENCE_NUMBER) +.IP +Add input to TX +.IP +locktime=N +.IP +Set TX lock time to N +.IP +nversion=N +.IP +Set TX version to N +.IP +outaddr=VALUE:ADDRESS +.IP +Add address\-based output to TX +.IP +outdata=[VALUE:]DATA +.IP +Add data\-based output to TX +.IP +outscript=VALUE:SCRIPT +.IP +Add raw script output to TX +.IP +sign=SIGHASH\-FLAGS +.IP +Add zero or more signatures to transaction. This command requires JSON +registers:prevtxs=JSON object, privatekeys=JSON object. See +signrawtransaction docs for format of sighash flags, JSON +objects. +.PP +Register Commands: +.IP +load=NAME:FILENAME +.IP +Load JSON file FILENAME into register NAME +.IP +set=NAME:JSON\-STRING +.IP +Set register NAME to given JSON\-STRING +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers + +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index 5c3e52f44..3b83f52cc 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -1,30 +1,480 @@ -.TH BITCOIND "1" "February 2016" "bitcoind 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIND "1" "December 2016" "bitcoind v0.13.2.0" "User Commands" .SH NAME -bitcoind \- peer-to-peer network based digital currency -.SH SYNOPSIS -bitcoin [options] [params] -.TP -bitcoin [options] help \- Get help for a command +bitcoind \- manual page for bitcoind v0.13.2.0 .SH DESCRIPTION -This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. - +Bitcoin Core Daemon version v0.13.2.0 +.SS "Usage:" +.TP +bitcoind [options] +Start Bitcoin Core Daemon .SH OPTIONS -.TP +.HP \-? -List of possible options. -.SH COMMANDS -.TP -\fBhelp\fR -List commands. +.IP +Print this help message and exit +.HP +\fB\-version\fR +.IP +Print version and exit +.HP +\fB\-alertnotify=\fR +.IP +Execute command when a relevant alert is received or we see a really +long fork (%s in cmd is replaced by message) +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-checkblocks=\fR +.IP +How many blocks to check at startup (default: 6, 0 = all) +.HP +\fB\-checklevel=\fR +.IP +How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-daemon\fR +.IP +Run in the background as a daemon and accept commands +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Set database cache size in megabytes (4 to 16384, default: 300) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external blk000??.dat file on startup +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +72) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = +leave that many cores free, default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by pruning (deleting) old blocks. This mode +is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting +this setting requires re\-downloading the entire blockchain. +(default: 0 = disable pruning blocks, >550 = target size in MiB +to use for block files) +.HP +\fB\-reindex\-chainstate\fR +.IP +Rebuild chain state from the currently indexed blocks +.HP +\fB\-reindex\fR +.IP +Rebuild chain state and block index from the blk*.dat files on disk +.HP +\fB\-sysperms\fR +.IP +Create new files with system default permissions, instead of umask 077 +(only effective with disabled wallet functionality) +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +Add a node to connect to and attempt to keep the connection open +.HP +\fB\-banscore=\fR +.IP +Threshold for disconnecting misbehaving peers (default: 100) +.HP +\fB\-bantime=\fR +.IP +Number of seconds to keep misbehaving peers from reconnecting (default: +86400) +.HP +\fB\-bind=\fR +.IP +Bind to given address and always listen on it. Use [host]:port notation +for IPv6 +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node(s) +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor hidden service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most connections to peers (default: 125) +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection send buffer, *1000 bytes (default: 1000) +.HP +\fB\-maxtimeadjustment\fR +.IP +Maximum allowed median peer time offset adjustment. Local perspective of +time may be influenced by peers forward or backward by this +amount. (default: 4200 seconds) +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor hidden services +(default: \fB\-proxy\fR) +.HP +\fB\-onlynet=\fR +.IP +Only connect to nodes in network (ipv4, ipv6 or onion) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay non\-P2SH multisig (default: 1) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +1) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333 or testnet: 18333) +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect +.HP +\fB\-timeout=\fR +.IP +Specify connection timeout in milliseconds (minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control port to use if onion listening enabled (default: +127.0.0.1:9051) +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-whitebind=\fR +.IP +Bind to given address and whitelist peers connecting to it. Use +[host]:port notation for IPv6 +.HP +\fB\-whitelist=\fR +.IP +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple +times. Whitelisted peers cannot be DoS banned and their +transactions are always relayed, even if they are already in the +mempool, useful e.g. for a gateway +.HP +\fB\-whitelistrelay\fR +.IP +Accept relayed transactions received from whitelisted peers even when +not relaying transactions (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Force relay of transactions from whitelisted peers even if they violate +local relay policy (default: 1) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target (in MiB per 24h), +0 = no limit (default: 0) +.PP +Wallet options: +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 100) +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kB) that will be used when fee estimation has +insufficient data (default: 0.0002) +.HP +\fB\-mintxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee (in BTC/kB) to add to transactions you send (default: 0.00) +.HP +\fB\-rescan\fR +.IP +Rescan the block chain for missing wallet transactions on startup +.HP +\fB\-salvagewallet\fR +.IP +Attempt to recover private keys from a corrupt wallet on startup +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 2) +.HP +\fB\-usehd\fR +.IP +Use hierarchical deterministic key generation (HD) after BIP32. Only has +effect during wallet creation/first start (default: 1) +.HP +\fB\-upgradewallet\fR +.IP +Upgrade wallet to latest format on startup +.HP +\fB\-wallet=\fR +.IP +Specify wallet file (within data directory) (default: wallet.dat) +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes (%s in cmd is replaced +by TxID) +.HP +\fB\-zapwallettxes=\fR +.IP +Delete all wallet transactions and only recover those parts of the +blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. +account owner and payment request information, 2 = drop tx meta +data) +.PP +Debugging/Testing options: +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.HP +\fB\-debug=\fR +.IP +Output debugging information (default: 0, supplying is +optional). If is not supplied or if = 1, +output all debugging information. can be: addrman, +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq. +.HP +\fB\-help\-debug\fR +.IP +Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for relaying, +mining and transaction creation (default: 0.00001) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction or raw +transaction; setting this too low may abort large transactions +(default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console instead of debug.log file +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Maximum size of data in data carrier transactions we relay and mine +(default: 83) +.HP +\fB\-mempoolreplacement\fR +.IP +Enable transaction replacement in the memory pool (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 3000000) +.HP +\fB\-blockmaxsize=\fR +.IP +Set maximum block size in bytes (default: 750000) +.HP +\fB\-blockprioritysize=\fR +.IP +Set maximum size of high\-priority/low\-fee transactions in bytes +(default: 0) +.PP +RPC server options: +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcbind=\fR +.IP +Bind to given address to listen for JSON\-RPC connections. Use +[host]:port notation for IPv6. This option can be specified +multiple times (default: bind to all interfaces) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie (default: data dir) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcauth=\fR +.IP +Username and hashed password for JSON\-RPC connections. The field + comes in the format: :$. A +canonical python script is included in share/rpcuser. This option +can be specified multiple times +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332 or testnet: +18332) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid for are a +single IP (e.g. 1.2.3.4), a network/netmask (e.g. +1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This +option can be specified multiple times +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 4) +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers -.TP -\fBhelp 'command'\fR -Get help for a command. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . -.SH "SEE ALSO" -bitcoin.conf(5) -.SH AUTHOR -This manual page was written by Micah Anderson for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation. - -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. From 0d719145b018e28d48d35c2646a5962b87c60436 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 2 Jan 2017 09:54:25 +0100 Subject: [PATCH 1218/1223] doc: Remove ... from release notes --- doc/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 9d35d8e5f..45fff5c8b 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -2,7 +2,7 @@ Bitcoin Core version 0.13.2 is now available from: -This is a new minor version release, including ..., various bugfixes and +This is a new minor version release, including various bugfixes and performance improvements, as well as updated translations. Please report bugs using the issue tracker at github: From 77eaadb6c9619370b09513fecba13cfe656d63d6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 3 Jan 2017 11:50:57 +0100 Subject: [PATCH 1219/1223] doc: Clean out release notes on 0.13.x branch Move old release notes to historical release notes. --- doc/release-notes.md | 125 +-------------- doc/release-notes/release-notes-0.13.2.md | 178 ++++++++++++++++++++++ 2 files changed, 184 insertions(+), 119 deletions(-) create mode 100644 doc/release-notes/release-notes-0.13.2.md diff --git a/doc/release-notes.md b/doc/release-notes.md index 45fff5c8b..955a45a40 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 0.13.2 is now available from: +Bitcoin Core version 0.13.x is now available from: - + This is a new minor version release, including various bugfixes and performance improvements, as well as updated translations. @@ -42,25 +42,10 @@ but severe issues with the libc++ version on 10.7.x keep it from running reliabl Notable changes =============== -Change to wallet handling of mempool rejection +Example item ----------------------------------------------- -When a newly created transaction failed to enter the mempool due to -the limits on chains of unconfirmed transactions the sending RPC -calls would return an error. The transaction would still be queued -in the wallet and, once some of the parent transactions were -confirmed, broadcast after the software was restarted. - -This behavior has been changed to return success and to reattempt -mempool insertion at the same time transaction rebroadcast is -attempted, avoiding a need for a restart. - -Transactions in the wallet which cannot be accepted into the mempool -can be abandoned with the previously existing abandontransaction RPC -(or in the GUI via a context menu on the transaction). - - -0.13.2 Change log +0.13.x Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -68,111 +53,13 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -### Consensus -- #9293 `e591c10` [0.13 Backport #9053] IBD using chainwork instead of height and not using header timestamp (gmaxwell) -- #9053 `5b93eee` IBD using chainwork instead of height and not using header timestamps (gmaxwell) - -### RPC and other APIs -- #8845 `1d048b9` Don't return the address of a P2SH of a P2SH (jnewbery) -- #9041 `87fbced` keypoololdest denote Unix epoch, not GMT (s-matthew-english) -- #9122 `f82c81b` fix getnettotals RPC description about timemillis (visvirial) -- #9042 `5bcb05d` [rpc] ParseHash: Fail when length is not 64 (MarcoFalke) -- #9194 `f26dab7` Add option to return non-segwit serialization via rpc (instagibbs) -- #9347 `b711390` [0.13.2] wallet/rpc backports (MarcoFalke) -- #9292 `c365556` Complain when unknown rpcserialversion is specified (sipa) -- #9322 `49a612f` [qa] Don't set unknown rpcserialversion (MarcoFalke) - -### Block and transaction handling -- #8357 `ce0d817` [mempool] Fix relaypriority calculation error (maiiz) -- #9267 `0a4aa87` [0.13 backport #9239] Disable fee estimates for a confirm target of 1 block (morcos) -- #9196 `0c09d9f` Send tip change notification from invalidateblock (ryanofsky) - -### P2P protocol and network code -- #8995 `9ef3875` Add missing cs_main lock to ::GETBLOCKTXN processing (TheBlueMatt) -- #9234 `94531b5` torcontrol: Explicitly request RSA1024 private key (laanwj) -- #8637 `2cad5db` Compact Block Tweaks (rebase of #8235) (sipa) -- #9058 `286e548` Fixes for p2p-compactblocks.py test timeouts on travis (#8842) (ryanofsky) -- #8865 `4c71fc4` Decouple peer-processing-logic from block-connection-logic (TheBlueMatt) -- #9117 `6fe3981` net: don't send feefilter messages before the version handshake is complete (theuni) -- #9188 `ca1fd75` Make orphan parent fetching ask for witnesses (gmaxwell) -- #9052 `3a3bcbf` Use RelevantServices instead of node_network in AttemptToEvict (gmaxwell) -- #9048 `9460771` [0.13 backport #9026] Fix handling of invalid compact blocks (sdaftuar) -- #9357 `03b6f62` [0.13 backport #9352] Attempt reconstruction from all compact block announcements (sdaftuar) -- #9189 `b96a8f7` Always add default_witness_commitment with GBT client support (sipa) -- #9253 `28d0f22` Fix calculation of number of bound sockets to use (TheBlueMatt) -- #9199 `da5a16b` Always drop the least preferred HB peer when adding a new one (gmaxwell) - -### Build system -- #9169 `d1b4da9` build: fix qt5.7 build under macOS (theuni) -- #9326 `a0f7ece` Update for OpenSSL 1.1 API (gmaxwell) -- #9224 `396c405` Prevent FD_SETSIZE error building on OpenBSD (ivdsangen) - -### GUI -- #8972 `6f86b53` Make warnings label selectable (jonasschnelli) (MarcoFalke) -- #9185 `6d70a73` Fix coincontrol sort issue (jonasschnelli) -- #9094 `5f3a12c` Use correct conversion function for boost::path datadir (laanwj) -- #8908 `4a974b2` Update bitcoin-qt.desktop (s-matthew-english) -- #9190 `dc46b10` Plug many memory leaks (laanwj) - -### Wallet -- #9290 `35174a0` Make RelayWalletTransaction attempt to AcceptToMemoryPool (gmaxwell) -- #9295 `43bcfca` Bugfix: Fundrawtransaction: don't terminate when keypool is empty (jonasschnelli) -- #9302 `f5d606e` Return txid even if ATMP fails for new transaction (sipa) -- #9262 `fe39f26` Prefer coins that have fewer ancestors, sanity check txn before ATMP (instagibbs) - -### Tests and QA -- #9159 `eca9b46` Wait for specific block announcement in p2p-compactblocks (ryanofsky) -- #9186 `dccdc3a` Fix use-after-free in scheduler tests (laanwj) -- #9168 `3107280` Add assert_raises_message to check specific error message (mrbandrews) -- #9191 `29435db` 0.13.2 Backports (MarcoFalke) -- #9077 `1d4c884` Increase wallet-dump RPC timeout (ryanofsky) -- #9098 `ecd7db5` Handle zombies and cluttered tmpdirs (MarcoFalke) -- #8927 `387ec9d` Add script tests for FindAndDelete in pre-segwit and segwit scripts (jl2012) -- #9200 `eebc699` bench: Fix subtle counting issue when rescaling iteration count (laanwj) - -### Miscellaneous -- #8838 `094848b` Calculate size and weight of block correctly in CreateNewBlock() (jnewbery) -- #8920 `40169dc` Set minimum required Boost to 1.47.0 (fanquake) -- #9251 `a710a43` Improvement of documentation of command line parameter 'whitelist' (wodry) -- #8932 `106da69` Allow bitcoin-tx to create v2 transactions (btcdrak) -- #8929 `12428b4` add software-properties-common (sigwo) -- #9120 `08d1c90` bug: Missed one "return false" in recent refactoring in #9067 (UdjinM6) -- #9067 `f85ee01` Fix exit codes (UdjinM6) -- #9340 `fb987b3` [0.13] Update secp256k1 subtree (MarcoFalke) -- #9229 `b172377` Remove calls to getaddrinfo_a (TheBlueMatt) +[to be filled in at release] Credits ======= Thanks to everyone who directly contributed to this release: -- Alex Morcos -- BtcDrak -- Cory Fields -- fanquake -- Gregory Maxwell -- Gregory Sanders -- instagibbs -- Ivo van der Sangen -- jnewbery -- Johnson Lau -- Jonas Schnelli -- Luke Dashjr -- maiiz -- MarcoFalke -- Masahiko Hyuga -- Matt Corallo -- matthias -- mrbandrews -- Pavel Janík -- Pieter Wuille -- randy-waterhouse -- Russell Yanofsky -- S. Matthew English -- Steven -- Suhas Daftuar -- UdjinM6 -- Wladimir J. van der Laan -- wodry +[to be filled in at release] As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.13.2.md b/doc/release-notes/release-notes-0.13.2.md new file mode 100644 index 000000000..45fff5c8b --- /dev/null +++ b/doc/release-notes/release-notes-0.13.2.md @@ -0,0 +1,178 @@ +Bitcoin Core version 0.13.2 is now available from: + + + +This is a new minor version release, including various bugfixes and +performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer version of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + +Notable changes +=============== + +Change to wallet handling of mempool rejection +----------------------------------------------- + +When a newly created transaction failed to enter the mempool due to +the limits on chains of unconfirmed transactions the sending RPC +calls would return an error. The transaction would still be queued +in the wallet and, once some of the parent transactions were +confirmed, broadcast after the software was restarted. + +This behavior has been changed to return success and to reattempt +mempool insertion at the same time transaction rebroadcast is +attempted, avoiding a need for a restart. + +Transactions in the wallet which cannot be accepted into the mempool +can be abandoned with the previously existing abandontransaction RPC +(or in the GUI via a context menu on the transaction). + + +0.13.2 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### Consensus +- #9293 `e591c10` [0.13 Backport #9053] IBD using chainwork instead of height and not using header timestamp (gmaxwell) +- #9053 `5b93eee` IBD using chainwork instead of height and not using header timestamps (gmaxwell) + +### RPC and other APIs +- #8845 `1d048b9` Don't return the address of a P2SH of a P2SH (jnewbery) +- #9041 `87fbced` keypoololdest denote Unix epoch, not GMT (s-matthew-english) +- #9122 `f82c81b` fix getnettotals RPC description about timemillis (visvirial) +- #9042 `5bcb05d` [rpc] ParseHash: Fail when length is not 64 (MarcoFalke) +- #9194 `f26dab7` Add option to return non-segwit serialization via rpc (instagibbs) +- #9347 `b711390` [0.13.2] wallet/rpc backports (MarcoFalke) +- #9292 `c365556` Complain when unknown rpcserialversion is specified (sipa) +- #9322 `49a612f` [qa] Don't set unknown rpcserialversion (MarcoFalke) + +### Block and transaction handling +- #8357 `ce0d817` [mempool] Fix relaypriority calculation error (maiiz) +- #9267 `0a4aa87` [0.13 backport #9239] Disable fee estimates for a confirm target of 1 block (morcos) +- #9196 `0c09d9f` Send tip change notification from invalidateblock (ryanofsky) + +### P2P protocol and network code +- #8995 `9ef3875` Add missing cs_main lock to ::GETBLOCKTXN processing (TheBlueMatt) +- #9234 `94531b5` torcontrol: Explicitly request RSA1024 private key (laanwj) +- #8637 `2cad5db` Compact Block Tweaks (rebase of #8235) (sipa) +- #9058 `286e548` Fixes for p2p-compactblocks.py test timeouts on travis (#8842) (ryanofsky) +- #8865 `4c71fc4` Decouple peer-processing-logic from block-connection-logic (TheBlueMatt) +- #9117 `6fe3981` net: don't send feefilter messages before the version handshake is complete (theuni) +- #9188 `ca1fd75` Make orphan parent fetching ask for witnesses (gmaxwell) +- #9052 `3a3bcbf` Use RelevantServices instead of node_network in AttemptToEvict (gmaxwell) +- #9048 `9460771` [0.13 backport #9026] Fix handling of invalid compact blocks (sdaftuar) +- #9357 `03b6f62` [0.13 backport #9352] Attempt reconstruction from all compact block announcements (sdaftuar) +- #9189 `b96a8f7` Always add default_witness_commitment with GBT client support (sipa) +- #9253 `28d0f22` Fix calculation of number of bound sockets to use (TheBlueMatt) +- #9199 `da5a16b` Always drop the least preferred HB peer when adding a new one (gmaxwell) + +### Build system +- #9169 `d1b4da9` build: fix qt5.7 build under macOS (theuni) +- #9326 `a0f7ece` Update for OpenSSL 1.1 API (gmaxwell) +- #9224 `396c405` Prevent FD_SETSIZE error building on OpenBSD (ivdsangen) + +### GUI +- #8972 `6f86b53` Make warnings label selectable (jonasschnelli) (MarcoFalke) +- #9185 `6d70a73` Fix coincontrol sort issue (jonasschnelli) +- #9094 `5f3a12c` Use correct conversion function for boost::path datadir (laanwj) +- #8908 `4a974b2` Update bitcoin-qt.desktop (s-matthew-english) +- #9190 `dc46b10` Plug many memory leaks (laanwj) + +### Wallet +- #9290 `35174a0` Make RelayWalletTransaction attempt to AcceptToMemoryPool (gmaxwell) +- #9295 `43bcfca` Bugfix: Fundrawtransaction: don't terminate when keypool is empty (jonasschnelli) +- #9302 `f5d606e` Return txid even if ATMP fails for new transaction (sipa) +- #9262 `fe39f26` Prefer coins that have fewer ancestors, sanity check txn before ATMP (instagibbs) + +### Tests and QA +- #9159 `eca9b46` Wait for specific block announcement in p2p-compactblocks (ryanofsky) +- #9186 `dccdc3a` Fix use-after-free in scheduler tests (laanwj) +- #9168 `3107280` Add assert_raises_message to check specific error message (mrbandrews) +- #9191 `29435db` 0.13.2 Backports (MarcoFalke) +- #9077 `1d4c884` Increase wallet-dump RPC timeout (ryanofsky) +- #9098 `ecd7db5` Handle zombies and cluttered tmpdirs (MarcoFalke) +- #8927 `387ec9d` Add script tests for FindAndDelete in pre-segwit and segwit scripts (jl2012) +- #9200 `eebc699` bench: Fix subtle counting issue when rescaling iteration count (laanwj) + +### Miscellaneous +- #8838 `094848b` Calculate size and weight of block correctly in CreateNewBlock() (jnewbery) +- #8920 `40169dc` Set minimum required Boost to 1.47.0 (fanquake) +- #9251 `a710a43` Improvement of documentation of command line parameter 'whitelist' (wodry) +- #8932 `106da69` Allow bitcoin-tx to create v2 transactions (btcdrak) +- #8929 `12428b4` add software-properties-common (sigwo) +- #9120 `08d1c90` bug: Missed one "return false" in recent refactoring in #9067 (UdjinM6) +- #9067 `f85ee01` Fix exit codes (UdjinM6) +- #9340 `fb987b3` [0.13] Update secp256k1 subtree (MarcoFalke) +- #9229 `b172377` Remove calls to getaddrinfo_a (TheBlueMatt) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Alex Morcos +- BtcDrak +- Cory Fields +- fanquake +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- Ivo van der Sangen +- jnewbery +- Johnson Lau +- Jonas Schnelli +- Luke Dashjr +- maiiz +- MarcoFalke +- Masahiko Hyuga +- Matt Corallo +- matthias +- mrbandrews +- Pavel Janík +- Pieter Wuille +- randy-waterhouse +- Russell Yanofsky +- S. Matthew English +- Steven +- Suhas Daftuar +- UdjinM6 +- Wladimir J. van der Laan +- wodry + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). From 59c37ae55a476d3cf84c9bafbc083904472fe4db Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Fri, 16 Dec 2016 16:52:35 +0900 Subject: [PATCH 1220/1223] Uses built-in byte swap if available (Apple) and if bswap_XX is undefined. Defers to pre-defined version if found (e.g. protobuf). For protobuf case, the definitions are identical and thus include order should not affect results. Github-Pull: #9366 Rebased-From: 815f4148b2eff6c64c764e910e79677d5a67adc7 --- src/Makefile.qttest.include | 6 +++++- src/Makefile.test.include | 1 + src/compat/byteswap.h | 19 +++++++++++++++++++ src/qt/test/compattests.cpp | 23 +++++++++++++++++++++++ src/qt/test/compattests.h | 19 +++++++++++++++++++ src/qt/test/test_main.cpp | 4 ++++ src/test/bswap_tests.cpp | 26 ++++++++++++++++++++++++++ 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/qt/test/compattests.cpp create mode 100644 src/qt/test/compattests.h create mode 100644 src/test/bswap_tests.cpp diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index a071fe136..22c5f6a0b 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -5,13 +5,16 @@ bin_PROGRAMS += qt/test/test_bitcoin-qt TESTS += qt/test/test_bitcoin-qt -TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp +TEST_QT_MOC_CPP = \ + qt/test/moc_compattests.cpp \ + qt/test/moc_uritests.cpp if ENABLE_WALLET TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp endif TEST_QT_H = \ + qt/test/compattests.h \ qt/test/uritests.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h @@ -20,6 +23,7 @@ qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) qt_test_test_bitcoin_qt_SOURCES = \ + qt/test/compattests.cpp \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ $(TEST_QT_H) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 0878d8234..256563332 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -50,6 +50,7 @@ BITCOIN_TESTS =\ test/bip32_tests.cpp \ test/blockencodings_tests.cpp \ test/bloom_tests.cpp \ + test/bswap_tests.cpp \ test/coins_tests.cpp \ test/compress_tests.cpp \ test/crypto_tests.cpp \ diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h index 899220bdc..5c86499d7 100644 --- a/src/compat/byteswap.h +++ b/src/compat/byteswap.h @@ -15,6 +15,23 @@ #include #endif +#if defined(__APPLE__) + +#if !defined(bswap_16) + +// Mac OS X / Darwin features; we include a check for bswap_16 because if it is already defined, protobuf has +// defined these macros for us already; if it isn't, we do it ourselves. In either case, we get the exact same +// result regardless which path was taken +#include +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#endif // !defined(bswap_16) + +#else +// Non-Mac OS X / non-Darwin + #if HAVE_DECL_BSWAP_16 == 0 inline uint16_t bswap_16(uint16_t x) { @@ -44,4 +61,6 @@ inline uint64_t bswap_64(uint64_t x) } #endif // HAVE_DECL_BSWAP64 +#endif // defined(__APPLE__) + #endif // BITCOIN_COMPAT_BYTESWAP_H diff --git a/src/qt/test/compattests.cpp b/src/qt/test/compattests.cpp new file mode 100644 index 000000000..2a7284b5b --- /dev/null +++ b/src/qt/test/compattests.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "paymentrequestplus.h" // this includes protobuf's port.h which defines its own bswap macos + +#include "compattests.h" + +#include "compat/byteswap.h" + +void CompatTests::bswapTests() +{ + // Sibling in bitcoin/src/test/bswap_tests.cpp + uint16_t u1 = 0x1234; + uint32_t u2 = 0x56789abc; + uint64_t u3 = 0xdef0123456789abc; + uint16_t e1 = 0x3412; + uint32_t e2 = 0xbc9a7856; + uint64_t e3 = 0xbc9a78563412f0de; + QVERIFY(bswap_16(u1) == e1); + QVERIFY(bswap_32(u2) == e2); + QVERIFY(bswap_64(u3) == e3); +} diff --git a/src/qt/test/compattests.h b/src/qt/test/compattests.h new file mode 100644 index 000000000..35dede774 --- /dev/null +++ b/src/qt/test/compattests.h @@ -0,0 +1,19 @@ +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_TEST_COMPATTESTS_H +#define BITCOIN_QT_TEST_COMPATTESTS_H + +#include +#include + +class CompatTests : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void bswapTests(); +}; + +#endif // BITCOIN_QT_TEST_COMPATTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index db193420b..02650320b 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -8,6 +8,7 @@ #include "util.h" #include "uritests.h" +#include "compattests.h" #ifdef ENABLE_WALLET #include "paymentservertests.h" @@ -48,6 +49,9 @@ int main(int argc, char *argv[]) if (QTest::qExec(&test2) != 0) fInvalid = true; #endif + CompatTests test4; + if (QTest::qExec(&test4) != 0) + fInvalid = true; return fInvalid; } diff --git a/src/test/bswap_tests.cpp b/src/test/bswap_tests.cpp new file mode 100644 index 000000000..7b3134d32 --- /dev/null +++ b/src/test/bswap_tests.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "compat/byteswap.h" +#include "test/test_bitcoin.h" + +#include + +BOOST_FIXTURE_TEST_SUITE(bswap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(bswap_tests) +{ + // Sibling in bitcoin/src/qt/test/compattests.cpp + uint16_t u1 = 0x1234; + uint32_t u2 = 0x56789abc; + uint64_t u3 = 0xdef0123456789abc; + uint16_t e1 = 0x3412; + uint32_t e2 = 0xbc9a7856; + uint64_t e3 = 0xbc9a78563412f0de; + BOOST_CHECK(bswap_16(u1) == e1); + BOOST_CHECK(bswap_32(u2) == e2); + BOOST_CHECK(bswap_64(u3) == e3); +} + +BOOST_AUTO_TEST_SUITE_END() From c6811c1bd314f4297b22f12a4cefdd1bbbb0c749 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 21 Feb 2017 14:36:36 +0100 Subject: [PATCH 1221/1223] Fix segfault crash when shutdown the GUI in disablewallet mode Github-Pull: #9817 Rebased-From: 312c4f10574ccf6dfe0d4ecb3ce928733d3a1e52 --- src/qt/bitcoingui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1a5d27f6e..38cfc262b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -499,7 +499,10 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Propagate cleared model to child objects rpcConsole->setClientModel(nullptr); #ifdef ENABLE_WALLET - walletFrame->setClientModel(nullptr); + if (walletFrame) + { + walletFrame->setClientModel(nullptr); + } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(nullptr); } From 8adf75e6a124267da1ae46be1eee50c52ce6082b Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 17 May 2017 17:41:52 +0800 Subject: [PATCH 1222/1223] [depends] miniupnpc 2.0.20170509 Github-Pull: #10414 Rebased-From: af5d48c9a03182fdf121623bd98136b66d0fcb27 --- depends/packages/miniupnpc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index e34cf7be2..1bb8cb5d2 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=2.0 +$(package)_version=2.0.20170509 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b +$(package)_sha256_hash=d3c368627f5cdfb66d3ebd64ca39ba54d6ff14a61966dbecb8dd296b7039f16a define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" From b6548420291de0e077b02de71b4f2cea3dac0f8c Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Thu, 18 May 2017 16:57:53 -0400 Subject: [PATCH 1223/1223] Populate services in GetLocalAddress Previously if we didn't have any local addresses, GetLocalAddress would return 0.0.0.0 and then we'd swap in a peer's notion of our address in AdvertiseLocal, but then nServices would never get set. Github-Pull: #10424 Rebased-From: 307013469f9a3b8f13d3eb9dbeea419a55148493 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 7cb612ee9..0b8bfd860 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -179,7 +179,7 @@ static std::vector convertSeed6(const std::vector &vSeedsIn // one by discovery. CAddress GetLocalAddress(const CNetAddr *paddrPeer) { - CAddress ret(CService("0.0.0.0",GetListenPort()), NODE_NONE); + CAddress ret(CService("0.0.0.0",GetListenPort()), nLocalServices); CService addr; if (GetLocal(addr, paddrPeer)) {